Skip to content

Rollup of 10 pull requests #135465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Jan 14, 2025
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
15c01eb
Fix cycle error only occurring with -Zdump-mir
oli-obk Dec 18, 2024
57f9f8f
Add test for `mut arg: &Ty` meant to be `arg: &mut Ty`
estebank Dec 31, 2024
c2ae386
On E0308, detect `mut arg: &Ty` meant to be `arg: &mut Ty`
estebank Dec 31, 2024
ec98df4
On unused assign lint, detect `mut arg: &Ty` meant to be `arg: &mut Ty`
estebank Dec 31, 2024
4438b32
review comments and make test `run-rustfix`
estebank Jan 11, 2025
6f833aa
re-added regression test for #122638
ranger-ross Jan 12, 2025
87f03a4
rm unnecessary `OpaqueTypeDecl` wrapper
lcnr Jan 13, 2025
1b068a0
Make sure to mark IMPL_TRAIT_REDUNDANT_CAPTURES as Allow in edition 2024
compiler-errors Jan 13, 2025
b3ba4de
Update books
rustbot Jan 13, 2025
75f3ebd
Mark rustbook as an external tool
ehuss Jan 13, 2025
6e67ffa
uefi: helpers: Introduce OwnedDevicePath
Ayush1325 Jan 12, 2025
a9f3240
bootstrap: fix outdated feature name in comment
jieyouxu Jan 13, 2025
aa14931
llvm: Allow sized-word rather than ymmword in tests
maurer Jan 13, 2025
4d0a838
Fix emscripten-wasm-eh with unwind=abort
hoodmane Jan 13, 2025
81f7429
Rollup merge of #134498 - oli-obk:push-wmxynprsyxvr, r=compiler-errors
jhpratt Jan 14, 2025
54c324f
Rollup merge of #134977 - estebank:issue-112357, r=BoxyUwU
jhpratt Jan 14, 2025
f10513f
Rollup merge of #135390 - ranger-ross:readd-test-122638, r=BoxyUwU
jhpratt Jan 14, 2025
954b06f
Rollup merge of #135393 - Ayush1325:uefi-helper-path, r=thomcc
jhpratt Jan 14, 2025
9bdb601
Rollup merge of #135440 - lcnr:yeeeeeeeeeeeeeeeeeeeeeeet, r=compiler-…
jhpratt Jan 14, 2025
77b7ee1
Rollup merge of #135441 - compiler-errors:redundant-captures-lint, r=lqd
jhpratt Jan 14, 2025
78aa0b9
Rollup merge of #135444 - rustbot:docs-update, r=ehuss
jhpratt Jan 14, 2025
05ae6bf
Rollup merge of #135450 - hoodmane:wasm-eh-abort-fix, r=workingjubilee
jhpratt Jan 14, 2025
ab77d15
Rollup merge of #135452 - jieyouxu:fix-comment, r=compiler-errors
jhpratt Jan 14, 2025
9fdebf6
Rollup merge of #135454 - maurer:sized-word-ymmword, r=jieyouxu
jhpratt Jan 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -25,8 +25,8 @@ pub(super) fn take_opaques_and_register_member_constraints<'tcx>(
let opaque_types = infcx
.take_opaque_types()
.into_iter()
.map(|(opaque_type_key, decl)| {
let hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
.map(|(opaque_type_key, hidden_type)| {
let hidden_type = infcx.resolve_vars_if_possible(hidden_type);
register_member_constraints(
typeck,
&mut member_constraints,
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -2451,10 +2451,10 @@ fn add_order_independent_options(
}

if sess.target.os == "emscripten" {
cmd.cc_arg(if sess.panic_strategy() == PanicStrategy::Abort {
"-sDISABLE_EXCEPTION_CATCHING=1"
} else if sess.opts.unstable_opts.emscripten_wasm_eh {
cmd.cc_arg(if sess.opts.unstable_opts.emscripten_wasm_eh {
"-fwasm-exceptions"
} else if sess.panic_strategy() == PanicStrategy::Abort {
"-sDISABLE_EXCEPTION_CATCHING=1"
} else {
"-sDISABLE_EXCEPTION_CATCHING=0"
});
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
@@ -436,9 +436,9 @@ fn check_opaque_meets_bounds<'tcx>(
} else {
// Check that any hidden types found during wf checking match the hidden types that `type_of` sees.
for (mut key, mut ty) in infcx.take_opaque_types() {
ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty);
ty.ty = infcx.resolve_vars_if_possible(ty.ty);
key = infcx.resolve_vars_if_possible(key);
sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?;
sanity_check_found_hidden_type(tcx, key, ty)?;
}
Ok(())
}
@@ -1873,7 +1873,7 @@ pub(super) fn check_coroutine_obligations(
// Check that any hidden types found when checking these stalled coroutine obligations
// are valid.
for (key, ty) in infcx.take_opaque_types() {
let hidden_type = infcx.resolve_vars_if_possible(ty.hidden_type);
let hidden_type = infcx.resolve_vars_if_possible(ty);
let key = infcx.resolve_vars_if_possible(key);
sanity_check_found_hidden_type(tcx, key, hidden_type)?;
}
95 changes: 95 additions & 0 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
@@ -85,6 +85,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

self.annotate_expected_due_to_let_ty(err, expr, error);
self.annotate_loop_expected_due_to_inference(err, expr, error);
if self.annotate_mut_binding_to_immutable_binding(err, expr, error) {
return;
}

// FIXME(#73154): For now, we do leak check when coercing function
// pointers in typeck, instead of only during borrowck. This can lead
@@ -795,6 +798,98 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

/// Detect the following case
///
/// ```text
/// fn change_object(mut a: &Ty) {
/// let a = Ty::new();
/// b = a;
/// }
/// ```
///
/// where the user likely meant to modify the value behind there reference, use `a` as an out
/// parameter, instead of mutating the local binding. When encountering this we suggest:
///
/// ```text
/// fn change_object(a: &'_ mut Ty) {
/// let a = Ty::new();
/// *b = a;
/// }
/// ```
fn annotate_mut_binding_to_immutable_binding(
&self,
err: &mut Diag<'_>,
expr: &hir::Expr<'_>,
error: Option<TypeError<'tcx>>,
) -> bool {
if let Some(TypeError::Sorts(ExpectedFound { expected, found })) = error
&& let ty::Ref(_, inner, hir::Mutability::Not) = expected.kind()

// The difference between the expected and found values is one level of borrowing.
&& self.can_eq(self.param_env, *inner, found)

// We have an `ident = expr;` assignment.
&& let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
self.tcx.parent_hir_node(expr.hir_id)
&& rhs.hir_id == expr.hir_id

// We are assigning to some binding.
&& let hir::ExprKind::Path(hir::QPath::Resolved(
None,
hir::Path { res: hir::def::Res::Local(hir_id), .. },
)) = lhs.kind
&& let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id)

// The pattern we have is an fn argument.
&& let hir::Node::Param(hir::Param { ty_span, .. }) =
self.tcx.parent_hir_node(pat.hir_id)
&& let item = self.tcx.hir().get_parent_item(pat.hir_id)
&& let item = self.tcx.hir_owner_node(item)
&& let Some(fn_decl) = item.fn_decl()

// We have a mutable binding in the argument.
&& let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind

// Look for the type corresponding to the argument pattern we have in the argument list.
&& let Some(ty_sugg) = fn_decl
.inputs
.iter()
.filter_map(|ty| {
if ty.span == *ty_span
&& let hir::TyKind::Ref(lt, x) = ty.kind
{
// `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
Some((
x.ty.span.shrink_to_lo(),
format!(
"{}mut ",
if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " }
),
))
} else {
None
}
})
.next()
{
let sugg = vec![
ty_sugg,
(pat.span.until(ident.span), String::new()),
(lhs.span.shrink_to_lo(), "*".to_string()),
];
// We suggest changing the argument from `mut ident: &Ty` to `ident: &'_ mut Ty` and the
// assignment from `ident = val;` to `*ident = val;`.
err.multipart_suggestion_verbose(
"you might have meant to mutate the pointed at value being passed in, instead of \
changing the reference in the local binding",
sugg,
Applicability::MaybeIncorrect,
);
return true;
}
false
}

fn annotate_alternative_method_deref(
&self,
err: &mut Diag<'_>,
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
@@ -562,9 +562,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// types or by using this function at the end of writeback and running it as a
// fixpoint.
let opaque_types = self.fcx.infcx.clone_opaque_types();
for (opaque_type_key, decl) in opaque_types {
let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span);
let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span);
for (opaque_type_key, hidden_type) in opaque_types {
let hidden_type = self.resolve(hidden_type, &hidden_type.span);
let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span);

if !self.fcx.next_trait_solver() {
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
@@ -155,12 +155,12 @@ impl<'tcx> InferCtxt<'tcx> {
.opaque_type_storage
.opaque_types
.iter()
.map(|(k, v)| (*k, v.hidden_type.ty))
.map(|(k, v)| (*k, v.ty))
.collect()
}

fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
self.take_opaque_types().into_iter().map(|(k, v)| (k, v.hidden_type.ty)).collect()
self.take_opaque_types().into_iter().map(|(k, v)| (k, v.ty)).collect()
}

/// Given the (canonicalized) result to a canonical query,
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -234,7 +234,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
pub fn iter_opaque_types(
&self,
) -> impl Iterator<Item = (ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>)> + '_ {
self.opaque_type_storage.opaque_types.iter().map(|(&k, v)| (k, v.hidden_type))
self.opaque_type_storage.opaque_types.iter().map(|(&k, &v)| (k, v))
}
}

13 changes: 1 addition & 12 deletions compiler/rustc_infer/src/infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
@@ -19,20 +19,9 @@ use crate::traits::{self, Obligation, PredicateObligations};

mod table;

pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>;
pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};

/// Information about the opaque types whose values we
/// are inferring in this function (these are the `impl Trait` that
/// appear in the return type).
#[derive(Clone, Debug)]
pub struct OpaqueTypeDecl<'tcx> {
/// The hidden types that have been inferred for this opaque type.
/// There can be multiple, but they are all `lub`ed together at the end
/// to obtain the canonical hidden type.
pub hidden_type: OpaqueHiddenType<'tcx>,
}

impl<'tcx> InferCtxt<'tcx> {
/// This is a backwards compatibility hack to prevent breaking changes from
/// lazy TAIT around RPIT handling.
21 changes: 12 additions & 9 deletions compiler/rustc_infer/src/infer/opaque_types/table.rs
Original file line number Diff line number Diff line change
@@ -3,23 +3,27 @@ use rustc_middle::bug;
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
use tracing::instrument;

use super::{OpaqueTypeDecl, OpaqueTypeMap};
use super::OpaqueTypeMap;
use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};

#[derive(Default, Debug, Clone)]
pub(crate) struct OpaqueTypeStorage<'tcx> {
/// Opaque types found in explicit return types and their
/// associated fresh inference variable. Writeback resolves these
/// variables to get the concrete type, which can be used to
/// 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
/// 'de-opaque' OpaqueHiddenType, after typeck is done with all functions.
pub opaque_types: OpaqueTypeMap<'tcx>,
}

impl<'tcx> OpaqueTypeStorage<'tcx> {
#[instrument(level = "debug")]
pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
if let Some(idx) = idx {
self.opaque_types.get_mut(&key).unwrap().hidden_type = idx;
pub(crate) fn remove(
&mut self,
key: OpaqueTypeKey<'tcx>,
prev: Option<OpaqueHiddenType<'tcx>>,
) {
if let Some(prev) = prev {
*self.opaque_types.get_mut(&key).unwrap() = prev;
} else {
// FIXME(#120456) - is `swap_remove` correct?
match self.opaque_types.swap_remove(&key) {
@@ -59,13 +63,12 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
key: OpaqueTypeKey<'tcx>,
hidden_type: OpaqueHiddenType<'tcx>,
) -> Option<Ty<'tcx>> {
if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
if let Some(entry) = self.storage.opaque_types.get_mut(&key) {
let prev = std::mem::replace(entry, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
return Some(prev.ty);
}
let decl = OpaqueTypeDecl { hidden_type };
self.storage.opaque_types.insert(key, decl);
self.storage.opaque_types.insert(key, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
None
}
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/impl_trait_overcaptures.rs
Original file line number Diff line number Diff line change
@@ -99,7 +99,7 @@ declare_lint! {
/// To fix this, remove the `use<'a>`, since the lifetime is already captured
/// since it is in scope.
pub IMPL_TRAIT_REDUNDANT_CAPTURES,
Warn,
Allow,
"redundant precise-capturing `use<...>` syntax on an `impl Trait`",
}

24 changes: 15 additions & 9 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
@@ -1555,16 +1555,22 @@ pub fn write_allocations<'tcx>(
write!(w, " (vtable: impl {dyn_ty} for {ty})")?
}
Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
match tcx.eval_static_initializer(did) {
Ok(alloc) => {
write!(w, " (static: {}, ", tcx.def_path_str(did))?;
write_allocation_track_relocs(w, alloc)?;
write!(w, " (static: {}", tcx.def_path_str(did))?;
if body.phase <= MirPhase::Runtime(RuntimePhase::PostCleanup)
&& tcx.hir().body_const_context(body.source.def_id()).is_some()
{
// Statics may be cyclic and evaluating them too early
// in the MIR pipeline may cause cycle errors even though
// normal compilation is fine.
write!(w, ")")?;
} else {
match tcx.eval_static_initializer(did) {
Ok(alloc) => {
write!(w, ", ")?;
write_allocation_track_relocs(w, alloc)?;
}
Err(_) => write!(w, ", error during initializer evaluation)")?,
}
Err(_) => write!(
w,
" (static: {}, error during initializer evaluation)",
tcx.def_path_str(did)
)?,
}
}
Some(GlobalAlloc::Static(did)) => {
3 changes: 3 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
@@ -799,6 +799,9 @@ passes_unused_assign = value assigned to `{$name}` is never read
passes_unused_assign_passed = value passed to `{$name}` is never read
.help = maybe it is overwritten before being read?

passes_unused_assign_suggestion =
you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding

passes_unused_capture_maybe_capture_ref = value captured by `{$name}` is never read
.help = did you mean to capture by reference instead?

19 changes: 18 additions & 1 deletion compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1787,9 +1787,26 @@ pub(crate) struct IneffectiveUnstableImpl;

#[derive(LintDiagnostic)]
#[diag(passes_unused_assign)]
#[help]
pub(crate) struct UnusedAssign {
pub name: String,
#[subdiagnostic]
pub suggestion: Option<UnusedAssignSuggestion>,
#[help]
pub help: bool,
}

#[derive(Subdiagnostic)]
#[multipart_suggestion(passes_unused_assign_suggestion, applicability = "maybe-incorrect")]
pub(crate) struct UnusedAssignSuggestion {
pub pre: &'static str,
#[suggestion_part(code = "{pre}mut ")]
pub ty_span: Span,
#[suggestion_part(code = "")]
pub ty_ref_span: Span,
#[suggestion_part(code = "*")]
pub ident_span: Span,
#[suggestion_part(code = "")]
pub expr_ref_span: Span,
}

#[derive(LintDiagnostic)]
81 changes: 77 additions & 4 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
@@ -1360,7 +1360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) {
self.check_unused_vars_in_pat(local.pat, None, None, |spans, hir_id, ln, var| {
if local.init.is_some() {
self.warn_about_dead_assign(spans, hir_id, ln, var);
self.warn_about_dead_assign(spans, hir_id, ln, var, None);
}
});

@@ -1460,7 +1460,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
// as being used.
let ln = self.live_node(expr.hir_id, expr.span);
let var = self.variable(var_hid, expr.span);
self.warn_about_dead_assign(vec![expr.span], expr.hir_id, ln, var);
let sugg = self.annotate_mut_binding_to_immutable_binding(var_hid, expr);
self.warn_about_dead_assign(vec![expr.span], expr.hir_id, ln, var, sugg);
}
}
_ => {
@@ -1585,6 +1586,70 @@ impl<'tcx> Liveness<'_, 'tcx> {
}
}

/// Detect the following case
///
/// ```text
/// fn change_object(mut a: &Ty) {
/// let a = Ty::new();
/// b = &a;
/// }
/// ```
///
/// where the user likely meant to modify the value behind there reference, use `a` as an out
/// parameter, instead of mutating the local binding. When encountering this we suggest:
///
/// ```text
/// fn change_object(a: &'_ mut Ty) {
/// let a = Ty::new();
/// *b = a;
/// }
/// ```
fn annotate_mut_binding_to_immutable_binding(
&self,
var_hid: HirId,
expr: &'tcx Expr<'tcx>,
) -> Option<errors::UnusedAssignSuggestion> {
if let hir::Node::Expr(parent) = self.ir.tcx.parent_hir_node(expr.hir_id)
&& let hir::ExprKind::Assign(_, rhs, _) = parent.kind
&& let hir::ExprKind::AddrOf(borrow_kind, _mut, inner) = rhs.kind
&& let hir::BorrowKind::Ref = borrow_kind
&& let hir::Node::Pat(pat) = self.ir.tcx.hir_node(var_hid)
&& let hir::Node::Param(hir::Param { ty_span, .. }) =
self.ir.tcx.parent_hir_node(pat.hir_id)
&& let item_id = self.ir.tcx.hir().get_parent_item(pat.hir_id)
&& let item = self.ir.tcx.hir_owner_node(item_id)
&& let Some(fn_decl) = item.fn_decl()
&& let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind
&& let Some((ty_span, pre)) = fn_decl
.inputs
.iter()
.filter_map(|ty| {
if ty.span == *ty_span
&& let hir::TyKind::Ref(lt, mut_ty) = ty.kind
{
// `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
Some((
mut_ty.ty.span.shrink_to_lo(),
if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " },
))
} else {
None
}
})
.next()
{
Some(errors::UnusedAssignSuggestion {
ty_span,
pre,
ty_ref_span: pat.span.until(ident.span),
ident_span: expr.span.shrink_to_lo(),
expr_ref_span: rhs.span.until(inner.span),
})
} else {
None
}
}

#[instrument(skip(self), level = "INFO")]
fn report_unused(
&self,
@@ -1738,15 +1803,23 @@ impl<'tcx> Liveness<'_, 'tcx> {
suggs
}

fn warn_about_dead_assign(&self, spans: Vec<Span>, hir_id: HirId, ln: LiveNode, var: Variable) {
fn warn_about_dead_assign(
&self,
spans: Vec<Span>,
hir_id: HirId,
ln: LiveNode,
var: Variable,
suggestion: Option<errors::UnusedAssignSuggestion>,
) {
if !self.live_on_exit(ln, var)
&& let Some(name) = self.should_warn(var)
{
let help = suggestion.is_none();
self.ir.tcx.emit_node_span_lint(
lint::builtin::UNUSED_ASSIGNMENTS,
hir_id,
spans,
errors::UnusedAssign { name },
errors::UnusedAssign { name, suggestion, help },
);
}
}
21 changes: 15 additions & 6 deletions library/std/src/sys/pal/uefi/helpers.rs
Original file line number Diff line number Diff line change
@@ -222,14 +222,14 @@ pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>>
NonNull::new(runtime_services)
}

pub(crate) struct DevicePath(NonNull<r_efi::protocols::device_path::Protocol>);
pub(crate) struct OwnedDevicePath(NonNull<r_efi::protocols::device_path::Protocol>);

impl DevicePath {
impl OwnedDevicePath {
pub(crate) fn from_text(p: &OsStr) -> io::Result<Self> {
fn inner(
p: &OsStr,
protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>,
) -> io::Result<DevicePath> {
) -> io::Result<OwnedDevicePath> {
let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec<u16>>();
if path_vec[..path_vec.len() - 1].contains(&0) {
return Err(const_error!(
@@ -242,7 +242,7 @@ impl DevicePath {
unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };

NonNull::new(path)
.map(DevicePath)
.map(OwnedDevicePath)
.ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path"))
}

@@ -275,12 +275,12 @@ impl DevicePath {
))
}

pub(crate) fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol {
pub(crate) const fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol {
self.0.as_ptr()
}
}

impl Drop for DevicePath {
impl Drop for OwnedDevicePath {
fn drop(&mut self) {
if let Some(bt) = boot_services() {
let bt: NonNull<r_efi::efi::BootServices> = bt.cast();
@@ -291,6 +291,15 @@ impl Drop for DevicePath {
}
}

impl crate::fmt::Debug for OwnedDevicePath {
fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
match device_path_to_text(self.0) {
Ok(p) => p.fmt(f),
Err(_) => f.debug_struct("OwnedDevicePath").finish_non_exhaustive(),
}
}
}

pub(crate) struct OwnedProtocol<T> {
guid: r_efi::efi::Guid,
handle: NonNull<crate::ffi::c_void>,
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/uefi/process.rs
Original file line number Diff line number Diff line change
@@ -326,7 +326,7 @@ mod uefi_command_internal {

impl Image {
pub fn load_image(p: &OsStr) -> io::Result<Self> {
let path = helpers::DevicePath::from_text(p)?;
let path = helpers::OwnedDevicePath::from_text(p)?;
let boot_services: NonNull<r_efi::efi::BootServices> = boot_services()
.ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
.cast();
2 changes: 1 addition & 1 deletion src/bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ xz2 = "0.1"
# Dependencies needed by the build-metrics feature
sysinfo = { version = "0.33.0", default-features = false, optional = true, features = ["system"] }

# Dependencies needed by the `logging` feature
# Dependencies needed by the `tracing` feature
tracing = { version = "0.1", optional = true, features = ["attributes"] }
tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter", "fmt", "registry", "std"] }
tracing-tree = { version = "0.4.0", optional = true }
6 changes: 5 additions & 1 deletion src/bootstrap/src/core/build_steps/tool.rs
Original file line number Diff line number Diff line change
@@ -334,7 +334,11 @@ macro_rules! bootstrap_tool {
}

bootstrap_tool!(
Rustbook, "src/tools/rustbook", "rustbook", submodules = SUBMODULES_FOR_RUSTBOOK;
// This is marked as an external tool because it includes dependencies
// from submodules. Trying to keep the lints in sync between all the repos
// is a bit of a pain. Unfortunately it means the rustbook source itself
// doesn't deny warnings, but it is a relatively small piece of code.
Rustbook, "src/tools/rustbook", "rustbook", is_external_tool = true, submodules = SUBMODULES_FOR_RUSTBOOK;
UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
Tidy, "src/tools/tidy", "tidy";
Linkchecker, "src/tools/linkchecker", "linkchecker";
2 changes: 1 addition & 1 deletion src/doc/nomicon
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-gather.rs
Original file line number Diff line number Diff line change
@@ -38,6 +38,6 @@ pub unsafe extern "C" fn gather_f64x4(mask: m64x4, ptrs: pf64x4) -> f64x4 {
// x86-avx512: vpsllq ymm0, ymm0, 63
// x86-avx512-NEXT: vpmovq2m k1, ymm0
// x86-avx512-NEXT: vpxor xmm0, xmm0, xmm0
// x86-avx512-NEXT: vgatherqpd ymm0 {k1}, ymmword ptr [1*ymm1]
// x86-avx512-NEXT: vgatherqpd ymm0 {k1}, {{(ymmword)|(qword)}} ptr [1*ymm1]
simd_gather(f64x4([0_f64, 0_f64, 0_f64, 0_f64]), ptrs, mask)
}
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-scatter.rs
Original file line number Diff line number Diff line change
@@ -34,6 +34,6 @@ extern "rust-intrinsic" {
pub unsafe extern "C" fn scatter_f64x4(values: f64x4, ptrs: pf64x4, mask: m64x4) {
// x86-avx512: vpsllq ymm2, ymm2, 63
// x86-avx512-NEXT: vpmovq2m k1, ymm2
// x86-avx512-NEXT: vscatterqpd ymmword ptr [1*ymm1] {k1}, ymm0
// x86-avx512-NEXT: vscatterqpd {{(ymmword)|(qword)}} ptr [1*ymm1] {k1}, ymm0
simd_scatter(values, ptrs, mask)
}
19 changes: 19 additions & 0 deletions tests/mir-opt/building/dump_mir_cycle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[derive(Debug)]
pub struct Thing {
pub next: &'static Thing,
}

pub static THING: Thing = Thing { next: &THING };
// CHECK: alloc{{.+}} (static: THING)

const fn thing() -> &'static Thing {
&MUTUALLY_RECURSIVE
}

pub static MUTUALLY_RECURSIVE: Thing = Thing { next: thing() };
// CHECK: alloc{{.+}} (static: MUTUALLY_RECURSIVE)

fn main() {
// Generate optimized MIR for the const fn, too.
thing();
}
Original file line number Diff line number Diff line change
@@ -15,6 +15,4 @@ const BAR::promoted[0]: &[&i32; 1] = {
}
}

ALLOC0 (static: Y, size: 4, align: 4) {
2a 00 00 00*...
}
ALLOC0 (static: Y)
Original file line number Diff line number Diff line change
@@ -38,9 +38,7 @@
bb2 (cleanup): {
resume;
}
- }
-
- ALLOC0 (static: Y, size: 4, align: 4) {
- 2a 00 00 00 │ *...
}
-
- ALLOC0 (static: Y)

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! Regression test for <https://github.com/rust-lang/rust/issues/122638>.
//@ check-fail
#![feature(min_specialization)]
impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> {
//~^ ERROR not all trait items implemented, missing: `Item` [E0046]
fn next(&mut self) -> Option<Self::Item> {}
//~^ ERROR mismatched types [E0308]
}
struct ConstChunksExact<'a, T: '_, const assert: usize> {}
//~^ ERROR `'_` cannot be used here [E0637]
//~| ERROR lifetime parameter `'a` is never used [E0392]
//~| ERROR type parameter `T` is never used [E0392]
impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> {
//~^ ERROR mismatched types [E0308]
//~| ERROR the const parameter `N` is not constrained by the impl trait, self type, or predicates [E0207]
type Item = &'a [T; N]; }

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
error[E0637]: `'_` cannot be used here
--> $DIR/normalizing_with_unconstrained_impl_params.rs:9:32
|
LL | struct ConstChunksExact<'a, T: '_, const assert: usize> {}
| ^^ `'_` is a reserved lifetime name

error[E0308]: mismatched types
--> $DIR/normalizing_with_unconstrained_impl_params.rs:13:83
|
LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> {
| ^^ expected `usize`, found `()`

error[E0046]: not all trait items implemented, missing: `Item`
--> $DIR/normalizing_with_unconstrained_impl_params.rs:4:1
|
LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
|
= help: implement the missing item: `type Item = /* Type */;`

error[E0392]: lifetime parameter `'a` is never used
--> $DIR/normalizing_with_unconstrained_impl_params.rs:9:25
|
LL | struct ConstChunksExact<'a, T: '_, const assert: usize> {}
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

error[E0392]: type parameter `T` is never used
--> $DIR/normalizing_with_unconstrained_impl_params.rs:9:29
|
LL | struct ConstChunksExact<'a, T: '_, const assert: usize> {}
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
--> $DIR/normalizing_with_unconstrained_impl_params.rs:13:30
|
LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> {
| ^^^^^^^^^^^^^^ unconstrained const parameter
|
= note: expressions using a const parameter must map each value to a distinct output value
= note: proving the result of expressions other than the parameter are unique is not supported

error[E0308]: mismatched types
--> $DIR/normalizing_with_unconstrained_impl_params.rs:6:27
|
LL | fn next(&mut self) -> Option<Self::Item> {}
| ---- ^^^^^^^^^^^^^^^^^^ expected `Option<_>`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected enum `Option<_>`
found unit type `()`

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0046, E0207, E0308, E0392, E0637.
For more information about an error, try `rustc --explain E0046`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//@ run-rustfix
#![deny(unused_assignments, unused_variables)]
struct Object;

fn change_object(object: &mut Object) { //~ HELP you might have meant to mutate
let object2 = Object;
*object = object2; //~ ERROR mismatched types
}

fn change_object2(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
//~^ HELP you might have meant to mutate
let object2 = Object;
*object = object2;
//~^ ERROR `object2` does not live long enough
//~| ERROR value assigned to `object` is never read
}

fn main() {
let mut object = Object;
change_object(&mut object);
change_object2(&mut object);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//@ run-rustfix
#![deny(unused_assignments, unused_variables)]
struct Object;

fn change_object(mut object: &Object) { //~ HELP you might have meant to mutate
let object2 = Object;
object = object2; //~ ERROR mismatched types
}

fn change_object2(mut object: &Object) { //~ ERROR variable `object` is assigned to, but never used
//~^ HELP you might have meant to mutate
let object2 = Object;
object = &object2;
//~^ ERROR `object2` does not live long enough
//~| ERROR value assigned to `object` is never read
}

fn main() {
let mut object = Object;
change_object(&mut object);
change_object2(&mut object);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
error[E0308]: mismatched types
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:7:14
|
LL | fn change_object(mut object: &Object) {
| ------- expected due to this parameter type
LL | let object2 = Object;
LL | object = object2;
| ^^^^^^^ expected `&Object`, found `Object`
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object(object: &mut Object) {
LL | let object2 = Object;
LL ~ *object = object2;
|

error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:5
|
LL | object = &object2;
| ^^^^^^
|
note: the lint level is defined here
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:9
|
LL | #![deny(unused_assignments, unused_variables)]
| ^^^^^^^^^^^^^^^^^^
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object2(object: &mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|

error: variable `object` is assigned to, but never used
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:10:23
|
LL | fn change_object2(mut object: &Object) {
| ^^^^^^
|
= note: consider using `_object` instead
note: the lint level is defined here
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:29
|
LL | #![deny(unused_assignments, unused_variables)]
| ^^^^^^^^^^^^^^^^

error[E0597]: `object2` does not live long enough
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:14
|
LL | fn change_object2(mut object: &Object) {
| - let's call the lifetime of this reference `'1`
LL |
LL | let object2 = Object;
| ------- binding `object2` declared here
LL | object = &object2;
| ---------^^^^^^^^
| | |
| | borrowed value does not live long enough
| assignment requires that `object2` is borrowed for `'1`
...
LL | }
| - `object2` dropped here while still borrowed

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0308, E0597.
For more information about an error, try `rustc --explain E0308`.
10 changes: 5 additions & 5 deletions tests/ui/impl-trait/precise-capturing/redundant.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
//@ edition: 2024
//@ check-pass

#![feature(precise_capturing_in_traits)]
#![deny(impl_trait_redundant_captures)]

fn hello<'a>() -> impl Sized + use<'a> {}
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured

struct Inherent;
impl Inherent {
fn inherent(&self) -> impl Sized + use<'_> {}
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured
}

trait Test<'a> {
fn in_trait() -> impl Sized + use<'a, Self>;
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured
}
impl<'a> Test<'a> for () {
fn in_trait() -> impl Sized + use<'a> {}
//~^ WARN all possible in-scope parameters are already captured
//~^ ERROR all possible in-scope parameters are already captured
}

fn main() {}
16 changes: 10 additions & 6 deletions tests/ui/impl-trait/precise-capturing/redundant.stderr
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:6:19
|
LL | fn hello<'a>() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax
|
= note: `#[warn(impl_trait_redundant_captures)]` on by default
note: the lint level is defined here
--> $DIR/redundant.rs:4:9
|
LL | #![deny(impl_trait_redundant_captures)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:11:27
|
LL | fn inherent(&self) -> impl Sized + use<'_> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax

warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:16:22
|
LL | fn in_trait() -> impl Sized + use<'a, Self>;
| ^^^^^^^^^^^^^-------------
| |
| help: remove the `use<...>` syntax

warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:20:22
|
LL | fn in_trait() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax

warning: 4 warnings emitted
error: aborting due to 4 previous errors