Skip to content

Commit

Permalink
Auto merge of rust-lang#127998 - matthiaskrgr:rollup-ykp0h5r, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#123196 (Add Process support for UEFI)
 - rust-lang#127556 (Replace a long inline "autoref" comment with method docs)
 - rust-lang#127693 (Migrate `crate-hash-rustc-version` to `rmake`)
 - rust-lang#127866 (Conditionally build `wasm-component-ld` )
 - rust-lang#127918 (Safely enforce thread name requirements)
 - rust-lang#127948 (fixes panic error `index out of bounds` in conflicting error)
 - rust-lang#127980 (Avoid ref when using format! in compiler)
 - rust-lang#127984 (Avoid ref when using format! in src)
 - rust-lang#127987 (More accurate suggestion for `-> Box<dyn Trait>` or `-> impl Trait`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jul 20, 2024
2 parents 41ff460 + 89798e9 commit 1afc5fd
Show file tree
Hide file tree
Showing 53 changed files with 1,296 additions and 294 deletions.
13 changes: 9 additions & 4 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,10 +456,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
if let Some(def_id) = def_id
&& self.infcx.tcx.def_kind(def_id).is_fn_like()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
&& let ty::Param(_) =
self.infcx.tcx.fn_sig(def_id).skip_binder().skip_binder().inputs()
[pos + offset]
.kind()
&& let Some(arg) = self
.infcx
.tcx
.fn_sig(def_id)
.skip_binder()
.skip_binder()
.inputs()
.get(pos + offset)
&& let ty::Param(_) = arg.kind()
{
let place = &self.move_data.move_paths[mpi].place;
let ty = place.ty(self.body, self.infcx.tcx).ty;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let nop_inst = fx.bcx.ins().nop();
fx.add_comment(
nop_inst,
format!("virtual call; self arg pass mode: {:?}", &fn_abi.args[0]),
format!("virtual call; self arg pass mode: {:?}", fn_abi.args[0]),
);
}

Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ fn link_natively(
sess.dcx().abort_if_errors();

// Invoke the system linker
info!("{:?}", &cmd);
info!("{cmd:?}");
let retry_on_segfault = env::var("RUSTC_RETRY_LINKER_ON_SEGFAULT").is_ok();
let unknown_arg_regex =
Regex::new(r"(unknown|unrecognized) (command line )?(option|argument)").unwrap();
Expand Down Expand Up @@ -796,7 +796,7 @@ fn link_natively(
cmd.arg(arg);
}
}
info!("{:?}", &cmd);
info!("{cmd:?}");
continue;
}

Expand All @@ -817,7 +817,7 @@ fn link_natively(
cmd.arg(arg);
}
}
info!("{:?}", &cmd);
info!("{cmd:?}");
continue;
}

Expand Down Expand Up @@ -878,7 +878,7 @@ fn link_natively(
cmd.arg(arg);
}
}
info!("{:?}", &cmd);
info!("{cmd:?}");
continue;
}

Expand Down Expand Up @@ -996,7 +996,7 @@ fn link_natively(
sess.dcx().emit_err(errors::UnableToExeLinker {
linker_path,
error: e,
command_formatted: format!("{:?}", &cmd),
command_formatted: format!("{cmd:?}"),
});
}

