authorbors <bors@rust-lang.org> 2024-07-20 08:27:20 UTC
committerbors <bors@rust-lang.org> 2024-07-20 08:27:20 UTC
log1afc5fd042f7583b9668dd62be98325487483d1c
tree1093181012ef22176bebe4b8ce548775c66ac9f5
parent41ff4608894d260462a7b6cf1ddefc6c8ecf6b1c
parent89798e9064282764247e7e9af4f7c153e865a19b

Auto merge of #127998 - matthiaskrgr:rollup-ykp0h5r, r=matthiaskrgr

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

53 files changed, 1296 insertions(+), 294 deletions(-)

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs+9-4
......@@ -456,10 +456,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
456456 if let Some(def_id) = def_id
457457 && self.infcx.tcx.def_kind(def_id).is_fn_like()
458458 && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
459 && let ty::Param(_) =
460 self.infcx.tcx.fn_sig(def_id).skip_binder().skip_binder().inputs()
461 [pos + offset]
462 .kind()
459 && let Some(arg) = self
460 .infcx
461 .tcx
462 .fn_sig(def_id)
463 .skip_binder()
464 .skip_binder()
465 .inputs()
466 .get(pos + offset)
467 && let ty::Param(_) = arg.kind()
463468 {
464469 let place = &self.move_data.move_paths[mpi].place;
465470 let ty = place.ty(self.body, self.infcx.tcx).ty;
compiler/rustc_codegen_cranelift/src/abi/mod.rs+1-1
......@@ -505,7 +505,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
505505 let nop_inst = fx.bcx.ins().nop();
506506 fx.add_comment(
507507 nop_inst,
508 format!("virtual call; self arg pass mode: {:?}", &fn_abi.args[0]),
508 format!("virtual call; self arg pass mode: {:?}", fn_abi.args[0]),
509509 );
510510 }
511511
compiler/rustc_codegen_ssa/src/back/link.rs+6-6
......@@ -759,7 +759,7 @@ fn link_natively(
759759 sess.dcx().abort_if_errors();
760760
761761 // Invoke the system linker
762 info!("{:?}", &cmd);
762 info!("{cmd:?}");
763763 let retry_on_segfault = env::var("RUSTC_RETRY_LINKER_ON_SEGFAULT").is_ok();
764764 let unknown_arg_regex =
765765 Regex::new(r"(unknown|unrecognized) (command line )?(option|argument)").unwrap();
......@@ -796,7 +796,7 @@ fn link_natively(
796796 cmd.arg(arg);
797797 }
798798 }
799 info!("{:?}", &cmd);
799 info!("{cmd:?}");
800800 continue;
801801 }
802802
......@@ -817,7 +817,7 @@ fn link_natively(
817817 cmd.arg(arg);
818818 }
819819 }
820 info!("{:?}", &cmd);
820 info!("{cmd:?}");
821821 continue;
822822 }
823823
......@@ -878,7 +878,7 @@ fn link_natively(
878878 cmd.arg(arg);
879879 }
880880 }
881 info!("{:?}", &cmd);
881 info!("{cmd:?}");
882882 continue;
883883 }
884884
......@@ -996,7 +996,7 @@ fn link_natively(
996996 sess.dcx().emit_err(errors::UnableToExeLinker {
997997 linker_path,
998998 error: e,
999 command_formatted: format!("{:?}", &cmd),
999 command_formatted: format!("{cmd:?}"),
10001000 });
10011001 }
10021002
......@@ -1567,7 +1567,7 @@ fn print_native_static_libs(
15671567 sess.dcx().emit_note(errors::StaticLibraryNativeArtifacts);
15681568 // Prefix for greppability
15691569 // Note: This must not be translated as tools are allowed to depend on this exact string.
1570 sess.dcx().note(format!("native-static-libs: {}", &lib_args.join(" ")));
1570 sess.dcx().note(format!("native-static-libs: {}", lib_args.join(" ")));
15711571 }
15721572 }
15731573 }
compiler/rustc_codegen_ssa/src/codegen_attrs.rs+2-2
......@@ -328,7 +328,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
328328 sym::link_section => {
329329 if let Some(val) = attr.value_str() {
330330 if val.as_str().bytes().any(|b| b == 0) {
331 let msg = format!("illegal null byte in link_section value: `{}`", &val);
331 let msg = format!("illegal null byte in link_section value: `{val}`");
332332 tcx.dcx().span_err(attr.span, msg);
333333 } else {
334334 codegen_fn_attrs.link_section = Some(val);
......@@ -726,7 +726,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
726726 if *ordinal <= u16::MAX as u128 {
727727 Some(ordinal.get() as u16)
728728 } else {
729 let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
729 let msg = format!("ordinal value in `link_ordinal` is too large: `{ordinal}`");
730730 tcx.dcx()
731731 .struct_span_err(attr.span, msg)
732732 .with_note("the value may not exceed `u16::MAX`")
compiler/rustc_codegen_ssa/src/mono_item.rs+1-1
......@@ -130,7 +130,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
130130
131131 let symbol_name = self.symbol_name(cx.tcx()).name;
132132
133 debug!("symbol {}", &symbol_name);
133 debug!("symbol {symbol_name}");
134134
135135 match *self {
136136 MonoItem::Static(def_id) => {
compiler/rustc_fluent_macro/src/fluent.rs+1-1
......@@ -253,7 +253,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
253253
254254 for Attribute { id: Identifier { name: attr_name }, .. } in attributes {
255255 let snake_name = Ident::new(
256 &format!("{}{}", &crate_prefix, &attr_name.replace('-', "_")),
256 &format!("{crate_prefix}{}", attr_name.replace('-', "_")),
257257 resource_str.span(),
258258 );
259259 if !previous_attrs.insert(snake_name.clone()) {
compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs+1-1
......@@ -651,7 +651,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
651651 self.path_segment.hir_id,
652652 num_params_to_take,
653653 );
654 debug!("suggested_args: {:?}", &suggested_args);
654 debug!("suggested_args: {suggested_args:?}");
655655
656656 match self.angle_brackets {
657657 AngleBrackets::Missing => {
compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs+3-3
......@@ -249,7 +249,7 @@ fn check_explicit_predicates<'tcx>(
249249 let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);
250250
251251 for (outlives_predicate, &span) in explicit_predicates.as_ref().skip_binder() {
252 debug!("outlives_predicate = {:?}", &outlives_predicate);
252 debug!("outlives_predicate = {outlives_predicate:?}");
253253
254254 // Careful: If we are inferring the effects of a `dyn Trait<..>`
255255 // type, then when we look up the predicates for `Trait`,
......@@ -289,12 +289,12 @@ fn check_explicit_predicates<'tcx>(
289289 && let GenericArgKind::Type(ty) = outlives_predicate.0.unpack()
290290 && ty.walk().any(|arg| arg == self_ty.into())
291291 {
292 debug!("skipping self ty = {:?}", &ty);
292 debug!("skipping self ty = {ty:?}");
293293 continue;
294294 }
295295
296296 let predicate = explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args);
297 debug!("predicate = {:?}", &predicate);
297 debug!("predicate = {predicate:?}");
298298 insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
299299 }
300300}
compiler/rustc_hir_typeck/src/method/suggest.rs+2-2
......@@ -1265,9 +1265,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12651265 }
12661266 (
12671267 match parent_pred {
1268 None => format!("`{}`", &p),
1268 None => format!("`{p}`"),
12691269 Some(parent_pred) => match format_pred(*parent_pred) {
1270 None => format!("`{}`", &p),
1270 None => format!("`{p}`"),
12711271 Some((parent_p, _)) => {
12721272 if !suggested
12731273 && !suggested_bounds.contains(pred)
compiler/rustc_middle/src/middle/stability.rs+1-1
......@@ -112,7 +112,7 @@ pub fn report_unstable(
112112) {
113113 let msg = match reason {
114114 Some(r) => format!("use of unstable library feature '{feature}': {r}"),
115 None => format!("use of unstable library feature '{}'", &feature),
115 None => format!("use of unstable library feature '{feature}'"),
116116 };
117117
118118 if is_soft {
compiler/rustc_middle/src/ty/print/pretty.rs+1-1
......@@ -2627,7 +2627,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
26272627 self.prepare_region_info(value);
26282628 }
26292629
2630 debug!("self.used_region_names: {:?}", &self.used_region_names);
2630 debug!("self.used_region_names: {:?}", self.used_region_names);
26312631
26322632 let mut empty = true;
26332633 let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
compiler/rustc_middle/src/util/find_self_call.rs+1-1
......@@ -14,7 +14,7 @@ pub fn find_self_call<'tcx>(
1414 local: Local,
1515 block: BasicBlock,
1616) -> Option<(DefId, GenericArgsRef<'tcx>)> {
17 debug!("find_self_call(local={:?}): terminator={:?}", local, &body[block].terminator);
17 debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
1818 if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
1919 &body[block].terminator
2020 {
compiler/rustc_mir_build/src/build/matches/mod.rs+84-81
......@@ -2162,92 +2162,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21622162
21632163 self.ascribe_types(block, ascriptions);
21642164
2165 // rust-lang/rust#27282: The `autoref` business deserves some
2166 // explanation here.
2167 //
2168 // The intent of the `autoref` flag is that when it is true,
2169 // then any pattern bindings of type T will map to a `&T`
2170 // within the context of the guard expression, but will
2171 // continue to map to a `T` in the context of the arm body. To
2172 // avoid surfacing this distinction in the user source code
2173 // (which would be a severe change to the language and require
2174 // far more revision to the compiler), when `autoref` is true,
2175 // then any occurrence of the identifier in the guard
2176 // expression will automatically get a deref op applied to it.
2177 //
2178 // So an input like:
2179 //
2180 // ```
2181 // let place = Foo::new();
2182 // match place { foo if inspect(foo)
2183 // => feed(foo), ... }
2184 // ```
2185 //
2186 // will be treated as if it were really something like:
2187 //
2188 // ```
2189 // let place = Foo::new();
2190 // match place { Foo { .. } if { let tmp1 = &place; inspect(*tmp1) }
2191 // => { let tmp2 = place; feed(tmp2) }, ... }
2192 // ```
2193 //
2194 // And an input like:
2195 //
2196 // ```
2197 // let place = Foo::new();
2198 // match place { ref mut foo if inspect(foo)
2199 // => feed(foo), ... }
2200 // ```
2201 //
2202 // will be treated as if it were really something like:
2203 //
2204 // ```
2205 // let place = Foo::new();
2206 // match place { Foo { .. } if { let tmp1 = & &mut place; inspect(*tmp1) }
2207 // => { let tmp2 = &mut place; feed(tmp2) }, ... }
2208 // ```
2209 //
2210 // In short, any pattern binding will always look like *some*
2211 // kind of `&T` within the guard at least in terms of how the
2212 // MIR-borrowck views it, and this will ensure that guard
2213 // expressions cannot mutate their the match inputs via such
2214 // bindings. (It also ensures that guard expressions can at
2215 // most *copy* values from such bindings; non-Copy things
2216 // cannot be moved via pattern bindings in guard expressions.)
2217 //
2218 // ----
2219 //
2220 // Implementation notes (under assumption `autoref` is true).
2221 //
2222 // To encode the distinction above, we must inject the
2223 // temporaries `tmp1` and `tmp2`.
2224 //
2225 // There are two cases of interest: binding by-value, and binding by-ref.
2226 //
2227 // 1. Binding by-value: Things are simple.
2228 //
2229 // * Establishing `tmp1` creates a reference into the
2230 // matched place. This code is emitted by
2231 // bind_matched_candidate_for_guard.
2232 //
2233 // * `tmp2` is only initialized "lazily", after we have
2234 // checked the guard. Thus, the code that can trigger
2235 // moves out of the candidate can only fire after the
2236 // guard evaluated to true. This initialization code is
2237 // emitted by bind_matched_candidate_for_arm.
2238 //
2239 // 2. Binding by-reference: Things are tricky.
2240 //
2241 // * Here, the guard expression wants a `&&` or `&&mut`
2242 // into the original input. This means we need to borrow
2243 // the reference that we create for the arm.
2244 // * So we eagerly create the reference for the arm and then take a
2245 // reference to that.
2165 // Lower an instance of the arm guard (if present) for this candidate,
2166 // and then perform bindings for the arm body.
22462167 if let Some((arm, match_scope)) = arm_match_scope
22472168 && let Some(guard) = arm.guard
22482169 {
22492170 let tcx = self.tcx;
22502171
2172 // Bindings for guards require some extra handling to automatically
2173 // insert implicit references/dereferences.
22512174 self.bind_matched_candidate_for_guard(block, schedule_drops, bindings.clone());
22522175 let guard_frame = GuardFrame {
22532176 locals: bindings.clone().map(|b| GuardFrameLocal::new(b.var_id)).collect(),
......@@ -2387,6 +2310,82 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
23872310 }
23882311 }
23892312
2313 /// Binding for guards is a bit different from binding for the arm body,
2314 /// because an extra layer of implicit reference/dereference is added.
2315 ///
2316 /// The idea is that any pattern bindings of type T will map to a `&T` within
2317 /// the context of the guard expression, but will continue to map to a `T`
2318 /// in the context of the arm body. To avoid surfacing this distinction in
2319 /// the user source code (which would be a severe change to the language and
2320 /// require far more revision to the compiler), any occurrence of the
2321 /// identifier in the guard expression will automatically get a deref op
2322 /// applied to it. (See the caller of [`Self::is_bound_var_in_guard`].)
2323 ///
2324 /// So an input like:
2325 ///
2326 /// ```ignore (illustrative)
2327 /// let place = Foo::new();
2328 /// match place { foo if inspect(foo)
2329 /// => feed(foo), ... }
2330 /// ```
2331 ///
2332 /// will be treated as if it were really something like:
2333 ///
2334 /// ```ignore (illustrative)
2335 /// let place = Foo::new();
2336 /// match place { Foo { .. } if { let tmp1 = &place; inspect(*tmp1) }
2337 /// => { let tmp2 = place; feed(tmp2) }, ... }
2338 /// ```
2339 ///
2340 /// And an input like:
2341 ///
2342 /// ```ignore (illustrative)
2343 /// let place = Foo::new();
2344 /// match place { ref mut foo if inspect(foo)
2345 /// => feed(foo), ... }
2346 /// ```
2347 ///
2348 /// will be treated as if it were really something like:
2349 ///
2350 /// ```ignore (illustrative)
2351 /// let place = Foo::new();
2352 /// match place { Foo { .. } if { let tmp1 = & &mut place; inspect(*tmp1) }
2353 /// => { let tmp2 = &mut place; feed(tmp2) }, ... }
2354 /// ```
2355 /// ---
2356 ///
2357 /// ## Implementation notes
2358 ///
2359 /// To encode the distinction above, we must inject the
2360 /// temporaries `tmp1` and `tmp2`.
2361 ///
2362 /// There are two cases of interest: binding by-value, and binding by-ref.
2363 ///
2364 /// 1. Binding by-value: Things are simple.
2365 ///
2366 /// * Establishing `tmp1` creates a reference into the
2367 /// matched place. This code is emitted by
2368 /// [`Self::bind_matched_candidate_for_guard`].
2369 ///
2370 /// * `tmp2` is only initialized "lazily", after we have
2371 /// checked the guard. Thus, the code that can trigger
2372 /// moves out of the candidate can only fire after the
2373 /// guard evaluated to true. This initialization code is
2374 /// emitted by [`Self::bind_matched_candidate_for_arm_body`].
2375 ///
2376 /// 2. Binding by-reference: Things are tricky.
2377 ///
2378 /// * Here, the guard expression wants a `&&` or `&&mut`
2379 /// into the original input. This means we need to borrow
2380 /// the reference that we create for the arm.
2381 /// * So we eagerly create the reference for the arm and then take a
2382 /// reference to that.
2383 ///
2384 /// ---
2385 ///
2386 /// See these PRs for some historical context:
2387 /// - <https://github.com/rust-lang/rust/pull/49870> (introduction of autoref)
2388 /// - <https://github.com/rust-lang/rust/pull/59114> (always use autoref)
23902389 fn bind_matched_candidate_for_guard<'b>(
23912390 &mut self,
23922391 block: BasicBlock,
......@@ -2418,10 +2417,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24182417 );
24192418 match binding.binding_mode.0 {
24202419 ByRef::No => {
2420 // The arm binding will be by value, so for the guard binding
2421 // just take a shared reference to the matched place.
24212422 let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source);
24222423 self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
24232424 }
24242425 ByRef::Yes(mutbl) => {
2426 // The arm binding will be by reference, so eagerly create it now.
24252427 let value_for_arm = self.storage_live_binding(
24262428 block,
24272429 binding.var_id,
......@@ -2433,6 +2435,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24332435 let rvalue =
24342436 Rvalue::Ref(re_erased, util::ref_pat_borrow_kind(mutbl), binding.source);
24352437 self.cfg.push_assign(block, source_info, value_for_arm, rvalue);
2438 // For the guard binding, take a shared reference to that reference.
24362439 let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, value_for_arm);
24372440 self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
24382441 }
compiler/rustc_mir_dataflow/src/impls/initialized.rs+1-1
......@@ -688,7 +688,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
688688 let init_loc_map = &move_data.init_loc_map;
689689 let rev_lookup = &move_data.rev_lookup;
690690
691 debug!("initializes move_indexes {:?}", &init_loc_map[location]);
691 debug!("initializes move_indexes {:?}", init_loc_map[location]);
692692 trans.gen_all(init_loc_map[location].iter().copied());
693693
694694 if let mir::StatementKind::StorageDead(local) = stmt.kind {
compiler/rustc_mir_transform/src/dead_store_elimination.rs+1-1
......@@ -102,7 +102,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
102102 | StatementKind::Nop => (),
103103
104104 StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => {
105 bug!("{:?} not found in this MIR phase!", &statement.kind)
105 bug!("{:?} not found in this MIR phase!", statement.kind)
106106 }
107107 }
108108 }
compiler/rustc_mir_transform/src/early_otherwise_branch.rs+2-2
......@@ -106,11 +106,11 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
106106 let parent = BasicBlock::from_usize(i);
107107 let Some(opt_data) = evaluate_candidate(tcx, body, parent) else { continue };
108108
109 if !tcx.consider_optimizing(|| format!("EarlyOtherwiseBranch {:?}", &opt_data)) {
109 if !tcx.consider_optimizing(|| format!("EarlyOtherwiseBranch {opt_data:?}")) {
110110 break;
111111 }
112112
113 trace!("SUCCESS: found optimization possibility to apply: {:?}", &opt_data);
113 trace!("SUCCESS: found optimization possibility to apply: {opt_data:?}");
114114
115115 should_cleanup = true;
116116
compiler/rustc_pattern_analysis/src/constructor.rs+1-1
......@@ -904,7 +904,7 @@ impl<Cx: PatCx> Constructor<Cx> {
904904 // be careful to detect strings here. However a string literal pattern will never
905905 // be reported as a non-exhaustiveness witness, so we can ignore this issue.
906906 Ref => {
907 write!(f, "&{:?}", &fields.next().unwrap())?;
907 write!(f, "&{:?}", fields.next().unwrap())?;
908908 }
909909 Slice(slice) => {
910910 write!(f, "[")?;
compiler/rustc_resolve/src/diagnostics.rs+3-3
......@@ -149,7 +149,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
149149 BuiltinLintDiag::AmbiguousGlobImports { diag },
150150 );
151151 } else {
152 let mut err = struct_span_code_err!(self.dcx(), diag.span, E0659, "{}", &diag.msg);
152 let mut err = struct_span_code_err!(self.dcx(), diag.span, E0659, "{}", diag.msg);
153153 report_ambiguity_error(&mut err, diag);
154154 err.emit();
155155 }
......@@ -798,7 +798,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
798798 }
799799 ResolutionError::FailedToResolve { segment, label, suggestion, module } => {
800800 let mut err =
801 struct_span_code_err!(self.dcx(), span, E0433, "failed to resolve: {}", &label);
801 struct_span_code_err!(self.dcx(), span, E0433, "failed to resolve: {label}");
802802 err.span_label(span, label);
803803
804804 if let Some((suggestions, msg, applicability)) = suggestion {
......@@ -2893,7 +2893,7 @@ fn show_candidates(
28932893 ""
28942894 };
28952895 candidate.0 =
2896 format!("{add_use}{}{append}{trailing}{additional_newline}", &candidate.0);
2896 format!("{add_use}{}{append}{trailing}{additional_newline}", candidate.0);
28972897 }
28982898
28992899 match mode {
compiler/rustc_resolve/src/imports.rs+1-1
......@@ -694,7 +694,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
694694 .collect::<Vec<_>>();
695695 let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
696696
697 let mut diag = struct_span_code_err!(self.dcx(), span, E0432, "{}", &msg);
697 let mut diag = struct_span_code_err!(self.dcx(), span, E0432, "{msg}");
698698
699699 if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
700700 diag.note(note.clone());
compiler/rustc_resolve/src/rustdoc.rs+1-1
......@@ -339,7 +339,7 @@ pub fn strip_generics_from_path(path_str: &str) -> Result<Box<str>, MalformedGen
339339 }
340340 }
341341
342 debug!("path_str: {:?}\nstripped segments: {:?}", path_str, &stripped_segments);
342 debug!("path_str: {path_str:?}\nstripped segments: {stripped_segments:?}");
343343
344344 let stripped_path = stripped_segments.join("::");
345345
compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs+14-14
......@@ -238,12 +238,12 @@ fn encode_predicate<'tcx>(
238238 match predicate.as_ref().skip_binder() {
239239 ty::ExistentialPredicate::Trait(trait_ref) => {
240240 let name = encode_ty_name(tcx, trait_ref.def_id);
241 let _ = write!(s, "u{}{}", name.len(), &name);
241 let _ = write!(s, "u{}{}", name.len(), name);
242242 s.push_str(&encode_args(tcx, trait_ref.args, trait_ref.def_id, true, dict, options));
243243 }
244244 ty::ExistentialPredicate::Projection(projection) => {
245245 let name = encode_ty_name(tcx, projection.def_id);
246 let _ = write!(s, "u{}{}", name.len(), &name);
246 let _ = write!(s, "u{}{}", name.len(), name);
247247 s.push_str(&encode_args(tcx, projection.args, projection.def_id, true, dict, options));
248248 match projection.term.unpack() {
249249 TermKind::Ty(ty) => s.push_str(&encode_ty(tcx, ty, dict, options)),
......@@ -258,7 +258,7 @@ fn encode_predicate<'tcx>(
258258 }
259259 ty::ExistentialPredicate::AutoTrait(def_id) => {
260260 let name = encode_ty_name(tcx, *def_id);
261 let _ = write!(s, "u{}{}", name.len(), &name);
261 let _ = write!(s, "u{}{}", name.len(), name);
262262 }
263263 };
264264 compress(dict, DictKey::Predicate(*predicate.as_ref().skip_binder()), &mut s);
......@@ -416,7 +416,7 @@ pub fn encode_ty<'tcx>(
416416 // A<array-length><element-type>
417417 let len = len.eval_target_usize(tcx, ty::ParamEnv::reveal_all());
418418 let mut s = String::from("A");
419 let _ = write!(s, "{}", &len);
419 let _ = write!(s, "{len}");
420420 s.push_str(&encode_ty(tcx, *ty0, dict, options));
421421 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
422422 typeid.push_str(&s);
......@@ -492,13 +492,13 @@ pub fn encode_ty<'tcx>(
492492 // calling convention (or extern types [i.e., ty::Foreign]) as <length><name>, where
493493 // <name> is <unscoped-name>.
494494 let name = tcx.item_name(def_id).to_string();
495 let _ = write!(s, "{}{}", name.len(), &name);
495 let _ = write!(s, "{}{}", name.len(), name);
496496 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
497497 } else {
498498 // u<length><name>[I<element-type1..element-typeN>E], where <element-type> is
499499 // <subst>, as vendor extended type.
500500 let name = encode_ty_name(tcx, def_id);
501 let _ = write!(s, "u{}{}", name.len(), &name);
501 let _ = write!(s, "u{}{}", name.len(), name);
502502 s.push_str(&encode_args(tcx, args, def_id, false, dict, options));
503503 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
504504 }
......@@ -530,7 +530,7 @@ pub fn encode_ty<'tcx>(
530530 }
531531 } else {
532532 let name = tcx.item_name(*def_id).to_string();
533 let _ = write!(s, "{}{}", name.len(), &name);
533 let _ = write!(s, "{}{}", name.len(), name);
534534 }
535535 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
536536 typeid.push_str(&s);
......@@ -542,7 +542,7 @@ pub fn encode_ty<'tcx>(
542542 // as vendor extended type.
543543 let mut s = String::new();
544544 let name = encode_ty_name(tcx, *def_id);
545 let _ = write!(s, "u{}{}", name.len(), &name);
545 let _ = write!(s, "u{}{}", name.len(), name);
546546 s.push_str(&encode_args(tcx, args, *def_id, false, dict, options));
547547 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
548548 typeid.push_str(&s);
......@@ -553,7 +553,7 @@ pub fn encode_ty<'tcx>(
553553 // as vendor extended type.
554554 let mut s = String::new();
555555 let name = encode_ty_name(tcx, *def_id);
556 let _ = write!(s, "u{}{}", name.len(), &name);
556 let _ = write!(s, "u{}{}", name.len(), name);
557557 let parent_args = tcx.mk_args(args.as_coroutine_closure().parent_args());
558558 s.push_str(&encode_args(tcx, parent_args, *def_id, false, dict, options));
559559 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
......@@ -565,7 +565,7 @@ pub fn encode_ty<'tcx>(
565565 // as vendor extended type.
566566 let mut s = String::new();
567567 let name = encode_ty_name(tcx, *def_id);
568 let _ = write!(s, "u{}{}", name.len(), &name);
568 let _ = write!(s, "u{}{}", name.len(), name);
569569 // Encode parent args only
570570 s.push_str(&encode_args(
571571 tcx,
......@@ -588,7 +588,7 @@ pub fn encode_ty<'tcx>(
588588 s.push('E');
589589 compress(dict, DictKey::Ty(Ty::new_imm_ref(tcx, *region, *ty0), TyQ::None), &mut s);
590590 if ty.is_mutable_ptr() {
591 s = format!("{}{}", "U3mut", &s);
591 s = format!("{}{}", "U3mut", s);
592592 compress(dict, DictKey::Ty(ty, TyQ::Mut), &mut s);
593593 }
594594 typeid.push_str(&s);
......@@ -600,10 +600,10 @@ pub fn encode_ty<'tcx>(
600600 let mut s = String::new();
601601 s.push_str(&encode_ty(tcx, *ptr_ty, dict, options));
602602 if !ty.is_mutable_ptr() {
603 s = format!("{}{}", "K", &s);
603 s = format!("{}{}", "K", s);
604604 compress(dict, DictKey::Ty(*ptr_ty, TyQ::Const), &mut s);
605605 };
606 s = format!("{}{}", "P", &s);
606 s = format!("{}{}", "P", s);
607607 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
608608 typeid.push_str(&s);
609609 }
......@@ -722,7 +722,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
722722 s.push('C');
723723 s.push_str(&to_disambiguator(tcx.stable_crate_id(def_path.krate).as_u64()));
724724 let crate_name = tcx.crate_name(def_path.krate).to_string();
725 let _ = write!(s, "{}{}", crate_name.len(), &crate_name);
725 let _ = write!(s, "{}{}", crate_name.len(), crate_name);
726726
727727 // Disambiguators and names
728728 def_path.data.reverse();
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+34-14
......@@ -1793,25 +1793,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17931793 err.children.clear();
17941794
17951795 let span = obligation.cause.span;
1796 if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span)
1796 let body = self.tcx.hir().body_owned_by(obligation.cause.body_id);
1797
1798 let mut visitor = ReturnsVisitor::default();
1799 visitor.visit_body(&body);
1800
1801 let (pre, impl_span) = if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span)
17971802 && snip.starts_with("dyn ")
17981803 {
1799 err.span_suggestion(
1800 span.with_hi(span.lo() + BytePos(4)),
1801 "return an `impl Trait` instead of a `dyn Trait`, \
1802 if all returned values are the same type",
1804 ("", span.with_hi(span.lo() + BytePos(4)))
1805 } else {
1806 ("dyn ", span.shrink_to_lo())
1807 };
1808 let alternatively = if visitor
1809 .returns
1810 .iter()
1811 .map(|expr| self.typeck_results.as_ref().unwrap().expr_ty_adjusted_opt(expr))
1812 .collect::<FxHashSet<_>>()
1813 .len()
1814 <= 1
1815 {
1816 err.span_suggestion_verbose(
1817 impl_span,
1818 "consider returning an `impl Trait` instead of a `dyn Trait`",
18031819 "impl ",
18041820 Applicability::MaybeIncorrect,
18051821 );
1806 }
1807
1808 let body = self.tcx.hir().body_owned_by(obligation.cause.body_id);
1809
1810 let mut visitor = ReturnsVisitor::default();
1811 visitor.visit_body(&body);
1822 "alternatively, "
1823 } else {
1824 err.help("if there were a single returned type, you could use `impl Trait` instead");
1825 ""
1826 };
18121827
1813 let mut sugg =
1814 vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())];
1828 let mut sugg = vec![
1829 (span.shrink_to_lo(), format!("Box<{pre}")),
1830 (span.shrink_to_hi(), ">".to_string()),
1831 ];
18151832 sugg.extend(visitor.returns.into_iter().flat_map(|expr| {
18161833 let span =
18171834 expr.span.find_ancestor_in_same_ctxt(obligation.cause.span).unwrap_or(expr.span);
......@@ -1837,7 +1854,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
18371854 }));
18381855
18391856 err.multipart_suggestion(
1840 "box the return type, and wrap all of the returned values in `Box::new`",
1857 format!(
1858 "{alternatively}box the return type, and wrap all of the returned values in \
1859 `Box::new`",
1860 ),
18411861 sugg,
18421862 Applicability::MaybeIncorrect,
18431863 );
compiler/rustc_type_ir/src/const_kind.rs+4-6
......@@ -65,15 +65,13 @@ impl<I: Interner> fmt::Debug for ConstKind<I> {
6565
6666 match self {
6767 Param(param) => write!(f, "{param:?}"),
68 Infer(var) => write!(f, "{:?}", &var),
68 Infer(var) => write!(f, "{var:?}"),
6969 Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var),
7070 Placeholder(placeholder) => write!(f, "{placeholder:?}"),
71 Unevaluated(uv) => {
72 write!(f, "{:?}", &uv)
73 }
74 Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &ty),
71 Unevaluated(uv) => write!(f, "{uv:?}"),
72 Value(ty, valtree) => write!(f, "({valtree:?}: {ty:?})"),
7573 Error(_) => write!(f, "{{const error}}"),
76 Expr(expr) => write!(f, "{:?}", &expr),
74 Expr(expr) => write!(f, "{expr:?}"),
7775 }
7876 }
7977}
compiler/rustc_type_ir/src/region_kind.rs+1-1
......@@ -232,7 +232,7 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
232232
233233 ReStatic => f.write_str("'static"),
234234
235 ReVar(vid) => write!(f, "{:?}", &vid),
235 ReVar(vid) => write!(f, "{vid:?}"),
236236
237237 RePlaceholder(placeholder) => write!(f, "{placeholder:?}"),
238238
compiler/rustc_type_ir/src/ty_kind.rs+7-9
......@@ -367,18 +367,16 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
367367 }
368368 Foreign(d) => f.debug_tuple("Foreign").field(d).finish(),
369369 Str => write!(f, "str"),
370 Array(t, c) => write!(f, "[{:?}; {:?}]", &t, &c),
371 Pat(t, p) => write!(f, "pattern_type!({:?} is {:?})", &t, &p),
370 Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
371 Pat(t, p) => write!(f, "pattern_type!({t:?} is {p:?})"),
372372 Slice(t) => write!(f, "[{:?}]", &t),
373373 RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
374374 Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
375375 FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
376 FnPtr(s) => write!(f, "{:?}", &s),
376 FnPtr(s) => write!(f, "{s:?}"),
377377 Dynamic(p, r, repr) => match repr {
378 DynKind::Dyn => write!(f, "dyn {:?} + {:?}", &p, &r),
379 DynKind::DynStar => {
380 write!(f, "dyn* {:?} + {:?}", &p, &r)
381 }
378 DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
379 DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
382380 },
383381 Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(),
384382 CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(),
......@@ -392,7 +390,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
392390 if count > 0 {
393391 write!(f, ", ")?;
394392 }
395 write!(f, "{:?}", &ty)?;
393 write!(f, "{ty:?}")?;
396394 count += 1;
397395 }
398396 // unary tuples need a trailing comma
......@@ -1050,7 +1048,7 @@ impl<I: Interner> fmt::Debug for FnSig<I> {
10501048 if i > 0 {
10511049 write!(f, ", ")?;
10521050 }
1053 write!(f, "{:?}", &ty)?;
1051 write!(f, "{ty:?}")?;
10541052 }
10551053 if *c_variadic {
10561054 if inputs.is_empty() {
compiler/stable_mir/src/mir/pretty.rs+5-5
......@@ -179,7 +179,7 @@ fn pretty_terminator_head<W: Write>(writer: &mut W, terminator: &TerminatorKind)
179179 if !expected {
180180 write!(writer, "!")?;
181181 }
182 write!(writer, "{}, ", &pretty_operand(cond))?;
182 write!(writer, "{}, ", pretty_operand(cond))?;
183183 pretty_assert_message(writer, msg)?;
184184 write!(writer, ")")
185185 }
......@@ -325,7 +325,7 @@ fn pretty_ty_const(ct: &TyConst) -> String {
325325fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
326326 match rval {
327327 Rvalue::AddressOf(mutability, place) => {
328 write!(writer, "&raw {}(*{:?})", &pretty_mut(*mutability), place)
328 write!(writer, "&raw {}(*{:?})", pretty_mut(*mutability), place)
329329 }
330330 Rvalue::Aggregate(aggregate_kind, operands) => {
331331 // FIXME: Add pretty_aggregate function that returns a pretty string
......@@ -336,13 +336,13 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
336336 write!(writer, ")")
337337 }
338338 Rvalue::BinaryOp(bin, op1, op2) => {
339 write!(writer, "{:?}({}, {})", bin, &pretty_operand(op1), pretty_operand(op2))
339 write!(writer, "{:?}({}, {})", bin, pretty_operand(op1), pretty_operand(op2))
340340 }
341341 Rvalue::Cast(_, op, ty) => {
342342 write!(writer, "{} as {}", pretty_operand(op), ty)
343343 }
344344 Rvalue::CheckedBinaryOp(bin, op1, op2) => {
345 write!(writer, "Checked{:?}({}, {})", bin, &pretty_operand(op1), pretty_operand(op2))
345 write!(writer, "Checked{:?}({}, {})", bin, pretty_operand(op1), pretty_operand(op2))
346346 }
347347 Rvalue::CopyForDeref(deref) => {
348348 write!(writer, "CopyForDeref({:?})", deref)
......@@ -363,7 +363,7 @@ fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
363363 write!(writer, "{kind}{:?}", place)
364364 }
365365 Rvalue::Repeat(op, cnst) => {
366 write!(writer, "{} \" \" {}", &pretty_operand(op), &pretty_ty_const(cnst))
366 write!(writer, "{} \" \" {}", pretty_operand(op), pretty_ty_const(cnst))
367367 }
368368 Rvalue::ShallowInitBox(_, _) => Ok(()),
369369 Rvalue::ThreadLocalRef(item) => {
config.example.toml+1
......@@ -333,6 +333,7 @@
333333# "rust-analyzer-proc-macro-srv",
334334# "analysis",
335335# "src",
336# "wasm-component-ld",
336337#]
337338
338339# Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose, 3 == print environment variables on each rustc invocation
library/std/Cargo.toml+1-1
......@@ -56,7 +56,7 @@ hermit-abi = { version = "0.4.0", features = ['rustc-dep-of-std'], public = true
5656wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
5757
5858[target.'cfg(target_os = "uefi")'.dependencies]
59r-efi = { version = "4.2.0", features = ['rustc-dep-of-std'] }
59r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] }
6060r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] }
6161
6262[features]
library/std/src/lib.rs+1
......@@ -293,6 +293,7 @@
293293#![feature(doc_masked)]
294294#![feature(doc_notable_trait)]
295295#![feature(dropck_eyepatch)]
296#![feature(extended_varargs_abi_support)]
296297#![feature(f128)]
297298#![feature(f16)]
298299#![feature(if_let_guard)]
library/std/src/sys/pal/uefi/helpers.rs+197-2
......@@ -12,15 +12,21 @@
1212use r_efi::efi::{self, Guid};
1313use r_efi::protocols::{device_path, device_path_to_text};
1414
15use crate::ffi::OsString;
15use crate::ffi::{OsStr, OsString};
1616use crate::io::{self, const_io_error};
1717use crate::mem::{size_of, MaybeUninit};
18use crate::os::uefi::{self, env::boot_services, ffi::OsStringExt};
18use crate::os::uefi::{self, env::boot_services, ffi::OsStrExt, ffi::OsStringExt};
1919use crate::ptr::NonNull;
2020use crate::slice;
2121use crate::sync::atomic::{AtomicPtr, Ordering};
2222use crate::sys_common::wstr::WStrUnits;
2323
24type BootInstallMultipleProtocolInterfaces =
25 unsafe extern "efiapi" fn(_: *mut r_efi::efi::Handle, _: ...) -> r_efi::efi::Status;
26
27type BootUninstallMultipleProtocolInterfaces =
28 unsafe extern "efiapi" fn(_: r_efi::efi::Handle, _: ...) -> r_efi::efi::Status;
29
2430const BOOT_SERVICES_UNAVAILABLE: io::Error =
2531 const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");
2632
......@@ -221,3 +227,192 @@ pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>>
221227 let runtime_services = unsafe { (*system_table.as_ptr()).runtime_services };
222228 NonNull::new(runtime_services)
223229}
230
231pub(crate) struct DevicePath(NonNull<r_efi::protocols::device_path::Protocol>);
232
233impl DevicePath {
234 pub(crate) fn from_text(p: &OsStr) -> io::Result<Self> {
235 fn inner(
236 p: &OsStr,
237 protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>,
238 ) -> io::Result<DevicePath> {
239 let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec<u16>>();
240 if path_vec[..path_vec.len() - 1].contains(&0) {
241 return Err(const_io_error!(
242 io::ErrorKind::InvalidInput,
243 "strings passed to UEFI cannot contain NULs",
244 ));
245 }
246
247 let path =
248 unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };
249
250 NonNull::new(path).map(DevicePath).ok_or_else(|| {
251 const_io_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")
252 })
253 }
254
255 static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> =
256 AtomicPtr::new(crate::ptr::null_mut());
257
258 if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {
259 if let Ok(protocol) = open_protocol::<r_efi::protocols::device_path_from_text::Protocol>(
260 handle,
261 r_efi::protocols::device_path_from_text::PROTOCOL_GUID,
262 ) {
263 return inner(p, protocol);
264 }
265 }
266
267 let handles = locate_handles(r_efi::protocols::device_path_from_text::PROTOCOL_GUID)?;
268 for handle in handles {
269 if let Ok(protocol) = open_protocol::<r_efi::protocols::device_path_from_text::Protocol>(
270 handle,
271 r_efi::protocols::device_path_from_text::PROTOCOL_GUID,
272 ) {
273 LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);
274 return inner(p, protocol);
275 }
276 }
277
278 io::Result::Err(const_io_error!(
279 io::ErrorKind::NotFound,
280 "DevicePathFromText Protocol not found"
281 ))
282 }
283
284 pub(crate) fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol {
285 self.0.as_ptr()
286 }
287}
288
289impl Drop for DevicePath {
290 fn drop(&mut self) {
291 if let Some(bt) = boot_services() {
292 let bt: NonNull<r_efi::efi::BootServices> = bt.cast();
293 unsafe {
294 ((*bt.as_ptr()).free_pool)(self.0.as_ptr() as *mut crate::ffi::c_void);
295 }
296 }
297 }
298}
299
300pub(crate) struct OwnedProtocol<T> {
301 guid: r_efi::efi::Guid,
302 handle: NonNull<crate::ffi::c_void>,
303 protocol: *mut T,
304}
305
306impl<T> OwnedProtocol<T> {
307 // FIXME: Consider using unsafe trait for matching protocol with guid
308 pub(crate) unsafe fn create(protocol: T, mut guid: r_efi::efi::Guid) -> io::Result<Self> {
309 let bt: NonNull<r_efi::efi::BootServices> =
310 boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
311 let protocol: *mut T = Box::into_raw(Box::new(protocol));
312 let mut handle: r_efi::efi::Handle = crate::ptr::null_mut();
313
314 // FIXME: Move into r-efi once extended_varargs_abi_support is stablized
315 let func: BootInstallMultipleProtocolInterfaces =
316 unsafe { crate::mem::transmute((*bt.as_ptr()).install_multiple_protocol_interfaces) };
317
318 let r = unsafe {
319 func(
320 &mut handle,
321 &mut guid as *mut _ as *mut crate::ffi::c_void,
322 protocol as *mut crate::ffi::c_void,
323 crate::ptr::null_mut() as *mut crate::ffi::c_void,
324 )
325 };
326
327 if r.is_error() {
328 drop(unsafe { Box::from_raw(protocol) });
329 return Err(crate::io::Error::from_raw_os_error(r.as_usize()));
330 };
331
332 let handle = NonNull::new(handle)
333 .ok_or(io::const_io_error!(io::ErrorKind::Uncategorized, "found null handle"))?;
334
335 Ok(Self { guid, handle, protocol })
336 }
337
338 pub(crate) fn handle(&self) -> NonNull<crate::ffi::c_void> {
339 self.handle
340 }
341}
342
343impl<T> Drop for OwnedProtocol<T> {
344 fn drop(&mut self) {
345 // Do not deallocate a runtime protocol
346 if let Some(bt) = boot_services() {
347 let bt: NonNull<r_efi::efi::BootServices> = bt.cast();
348 // FIXME: Move into r-efi once extended_varargs_abi_support is stablized
349 let func: BootUninstallMultipleProtocolInterfaces = unsafe {
350 crate::mem::transmute((*bt.as_ptr()).uninstall_multiple_protocol_interfaces)
351 };
352 let status = unsafe {
353 func(
354 self.handle.as_ptr(),
355 &mut self.guid as *mut _ as *mut crate::ffi::c_void,
356 self.protocol as *mut crate::ffi::c_void,
357 crate::ptr::null_mut() as *mut crate::ffi::c_void,
358 )
359 };
360
361 // Leak the protocol in case uninstall fails
362 if status == r_efi::efi::Status::SUCCESS {
363 let _ = unsafe { Box::from_raw(self.protocol) };
364 }
365 }
366 }
367}
368
369impl<T> AsRef<T> for OwnedProtocol<T> {
370 fn as_ref(&self) -> &T {
371 unsafe { self.protocol.as_ref().unwrap() }
372 }
373}
374
375pub(crate) struct OwnedTable<T> {
376 layout: crate::alloc::Layout,
377 ptr: *mut T,
378}
379
380impl<T> OwnedTable<T> {
381 pub(crate) fn from_table_header(hdr: &r_efi::efi::TableHeader) -> Self {
382 let header_size = hdr.header_size as usize;
383 let layout = crate::alloc::Layout::from_size_align(header_size, 8).unwrap();
384 let ptr = unsafe { crate::alloc::alloc(layout) as *mut T };
385 Self { layout, ptr }
386 }
387
388 pub(crate) const fn as_ptr(&self) -> *const T {
389 self.ptr
390 }
391
392 pub(crate) const fn as_mut_ptr(&self) -> *mut T {
393 self.ptr
394 }
395}
396
397impl OwnedTable<r_efi::efi::SystemTable> {
398 pub(crate) fn from_table(tbl: *const r_efi::efi::SystemTable) -> Self {
399 let hdr = unsafe { (*tbl).hdr };
400
401 let owned_tbl = Self::from_table_header(&hdr);
402 unsafe {
403 crate::ptr::copy_nonoverlapping(
404 tbl as *const u8,
405 owned_tbl.as_mut_ptr() as *mut u8,
406 hdr.header_size as usize,
407 )
408 };
409
410 owned_tbl
411 }
412}
413
414impl<T> Drop for OwnedTable<T> {
415 fn drop(&mut self) {
416 unsafe { crate::alloc::dealloc(self.ptr as *mut u8, self.layout) };
417 }
418}
library/std/src/sys/pal/uefi/mod.rs-1
......@@ -25,7 +25,6 @@ pub mod net;
2525pub mod os;
2626#[path = "../unsupported/pipe.rs"]
2727pub mod pipe;
28#[path = "../unsupported/process.rs"]
2928pub mod process;
3029pub mod stdio;
3130pub mod thread;
library/std/src/sys/pal/uefi/process.rs created+689
......@@ -0,0 +1,689 @@
1use r_efi::protocols::simple_text_output;
2
3use crate::ffi::OsStr;
4use crate::ffi::OsString;
5use crate::fmt;
6use crate::io;
7use crate::num::NonZero;
8use crate::num::NonZeroI32;
9use crate::path::Path;
10use crate::sys::fs::File;
11use crate::sys::pipe::AnonPipe;
12use crate::sys::unsupported;
13use crate::sys_common::process::{CommandEnv, CommandEnvs};
14
15pub use crate::ffi::OsString as EnvKey;
16
17use super::helpers;
18
19////////////////////////////////////////////////////////////////////////////////
20// Command
21////////////////////////////////////////////////////////////////////////////////
22
23#[derive(Debug)]
24pub struct Command {
25 prog: OsString,
26 stdout: Option<Stdio>,
27 stderr: Option<Stdio>,
28}
29
30// passed back to std::process with the pipes connected to the child, if any
31// were requested
32pub struct StdioPipes {
33 pub stdin: Option<AnonPipe>,
34 pub stdout: Option<AnonPipe>,
35 pub stderr: Option<AnonPipe>,
36}
37
38#[derive(Copy, Clone, Debug)]
39pub enum Stdio {
40 Inherit,
41 Null,
42 MakePipe,
43}
44
45impl Command {
46 pub fn new(program: &OsStr) -> Command {
47 Command { prog: program.to_os_string(), stdout: None, stderr: None }
48 }
49
50 // FIXME: Implement arguments as reverse of parsing algorithm
51 pub fn arg(&mut self, _arg: &OsStr) {
52 panic!("unsupported")
53 }
54
55 pub fn env_mut(&mut self) -> &mut CommandEnv {
56 panic!("unsupported")
57 }
58
59 pub fn cwd(&mut self, _dir: &OsStr) {
60 panic!("unsupported")
61 }
62
63 pub fn stdin(&mut self, _stdin: Stdio) {
64 panic!("unsupported")
65 }
66
67 pub fn stdout(&mut self, stdout: Stdio) {
68 self.stdout = Some(stdout);
69 }
70
71 pub fn stderr(&mut self, stderr: Stdio) {
72 self.stderr = Some(stderr);
73 }
74
75 pub fn get_program(&self) -> &OsStr {
76 self.prog.as_ref()
77 }
78
79 pub fn get_args(&self) -> CommandArgs<'_> {
80 panic!("unsupported")
81 }
82
83 pub fn get_envs(&self) -> CommandEnvs<'_> {
84 panic!("unsupported")
85 }
86
87 pub fn get_current_dir(&self) -> Option<&Path> {
88 None
89 }
90
91 pub fn spawn(
92 &mut self,
93 _default: Stdio,
94 _needs_stdin: bool,
95 ) -> io::Result<(Process, StdioPipes)> {
96 unsupported()
97 }
98
99 fn create_pipe(
100 s: Stdio,
101 ) -> io::Result<Option<helpers::OwnedProtocol<uefi_command_internal::PipeProtocol>>> {
102 match s {
103 Stdio::MakePipe => unsafe {
104 helpers::OwnedProtocol::create(
105 uefi_command_internal::PipeProtocol::new(),
106 simple_text_output::PROTOCOL_GUID,
107 )
108 }
109 .map(Some),
110 Stdio::Null => unsafe {
111 helpers::OwnedProtocol::create(
112 uefi_command_internal::PipeProtocol::null(),
113 simple_text_output::PROTOCOL_GUID,
114 )
115 }
116 .map(Some),
117 Stdio::Inherit => Ok(None),
118 }
119 }
120
121 pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
122 let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?;
123
124 // Setup Stdout
125 let stdout = self.stdout.unwrap_or(Stdio::MakePipe);
126 let stdout = Self::create_pipe(stdout)?;
127 if let Some(con) = stdout {
128 cmd.stdout_init(con)
129 } else {
130 cmd.stdout_inherit()
131 };
132
133 // Setup Stderr
134 let stderr = self.stderr.unwrap_or(Stdio::MakePipe);
135 let stderr = Self::create_pipe(stderr)?;
136 if let Some(con) = stderr {
137 cmd.stderr_init(con)
138 } else {
139 cmd.stderr_inherit()
140 };
141
142 let stat = cmd.start_image()?;
143
144 let stdout = cmd.stdout()?;
145 let stderr = cmd.stderr()?;
146
147 Ok((ExitStatus(stat), stdout, stderr))
148 }
149}
150
151impl From<AnonPipe> for Stdio {
152 fn from(pipe: AnonPipe) -> Stdio {
153 pipe.diverge()
154 }
155}
156
157impl From<io::Stdout> for Stdio {
158 fn from(_: io::Stdout) -> Stdio {
159 // FIXME: This is wrong.
160 // Instead, the Stdio we have here should be a unit struct.
161 panic!("unsupported")
162 }
163}
164
165impl From<io::Stderr> for Stdio {
166 fn from(_: io::Stderr) -> Stdio {
167 // FIXME: This is wrong.
168 // Instead, the Stdio we have here should be a unit struct.
169 panic!("unsupported")
170 }
171}
172
173impl From<File> for Stdio {
174 fn from(_file: File) -> Stdio {
175 // FIXME: This is wrong.
176 // Instead, the Stdio we have here should be a unit struct.
177 panic!("unsupported")
178 }
179}
180
181#[derive(PartialEq, Eq, Clone, Copy, Debug)]
182#[non_exhaustive]
183pub struct ExitStatus(r_efi::efi::Status);
184
185impl ExitStatus {
186 pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
187 if self.0 == r_efi::efi::Status::SUCCESS { Ok(()) } else { Err(ExitStatusError(self.0)) }
188 }
189
190 pub fn code(&self) -> Option<i32> {
191 Some(self.0.as_usize() as i32)
192 }
193}
194
195impl fmt::Display for ExitStatus {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 let err_str = super::os::error_string(self.0.as_usize());
198 write!(f, "{}", err_str)
199 }
200}
201
202impl Default for ExitStatus {
203 fn default() -> Self {
204 ExitStatus(r_efi::efi::Status::SUCCESS)
205 }
206}
207
208#[derive(Clone, Copy, PartialEq, Eq)]
209pub struct ExitStatusError(r_efi::efi::Status);
210
211impl fmt::Debug for ExitStatusError {
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 let err_str = super::os::error_string(self.0.as_usize());
214 write!(f, "{}", err_str)
215 }
216}
217
218impl Into<ExitStatus> for ExitStatusError {
219 fn into(self) -> ExitStatus {
220 ExitStatus(self.0)
221 }
222}
223
224impl ExitStatusError {
225 pub fn code(self) -> Option<NonZero<i32>> {
226 NonZeroI32::new(self.0.as_usize() as i32)
227 }
228}
229
230#[derive(PartialEq, Eq, Clone, Copy, Debug)]
231pub struct ExitCode(bool);
232
233impl ExitCode {
234 pub const SUCCESS: ExitCode = ExitCode(false);
235 pub const FAILURE: ExitCode = ExitCode(true);
236
237 pub fn as_i32(&self) -> i32 {
238 self.0 as i32
239 }
240}
241
242impl From<u8> for ExitCode {
243 fn from(code: u8) -> Self {
244 match code {
245 0 => Self::SUCCESS,
246 1..=255 => Self::FAILURE,
247 }
248 }
249}
250
251pub struct Process(!);
252
253impl Process {
254 pub fn id(&self) -> u32 {
255 self.0
256 }
257
258 pub fn kill(&mut self) -> io::Result<()> {
259 self.0
260 }
261
262 pub fn wait(&mut self) -> io::Result<ExitStatus> {
263 self.0
264 }
265
266 pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
267 self.0
268 }
269}
270
271pub struct CommandArgs<'a> {
272 iter: crate::slice::Iter<'a, OsString>,
273}
274
275impl<'a> Iterator for CommandArgs<'a> {
276 type Item = &'a OsStr;
277
278 fn next(&mut self) -> Option<&'a OsStr> {
279 self.iter.next().map(|x| x.as_ref())
280 }
281
282 fn size_hint(&self) -> (usize, Option<usize>) {
283 self.iter.size_hint()
284 }
285}
286
287impl<'a> ExactSizeIterator for CommandArgs<'a> {
288 fn len(&self) -> usize {
289 self.iter.len()
290 }
291
292 fn is_empty(&self) -> bool {
293 self.iter.is_empty()
294 }
295}
296
297impl<'a> fmt::Debug for CommandArgs<'a> {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 f.debug_list().entries(self.iter.clone()).finish()
300 }
301}
302
303#[allow(dead_code)]
304mod uefi_command_internal {
305 use r_efi::protocols::{loaded_image, simple_text_output};
306
307 use super::super::helpers;
308 use crate::ffi::{OsStr, OsString};
309 use crate::io::{self, const_io_error};
310 use crate::mem::MaybeUninit;
311 use crate::os::uefi::env::{boot_services, image_handle, system_table};
312 use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
313 use crate::ptr::NonNull;
314 use crate::slice;
315 use crate::sys::pal::uefi::helpers::OwnedTable;
316 use crate::sys_common::wstr::WStrUnits;
317
318 pub struct Image {
319 handle: NonNull<crate::ffi::c_void>,
320 stdout: Option<helpers::OwnedProtocol<PipeProtocol>>,
321 stderr: Option<helpers::OwnedProtocol<PipeProtocol>>,
322 st: OwnedTable<r_efi::efi::SystemTable>,
323 args: Option<Vec<u16>>,
324 }
325
326 impl Image {
327 pub fn load_image(p: &OsStr) -> io::Result<Self> {
328 let path = helpers::DevicePath::from_text(p)?;
329 let boot_services: NonNull<r_efi::efi::BootServices> = boot_services()
330 .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
331 .cast();
332 let mut child_handle: MaybeUninit<r_efi::efi::Handle> = MaybeUninit::uninit();
333 let image_handle = image_handle();
334
335 let r = unsafe {
336 ((*boot_services.as_ptr()).load_image)(
337 r_efi::efi::Boolean::FALSE,
338 image_handle.as_ptr(),
339 path.as_ptr(),
340 crate::ptr::null_mut(),
341 0,
342 child_handle.as_mut_ptr(),
343 )
344 };
345
346 if r.is_error() {
347 Err(io::Error::from_raw_os_error(r.as_usize()))
348 } else {
349 let child_handle = unsafe { child_handle.assume_init() };
350 let child_handle = NonNull::new(child_handle).unwrap();
351
352 let loaded_image: NonNull<loaded_image::Protocol> =
353 helpers::open_protocol(child_handle, loaded_image::PROTOCOL_GUID).unwrap();
354 let st = OwnedTable::from_table(unsafe { (*loaded_image.as_ptr()).system_table });
355
356 Ok(Self { handle: child_handle, stdout: None, stderr: None, st, args: None })
357 }
358 }
359
360 pub fn start_image(&mut self) -> io::Result<r_efi::efi::Status> {
361 self.update_st_crc32()?;
362
363 // Use our system table instead of the default one
364 let loaded_image: NonNull<loaded_image::Protocol> =
365 helpers::open_protocol(self.handle, loaded_image::PROTOCOL_GUID).unwrap();
366 unsafe {
367 (*loaded_image.as_ptr()).system_table = self.st.as_mut_ptr();
368 }
369
370 let boot_services: NonNull<r_efi::efi::BootServices> = boot_services()
371 .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
372 .cast();
373 let mut exit_data_size: usize = 0;
374 let mut exit_data: MaybeUninit<*mut u16> = MaybeUninit::uninit();
375
376 let r = unsafe {
377 ((*boot_services.as_ptr()).start_image)(
378 self.handle.as_ptr(),
379 &mut exit_data_size,
380 exit_data.as_mut_ptr(),
381 )
382 };
383
384 // Drop exitdata
385 if exit_data_size != 0 {
386 unsafe {
387 let exit_data = exit_data.assume_init();
388 ((*boot_services.as_ptr()).free_pool)(exit_data as *mut crate::ffi::c_void);
389 }
390 }
391
392 Ok(r)
393 }
394
395 fn set_stdout(
396 &mut self,
397 handle: r_efi::efi::Handle,
398 protocol: *mut simple_text_output::Protocol,
399 ) {
400 unsafe {
401 (*self.st.as_mut_ptr()).console_out_handle = handle;
402 (*self.st.as_mut_ptr()).con_out = protocol;
403 }
404 }
405
406 fn set_stderr(
407 &mut self,
408 handle: r_efi::efi::Handle,
409 protocol: *mut simple_text_output::Protocol,
410 ) {
411 unsafe {
412 (*self.st.as_mut_ptr()).standard_error_handle = handle;
413 (*self.st.as_mut_ptr()).std_err = protocol;
414 }
415 }
416
417 pub fn stdout_init(&mut self, protocol: helpers::OwnedProtocol<PipeProtocol>) {
418 self.set_stdout(
419 protocol.handle().as_ptr(),
420 protocol.as_ref() as *const PipeProtocol as *mut simple_text_output::Protocol,
421 );
422 self.stdout = Some(protocol);
423 }
424
425 pub fn stdout_inherit(&mut self) {
426 let st: NonNull<r_efi::efi::SystemTable> = system_table().cast();
427 unsafe { self.set_stdout((*st.as_ptr()).console_out_handle, (*st.as_ptr()).con_out) }
428 }
429
430 pub fn stderr_init(&mut self, protocol: helpers::OwnedProtocol<PipeProtocol>) {
431 self.set_stderr(
432 protocol.handle().as_ptr(),
433 protocol.as_ref() as *const PipeProtocol as *mut simple_text_output::Protocol,
434 );
435 self.stderr = Some(protocol);
436 }
437
438 pub fn stderr_inherit(&mut self) {
439 let st: NonNull<r_efi::efi::SystemTable> = system_table().cast();
440 unsafe { self.set_stderr((*st.as_ptr()).standard_error_handle, (*st.as_ptr()).std_err) }
441 }
442
443 pub fn stderr(&self) -> io::Result<Vec<u8>> {
444 match &self.stderr {
445 Some(stderr) => stderr.as_ref().utf8(),
446 None => Ok(Vec::new()),
447 }
448 }
449
450 pub fn stdout(&self) -> io::Result<Vec<u8>> {
451 match &self.stdout {
452 Some(stdout) => stdout.as_ref().utf8(),
453 None => Ok(Vec::new()),
454 }
455 }
456
457 pub fn set_args(&mut self, args: &OsStr) {
458 let loaded_image: NonNull<loaded_image::Protocol> =
459 helpers::open_protocol(self.handle, loaded_image::PROTOCOL_GUID).unwrap();
460
461 let mut args = args.encode_wide().collect::<Vec<u16>>();
462 let args_size = (crate::mem::size_of::<u16>() * args.len()) as u32;
463
464 unsafe {
465 (*loaded_image.as_ptr()).load_options =
466 args.as_mut_ptr() as *mut crate::ffi::c_void;
467 (*loaded_image.as_ptr()).load_options_size = args_size;
468 }
469
470 self.args = Some(args);
471 }
472
473 fn update_st_crc32(&mut self) -> io::Result<()> {
474 let bt: NonNull<r_efi::efi::BootServices> = boot_services().unwrap().cast();
475 let st_size = unsafe { (*self.st.as_ptr()).hdr.header_size as usize };
476 let mut crc32: u32 = 0;
477
478 // Set crc to 0 before calcuation
479 unsafe {
480 (*self.st.as_mut_ptr()).hdr.crc32 = 0;
481 }
482
483 let r = unsafe {
484 ((*bt.as_ptr()).calculate_crc32)(
485 self.st.as_mut_ptr() as *mut crate::ffi::c_void,
486 st_size,
487 &mut crc32,
488 )
489 };
490
491 if r.is_error() {
492 Err(io::Error::from_raw_os_error(r.as_usize()))
493 } else {
494 unsafe {
495 (*self.st.as_mut_ptr()).hdr.crc32 = crc32;
496 }
497 Ok(())
498 }
499 }
500 }
501
502 impl Drop for Image {
503 fn drop(&mut self) {
504 if let Some(bt) = boot_services() {
505 let bt: NonNull<r_efi::efi::BootServices> = bt.cast();
506 unsafe {
507 ((*bt.as_ptr()).unload_image)(self.handle.as_ptr());
508 }
509 }
510 }
511 }
512
513 #[repr(C)]
514 pub struct PipeProtocol {
515 reset: simple_text_output::ProtocolReset,
516 output_string: simple_text_output::ProtocolOutputString,
517 test_string: simple_text_output::ProtocolTestString,
518 query_mode: simple_text_output::ProtocolQueryMode,
519 set_mode: simple_text_output::ProtocolSetMode,
520 set_attribute: simple_text_output::ProtocolSetAttribute,
521 clear_screen: simple_text_output::ProtocolClearScreen,
522 set_cursor_position: simple_text_output::ProtocolSetCursorPosition,
523 enable_cursor: simple_text_output::ProtocolEnableCursor,
524 mode: *mut simple_text_output::Mode,
525 _buffer: Vec<u16>,
526 }
527
528 impl PipeProtocol {
529 pub fn new() -> Self {
530 let mode = Box::new(simple_text_output::Mode {
531 max_mode: 0,
532 mode: 0,
533 attribute: 0,
534 cursor_column: 0,
535 cursor_row: 0,
536 cursor_visible: r_efi::efi::Boolean::FALSE,
537 });
538 Self {
539 reset: Self::reset,
540 output_string: Self::output_string,
541 test_string: Self::test_string,
542 query_mode: Self::query_mode,
543 set_mode: Self::set_mode,
544 set_attribute: Self::set_attribute,
545 clear_screen: Self::clear_screen,
546 set_cursor_position: Self::set_cursor_position,
547 enable_cursor: Self::enable_cursor,
548 mode: Box::into_raw(mode),
549 _buffer: Vec::new(),
550 }
551 }
552
553 pub fn null() -> Self {
554 let mode = Box::new(simple_text_output::Mode {
555 max_mode: 0,
556 mode: 0,
557 attribute: 0,
558 cursor_column: 0,
559 cursor_row: 0,
560 cursor_visible: r_efi::efi::Boolean::FALSE,
561 });
562 Self {
563 reset: Self::reset_null,
564 output_string: Self::output_string_null,
565 test_string: Self::test_string,
566 query_mode: Self::query_mode,
567 set_mode: Self::set_mode,
568 set_attribute: Self::set_attribute,
569 clear_screen: Self::clear_screen,
570 set_cursor_position: Self::set_cursor_position,
571 enable_cursor: Self::enable_cursor,
572 mode: Box::into_raw(mode),
573 _buffer: Vec::new(),
574 }
575 }
576
577 pub fn utf8(&self) -> io::Result<Vec<u8>> {
578 OsString::from_wide(&self._buffer)
579 .into_string()
580 .map(Into::into)
581 .map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed"))
582 }
583
584 extern "efiapi" fn reset(
585 proto: *mut simple_text_output::Protocol,
586 _: r_efi::efi::Boolean,
587 ) -> r_efi::efi::Status {
588 let proto: *mut PipeProtocol = proto.cast();
589 unsafe {
590 (*proto)._buffer.clear();
591 }
592 r_efi::efi::Status::SUCCESS
593 }
594
595 extern "efiapi" fn reset_null(
596 _: *mut simple_text_output::Protocol,
597 _: r_efi::efi::Boolean,
598 ) -> r_efi::efi::Status {
599 r_efi::efi::Status::SUCCESS
600 }
601
602 extern "efiapi" fn output_string(
603 proto: *mut simple_text_output::Protocol,
604 buf: *mut r_efi::efi::Char16,
605 ) -> r_efi::efi::Status {
606 let proto: *mut PipeProtocol = proto.cast();
607 let buf_len = unsafe {
608 if let Some(x) = WStrUnits::new(buf) {
609 x.count()
610 } else {
611 return r_efi::efi::Status::INVALID_PARAMETER;
612 }
613 };
614 let buf_slice = unsafe { slice::from_raw_parts(buf, buf_len) };
615
616 unsafe {
617 (*proto)._buffer.extend_from_slice(buf_slice);
618 };
619
620 r_efi::efi::Status::SUCCESS
621 }
622
623 extern "efiapi" fn output_string_null(
624 _: *mut simple_text_output::Protocol,
625 _: *mut r_efi::efi::Char16,
626 ) -> r_efi::efi::Status {
627 r_efi::efi::Status::SUCCESS
628 }
629
630 extern "efiapi" fn test_string(
631 _: *mut simple_text_output::Protocol,
632 _: *mut r_efi::efi::Char16,
633 ) -> r_efi::efi::Status {
634 r_efi::efi::Status::SUCCESS
635 }
636
637 extern "efiapi" fn query_mode(
638 _: *mut simple_text_output::Protocol,
639 _: usize,
640 _: *mut usize,
641 _: *mut usize,
642 ) -> r_efi::efi::Status {
643 r_efi::efi::Status::UNSUPPORTED
644 }
645
646 extern "efiapi" fn set_mode(
647 _: *mut simple_text_output::Protocol,
648 _: usize,
649 ) -> r_efi::efi::Status {
650 r_efi::efi::Status::UNSUPPORTED
651 }
652
653 extern "efiapi" fn set_attribute(
654 _: *mut simple_text_output::Protocol,
655 _: usize,
656 ) -> r_efi::efi::Status {
657 r_efi::efi::Status::UNSUPPORTED
658 }
659
660 extern "efiapi" fn clear_screen(
661 _: *mut simple_text_output::Protocol,
662 ) -> r_efi::efi::Status {
663 r_efi::efi::Status::UNSUPPORTED
664 }
665
666 extern "efiapi" fn set_cursor_position(
667 _: *mut simple_text_output::Protocol,
668 _: usize,
669 _: usize,
670 ) -> r_efi::efi::Status {
671 r_efi::efi::Status::UNSUPPORTED
672 }
673
674 extern "efiapi" fn enable_cursor(
675 _: *mut simple_text_output::Protocol,
676 _: r_efi::efi::Boolean,
677 ) -> r_efi::efi::Status {
678 r_efi::efi::Status::UNSUPPORTED
679 }
680 }
681
682 impl Drop for PipeProtocol {
683 fn drop(&mut self) {
684 unsafe {
685 let _ = Box::from_raw(self.mode);
686 }
687 }
688 }
689}
library/std/src/thread/mod.rs+51-23
......@@ -161,7 +161,7 @@ mod tests;
161161use crate::any::Any;
162162use crate::cell::{Cell, OnceCell, UnsafeCell};
163163use crate::env;
164use crate::ffi::{CStr, CString};
164use crate::ffi::CStr;
165165use crate::fmt;
166166use crate::io;
167167use crate::marker::PhantomData;
......@@ -487,11 +487,7 @@ impl Builder {
487487 amt
488488 });
489489
490 let my_thread = name.map_or_else(Thread::new_unnamed, |name| unsafe {
491 Thread::new(
492 CString::new(name).expect("thread name may not contain interior null bytes"),
493 )
494 });
490 let my_thread = name.map_or_else(Thread::new_unnamed, Thread::new);
495491 let their_thread = my_thread.clone();
496492
497493 let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {
......@@ -1299,10 +1295,51 @@ impl ThreadId {
12991295/// The internal representation of a `Thread`'s name.
13001296enum ThreadName {
13011297 Main,
1302 Other(CString),
1298 Other(ThreadNameString),
13031299 Unnamed,
13041300}
13051301
1302// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
1303mod thread_name_string {
1304 use super::ThreadName;
1305 use crate::ffi::{CStr, CString};
1306 use core::str;
1307
1308 /// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
1309 pub(crate) struct ThreadNameString {
1310 inner: CString,
1311 }
1312 impl core::ops::Deref for ThreadNameString {
1313 type Target = CStr;
1314 fn deref(&self) -> &CStr {
1315 &self.inner
1316 }
1317 }
1318 impl From<String> for ThreadNameString {
1319 fn from(s: String) -> Self {
1320 Self {
1321 inner: CString::new(s).expect("thread name may not contain interior null bytes"),
1322 }
1323 }
1324 }
1325 impl ThreadName {
1326 pub fn as_cstr(&self) -> Option<&CStr> {
1327 match self {
1328 ThreadName::Main => Some(c"main"),
1329 ThreadName::Other(other) => Some(other),
1330 ThreadName::Unnamed => None,
1331 }
1332 }
1333
1334 pub fn as_str(&self) -> Option<&str> {
1335 // SAFETY: `as_cstr` can only return `Some` for a fixed CStr or a `ThreadNameString`,
1336 // which is guaranteed to be UTF-8.
1337 self.as_cstr().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
1338 }
1339 }
1340}
1341pub(crate) use thread_name_string::ThreadNameString;
1342
13061343/// The internal representation of a `Thread` handle
13071344struct Inner {
13081345 name: ThreadName, // Guaranteed to be UTF-8
......@@ -1342,25 +1379,20 @@ pub struct Thread {
13421379
13431380impl Thread {
13441381 /// Used only internally to construct a thread object without spawning.
1345 ///
1346 /// # Safety
1347 /// `name` must be valid UTF-8.
1348 pub(crate) unsafe fn new(name: CString) -> Thread {
1349 unsafe { Self::new_inner(ThreadName::Other(name)) }
1382 pub(crate) fn new(name: String) -> Thread {
1383 Self::new_inner(ThreadName::Other(name.into()))
13501384 }
13511385
13521386 pub(crate) fn new_unnamed() -> Thread {
1353 unsafe { Self::new_inner(ThreadName::Unnamed) }
1387 Self::new_inner(ThreadName::Unnamed)
13541388 }
13551389
13561390 // Used in runtime to construct main thread
13571391 pub(crate) fn new_main() -> Thread {
1358 unsafe { Self::new_inner(ThreadName::Main) }
1392 Self::new_inner(ThreadName::Main)
13591393 }
13601394
1361 /// # Safety
1362 /// If `name` is `ThreadName::Other(_)`, the contained string must be valid UTF-8.
1363 unsafe fn new_inner(name: ThreadName) -> Thread {
1395 fn new_inner(name: ThreadName) -> Thread {
13641396 // We have to use `unsafe` here to construct the `Parker` in-place,
13651397 // which is required for the UNIX implementation.
13661398 //
......@@ -1483,15 +1515,11 @@ impl Thread {
14831515 #[stable(feature = "rust1", since = "1.0.0")]
14841516 #[must_use]
14851517 pub fn name(&self) -> Option<&str> {
1486 self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
1518 self.inner.name.as_str()
14871519 }
14881520
14891521 fn cname(&self) -> Option<&CStr> {
1490 match &self.inner.name {
1491 ThreadName::Main => Some(c"main"),
1492 ThreadName::Other(other) => Some(&other),
1493 ThreadName::Unnamed => None,
1494 }
1522 self.inner.name.as_cstr()
14951523 }
14961524}
14971525
src/bootstrap/src/core/build_steps/compile.rs+8-6
......@@ -695,7 +695,7 @@ fn copy_sanitizers(
695695 || target == "x86_64-apple-ios"
696696 {
697697 // Update the library’s install name to reflect that it has been renamed.
698 apple_darwin_update_library_name(builder, &dst, &format!("@rpath/{}", &runtime.name));
698 apple_darwin_update_library_name(builder, &dst, &format!("@rpath/{}", runtime.name));
699699 // Upon renaming the install name, the code signature of the file will invalidate,
700700 // so we will sign it again.
701701 apple_darwin_sign_file(builder, &dst);
......@@ -1820,12 +1820,14 @@ impl Step for Assemble {
18201820 &self_contained_lld_dir.join(exe(name, target_compiler.host)),
18211821 );
18221822 }
1823 }
18231824
1824 // In addition to `rust-lld` also install `wasm-component-ld` when
1825 // LLD is enabled. This is a relatively small binary that primarily
1826 // delegates to the `rust-lld` binary for linking and then runs
1827 // logic to create the final binary. This is used by the
1828 // `wasm32-wasip2` target of Rust.
1825 // In addition to `rust-lld` also install `wasm-component-ld` when
1826 // LLD is enabled. This is a relatively small binary that primarily
1827 // delegates to the `rust-lld` binary for linking and then runs
1828 // logic to create the final binary. This is used by the
1829 // `wasm32-wasip2` target of Rust.
1830 if builder.build_wasm_component_ld() {
18291831 let wasm_component_ld_exe =
18301832 builder.ensure(crate::core::build_steps::tool::WasmComponentLd {
18311833 compiler: build_compiler,
src/bootstrap/src/core/build_steps/llvm.rs+1-1
......@@ -1411,7 +1411,7 @@ impl Step for Libunwind {
14111411 }
14121412 }
14131413 }
1414 assert_eq!(cpp_len, count, "Can't get object files from {:?}", &out_dir);
1414 assert_eq!(cpp_len, count, "Can't get object files from {out_dir:?}");
14151415
14161416 cc_cfg.compile("unwind");
14171417 out_dir
src/bootstrap/src/lib.rs+13
......@@ -1414,6 +1414,19 @@ Executed at: {executed_at}"#,
14141414 None
14151415 }
14161416
1417 /// Returns whether it's requested that `wasm-component-ld` is built as part
1418 /// of the sysroot. This is done either with the `extended` key in
1419 /// `config.toml` or with the `tools` set.
1420 fn build_wasm_component_ld(&self) -> bool {
1421 if self.config.extended {
1422 return true;
1423 }
1424 match &self.config.tools {
1425 Some(set) => set.contains("wasm-component-ld"),
1426 None => false,
1427 }
1428 }
1429
14171430 /// Returns the root of the "rootfs" image that this target will be using,
14181431 /// if one was configured.
14191432 ///
src/bootstrap/src/utils/cc_detect.rs+5-5
......@@ -142,15 +142,15 @@ pub fn find_target(build: &Build, target: TargetSelection) {
142142 build.cxx.borrow_mut().insert(target, compiler);
143143 }
144144
145 build.verbose(|| println!("CC_{} = {:?}", &target.triple, build.cc(target)));
146 build.verbose(|| println!("CFLAGS_{} = {:?}", &target.triple, cflags));
145 build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
146 build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
147147 if let Ok(cxx) = build.cxx(target) {
148148 let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
149 build.verbose(|| println!("CXX_{} = {:?}", &target.triple, cxx));
150 build.verbose(|| println!("CXXFLAGS_{} = {:?}", &target.triple, cxxflags));
149 build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
150 build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
151151 }
152152 if let Some(ar) = ar {
153 build.verbose(|| println!("AR_{} = {:?}", &target.triple, ar));
153 build.verbose(|| println!("AR_{} = {ar:?}", target.triple));
154154 build.ar.borrow_mut().insert(target, ar);
155155 }
156156
src/bootstrap/src/utils/change_tracker.rs+5
......@@ -205,4 +205,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
205205 severity: ChangeSeverity::Warning,
206206 summary: "`debug-logging` option has been removed from the default `tools` profile.",
207207 },
208 ChangeInfo {
209 change_id: 127866,
210 severity: ChangeSeverity::Info,
211 summary: "the `wasm-component-ld` tool is now built as part of `build.extended` and can be a member of `build.tools`",
212 },
208213];
src/bootstrap/src/utils/tarball.rs+1-1
......@@ -244,7 +244,7 @@ impl<'a> Tarball<'a> {
244244 cmd.arg("generate")
245245 .arg("--image-dir")
246246 .arg(&this.image_dir)
247 .arg(format!("--component-name={}", &component_name));
247 .arg(format!("--component-name={component_name}"));
248248
249249 if let Some((dir, dirs)) = this.bulk_dirs.split_first() {
250250 let mut arg = dir.as_os_str().to_os_string();
src/librustdoc/html/format.rs+1-1
......@@ -850,7 +850,7 @@ fn resolved_path<'cx>(
850850 }
851851 }
852852 if w.alternate() {
853 write!(w, "{}{:#}", &last.name, last.args.print(cx))?;
853 write!(w, "{}{:#}", last.name, last.args.print(cx))?;
854854 } else {
855855 let path = if use_absolute {
856856 if let Ok((_, _, fqp)) = href(did, cx) {
src/tools/tidy/src/allowed_run_make_makefiles.txt-1
......@@ -9,7 +9,6 @@ run-make/cat-and-grep-sanity-check/Makefile
99run-make/cdylib-dylib-linkage/Makefile
1010run-make/compiler-lookup-paths-2/Makefile
1111run-make/compiler-rt-works-on-mingw/Makefile
12run-make/crate-hash-rustc-version/Makefile
1312run-make/cross-lang-lto-clang/Makefile
1413run-make/cross-lang-lto-pgo-smoketest/Makefile
1514run-make/cross-lang-lto-upstream-rlibs/Makefile
tests/run-make/crate-hash-rustc-version/Makefile deleted-38
......@@ -1,38 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3
4# Ensure that crates compiled with different rustc versions cannot
5# be dynamically linked.
6
7FLAGS := -Cprefer-dynamic -Csymbol-mangling-version=v0
8UNAME := $(shell uname)
9ifeq ($(UNAME),Linux)
10 EXT=".so"
11 NM_CMD := nm -D
12endif
13ifeq ($(UNAME),Darwin)
14 EXT=".dylib"
15 NM_CMD := nm
16endif
17
18ifndef NM_CMD
19all:
20 exit 0
21else
22all:
23 # a.rs is a dylib
24 $(RUSTC) a.rs --crate-type=dylib $(FLAGS)
25 # Write symbols to disk.
26 $(NM_CMD) $(call DYLIB,a) > $(TMPDIR)/symbolsbefore
27 # b.rs is a binary
28 $(RUSTC) b.rs --extern a=$(TMPDIR)/liba$(EXT) --crate-type=bin -Crpath $(FLAGS)
29 $(call RUN,b)
30 # Now re-compile a.rs with another rustc version
31 RUSTC_FORCE_RUSTC_VERSION=deadfeed $(RUSTC) a.rs --crate-type=dylib $(FLAGS)
32 # After compiling with a different rustc version, write symbols to disk again.
33 $(NM_CMD) $(call DYLIB,a) > $(TMPDIR)/symbolsafter
34 # As a sanity check, test if the symbols changed:
35 # If the symbols are identical, there's been an error.
36 if diff $(TMPDIR)/symbolsbefore $(TMPDIR)/symbolsafter; then exit 1; fi
37 $(call FAIL,b)
38endif
tests/run-make/crate-hash-rustc-version/rmake.rs created+57
......@@ -0,0 +1,57 @@
1// Ensure that crates compiled with different rustc versions cannot
2// be dynamically linked.
3
4//@ ignore-cross-compile
5//@ only-unix
6
7use run_make_support::llvm;
8use run_make_support::{diff, dynamic_lib_name, is_darwin, run, run_fail, rustc};
9
10fn llvm_readobj() -> llvm::LlvmReadobj {
11 let mut cmd = llvm::llvm_readobj();
12 if is_darwin() {
13 cmd.symbols();
14 } else {
15 cmd.dynamic_table();
16 }
17 cmd
18}
19
20fn main() {
21 let flags = ["-Cprefer-dynamic", "-Csymbol-mangling-version=v0"];
22
23 // a.rs is compiled to a dylib
24 rustc().input("a.rs").crate_type("dylib").args(&flags).run();
25
26 // Store symbols
27 let symbols_before = llvm_readobj().arg(dynamic_lib_name("a")).run().stdout_utf8();
28
29 // b.rs is compiled to a binary
30 rustc()
31 .input("b.rs")
32 .extern_("a", dynamic_lib_name("a"))
33 .crate_type("bin")
34 .arg("-Crpath")
35 .args(&flags)
36 .run();
37 run("b");
38
39 // Now re-compile a.rs with another rustc version
40 rustc()
41 .env("RUSTC_FORCE_RUSTC_VERSION", "deadfeed")
42 .input("a.rs")
43 .crate_type("dylib")
44 .args(&flags)
45 .run();
46
47 // After compiling with a different rustc version, store symbols again.
48 let symbols_after = llvm_readobj().arg(dynamic_lib_name("a")).run().stdout_utf8();
49
50 // As a sanity check, test if the symbols changed:
51 // If the symbols are identical, there's been an error.
52 diff()
53 .expected_text("symbols_before", symbols_before)
54 .actual_text("symbols_after", symbols_after)
55 .run_fail();
56 run_fail("b");
57}
tests/ui/borrowck/move-error-suggest-clone-panic-issue-127915.rs created+15
......@@ -0,0 +1,15 @@
1#![allow(dead_code)]
2
3extern "C" {
4 fn rust_interesting_average(_: i64, ...) -> f64;
5}
6
7fn test<T, U>(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 {
8 unsafe {
9 rust_interesting_average(
10 6, a as f64, b, b as f64, f, c as f64, d, d as f64, e, e as f64, f, g, //~ ERROR use of moved value: `f` [E0382]
11 ) as i64
12 }
13}
14
15fn main() {}
tests/ui/borrowck/move-error-suggest-clone-panic-issue-127915.stderr created+25
......@@ -0,0 +1,25 @@
1error[E0382]: use of moved value: `f`
2 --> $DIR/move-error-suggest-clone-panic-issue-127915.rs:10:78
3 |
4LL | fn test<T, U>(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 {
5 | - move occurs because `f` has type `T`, which does not implement the `Copy` trait
6...
7LL | 6, a as f64, b, b as f64, f, c as f64, d, d as f64, e, e as f64, f, g,
8 | - value moved here ^ value used here after move
9 |
10help: if `T` implemented `Clone`, you could clone the value
11 --> $DIR/move-error-suggest-clone-panic-issue-127915.rs:7:9
12 |
13LL | fn test<T, U>(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 {
14 | ^ consider constraining this type parameter with `Clone`
15...
16LL | 6, a as f64, b, b as f64, f, c as f64, d, d as f64, e, e as f64, f, g,
17 | - you could clone this value
18help: consider restricting type parameter `T`
19 |
20LL | fn test<T: Copy, U>(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 {
21 | ++++++
22
23error: aborting due to 1 previous error
24
25For more information about this error, try `rustc --explain E0382`.
tests/ui/error-codes/E0746.stderr+3-6
......@@ -4,11 +4,11 @@ error[E0746]: return type cannot have an unboxed trait object
44LL | fn foo() -> dyn Trait { Struct }
55 | ^^^^^^^^^ doesn't have a size known at compile-time
66 |
7help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
7help: consider returning an `impl Trait` instead of a `dyn Trait`
88 |
99LL | fn foo() -> impl Trait { Struct }
1010 | ~~~~
11help: box the return type, and wrap all of the returned values in `Box::new`
11help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
1212 |
1313LL | fn foo() -> Box<dyn Trait> { Box::new(Struct) }
1414 | ++++ + +++++++++ +
......@@ -19,10 +19,7 @@ error[E0746]: return type cannot have an unboxed trait object
1919LL | fn bar() -> dyn Trait {
2020 | ^^^^^^^^^ doesn't have a size known at compile-time
2121 |
22help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
23 |
24LL | fn bar() -> impl Trait {
25 | ~~~~
22 = help: if there were a single returned type, you could use `impl Trait` instead
2623help: box the return type, and wrap all of the returned values in `Box::new`
2724 |
2825LL ~ fn bar() -> Box<dyn Trait> {
tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr+15-23
......@@ -48,10 +48,14 @@ error[E0746]: return type cannot have an unboxed trait object
4848LL | fn bap() -> Trait { Struct }
4949 | ^^^^^ doesn't have a size known at compile-time
5050 |
51help: box the return type, and wrap all of the returned values in `Box::new`
51help: consider returning an `impl Trait` instead of a `dyn Trait`
52 |
53LL | fn bap() -> impl Trait { Struct }
54 | ++++
55help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
5256 |
53LL | fn bap() -> Box<Trait> { Box::new(Struct) }
54 | ++++ + +++++++++ +
57LL | fn bap() -> Box<dyn Trait> { Box::new(Struct) }
58 | +++++++ + +++++++++ +
5559
5660error[E0746]: return type cannot have an unboxed trait object
5761 --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
......@@ -59,11 +63,11 @@ error[E0746]: return type cannot have an unboxed trait object
5963LL | fn ban() -> dyn Trait { Struct }
6064 | ^^^^^^^^^ doesn't have a size known at compile-time
6165 |
62help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
66help: consider returning an `impl Trait` instead of a `dyn Trait`
6367 |
6468LL | fn ban() -> impl Trait { Struct }
6569 | ~~~~
66help: box the return type, and wrap all of the returned values in `Box::new`
70help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
6771 |
6872LL | fn ban() -> Box<dyn Trait> { Box::new(Struct) }
6973 | ++++ + +++++++++ +
......@@ -74,11 +78,11 @@ error[E0746]: return type cannot have an unboxed trait object
7478LL | fn bak() -> dyn Trait { unimplemented!() }
7579 | ^^^^^^^^^ doesn't have a size known at compile-time
7680 |
77help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
81help: consider returning an `impl Trait` instead of a `dyn Trait`
7882 |
7983LL | fn bak() -> impl Trait { unimplemented!() }
8084 | ~~~~
81help: box the return type, and wrap all of the returned values in `Box::new`
85help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
8286 |
8387LL | fn bak() -> Box<dyn Trait> { Box::new(unimplemented!()) }
8488 | ++++ + +++++++++ +
......@@ -89,10 +93,7 @@ error[E0746]: return type cannot have an unboxed trait object
8993LL | fn bal() -> dyn Trait {
9094 | ^^^^^^^^^ doesn't have a size known at compile-time
9195 |
92help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
93 |
94LL | fn bal() -> impl Trait {
95 | ~~~~
96 = help: if there were a single returned type, you could use `impl Trait` instead
9697help: box the return type, and wrap all of the returned values in `Box::new`
9798 |
9899LL ~ fn bal() -> Box<dyn Trait> {
......@@ -108,10 +109,7 @@ error[E0746]: return type cannot have an unboxed trait object
108109LL | fn bax() -> dyn Trait {
109110 | ^^^^^^^^^ doesn't have a size known at compile-time
110111 |
111help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
112 |
113LL | fn bax() -> impl Trait {
114 | ~~~~
112 = help: if there were a single returned type, you could use `impl Trait` instead
115113help: box the return type, and wrap all of the returned values in `Box::new`
116114 |
117115LL ~ fn bax() -> Box<dyn Trait> {
......@@ -263,10 +261,7 @@ error[E0746]: return type cannot have an unboxed trait object
263261LL | fn bat() -> dyn Trait {
264262 | ^^^^^^^^^ doesn't have a size known at compile-time
265263 |
266help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
267 |
268LL | fn bat() -> impl Trait {
269 | ~~~~
264 = help: if there were a single returned type, you could use `impl Trait` instead
270265help: box the return type, and wrap all of the returned values in `Box::new`
271266 |
272267LL ~ fn bat() -> Box<dyn Trait> {
......@@ -282,10 +277,7 @@ error[E0746]: return type cannot have an unboxed trait object
282277LL | fn bay() -> dyn Trait {
283278 | ^^^^^^^^^ doesn't have a size known at compile-time
284279 |
285help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
286 |
287LL | fn bay() -> impl Trait {
288 | ~~~~
280 = help: if there were a single returned type, you could use `impl Trait` instead
289281help: box the return type, and wrap all of the returned values in `Box::new`
290282 |
291283LL ~ fn bay() -> Box<dyn Trait> {
tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr+1-4
......@@ -54,10 +54,7 @@ error[E0746]: return type cannot have an unboxed trait object
5454LL | fn car() -> dyn NotObjectSafe {
5555 | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
5656 |
57help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
58 |
59LL | fn car() -> impl NotObjectSafe {
60 | ~~~~
57 = help: if there were a single returned type, you could use `impl Trait` instead
6158help: box the return type, and wrap all of the returned values in `Box::new`
6259 |
6360LL ~ fn car() -> Box<dyn NotObjectSafe> {
tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr+5-8
......@@ -171,11 +171,11 @@ error[E0746]: return type cannot have an unboxed trait object
171171LL | fn hat() -> dyn std::fmt::Display {
172172 | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
173173 |
174help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
174help: consider returning an `impl Trait` instead of a `dyn Trait`
175175 |
176176LL | fn hat() -> impl std::fmt::Display {
177177 | ~~~~
178help: box the return type, and wrap all of the returned values in `Box::new`
178help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
179179 |
180180LL ~ fn hat() -> Box<dyn std::fmt::Display> {
181181LL | match 13 {
......@@ -192,11 +192,11 @@ error[E0746]: return type cannot have an unboxed trait object
192192LL | fn pug() -> dyn std::fmt::Display {
193193 | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
194194 |
195help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
195help: consider returning an `impl Trait` instead of a `dyn Trait`
196196 |
197197LL | fn pug() -> impl std::fmt::Display {
198198 | ~~~~
199help: box the return type, and wrap all of the returned values in `Box::new`
199help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
200200 |
201201LL ~ fn pug() -> Box<dyn std::fmt::Display> {
202202LL | match 13 {
......@@ -211,10 +211,7 @@ error[E0746]: return type cannot have an unboxed trait object
211211LL | fn man() -> dyn std::fmt::Display {
212212 | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
213213 |
214help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
215 |
216LL | fn man() -> impl std::fmt::Display {
217 | ~~~~
214 = help: if there were a single returned type, you could use `impl Trait` instead
218215help: box the return type, and wrap all of the returned values in `Box::new`
219216 |
220217LL ~ fn man() -> Box<dyn std::fmt::Display> {
tests/ui/issues/issue-18107.stderr+2-2
......@@ -4,11 +4,11 @@ error[E0746]: return type cannot have an unboxed trait object
44LL | dyn AbstractRenderer
55 | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
66 |
7help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
7help: consider returning an `impl Trait` instead of a `dyn Trait`
88 |
99LL | impl AbstractRenderer
1010 | ~~~~
11help: box the return type, and wrap all of the returned values in `Box::new`
11help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
1212 |
1313LL ~ Box<dyn AbstractRenderer>
1414LL |
tests/ui/unsized/box-instead-of-dyn-fn.stderr+2-2
......@@ -4,11 +4,11 @@ error[E0746]: return type cannot have an unboxed trait object
44LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a {
55 | ^^^^^^^^^^^^^ doesn't have a size known at compile-time
66 |
7help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
7help: consider returning an `impl Trait` instead of a `dyn Trait`
88 |
99LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> impl Fn() + 'a {
1010 | ~~~~
11help: box the return type, and wrap all of the returned values in `Box::new`
11help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
1212 |
1313LL ~ fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> Box<dyn Fn() + 'a> {
1414LL |
tests/ui/unsized/issue-91801.stderr+7-3
......@@ -4,10 +4,14 @@ error[E0746]: return type cannot have an unboxed trait object
44LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> {
55 | ^^^^^^^^^^^^^ doesn't have a size known at compile-time
66 |
7help: box the return type, and wrap all of the returned values in `Box::new`
7help: consider returning an `impl Trait` instead of a `dyn Trait`
88 |
9LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box<Validator<'a>> {
10 | ++++ +
9LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> impl Validator<'a> {
10 | ++++
11help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
12 |
13LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box<dyn Validator<'a>> {
14 | +++++++ +
1115
1216error: aborting due to 1 previous error
1317
tests/ui/unsized/issue-91803.stderr+2-2
......@@ -4,11 +4,11 @@ error[E0746]: return type cannot have an unboxed trait object
44LL | fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> {
55 | ^^^^^^^^^^^ doesn't have a size known at compile-time
66 |
7help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
7help: consider returning an `impl Trait` instead of a `dyn Trait`
88 |
99LL | fn or<'a>(first: &'static dyn Foo<'a>) -> impl Foo<'a> {
1010 | ~~~~
11help: box the return type, and wrap all of the returned values in `Box::new`
11help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
1212 |
1313LL | fn or<'a>(first: &'static dyn Foo<'a>) -> Box<dyn Foo<'a>> {
1414 | ++++ +