Expand Down Expand Up @@ -1567,7 +1567,7 @@ fn print_native_static_libs(
sess.dcx().emit_note(errors::StaticLibraryNativeArtifacts);
// Prefix for greppability
// Note: This must not be translated as tools are allowed to depend on this exact string.
sess.dcx().note(format!("native-static-libs: {}", &lib_args.join(" ")));
sess.dcx().note(format!("native-static-libs: {}", lib_args.join(" ")));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
sym::link_section => {
if let Some(val) = attr.value_str() {
if val.as_str().bytes().any(|b| b == 0) {
let msg = format!("illegal null byte in link_section value: `{}`", &val);
let msg = format!("illegal null byte in link_section value: `{val}`");
tcx.dcx().span_err(attr.span, msg);
} else {
codegen_fn_attrs.link_section = Some(val);
Expand Down Expand Up @@ -726,7 +726,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
if *ordinal <= u16::MAX as u128 {
Some(ordinal.get() as u16)
} else {
let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
let msg = format!("ordinal value in `link_ordinal` is too large: `{ordinal}`");
tcx.dcx()
.struct_span_err(attr.span, msg)
.with_note("the value may not exceed `u16::MAX`")
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {

let symbol_name = self.symbol_name(cx.tcx()).name;

debug!("symbol {}", &symbol_name);
debug!("symbol {symbol_name}");

match *self {
MonoItem::Static(def_id) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_fluent_macro/src/fluent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok

for Attribute { id: Identifier { name: attr_name }, .. } in attributes {
let snake_name = Ident::new(
&format!("{}{}", &crate_prefix, &attr_name.replace('-', "_")),
&format!("{crate_prefix}{}", attr_name.replace('-', "_")),
resource_str.span(),
);
if !previous_attrs.insert(snake_name.clone()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
self.path_segment.hir_id,
num_params_to_take,
);
debug!("suggested_args: {:?}", &suggested_args);
debug!("suggested_args: {suggested_args:?}");

match self.angle_brackets {
AngleBrackets::Missing => {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ fn check_explicit_predicates<'tcx>(
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);

for (outlives_predicate, &span) in explicit_predicates.as_ref().skip_binder() {
debug!("outlives_predicate = {:?}", &outlives_predicate);
debug!("outlives_predicate = {outlives_predicate:?}");

// Careful: If we are inferring the effects of a `dyn Trait<..>`
// type, then when we look up the predicates for `Trait`,
Expand Down Expand Up @@ -289,12 +289,12 @@ fn check_explicit_predicates<'tcx>(
&& let GenericArgKind::Type(ty) = outlives_predicate.0.unpack()
&& ty.walk().any(|arg| arg == self_ty.into())
{
debug!("skipping self ty = {:?}", &ty);
debug!("skipping self ty = {ty:?}");
continue;
}

let predicate = explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args);
debug!("predicate = {:?}", &predicate);
debug!("predicate = {predicate:?}");
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1265,9 +1265,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
(
match parent_pred {
None => format!("`{}`", &p),
None => format!("`{p}`"),
Some(parent_pred) => match format_pred(*parent_pred) {
None => format!("`{}`", &p),
None => format!("`{p}`"),
Some((parent_p, _)) => {
if !suggested
&& !suggested_bounds.contains(pred)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub fn report_unstable(
) {
let msg = match reason {
Some(r) => format!("use of unstable library feature '{feature}': {r}"),
None => format!("use of unstable library feature '{}'", &feature),
None => format!("use of unstable library feature '{feature}'"),
};

if is_soft {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2627,7 +2627,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
self.prepare_region_info(value);
}

debug!("self.used_region_names: {:?}", &self.used_region_names);
debug!("self.used_region_names: {:?}", self.used_region_names);

let mut empty = true;
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/util/find_self_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn find_self_call<'tcx>(
local: Local,
block: BasicBlock,
) -> Option<(DefId, GenericArgsRef<'tcx>)> {
debug!("find_self_call(local={:?}): terminator={:?}", local, &body[block].terminator);
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
&body[block].terminator
{
Expand Down
165 changes: 84 additions & 81 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2162,92 +2162,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

self.ascribe_types(block, ascriptions);

// rust-lang/rust#27282: The `autoref` business deserves some
// explanation here.
//
// The intent of the `autoref` flag is that when it is true,
// then any pattern bindings of type T will map to a `&T`
// within the context of the guard expression, but will
// continue to map to a `T` in the context of the arm body. To
// avoid surfacing this distinction in the user source code
// (which would be a severe change to the language and require
// far more revision to the compiler), when `autoref` is true,
// then any occurrence of the identifier in the guard
// expression will automatically get a deref op applied to it.
//
// So an input like:
//
// ```
// let place = Foo::new();
// match place { foo if inspect(foo)
// => feed(foo), ... }
// ```
//
// will be treated as if it were really something like:
//
// ```
// let place = Foo::new();
// match place { Foo { .. } if { let tmp1 = &place; inspect(*tmp1) }
// => { let tmp2 = place; feed(tmp2) }, ... }
// ```
//
// And an input like:
//
// ```
// let place = Foo::new();
// match place { ref mut foo if inspect(foo)
// => feed(foo), ... }
// ```
//
// will be treated as if it were really something like:
//
// ```
// let place = Foo::new();
// match place { Foo { .. } if { let tmp1 = & &mut place; inspect(*tmp1) }
// => { let tmp2 = &mut place; feed(tmp2) }, ... }
// ```
//
// In short, any pattern binding will always look like *some*
// kind of `&T` within the guard at least in terms of how the
// MIR-borrowck views it, and this will ensure that guard
// expressions cannot mutate their the match inputs via such
// bindings. (It also ensures that guard expressions can at
// most *copy* values from such bindings; non-Copy things
// cannot be moved via pattern bindings in guard expressions.)
//
// ----
//
// Implementation notes (under assumption `autoref` is true).
//
// To encode the distinction above, we must inject the
// temporaries `tmp1` and `tmp2`.
//
// There are two cases of interest: binding by-value, and binding by-ref.
//
// 1. Binding by-value: Things are simple.
//
// * Establishing `tmp1` creates a reference into the
// matched place. This code is emitted by
// bind_matched_candidate_for_guard.
//
// * `tmp2` is only initialized "lazily", after we have
// checked the guard. Thus, the code that can trigger
// moves out of the candidate can only fire after the
// guard evaluated to true. This initialization code is
// emitted by bind_matched_candidate_for_arm.
//
// 2. Binding by-reference: Things are tricky.
//
// * Here, the guard expression wants a `&&` or `&&mut`
// into the original input. This means we need to borrow
// the reference that we create for the arm.
// * So we eagerly create the reference for the arm and then take a
// reference to that.
// Lower an instance of the arm guard (if present) for this candidate,
// and then perform bindings for the arm body.
if let Some((arm, match_scope)) = arm_match_scope
&& let Some(guard) = arm.guard
{
let tcx = self.tcx;

// Bindings for guards require some extra handling to automatically
// insert implicit references/dereferences.
self.bind_matched_candidate_for_guard(block, schedule_drops, bindings.clone());
let guard_frame = GuardFrame {
locals: bindings.clone().map(|b| GuardFrameLocal::new(b.var_id)).collect(),
Expand Down Expand Up @@ -2387,6 +2310,82 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}

/// Binding for guards is a bit different from binding for the arm body,
/// because an extra layer of implicit reference/dereference is added.
///
/// The idea is that any pattern bindings of type T will map to a `&T` within
/// the context of the guard expression, but will continue to map to a `T`
/// in the context of the arm body. To avoid surfacing this distinction in
/// the user source code (which would be a severe change to the language and
/// require far more revision to the compiler), any occurrence of the
/// identifier in the guard expression will automatically get a deref op
/// applied to it. (See the caller of [`Self::is_bound_var_in_guard`].)
///
/// So an input like:
///
/// ```ignore (illustrative)
/// let place = Foo::new();
/// match place { foo if inspect(foo)
/// => feed(foo), ... }
/// ```
///
/// will be treated as if it were really something like:
///
/// ```ignore (illustrative)
/// let place = Foo::new();
/// match place { Foo { .. } if { let tmp1 = &place; inspect(*tmp1) }
/// => { let tmp2 = place; feed(tmp2) }, ... }
/// ```
///
/// And an input like:
///
/// ```ignore (illustrative)
/// let place = Foo::new();
/// match place { ref mut foo if inspect(foo)
/// => feed(foo), ... }
/// ```
///
/// will be treated as if it were really something like:
///
/// ```ignore (illustrative)
/// let place = Foo::new();
/// match place { Foo { .. } if { let tmp1 = & &mut place; inspect(*tmp1) }
/// => { let tmp2 = &mut place; feed(tmp2) }, ... }
/// ```
/// ---
///
/// ## Implementation notes
///
/// To encode the distinction above, we must inject the
/// temporaries `tmp1` and `tmp2`.
///
/// There are two cases of interest: binding by-value, and binding by-ref.
///
/// 1. Binding by-value: Things are simple.
///
/// * Establishing `tmp1` creates a reference into the
/// matched place. This code is emitted by
/// [`Self::bind_matched_candidate_for_guard`].
///
/// * `tmp2` is only initialized "lazily", after we have
/// checked the guard. Thus, the code that can trigger
/// moves out of the candidate can only fire after the
/// guard evaluated to true. This initialization code is
/// emitted by [`Self::bind_matched_candidate_for_arm_body`].
///
/// 2. Binding by-reference: Things are tricky.
///
/// * Here, the guard expression wants a `&&` or `&&mut`
/// into the original input. This means we need to borrow
/// the reference that we create for the arm.
/// * So we eagerly create the reference for the arm and then take a
/// reference to that.
///
/// ---
///
/// See these PRs for some historical context:
/// - <https://github.com/rust-lang/rust/pull/49870> (introduction of autoref)
/// - <https://github.com/rust-lang/rust/pull/59114> (always use autoref)
fn bind_matched_candidate_for_guard<'b>(
&mut self,
block: BasicBlock,
Expand Down Expand Up @@ -2418,10 +2417,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
match binding.binding_mode.0 {
ByRef::No => {
// The arm binding will be by value, so for the guard binding
// just take a shared reference to the matched place.
let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source);
self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
}
ByRef::Yes(mutbl) => {
// The arm binding will be by reference, so eagerly create it now.
let value_for_arm = self.storage_live_binding(
block,
binding.var_id,
Expand All @@ -2433,6 +2435,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let rvalue =
Rvalue::Ref(re_erased, util::ref_pat_borrow_kind(mutbl), binding.source);
self.cfg.push_assign(block, source_info, value_for_arm, rvalue);
// For the guard binding, take a shared reference to that reference.
let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, value_for_arm);
self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
}
Expand Down
Loading

0 comments on commit 1afc5fd

Please sign in to comment.