From 3540fe51444ecc07616ffb9448f2285a1ac785d1 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Mon, 7 Sep 2026 21:20:42 -0700 Subject: [PATCH 01/22] add fcw for ill-formed HRTB args --- .../rustc_hir_analysis/src/check/wfcheck.rs | 144 ++++++++++++++++-- compiler/rustc_lint_defs/src/builtin.rs | 52 +++++++ .../rustc_trait_selection/src/traits/wf.rs | 127 +++++++++------ tests/ui/inference/issue-80409.compat.stderr | 18 ++- .../ui/inference/issue-80409.no-compat.stderr | 18 ++- tests/ui/inference/issue-80409.rs | 2 + tests/ui/wf/closure-wf.current.stderr | 30 ++++ tests/ui/wf/closure-wf.next.stderr | 39 +++++ tests/ui/wf/closure-wf.rs | 8 + tests/ui/wf/closure-wf.stderr | 20 --- .../unsatisfied-hrtb-arg-gated.current.stderr | 19 +++ .../wf/unsatisfied-hrtb-arg-gated.next.stderr | 19 +++ tests/ui/wf/unsatisfied-hrtb-arg-gated.rs | 15 ++ ...satisfied-hrtb-arg-lifetime.current.stderr | 12 ++ .../unsatisfied-hrtb-arg-lifetime.next.stderr | 22 +++ tests/ui/wf/unsatisfied-hrtb-arg-lifetime.rs | 25 +++ tests/ui/wf/unsatisfied-hrtb-arg-no-warn.rs | 15 ++ .../ui/wf/unsatisfied-hrtb-arg.current.stderr | 12 ++ tests/ui/wf/unsatisfied-hrtb-arg.next.stderr | 12 ++ tests/ui/wf/unsatisfied-hrtb-arg.rs | 27 ++++ 20 files changed, 549 insertions(+), 87 deletions(-) create mode 100644 tests/ui/wf/closure-wf.current.stderr create mode 100644 tests/ui/wf/closure-wf.next.stderr delete mode 100644 tests/ui/wf/closure-wf.stderr create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg-gated.current.stderr create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg-gated.next.stderr create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg-gated.rs create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg-lifetime.current.stderr create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg-lifetime.next.stderr create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg-lifetime.rs create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg-no-warn.rs create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg.current.stderr create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg.next.stderr create mode 100644 tests/ui/wf/unsatisfied-hrtb-arg.rs diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 86f386381b9e2..4f688ca449477 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1,4 +1,4 @@ -use std::cell::LazyCell; +use std::cell::{LazyCell, RefCell}; use std::ops::{ControlFlow, Deref}; use hir::intravisit::{self, Visitor}; @@ -15,9 +15,13 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{AmbigArg, ItemKind}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{BoundRegionConversionTime, SolverRegionConstraint, TyCtxtInferExt}; +use rustc_infer::infer::{ + BoundRegionConversionTime, RegionResolutionError, SolverRegionConstraint, TyCtxtInferExt, +}; use rustc_infer::traits::{PredicateObligations, TraitErrors}; -use rustc_lint_defs::builtin::{REDUNDANT_LIFETIMES, SHADOWING_SUPERTRAIT_ITEMS}; +use rustc_lint_defs::builtin::{ + REDUNDANT_LIFETIMES, SHADOWING_SUPERTRAIT_ITEMS, UNSATISFIED_HRTB_ARG, +}; use rustc_macros::{Diagnostic, TypeFoldable, TypeVisitable}; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::solve::NoSolution; @@ -53,6 +57,11 @@ pub(super) struct WfCheckingCtxt<'a, 'tcx> { pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>, body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, + + /// Obligations with escaping bound vars. As emitting a hard error if such + /// obligations fail would cause significant crater breakage, we instead + /// prove them in a forked infcx and emit a FCW if any fail. + fcw_obligations: RefCell>, } impl<'a, 'tcx> Deref for WfCheckingCtxt<'a, 'tcx> { type Target = ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>; @@ -133,6 +142,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { )); } + pub(super) fn register_fcw_obligations(&self, obligations: PredicateObligations<'tcx>) { + self.fcw_obligations.borrow_mut().extend(obligations); + } + pub(super) fn unnormalized_obligations( &self, span: Span, @@ -159,8 +172,9 @@ where let param_env = tcx.param_env(body_def_id); let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); + let fcw_obligations = RefCell::new(PredicateObligations::new()); - let mut wfcx = WfCheckingCtxt { ocx, body_def_id, param_env }; + let mut wfcx = WfCheckingCtxt { ocx, body_def_id, param_env, fcw_obligations }; // As of now, bounds are only enforced on checked type aliases, they're ignored for most type // aliases. So, only check for false global bounds if we're not ignoring bounds altogether. @@ -181,6 +195,76 @@ where debug!(?assumed_wf_types); let infcx_compat = infcx.fork(); + let infcx_fcw = infcx.fork(); + + let check_escaping_bound_vars_fcw = || { + if wfcx.fcw_obligations.borrow().is_empty() { + return; + } + + let ocx = ObligationCtxt::new_with_diagnostics(&infcx_fcw); + ocx.register_obligations(wfcx.fcw_obligations.into_inner()); + let trait_errors = ocx.try_evaluate_obligations(); + + let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat( + &infcx_fcw, + body_def_id, + param_env, + assumed_wf_types.iter().copied(), + true, + ); + let mut region_errors = infcx_fcw.resolve_regions_with_outlives_env(&outlives_env); + + if let TraitErrors::HasErrors(errors) = trait_errors { + for error in errors { + tcx.emit_node_span_lint( + UNSATISFIED_HRTB_ARG, + tcx.local_def_id_to_hir_id(body_def_id), + error.obligation.cause.span, + rustc_errors::DiagDecorator(|err| { + let predicate = + tcx.short_string(error.obligation.predicate, err.long_ty_path()); + err.primary_message(format!( + "the trait bound `{predicate}` is not satisfied" + )); + }), + ); + } + } else if !region_errors.is_empty() { + let is_bound_failure = |e: &RegionResolutionError<'tcx>| { + matches!(e, RegionResolutionError::GenericBoundFailure(..)) + }; + if !region_errors.iter().all(&is_bound_failure) { + region_errors.retain(|e| !is_bound_failure(e)); + } + region_errors.sort_by_key(|e| e.origin().span()); + + for error in ®ion_errors { + let span = error.origin().span(); + tcx.emit_node_span_lint( + UNSATISFIED_HRTB_ARG, + tcx.local_def_id_to_hir_id(body_def_id), + span, + rustc_errors::DiagDecorator(|err| match error { + RegionResolutionError::GenericBoundFailure(_, kind, sub) => { + let desc = kind.to_ty(tcx).prefix_string(tcx); + err.primary_message(format!( + "the {desc} `{kind}` may not live long enough" + )); + err.span_label(span, format!("`{kind}` must outlive `{sub}`")); + } + RegionResolutionError::ConcreteFailure(_, sub, sup) => { + err.primary_message("lifetime may not live long enough"); + err.span_label(span, format!("`{sup}` must outlive `{sub}`")); + } + _ => { + err.primary_message("unsatisfied lifetime requirements"); + } + }), + ); + } + } + }; // We specifically want to *disable* the implied bounds hack, first, // so we can detect when failures are due to bevy's implied bounds. @@ -196,6 +280,7 @@ where let errors = infcx.resolve_regions_with_outlives_env(&outlives_env); if errors.is_empty() { + check_escaping_bound_vars_fcw(); return Ok(()); } @@ -203,13 +288,15 @@ where &infcx_compat, body_def_id, param_env, - assumed_wf_types, + assumed_wf_types.iter().copied(), // Don't *disable* the implied bounds hack; though this will only apply // the implied bounds hack if this contains `bevy_ecs`'s `ParamSet` type. false, ); let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env); if errors_compat.is_empty() { + check_escaping_bound_vars_fcw(); + // FIXME: Once we fix bevy, this would be the place to insert a warning // to upgrade bevy. Ok(()) @@ -1124,13 +1211,15 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt debug!("check_associated_type_bounds: bounds={:?}", bounds); let wf_obligations = bounds.iter_identity_copied().map(Unnormalized::skip_norm_wip).flat_map( |(bound, bound_span)| { - traits::wf::clause_obligations( + let (obligations, fcw_obligations) = traits::wf::clause_obligations( wfcx.infcx, wfcx.param_env, wfcx.body_def_id, bound, bound_span, - ) + ); + wfcx.register_fcw_obligations(fcw_obligations); + obligations }, ); @@ -1607,13 +1696,40 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: assert_eq!(gen_clauses.clauses.len(), gen_clauses.spans.len()); let wf_obligations = gen_clauses.into_iter().flat_map(|(p, sp)| { - traits::wf::clause_obligations( - infcx, - wfcx.param_env, - wfcx.body_def_id, - p.skip_norm_wip(), - sp, - ) + let clause = p.skip_norm_wip(); + let (obligations, mut fcw_obligations) = + traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, clause, sp); + + // On a where-clause like `for<'a> W<'a, T>: Sized`, we want to point to the entire + // clause including the self ty, not just the `Sized` bound. + let self_ty_span_for_fcw = || { + // A self ty that has no escaping bound vars, like the one in + // `for<'a> X: Trait>`, already has the correct span. + if clause.as_trait_clause().is_none_or(|trait_pred| { + !trait_pred.skip_binder().trait_ref.self_ty().has_escaping_bound_vars() + }) { + return None; + } + + for pred in tcx.hir_node_by_def_id(def_id).generics()?.predicates { + if let hir::WherePredicateKind::BoundPredicate(bound_pred) = pred.kind + && bound_pred.bounds.iter().any(|bound| bound.span() == sp) + { + return Some(pred.span); + } + } + None + }; + if !fcw_obligations.is_empty() + && let Some(span) = self_ty_span_for_fcw() + { + for obligation in &mut fcw_obligations { + obligation.cause.span = span; + } + } + wfcx.register_fcw_obligations(fcw_obligations); + + obligations }); let obligations: Vec<_> = wf_obligations.chain(default_obligations).chain(assoc_const_obligations).collect(); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 979dc2b903c88..e37e895304bc6 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -138,6 +138,7 @@ pub mod hardwired { UNREACHABLE_PATTERNS, UNSAFE_ATTR_OUTSIDE_UNSAFE, UNSAFE_OP_IN_UNSAFE_FN, + UNSATISFIED_HRTB_ARG, UNSTABLE_IMPORTS, UNSTABLE_NAME_COLLISIONS, UNSTABLE_SYNTAX_PRE_EXPANSION, @@ -5085,6 +5086,57 @@ declare_lint! { }; } +declare_lint! { + /// The `unsatisfied_hrtb_arg` lint detects arguments of [higher-ranked + /// trait bounds] that don't satisfy the bounds declared on their own + /// types. + /// + /// ### Example + /// + /// ```rust + /// trait Bound {} + /// struct W<'a, T: Bound>(&'a T); + /// + /// fn wf() where for<'a> W<'a, T>: Sized {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The compiler previously accepted higher-ranked trait bounds without + /// checking that their arguments satisfy the bounds declared on the + /// argument types, if the arguments of the type mention one of the bound + /// variables (like `'a` in the above example). `W` requires that + /// `T: Bound`, which isn't satisfied in `wf`, yet the compiler used to + /// accept this code. + /// + /// To fix this, add the bound that `W` requires to `wf`: + /// + /// ```rust + /// trait Bound {} + /// struct W<'a, T: Bound>(&'a T); + /// + /// fn wf() where for<'a> W<'a, T>: Sized {} + /// ``` + /// + /// This is a lint instead of a hard error because many existing projects + /// were found to hit this error. It will become a hard error in a future + /// release. + /// + /// See [issue #162200] for more details. + /// + /// [higher-ranked trait bounds]: https://doc.rust-lang.org/reference/trait-bounds.html#higher-ranked-trait-bounds + /// [issue #162200]: https://github.com/rust-lang/rust/issues/162200 + /// [future-incompatible]: ../index.md#future-incompatible-lints + pub UNSATISFIED_HRTB_ARG, + Warn, + "arguments of higher-ranked trait bounds that don't satisfy the bounds their types declare", + @future_incompatible = FutureIncompatibleInfo { + reason: fcw!(FutureReleaseError #162200), + }; +} + declare_lint! { /// The `unsafe_attr_outside_unsafe` lint detects a missing unsafe keyword /// on attributes considered unsafe. diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 41e6797e71d2d..24ab8babb249a 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -144,7 +144,7 @@ pub fn trait_obligations<'tcx>( item: Some(item), visited_tys: Default::default(), }; - wf.add_wf_preds_for_trait_pred(trait_pred, Elaborate::All); + wf.add_wf_preds_for_trait_pred(trait_pred, Elaborate::All, None); debug!(obligations = ?wf.out); wf.normalize(infcx) } @@ -161,7 +161,7 @@ pub fn clause_obligations<'tcx>( body_def_id: LocalDefId, clause: ty::Clause<'tcx>, span: Span, -) -> PredicateObligations<'tcx> { +) -> (PredicateObligations<'tcx>, PredicateObligations<'tcx>) { let mut wf = WfPredicates { infcx, param_env, @@ -172,11 +172,12 @@ pub fn clause_obligations<'tcx>( item: None, visited_tys: Default::default(), }; + let mut fcw_obligations = PredicateObligations::new(); // It's ok to skip the binder here because wf code is prepared for it match clause.kind().skip_binder() { ty::ClauseKind::Trait(t) => { - wf.add_wf_preds_for_trait_pred(t, Elaborate::None); + wf.add_wf_preds_for_trait_pred(t, Elaborate::None, Some(&mut fcw_obligations)); } ty::ClauseKind::HostEffect(..) => { // Technically the well-formedness of this clause is implied by @@ -187,7 +188,7 @@ pub fn clause_obligations<'tcx>( wf.add_wf_preds_for_term(ty.into()); } ty::ClauseKind::Projection(t) => { - wf.add_wf_preds_for_projection_term(t.projection_term); + wf.add_wf_preds_for_projection_term(t.projection_term, &mut fcw_obligations); wf.add_wf_preds_for_term(t.term); } ty::ClauseKind::ConstArgHasType(ct, ty) => { @@ -204,7 +205,9 @@ pub fn clause_obligations<'tcx>( ty::ClauseKind::UnstableFeature(_) => {} } - wf.normalize(infcx) + // `fcw_obligations` is already normalized, since everything that writes to it + // goes through `obligations()`, which calls `wf.normalize()` at the end. + (wf.normalize(infcx), fcw_obligations) } struct WfPredicates<'a, 'tcx> { @@ -382,6 +385,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { &mut self, trait_pred: ty::TraitClause<'tcx>, elaborate: Elaborate, + mut fcw_obligations: Option<&mut PredicateObligations<'tcx>>, ) { let tcx = self.tcx(); let trait_ref = trait_pred.trait_ref; @@ -425,32 +429,45 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { }); } - self.out.extend( - trait_ref - .args - .iter() - .enumerate() - .filter_map(|(i, arg)| arg.as_term().map(|t| (i, t))) - .filter(|(_, term)| !term.has_escaping_bound_vars()) - .map(|(i, term)| { - let mut cause = traits::ObligationCause::misc(self.span, self.body_def_id); - // The first arg is the self ty - use the correct span for it. - if i == 0 { - if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = - item.map(|i| &i.kind) - { - cause.span = self_ty.span; - } + self.out.extend(trait_ref.args.iter().enumerate().filter_map(|(i, arg)| { + let term = arg.as_term()?; + + if term.has_escaping_bound_vars() { + let obligations = obligations( + self.infcx, + param_env, + self.body_def_id, + depth + 1, + term, + self.span, + ) + .expect("inference vars shouldn't have escaping bound vars"); + + fcw_obligations + .as_deref_mut() + .expect("impl trait refs shouldn't have escaping bound vars") + .extend(obligations); + + None + } else { + let mut cause = traits::ObligationCause::misc(self.span, self.body_def_id); + // The first arg is the self ty - use the correct span for it. + if i == 0 { + if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = + item.map(|i| &i.kind) + { + cause.span = self_ty.span; } - traits::Obligation::with_depth( - tcx, - cause, - depth, - param_env, - ty::ClauseKind::WellFormed(term), - ) - }), - ); + } + Some(traits::Obligation::with_depth( + tcx, + cause, + depth, + param_env, + ty::ClauseKind::WellFormed(term), + )) + } + })); } // Compute the obligations that are required for `trait_ref` to be WF, @@ -464,7 +481,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } /// Pushes the obligations required for a projection to be WF into `self.out`. - fn add_wf_preds_for_projection_term(&mut self, data: ty::AliasTerm<'tcx>) { + fn add_wf_preds_for_projection_term( + &mut self, + data: ty::AliasTerm<'tcx>, + fcw_obligations: &mut PredicateObligations<'tcx>, + ) { // A projection is well-formed if // // (a) its predicates hold (*) @@ -490,7 +511,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { this.out.push(obligation) }); - self.add_wf_preds_for_projection_args(data.args); + self.add_wf_preds_for_projection_args(data.args, fcw_obligations); } /// Pushes the obligations required for an inherent alias to be WF @@ -532,26 +553,42 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { data.args.visit_with(self); } - fn add_wf_preds_for_projection_args(&mut self, args: GenericArgsRef<'tcx>) { + fn add_wf_preds_for_projection_args( + &mut self, + args: GenericArgsRef<'tcx>, + fcw_obligations: &mut PredicateObligations<'tcx>, + ) { let tcx = self.tcx(); let cause = self.cause(ObligationCauseCode::WellFormed(WellFormedLoc::None)); let param_env = self.param_env; let depth = self.recursion_depth; - self.out.extend( - args.iter() - .filter_map(|arg| arg.as_term()) - .filter(|term| !term.has_escaping_bound_vars()) - .map(|term| { - traits::Obligation::with_depth( - tcx, - cause.clone(), - depth, + self.out.extend(args.iter().filter_map(|arg| { + let term = arg.as_term()?; + + if term.has_escaping_bound_vars() { + fcw_obligations.extend( + obligations( + self.infcx, param_env, - ty::ClauseKind::WellFormed(term), + self.body_def_id, + depth + 1, + term, + self.span, ) - }), - ); + .expect("inference vars shouldn't have escaping bound vars"), + ); + None + } else { + Some(traits::Obligation::with_depth( + tcx, + cause.clone(), + depth, + param_env, + ty::ClauseKind::WellFormed(term), + )) + } + })); } fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { diff --git a/tests/ui/inference/issue-80409.compat.stderr b/tests/ui/inference/issue-80409.compat.stderr index 2f3f6cef20926..a28abcd4cd7bc 100644 --- a/tests/ui/inference/issue-80409.compat.stderr +++ b/tests/ui/inference/issue-80409.compat.stderr @@ -1,20 +1,30 @@ +warning: the trait bound `TFsm: Fsm` is not satisfied + --> $DIR/issue-80409.rs:23:26 + | +LL | fn on_entry)>(&self, _action: TAction) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + error[E0277]: the trait bound `usize: Fsm` is not satisfied - --> $DIR/issue-80409.rs:36:31 + --> $DIR/issue-80409.rs:38:31 | LL | builder.state().on_entry(|_| {}); | ^ the trait `Fsm` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/issue-80409.rs:26:1 + --> $DIR/issue-80409.rs:28:1 | LL | trait Fsm { | ^^^^^^^^^ note: required by a bound in `StateContext` - --> $DIR/issue-80409.rs:30:31 + --> $DIR/issue-80409.rs:32:31 | LL | struct StateContext<'a, TFsm: Fsm> { | ^^^ required by this bound in `StateContext` -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/inference/issue-80409.no-compat.stderr b/tests/ui/inference/issue-80409.no-compat.stderr index 2f3f6cef20926..a28abcd4cd7bc 100644 --- a/tests/ui/inference/issue-80409.no-compat.stderr +++ b/tests/ui/inference/issue-80409.no-compat.stderr @@ -1,20 +1,30 @@ +warning: the trait bound `TFsm: Fsm` is not satisfied + --> $DIR/issue-80409.rs:23:26 + | +LL | fn on_entry)>(&self, _action: TAction) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + error[E0277]: the trait bound `usize: Fsm` is not satisfied - --> $DIR/issue-80409.rs:36:31 + --> $DIR/issue-80409.rs:38:31 | LL | builder.state().on_entry(|_| {}); | ^ the trait `Fsm` is not implemented for `usize` | help: this trait has no implementations, consider adding one - --> $DIR/issue-80409.rs:26:1 + --> $DIR/issue-80409.rs:28:1 | LL | trait Fsm { | ^^^^^^^^^ note: required by a bound in `StateContext` - --> $DIR/issue-80409.rs:30:31 + --> $DIR/issue-80409.rs:32:31 | LL | struct StateContext<'a, TFsm: Fsm> { | ^^^ required by this bound in `StateContext` -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/inference/issue-80409.rs b/tests/ui/inference/issue-80409.rs index 86dac3cda9199..a096a003d335b 100644 --- a/tests/ui/inference/issue-80409.rs +++ b/tests/ui/inference/issue-80409.rs @@ -21,6 +21,8 @@ struct FsmStateBuilder { impl FsmStateBuilder { fn on_entry)>(&self, _action: TAction) {} + //~^ WARN the trait bound `TFsm: Fsm` is not satisfied + //~| WARN this was previously accepted by the compiler } trait Fsm { diff --git a/tests/ui/wf/closure-wf.current.stderr b/tests/ui/wf/closure-wf.current.stderr new file mode 100644 index 0000000000000..003dda9c20be9 --- /dev/null +++ b/tests/ui/wf/closure-wf.current.stderr @@ -0,0 +1,30 @@ +warning: the trait bound `T: Bound` is not satisfied + --> $DIR/closure-wf.rs:10:26 + | +LL | fn constrain_inner FnOnce(&'a (), NeedsBound)>(_: T, _: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + +error[E0277]: the trait bound `u32: Bound` is not satisfied + --> $DIR/closure-wf.rs:17:33 + | +LL | constrain_inner(1u32, |&(), _| ()); + | ^ the trait `Bound` is not implemented for `u32` + | +help: this trait has no implementations, consider adding one + --> $DIR/closure-wf.rs:5:1 + | +LL | trait Bound {} + | ^^^^^^^^^^^ +note: required by a bound in `NeedsBound` + --> $DIR/closure-wf.rs:6:22 + | +LL | struct NeedsBound(T); + | ^^^^^ required by this bound in `NeedsBound` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/closure-wf.next.stderr b/tests/ui/wf/closure-wf.next.stderr new file mode 100644 index 0000000000000..15b68bd9d65a2 --- /dev/null +++ b/tests/ui/wf/closure-wf.next.stderr @@ -0,0 +1,39 @@ +warning: the trait bound `T: Bound` is not satisfied + --> $DIR/closure-wf.rs:10:26 + | +LL | fn constrain_inner FnOnce(&'a (), NeedsBound)>(_: T, _: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: the trait bound `T: Bound` is not satisfied + --> $DIR/closure-wf.rs:10:34 + | +LL | fn constrain_inner FnOnce(&'a (), NeedsBound)>(_: T, _: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + +error[E0277]: the trait bound `u32: Bound` is not satisfied + --> $DIR/closure-wf.rs:17:33 + | +LL | constrain_inner(1u32, |&(), _| ()); + | ^ the trait `Bound` is not implemented for `u32` + | +help: this trait has no implementations, consider adding one + --> $DIR/closure-wf.rs:5:1 + | +LL | trait Bound {} + | ^^^^^^^^^^^ +note: required by a bound in `NeedsBound` + --> $DIR/closure-wf.rs:6:22 + | +LL | struct NeedsBound(T); + | ^^^^^ required by this bound in `NeedsBound` + +error: aborting due to 1 previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/closure-wf.rs b/tests/ui/wf/closure-wf.rs index 48baeb30ce59b..6c9c93217932f 100644 --- a/tests/ui/wf/closure-wf.rs +++ b/tests/ui/wf/closure-wf.rs @@ -1,9 +1,17 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + trait Bound {} struct NeedsBound(T); // Checks that we enforce that closure args are WF. fn constrain_inner FnOnce(&'a (), NeedsBound)>(_: T, _: F) {} +//~^ WARN the trait bound `T: Bound` is not satisfied +//~| WARN this was previously accepted by the compiler +//[next]~| WARN the trait bound `T: Bound` is not satisfied +//[next]~| WARN this was previously accepted by the compiler fn main() { constrain_inner(1u32, |&(), _| ()); diff --git a/tests/ui/wf/closure-wf.stderr b/tests/ui/wf/closure-wf.stderr deleted file mode 100644 index 4beef3bb7c577..0000000000000 --- a/tests/ui/wf/closure-wf.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0277]: the trait bound `u32: Bound` is not satisfied - --> $DIR/closure-wf.rs:9:33 - | -LL | constrain_inner(1u32, |&(), _| ()); - | ^ the trait `Bound` is not implemented for `u32` - | -help: this trait has no implementations, consider adding one - --> $DIR/closure-wf.rs:1:1 - | -LL | trait Bound {} - | ^^^^^^^^^^^ -note: required by a bound in `NeedsBound` - --> $DIR/closure-wf.rs:2:22 - | -LL | struct NeedsBound(T); - | ^^^^^ required by this bound in `NeedsBound` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/unsatisfied-hrtb-arg-gated.current.stderr b/tests/ui/wf/unsatisfied-hrtb-arg-gated.current.stderr new file mode 100644 index 0000000000000..4b3ac33211ffa --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg-gated.current.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `T: Bound` is not satisfied + --> $DIR/unsatisfied-hrtb-arg-gated.rs:12:37 + | +LL | fn errors() where W<'static, T>: Sized, for<'a> W<'a, T>: Sized {} + | ^^^^^ the trait `Bound` is not implemented for `T` + | +note: required by a bound in `W` + --> $DIR/unsatisfied-hrtb-arg-gated.rs:10:17 + | +LL | struct W<'a, T: Bound>(&'a T); + | ^^^^^ required by this bound in `W` +help: consider further restricting type parameter `T` with trait `Bound` + | +LL | fn errors() where W<'static, T>: Sized, for<'a> W<'a, T>: Sized, T: Bound {} + | ++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/unsatisfied-hrtb-arg-gated.next.stderr b/tests/ui/wf/unsatisfied-hrtb-arg-gated.next.stderr new file mode 100644 index 0000000000000..4b3ac33211ffa --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg-gated.next.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `T: Bound` is not satisfied + --> $DIR/unsatisfied-hrtb-arg-gated.rs:12:37 + | +LL | fn errors() where W<'static, T>: Sized, for<'a> W<'a, T>: Sized {} + | ^^^^^ the trait `Bound` is not implemented for `T` + | +note: required by a bound in `W` + --> $DIR/unsatisfied-hrtb-arg-gated.rs:10:17 + | +LL | struct W<'a, T: Bound>(&'a T); + | ^^^^^ required by this bound in `W` +help: consider further restricting type parameter `T` with trait `Bound` + | +LL | fn errors() where W<'static, T>: Sized, for<'a> W<'a, T>: Sized, T: Bound {} + | ++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/unsatisfied-hrtb-arg-gated.rs b/tests/ui/wf/unsatisfied-hrtb-arg-gated.rs new file mode 100644 index 0000000000000..61b53750b163e --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg-gated.rs @@ -0,0 +1,15 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +// Do not emit the UNSATISFIED_HRTB_ARG FCW if we have ill-formed types. + +#![allow(dead_code)] + +trait Bound {} +struct W<'a, T: Bound>(&'a T); + +fn errors() where W<'static, T>: Sized, for<'a> W<'a, T>: Sized {} +//~^ ERROR the trait bound `T: Bound` is not satisfied + +fn main() {} diff --git a/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.current.stderr b/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.current.stderr new file mode 100644 index 0000000000000..8097260563ea0 --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.current.stderr @@ -0,0 +1,12 @@ +warning: the type parameter `T` may not live long enough + --> $DIR/unsatisfied-hrtb-arg-lifetime.rs:16:34 + | +LL | fn warns<'b, T>(_: &'b ()) where for<'a> W<'a, 'b, T>: Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` must outlive `'b` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.next.stderr b/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.next.stderr new file mode 100644 index 0000000000000..f255c0543546e --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.next.stderr @@ -0,0 +1,22 @@ +warning: the type parameter `T` may not live long enough + --> $DIR/unsatisfied-hrtb-arg-lifetime.rs:16:34 + | +LL | fn warns<'b, T>(_: &'b ()) where for<'a> W<'a, 'b, T>: Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` must outlive `'b` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: the type parameter `T` may not live long enough + --> $DIR/unsatisfied-hrtb-arg-lifetime.rs:16:34 + | +LL | fn warns<'b, T>(_: &'b ()) where for<'a> W<'a, 'b, T>: Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` must outlive `'b` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: 2 warnings emitted + diff --git a/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.rs b/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.rs new file mode 100644 index 0000000000000..01cac32c18459 --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg-lifetime.rs @@ -0,0 +1,25 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Arguments of HRTBs must satisfy the lifetime bounds declared +// on the argument types. We currently emit a FCW for such +// code, as emitting a hard error would cause substantial +// crater breakage. +// See . + +#![allow(dead_code)] + +struct W<'a, 'b, T: 'b>(&'a (), &'b T); + +fn warns<'b, T>(_: &'b ()) where for<'a> W<'a, 'b, T>: Sized {} +//~^ WARN the type parameter `T` may not live long enough +//~| WARN this was previously accepted by the compiler +//[next]~| WARN the type parameter `T` may not live long enough +//[next]~| WARN this was previously accepted by the compiler + +// Adding the required bound silences the lint. +fn fixed<'b, T: 'b>(_: &'b ()) where for<'a> W<'a, 'b, T>: Sized {} + +fn main() {} diff --git a/tests/ui/wf/unsatisfied-hrtb-arg-no-warn.rs b/tests/ui/wf/unsatisfied-hrtb-arg-no-warn.rs new file mode 100644 index 0000000000000..755d97b9c0b70 --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg-no-warn.rs @@ -0,0 +1,15 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass +//@ edition: 2021 + +// Do not emit the UNSATISFIED_HRTB_ARG FCW for perfectly fine code. + +#![allow(dead_code)] + +fn f(_: impl for<'a> Fn(&'a T)) {} + +fn g(_: &T) where for<'a> &'a T: Copy {} + +fn main() {} diff --git a/tests/ui/wf/unsatisfied-hrtb-arg.current.stderr b/tests/ui/wf/unsatisfied-hrtb-arg.current.stderr new file mode 100644 index 0000000000000..a6b9eec1f0fac --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg.current.stderr @@ -0,0 +1,12 @@ +warning: the trait bound `T: Bound` is not satisfied + --> $DIR/unsatisfied-hrtb-arg.rs:17:21 + | +LL | fn warns() where for<'a> W<'a, T>: Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/wf/unsatisfied-hrtb-arg.next.stderr b/tests/ui/wf/unsatisfied-hrtb-arg.next.stderr new file mode 100644 index 0000000000000..a6b9eec1f0fac --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg.next.stderr @@ -0,0 +1,12 @@ +warning: the trait bound `T: Bound` is not satisfied + --> $DIR/unsatisfied-hrtb-arg.rs:17:21 + | +LL | fn warns() where for<'a> W<'a, T>: Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #162200 + = note: `#[warn(unsatisfied_hrtb_arg)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/wf/unsatisfied-hrtb-arg.rs b/tests/ui/wf/unsatisfied-hrtb-arg.rs new file mode 100644 index 0000000000000..f619c910fc72a --- /dev/null +++ b/tests/ui/wf/unsatisfied-hrtb-arg.rs @@ -0,0 +1,27 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Arguments of HRTBs must satisfy the trait bounds declared +// on the argument types. We currently emit a FCW for such +// code, as emitting a hard error would cause substantial +// crater breakage. +// See . + +#![allow(dead_code)] + +trait Bound {} +struct W<'a, T: Bound>(&'a T); + +fn warns() where for<'a> W<'a, T>: Sized {} +//~^ WARN the trait bound `T: Bound` is not satisfied +//~| WARN this was previously accepted by the compiler + +// Adding the required bound silences the lint. +fn fixed() where for<'a> W<'a, T>: Sized {} + +#[allow(unsatisfied_hrtb_arg)] +fn allowed() where for<'a> W<'a, T>: Sized {} + +fn main() {} From f59c672f6a515507aa36a3596e363d96f03ba8e4 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Fri, 18 Sep 2026 12:45:12 -0700 Subject: [PATCH 02/22] cr8r --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e37e895304bc6..9ad9fd4a9b02c 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -5130,7 +5130,7 @@ declare_lint! { /// [issue #162200]: https://github.com/rust-lang/rust/issues/162200 /// [future-incompatible]: ../index.md#future-incompatible-lints pub UNSATISFIED_HRTB_ARG, - Warn, + Forbid, "arguments of higher-ranked trait bounds that don't satisfy the bounds their types declare", @future_incompatible = FutureIncompatibleInfo { reason: fcw!(FutureReleaseError #162200), From 73651c82a9bd8bb147b8a360b04238461bc2dc73 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Tue, 22 Sep 2026 17:21:42 -0700 Subject: [PATCH 03/22] fix bootstrap --- src/build_helper/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/build_helper/src/lib.rs b/src/build_helper/src/lib.rs index 493ff92fbdbc3..46d8cd4275d48 100644 --- a/src/build_helper/src/lib.rs +++ b/src/build_helper/src/lib.rs @@ -30,7 +30,6 @@ pub const RUSTC_PGO_CRATES: &[&str] = &[ "token-stream-stress", "match-stress", "tuple-stress", - "diesel-2.2.10", "bitmaps-3.2.1", "serde-1.0.219-new-solver", ]; From f4e8bb758df2b41ce307d151572ab88cdea16b6b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 29 Jul 2026 19:12:43 -0400 Subject: [PATCH 04/22] Implement `Fn` traits for functions of any ABI This brings the behavior of the language in line with the documentation in `library/core/src/primitive_docs.rs`. --- compiler/rustc_abi/src/extern_abi.rs | 37 ++++++++++++++ .../src/error_reporting/traits/suggestions.rs | 5 +- compiler/rustc_type_ir/src/ty_kind.rs | 2 +- src/tools/miri/tests/pass/fn-traits-abi.rs | 39 +++++++++++++++ .../async-closures/fn-exception.rs | 2 +- .../async-closures/fn-exception.stderr | 16 +------ tests/ui/extern/extern-wrong-value-type.rs | 8 ++-- .../ui/extern/extern-wrong-value-type.stderr | 19 -------- .../suggest-option-asderef-unfixable.rs | 12 ++--- .../suggest-option-asderef-unfixable.stderr | 48 ++++++++----------- tests/ui/traits/next-solver/fn-trait.rs | 2 - tests/ui/traits/next-solver/fn-trait.stderr | 36 +------------- .../unboxed-closures/unboxed-closures-abi.rs | 40 ++++++++++++++++ .../unboxed-closures-wrong-abi.rs | 34 ------------- .../unboxed-closures-wrong-abi.stderr | 48 ------------------- 15 files changed, 150 insertions(+), 198 deletions(-) create mode 100644 src/tools/miri/tests/pass/fn-traits-abi.rs delete mode 100644 tests/ui/extern/extern-wrong-value-type.stderr create mode 100644 tests/ui/unboxed-closures/unboxed-closures-abi.rs delete mode 100644 tests/ui/unboxed-closures/unboxed-closures-wrong-abi.rs delete mode 100644 tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 79cee81d0fa2d..91c0bc0b59bca 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -369,6 +369,43 @@ impl ExternAbi { | Self::Swift => true, } } + + /// Returns whether safe functions with this ABI implement the `Fn` traits. + /// `false` only for uncallable or internal ABIs. + pub fn is_fn_trait_compatible(self) -> bool { + match self { + ExternAbi::C { .. } + | ExternAbi::System { .. } + | ExternAbi::Rust + | ExternAbi::RustCold + | ExternAbi::RustPreserveNone + | ExternAbi::RustTail + | ExternAbi::EfiApi + | ExternAbi::Swift + | ExternAbi::Aapcs { .. } + | ExternAbi::CmseNonSecureCall + | ExternAbi::CmseNonSecureEntry + | ExternAbi::Cdecl { .. } + | ExternAbi::Stdcall { .. } + | ExternAbi::Fastcall { .. } + | ExternAbi::Thiscall { .. } + | ExternAbi::Vectorcall { .. } + | ExternAbi::SysV64 { .. } + | ExternAbi::Win64 { .. } => true, + ExternAbi::RustCall + | ExternAbi::RustInvalid + | ExternAbi::LlvmIntrinsic + | ExternAbi::Custom + | ExternAbi::GpuKernel + | ExternAbi::PtxKernel + | ExternAbi::AvrInterrupt + | ExternAbi::AvrNonBlockingInterrupt + | ExternAbi::Msp430Interrupt + | ExternAbi::RiscvInterruptM + | ExternAbi::RiscvInterruptS + | ExternAbi::X86Interrupt => false, + } + } } pub fn all_names() -> Vec<&'static str> { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 5a17d65b0c0d6..b1a7eece91d00 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -5,7 +5,6 @@ use std::path::PathBuf; use std::{debug_assert_matches, iter}; use itertools::{EitherOrBoth, Itertools}; -use rustc_abi::ExternAbi; use rustc_attr_ir::lang_items::{self, LangItem}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; @@ -5520,9 +5519,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .. } = fn_ty.fn_sig(tcx).skip_binder() // FIXME(splat): this might need to change if the Fn* traits start using/supporting splat - && fn_sig.abi() == ExternAbi::Rust - && !fn_sig.c_variadic() - && fn_sig.safety() == hir::Safety::Safe + && fn_sig.is_fn_trait_compatible() // Extract first param of fn sig with peeled refs, e.g. `fn(&T)` -> `T` && let Some(&ty::Ref(_, target_ty, needs_mut)) = fn_sig.inputs().first().map(|t| t.kind()) diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 35f8897afd4c4..4d2c51e577a1f 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -1147,7 +1147,7 @@ impl FnSig { } pub fn is_fn_trait_compatible(self) -> bool { - !self.c_variadic() && self.safety().is_safe() && self.abi() == ExternAbi::Rust + !self.c_variadic() && self.safety().is_safe() && self.abi().is_fn_trait_compatible() } /// Set the safety flag. diff --git a/src/tools/miri/tests/pass/fn-traits-abi.rs b/src/tools/miri/tests/pass/fn-traits-abi.rs new file mode 100644 index 0000000000000..ed2579f7ab529 --- /dev/null +++ b/src/tools/miri/tests/pass/fn-traits-abi.rs @@ -0,0 +1,39 @@ +//! Test implementation of `Fn` traits for functions with non-`Rust` ABI + +use std::ops::{Fn, FnMut, FnOnce}; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct Foo(i32, i32); + +extern "C" fn square(foo: Foo) -> Foo { + Foo(foo.0 * foo.1, foo.0 - foo.1) +} + +fn call_it Foo>(f: &F, i: Foo) -> Foo { + f(i) +} + +fn call_it_mut Foo>(f: &mut F, i: Foo) -> Foo { + f(i) +} + +fn call_it_once Foo>(f: F, i: Foo) -> Foo { + f(i) +} + +fn main() { + assert_eq!(call_it(&square, Foo(20, 10)), Foo(200, 10)); + assert_eq!(call_it_mut(&mut square, Foo(21, 9)), Foo(189, 12)); + assert_eq!(call_it_once(square, Foo(18, -3)), Foo(-54, 21)); + + let mut square_ptr: extern "C" fn(Foo) -> Foo = square; + assert_eq!(call_it(&square_ptr, Foo(30, 11)), Foo(330, 19)); + assert_eq!(call_it_mut(&mut square_ptr, Foo(273, -1)), Foo(-273, 274)); + assert_eq!(call_it_once(square_ptr, Foo(27, 27)), Foo(729, 0)); + + let mut square_dyn: Box Foo> = Box::new(square); + assert_eq!(call_it(&*square_dyn, Foo(1, 3)), Foo(3, -2)); + assert_eq!(call_it_mut(&mut *square_dyn, Foo(5, 25)), Foo(125, -20)); + assert_eq!(call_it_once(square_dyn, Foo(9, 2)), Foo(18, 7)); +} diff --git a/tests/ui/async-await/async-closures/fn-exception.rs b/tests/ui/async-await/async-closures/fn-exception.rs index 8ff63983e7932..71df2178ff0c4 100644 --- a/tests/ui/async-await/async-closures/fn-exception.rs +++ b/tests/ui/async-await/async-closures/fn-exception.rs @@ -15,5 +15,5 @@ fn test(f: impl AsyncFn()) {} fn main() { test(unsafety); //~ ERROR the trait bound - test(abi); //~ ERROR the trait bound + test(abi); } diff --git a/tests/ui/async-await/async-closures/fn-exception.stderr b/tests/ui/async-await/async-closures/fn-exception.stderr index aa74ed234df00..a3366dda5ba73 100644 --- a/tests/ui/async-await/async-closures/fn-exception.stderr +++ b/tests/ui/async-await/async-closures/fn-exception.stderr @@ -12,20 +12,6 @@ note: required by a bound in `test` LL | fn test(f: impl AsyncFn()) {} | ^^^^^^^^^ required by this bound in `test` -error[E0277]: the trait bound `extern "C" fn() -> Pin + 'static)>> {abi}: AsyncFn()` is not satisfied - --> $DIR/fn-exception.rs:18:10 - | -LL | test(abi); - | ---- ^^^ the trait `AsyncFn()` is not implemented for fn item `extern "C" fn() -> Pin + 'static)>> {abi}` - | | - | required by a bound introduced by this call - | -note: required by a bound in `test` - --> $DIR/fn-exception.rs:14:17 - | -LL | fn test(f: impl AsyncFn()) {} - | ^^^^^^^^^ required by this bound in `test` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/extern/extern-wrong-value-type.rs b/tests/ui/extern/extern-wrong-value-type.rs index ae07a721e83ee..3aa3539777cad 100644 --- a/tests/ui/extern/extern-wrong-value-type.rs +++ b/tests/ui/extern/extern-wrong-value-type.rs @@ -1,11 +1,13 @@ +//@ run-pass + extern "C" fn f() { } -fn is_fn(_: F) where F: Fn() {} +fn is_fn(f: F) where F: Fn() { + f(); +} fn main() { - // extern functions are extern "C" fn let _x: extern "C" fn() = f; // OK is_fn(f); - //~^ ERROR expected an `Fn()` closure, found `extern "C" fn() {f}` } diff --git a/tests/ui/extern/extern-wrong-value-type.stderr b/tests/ui/extern/extern-wrong-value-type.stderr deleted file mode 100644 index e1686f8a3ab9b..0000000000000 --- a/tests/ui/extern/extern-wrong-value-type.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: expected an `Fn()` closure, found `extern "C" fn() {f}` - --> $DIR/extern-wrong-value-type.rs:9:11 - | -LL | is_fn(f); - | ----- ^ expected an `Fn()` closure, found `extern "C" fn() {f}` - | | - | required by a bound introduced by this call - | - = help: the trait `Fn()` is not implemented for fn item `extern "C" fn() {f}` - = note: wrap the `extern "C" fn() {f}` in a closure with no arguments: `|| { /* code */ }` -note: required by a bound in `is_fn` - --> $DIR/extern-wrong-value-type.rs:4:28 - | -LL | fn is_fn(_: F) where F: Fn() {} - | ^^^^ required by this bound in `is_fn` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.rs b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.rs index 445a98cd49630..1fcb41e256d48 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.rs +++ b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.rs @@ -2,7 +2,7 @@ fn produces_string() -> Option { Some("my cool string".to_owned()) } -fn takes_str_but_too_many_refs(_: &&str) -> Option<()> { +fn takes_str_but_too_many_refs(_: &str) -> Option<()> { Some(()) } @@ -10,11 +10,7 @@ fn no_args() -> Option<()> { Some(()) } -extern "C" fn takes_str_but_wrong_abi(_: &str) -> Option<()> { - Some(()) -} - -unsafe fn takes_str_but_unsafe(_: &str) -> Option<()> { +unsafe fn takes_str_but_unsafe(_: String) -> Option<()> { Some(()) } @@ -23,10 +19,8 @@ struct TypeWithoutDeref; fn main() { let _ = produces_string().and_then(takes_str_but_too_many_refs); //~^ ERROR type mismatch in function arguments - let _ = produces_string().and_then(takes_str_but_wrong_abi); - //~^ ERROR expected an `FnOnce(String)` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}` let _ = produces_string().and_then(takes_str_but_unsafe); - //~^ ERROR expected an `FnOnce(String)` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}` + //~^ ERROR expected an `FnOnce(String)` closure, found `unsafe fn(String) -> Option<()> {takes_str_but_unsafe}` let _ = produces_string().and_then(no_args); //~^ ERROR function is expected to take 1 argument, but it takes 0 arguments let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs); diff --git a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr index 14c821b260299..4c1b0bec4d745 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr @@ -1,8 +1,8 @@ error[E0631]: type mismatch in function arguments - --> $DIR/suggest-option-asderef-unfixable.rs:24:40 + --> $DIR/suggest-option-asderef-unfixable.rs:20:40 | -LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> { - | ------------------------------------------------------ found signature defined here +LL | fn takes_str_but_too_many_refs(_: &str) -> Option<()> { + | ----------------------------------------------------- found signature defined here ... LL | let _ = produces_string().and_then(takes_str_but_too_many_refs); | -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected due to this @@ -10,41 +10,33 @@ LL | let _ = produces_string().and_then(takes_str_but_too_many_refs); | required by a bound introduced by this call | = note: expected function signature `fn(String) -> _` - found function signature `fn(&&str) -> _` + found function signature `fn(&str) -> _` note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure | -LL | let _ = produces_string().and_then(|arg0: String| takes_str_but_too_many_refs(/* &&str */)); - | ++++++++++++++ +++++++++++++ - -error[E0277]: expected an `FnOnce(String)` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}` - --> $DIR/suggest-option-asderef-unfixable.rs:26:40 - | -LL | let _ = produces_string().and_then(takes_str_but_wrong_abi); - | -------- ^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce(String)` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}` - | | - | required by a bound introduced by this call +LL | let _ = produces_string().and_then(|arg0: String| takes_str_but_too_many_refs(/* &str */)); + | ++++++++++++++ ++++++++++++ +help: call `Option::as_deref()` first | - = help: the trait `FnOnce(String)` is not implemented for fn item `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}` -note: required by a bound in `Option::::and_then` - --> $SRC_DIR/core/src/option.rs:LL:COL +LL | let _ = produces_string().as_deref().and_then(takes_str_but_too_many_refs); + | +++++++++++ -error[E0277]: expected an `FnOnce(String)` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}` - --> $DIR/suggest-option-asderef-unfixable.rs:28:40 +error[E0277]: expected an `FnOnce(String)` closure, found `unsafe fn(String) -> Option<()> {takes_str_but_unsafe}` + --> $DIR/suggest-option-asderef-unfixable.rs:22:40 | LL | let _ = produces_string().and_then(takes_str_but_unsafe); | -------- ^^^^^^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` | | | required by a bound introduced by this call | - = help: the trait `FnOnce(String)` is not implemented for fn item `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}` + = help: the trait `FnOnce(String)` is not implemented for fn item `unsafe fn(String) -> Option<()> {takes_str_but_unsafe}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL error[E0593]: function is expected to take 1 argument, but it takes 0 arguments - --> $DIR/suggest-option-asderef-unfixable.rs:30:40 + --> $DIR/suggest-option-asderef-unfixable.rs:24:40 | LL | fn no_args() -> Option<()> { | -------------------------- takes 0 arguments @@ -58,10 +50,10 @@ note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL error[E0631]: type mismatch in function arguments - --> $DIR/suggest-option-asderef-unfixable.rs:32:45 + --> $DIR/suggest-option-asderef-unfixable.rs:26:45 | -LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> { - | ------------------------------------------------------ found signature defined here +LL | fn takes_str_but_too_many_refs(_: &str) -> Option<()> { + | ----------------------------------------------------- found signature defined here ... LL | let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs); | -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected due to this @@ -69,15 +61,15 @@ LL | let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs); | required by a bound introduced by this call | = note: expected function signature `fn(TypeWithoutDeref) -> _` - found function signature `fn(&&str) -> _` + found function signature `fn(&str) -> _` note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure | -LL | let _ = Some(TypeWithoutDeref).and_then(|arg0: TypeWithoutDeref| takes_str_but_too_many_refs(/* &&str */)); - | ++++++++++++++++++++++++ +++++++++++++ +LL | let _ = Some(TypeWithoutDeref).and_then(|arg0: TypeWithoutDeref| takes_str_but_too_many_refs(/* &str */)); + | ++++++++++++++++++++++++ ++++++++++++ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0593, E0631. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/fn-trait.rs b/tests/ui/traits/next-solver/fn-trait.rs index e31d4d2b580a5..de9841089b7e9 100644 --- a/tests/ui/traits/next-solver/fn-trait.rs +++ b/tests/ui/traits/next-solver/fn-trait.rs @@ -20,9 +20,7 @@ fn main() { require_fn(f as unsafe fn() -> i32); //~^ ERROR: expected an `Fn()` closure, found `unsafe fn() -> i32` require_fn(g); - //~^ ERROR: expected an `Fn()` closure, found `extern "C" fn() -> i32 {g}` require_fn(g as extern "C" fn() -> i32); - //~^ ERROR: expected an `Fn()` closure, found `extern "C" fn() -> i32` require_fn(h); //~^ ERROR: expected an `Fn()` closure, found `unsafe fn() -> i32 {h}` } diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr index 6218928b309f7..65bad29a67751 100644 --- a/tests/ui/traits/next-solver/fn-trait.stderr +++ b/tests/ui/traits/next-solver/fn-trait.stderr @@ -15,40 +15,8 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0277]: expected an `Fn()` closure, found `extern "C" fn() -> i32 {g}` - --> $DIR/fn-trait.rs:22:16 - | -LL | require_fn(g); - | ---------- ^ expected an `Fn()` closure, found `extern "C" fn() -> i32 {g}` - | | - | required by a bound introduced by this call - | - = help: the trait `Fn()` is not implemented for fn item `extern "C" fn() -> i32 {g}` - = note: wrap the `extern "C" fn() -> i32 {g}` in a closure with no arguments: `|| { /* code */ }` -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:23 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^^^^^^^^^ required by this bound in `require_fn` - -error[E0277]: expected an `Fn()` closure, found `extern "C" fn() -> i32` - --> $DIR/fn-trait.rs:24:16 - | -LL | require_fn(g as extern "C" fn() -> i32); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn()` closure, found `extern "C" fn() -> i32` - | | - | required by a bound introduced by this call - | - = help: the trait `Fn()` is not implemented for `extern "C" fn() -> i32` - = note: wrap the `extern "C" fn() -> i32` in a closure with no arguments: `|| { /* code */ }` -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:23 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^^^^^^^^^ required by this bound in `require_fn` - error[E0277]: expected an `Fn()` closure, found `unsafe fn() -> i32 {h}` - --> $DIR/fn-trait.rs:26:16 + --> $DIR/fn-trait.rs:24:16 | LL | require_fn(h); | ---------- ^ call the function in a closure: `|| unsafe { /* code */ }` @@ -64,6 +32,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unboxed-closures/unboxed-closures-abi.rs b/tests/ui/unboxed-closures/unboxed-closures-abi.rs new file mode 100644 index 0000000000000..5aabc12971e63 --- /dev/null +++ b/tests/ui/unboxed-closures/unboxed-closures-abi.rs @@ -0,0 +1,40 @@ +//@ run-pass +//! Test implementation of `Fn` traits for functions with non-`Rust` ABI + +use std::ops::{Fn, FnMut, FnOnce}; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct Foo(i32, i32); + +extern "C" fn square(foo: Foo) -> Foo { + Foo(foo.0 * foo.1, foo.0 - foo.1) +} + +fn call_it Foo>(f: &F, i: Foo) -> Foo { + f(i) +} + +fn call_it_mut Foo>(f: &mut F, i: Foo) -> Foo { + f(i) +} + +fn call_it_once Foo>(f: F, i: Foo) -> Foo { + f(i) +} + +fn main() { + assert_eq!(call_it(&square, Foo(20, 10)), Foo(200, 10)); + assert_eq!(call_it_mut(&mut square, Foo(21, 9)), Foo(189, 12)); + assert_eq!(call_it_once(square, Foo(18, -3)), Foo(-54, 21)); + + let mut square_ptr: extern "C" fn(Foo) -> Foo = square; + assert_eq!(call_it(&square_ptr, Foo(30, 11)), Foo(330, 19)); + assert_eq!(call_it_mut(&mut square_ptr, Foo(273, -1)), Foo(-273, 274)); + assert_eq!(call_it_once(square_ptr, Foo(27, 27)), Foo(729, 0)); + + let mut square_dyn: Box Foo> = Box::new(square); + assert_eq!(call_it(&*square_dyn, Foo(1, 3)), Foo(3, -2)); + assert_eq!(call_it_mut(&mut *square_dyn, Foo(5, 25)), Foo(125, -20)); + assert_eq!(call_it_once(square_dyn, Foo(9, 2)), Foo(18, 7)); +} diff --git a/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.rs b/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.rs deleted file mode 100644 index dd76c597d28ad..0000000000000 --- a/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Tests that unsafe extern fn pointers do not implement any Fn traits. - -use std::ops::{Fn, FnMut, FnOnce}; - -extern "C" fn square(x: &isize) -> isize { - (*x) * (*x) -} - -fn call_it isize>(_: &F, _: isize) -> isize { - 0 -} -fn call_it_mut isize>(_: &mut F, _: isize) -> isize { - 0 -} -fn call_it_once isize>(_: F, _: isize) -> isize { - 0 -} - -fn a() { - let x = call_it(&square, 22); - //~^ ERROR E0277 -} - -fn b() { - let y = call_it_mut(&mut square, 22); - //~^ ERROR E0277 -} - -fn c() { - let z = call_it_once(square, 22); - //~^ ERROR E0277 -} - -fn main() {} diff --git a/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr deleted file mode 100644 index 25cf793ca00e8..0000000000000 --- a/tests/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error[E0277]: expected an `Fn(&isize)` closure, found `for<'a> extern "C" fn(&'a isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-abi.rs:20:21 - | -LL | let x = call_it(&square, 22); - | ------- ^^^^^^^ expected an `Fn(&isize)` closure, found `for<'a> extern "C" fn(&'a isize) -> isize {square}` - | | - | required by a bound introduced by this call - | - = help: the trait `for<'a> Fn(&'a isize)` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` -note: required by a bound in `call_it` - --> $DIR/unboxed-closures-wrong-abi.rs:9:15 - | -LL | fn call_it isize>(_: &F, _: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `call_it` - -error[E0277]: expected an `FnMut(&isize)` closure, found `for<'a> extern "C" fn(&'a isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-abi.rs:25:25 - | -LL | let y = call_it_mut(&mut square, 22); - | ----------- ^^^^^^^^^^^ expected an `FnMut(&isize)` closure, found `for<'a> extern "C" fn(&'a isize) -> isize {square}` - | | - | required by a bound introduced by this call - | - = help: the trait `for<'a> FnMut(&'a isize)` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` -note: required by a bound in `call_it_mut` - --> $DIR/unboxed-closures-wrong-abi.rs:12:19 - | -LL | fn call_it_mut isize>(_: &mut F, _: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call_it_mut` - -error[E0277]: expected an `FnOnce(&isize)` closure, found `for<'a> extern "C" fn(&'a isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-abi.rs:30:26 - | -LL | let z = call_it_once(square, 22); - | ------------ ^^^^^^ expected an `FnOnce(&isize)` closure, found `for<'a> extern "C" fn(&'a isize) -> isize {square}` - | | - | required by a bound introduced by this call - | - = help: the trait `for<'a> FnOnce(&'a isize)` is not implemented for fn item `for<'a> extern "C" fn(&'a isize) -> isize {square}` -note: required by a bound in `call_it_once` - --> $DIR/unboxed-closures-wrong-abi.rs:15:20 - | -LL | fn call_it_once isize>(_: F, _: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call_it_once` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. From d559364035202f98b310a2d938b940bf51e4efab Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 2 Oct 2026 01:26:09 -0400 Subject: [PATCH 05/22] Add `extern "C"` + `AsyncFn` test --- .../async-closures/c-fn-ptr-asyncfn.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/ui/async-await/async-closures/c-fn-ptr-asyncfn.rs diff --git a/tests/ui/async-await/async-closures/c-fn-ptr-asyncfn.rs b/tests/ui/async-await/async-closures/c-fn-ptr-asyncfn.rs new file mode 100644 index 0000000000000..45d5302b1584d --- /dev/null +++ b/tests/ui/async-await/async-closures/c-fn-ptr-asyncfn.rs @@ -0,0 +1,21 @@ +//@ run-pass +//@ edition: 2021 + +use std::future::Future; +use std::pin::Pin; + +#[expect(improper_ctypes_definitions)] +pub extern "C" fn abi() -> Pin + 'static>> { + Box::pin(async {}) +} + +fn test(f: impl AsyncFn()) { + let _ = async { + f().await; + f().await; + }; +} + +fn main() { + test(abi); +} From 63991e8e46fd9191aeda4ef117bf1862811ece29 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sat, 3 Oct 2026 15:31:28 +0200 Subject: [PATCH 06/22] reserve unknown doc attributes --- .../rustc_attr_parsing/src/attributes/doc.rs | 47 ++++++++++++------- .../rustc_attr_parsing/src/diagnostics.rs | 8 ++++ tests/rustdoc-ui/lints/doc-attr-2.rs | 9 ++-- tests/rustdoc-ui/lints/doc-attr-2.stderr | 22 ++++----- tests/ui/attributes/doc-attr.rs | 8 ++-- tests/ui/attributes/doc-attr.stderr | 39 ++++++++------- tests/ui/repr/invalid_repr_list_help.rs | 2 +- tests/ui/repr/invalid_repr_list_help.stderr | 8 +--- tests/ui/rustdoc/deny-invalid-doc-attrs.rs | 4 +- .../ui/rustdoc/deny-invalid-doc-attrs.stderr | 10 +--- tests/ui/rustdoc/doc-primitive.rs | 2 +- tests/ui/rustdoc/doc-primitive.stderr | 8 +--- 12 files changed, 80 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 7dc5c6ce9f2b8..ce734162ce0fc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -19,9 +19,9 @@ use crate::diagnostics::{ DocAutoCfgHideShowExpectsList, DocAutoCfgHideShowNoIdentBeforeValues, DocAutoCfgHideShowUnexpectedItem, DocAutoCfgHideShowUnexpectedItemAfterValues, DocAutoCfgHideShowValuesMix, DocAutoCfgWrongLiteral, DocInlineConflict, DocInlineOnlyUse, - DocKeywordNotKeyword, DocTestLiteral, DocTestTakesList, DocTestUnknown, DocUnknownAny, - DocUnknownInclude, DocUnknownPasses, DocUnknownPlugins, DocUnknownSpotlight, ExpectedNameValue, - ExpectedNoArgs, IllFormedAttributeInput, MalformedDoc, UnusedDuplicate, + DocKeywordNotKeyword, DocReserved, DocTestLiteral, DocTestTakesList, DocTestUnknown, + DocUnknownAny, DocUnknownInclude, DocUnknownPasses, DocUnknownPlugins, DocUnknownSpotlight, + ExpectedNameValue, ExpectedNoArgs, IllFormedAttributeInput, MalformedDoc, UnusedDuplicate, }; use crate::parser::{ ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser, @@ -688,18 +688,30 @@ impl DocParser { let span = path.span(); cx.emit_lint(INVALID_DOC_ATTRIBUTES, DocUnknownSpotlight { sugg_span: span }, span); } - Some(sym::include) if let Some(nv) = args.as_name_value() => { - let inner = match cx.attr_style { - AttrStyle::Outer => "", - AttrStyle::Inner => "!", - }; - let value = nv.value_as_lit().symbol; - let span = path.span(); - cx.emit_lint( - INVALID_DOC_ATTRIBUTES, - DocUnknownInclude { inner, value, sugg: (span, Applicability::MaybeIncorrect) }, - span, - ); + Some(sym::include) => { + if let Some(nv) = args.as_name_value() { + let inner = match cx.attr_style { + AttrStyle::Outer => "", + AttrStyle::Inner => "!", + }; + let value = nv.value_as_lit().symbol; + let span = path.span(); + cx.emit_lint( + INVALID_DOC_ATTRIBUTES, + DocUnknownInclude { + inner, + value, + sugg: (span, Applicability::MaybeIncorrect), + }, + span, + ); + } else { + cx.emit_lint( + INVALID_DOC_ATTRIBUTES, + DocUnknownAny { name: sym::include }, + path.span(), + ); + } } Some(name @ (sym::passes | sym::no_default_passes)) => { let span = path.span(); @@ -714,13 +726,14 @@ impl DocParser { cx.emit_lint(INVALID_DOC_ATTRIBUTES, DocUnknownPlugins { label_span: span }, span); } Some(name) => { - cx.emit_lint(INVALID_DOC_ATTRIBUTES, DocUnknownAny { name }, path.span()); + cx.emit_err(DocReserved { name, span: path.span() }); } None => { let full_name = path.segments().map(|s| s.as_str()).intersperse("::").collect::(); let name = Symbol::intern(&full_name); - cx.emit_lint(INVALID_DOC_ATTRIBUTES, DocUnknownAny { name }, path.span()); + + cx.emit_err(DocReserved { name, span: path.span() }); } } } diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index 7d0a7832f52cf..30ede8dc33fab 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -298,6 +298,14 @@ pub(crate) struct DocUnknownAny { pub name: Symbol, } +#[derive(Diagnostic)] +#[diag("reserved `doc` attribute `{$name}`")] +pub(crate) struct DocReserved { + pub name: Symbol, + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("expected boolean for `#[doc(auto_cfg = ...)]`")] pub(crate) struct DocAutoCfgWrongLiteral; diff --git a/tests/rustdoc-ui/lints/doc-attr-2.rs b/tests/rustdoc-ui/lints/doc-attr-2.rs index 9802fb5d95a5c..adf69e81f4a18 100644 --- a/tests/rustdoc-ui/lints/doc-attr-2.rs +++ b/tests/rustdoc-ui/lints/doc-attr-2.rs @@ -1,12 +1,11 @@ -#![deny(invalid_doc_attributes)] #![doc(as_ptr)] -//~^ ERROR unknown `doc` attribute `as_ptr` +//~^ ERROR reserved `doc` attribute `as_ptr` #[doc(as_ptr)] -//~^ ERROR unknown `doc` attribute `as_ptr` +//~^ ERROR reserved `doc` attribute `as_ptr` pub fn foo() {} #[doc(foo::bar, crate::bar::baz = "bye")] -//~^ ERROR unknown `doc` attribute `foo::bar` -//~| ERROR unknown `doc` attribute `crate::bar::baz` +//~^ ERROR reserved `doc` attribute `foo::bar` +//~| ERROR reserved `doc` attribute `crate::bar::baz` fn bar() {} diff --git a/tests/rustdoc-ui/lints/doc-attr-2.stderr b/tests/rustdoc-ui/lints/doc-attr-2.stderr index 7c10f7b546612..ae90b83100fa0 100644 --- a/tests/rustdoc-ui/lints/doc-attr-2.stderr +++ b/tests/rustdoc-ui/lints/doc-attr-2.stderr @@ -1,29 +1,23 @@ -error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr-2.rs:2:8 +error: reserved `doc` attribute `as_ptr` + --> $DIR/doc-attr-2.rs:1:8 | LL | #![doc(as_ptr)] | ^^^^^^ - | -note: the lint level is defined here - --> $DIR/doc-attr-2.rs:1:9 - | -LL | #![deny(invalid_doc_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^ -error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr-2.rs:5:7 +error: reserved `doc` attribute `as_ptr` + --> $DIR/doc-attr-2.rs:4:7 | LL | #[doc(as_ptr)] | ^^^^^^ -error: unknown `doc` attribute `foo::bar` - --> $DIR/doc-attr-2.rs:9:7 +error: reserved `doc` attribute `foo::bar` + --> $DIR/doc-attr-2.rs:8:7 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] | ^^^^^^^^ -error: unknown `doc` attribute `crate::bar::baz` - --> $DIR/doc-attr-2.rs:9:17 +error: reserved `doc` attribute `crate::bar::baz` + --> $DIR/doc-attr-2.rs:8:17 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/attributes/doc-attr.rs b/tests/ui/attributes/doc-attr.rs index 8c81bc18d6aec..0c212e833e2c9 100644 --- a/tests/ui/attributes/doc-attr.rs +++ b/tests/ui/attributes/doc-attr.rs @@ -1,10 +1,10 @@ #![deny(invalid_doc_attributes)] #![crate_type = "lib"] #![doc(as_ptr)] -//~^ ERROR unknown `doc` attribute +//~^ ERROR reserved `doc` attribute #[doc(as_ptr)] -//~^ ERROR unknown `doc` attribute +//~^ ERROR reserved `doc` attribute pub fn foo() {} #[doc(123)] @@ -16,6 +16,6 @@ pub fn foo() {} //~| WARN //~| WARN #[doc(foo::bar, crate::bar::baz = "bye")] -//~^ ERROR unknown `doc` attribute -//~| ERROR unknown `doc` attribute +//~^ ERROR reserved `doc` attribute +//~| ERROR reserved `doc` attribute fn bar() {} diff --git a/tests/ui/attributes/doc-attr.stderr b/tests/ui/attributes/doc-attr.stderr index 4dc096d87cb40..3dbd2bf79d186 100644 --- a/tests/ui/attributes/doc-attr.stderr +++ b/tests/ui/attributes/doc-attr.stderr @@ -1,21 +1,27 @@ -error: unknown `doc` attribute `as_ptr` +error: reserved `doc` attribute `as_ptr` --> $DIR/doc-attr.rs:3:8 | LL | #![doc(as_ptr)] | ^^^^^^ - | -note: the lint level is defined here - --> $DIR/doc-attr.rs:1:9 - | -LL | #![deny(invalid_doc_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^ -error: unknown `doc` attribute `as_ptr` +error: reserved `doc` attribute `as_ptr` --> $DIR/doc-attr.rs:6:7 | LL | #[doc(as_ptr)] | ^^^^^^ +error: reserved `doc` attribute `foo::bar` + --> $DIR/doc-attr.rs:18:7 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^ + +error: reserved `doc` attribute `crate::bar::baz` + --> $DIR/doc-attr.rs:18:17 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^^^^^^^^ + error: expected this to be of the form `... = "..."` --> $DIR/doc-attr.rs:10:7 | @@ -23,6 +29,11 @@ LL | #[doc(123)] | ^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/doc-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: expected this to be of the form `... = "..."` --> $DIR/doc-attr.rs:13:7 @@ -40,17 +51,5 @@ LL | #[doc("hello", "bar")] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: unknown `doc` attribute `foo::bar` - --> $DIR/doc-attr.rs:18:7 - | -LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^ - -error: unknown `doc` attribute `crate::bar::baz` - --> $DIR/doc-attr.rs:18:17 - | -LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^^^^^^^^ - error: aborting due to 7 previous errors diff --git a/tests/ui/repr/invalid_repr_list_help.rs b/tests/ui/repr/invalid_repr_list_help.rs index 407514d014d8a..930ec0d334128 100644 --- a/tests/ui/repr/invalid_repr_list_help.rs +++ b/tests/ui/repr/invalid_repr_list_help.rs @@ -18,5 +18,5 @@ pub enum OwO4 { } #[repr(uwu)] //~ERROR: malformed `repr` attribute input -#[doc(owo)] //~ERROR: unknown `doc` attribute +#[doc(owo)] //~ERROR: reserved `doc` attribute pub struct Owo5; diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr index 17e6e99c82f4f..7265602ed9a89 100644 --- a/tests/ui/repr/invalid_repr_list_help.stderr +++ b/tests/ui/repr/invalid_repr_list_help.stderr @@ -48,17 +48,11 @@ LL | #[repr(uwu)] | = note: for more information, visit -error: unknown `doc` attribute `owo` +error: reserved `doc` attribute `owo` --> $DIR/invalid_repr_list_help.rs:21:7 | LL | #[doc(owo)] | ^^^ - | -note: the lint level is defined here - --> $DIR/invalid_repr_list_help.rs:1:9 - | -LL | #![deny(invalid_doc_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/rustdoc/deny-invalid-doc-attrs.rs b/tests/ui/rustdoc/deny-invalid-doc-attrs.rs index 15bfd723424e2..5ae438db6e376 100644 --- a/tests/ui/rustdoc/deny-invalid-doc-attrs.rs +++ b/tests/ui/rustdoc/deny-invalid-doc-attrs.rs @@ -1,5 +1,3 @@ -#![deny(invalid_doc_attributes)] -//~^ NOTE defined here #![doc(x)] -//~^ ERROR unknown `doc` attribute `x` +//~^ ERROR reserved `doc` attribute `x` fn main() {} diff --git a/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr b/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr index 0884e9c8bb2e7..15fbffe4a28d8 100644 --- a/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr +++ b/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr @@ -1,14 +1,8 @@ -error: unknown `doc` attribute `x` - --> $DIR/deny-invalid-doc-attrs.rs:3:8 +error: reserved `doc` attribute `x` + --> $DIR/deny-invalid-doc-attrs.rs:1:8 | LL | #![doc(x)] | ^ - | -note: the lint level is defined here - --> $DIR/deny-invalid-doc-attrs.rs:1:9 - | -LL | #![deny(invalid_doc_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rustdoc/doc-primitive.rs b/tests/ui/rustdoc/doc-primitive.rs index fbb1e1bc1fa23..64348f932f27a 100644 --- a/tests/ui/rustdoc/doc-primitive.rs +++ b/tests/ui/rustdoc/doc-primitive.rs @@ -1,7 +1,7 @@ #![deny(invalid_doc_attributes)] #[doc(primitive = "foo")] -//~^ ERROR unknown `doc` attribute `primitive` +//~^ ERROR reserved `doc` attribute `primitive` mod bar {} fn main() {} diff --git a/tests/ui/rustdoc/doc-primitive.stderr b/tests/ui/rustdoc/doc-primitive.stderr index 4ba310ca24101..d9cb5405360f0 100644 --- a/tests/ui/rustdoc/doc-primitive.stderr +++ b/tests/ui/rustdoc/doc-primitive.stderr @@ -1,14 +1,8 @@ -error: unknown `doc` attribute `primitive` +error: reserved `doc` attribute `primitive` --> $DIR/doc-primitive.rs:3:7 | LL | #[doc(primitive = "foo")] | ^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/doc-primitive.rs:1:9 - | -LL | #![deny(invalid_doc_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error From 28b9b0e42f84a6d977ca3009cff7441abb435f3d Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sat, 3 Oct 2026 20:22:55 +0200 Subject: [PATCH 07/22] Fix rust_logo feature gate --- compiler/rustc_attr_parsing/src/attributes/doc.rs | 12 +++++------- tests/ui/feature-gates/doc-rust-logo.rs | 3 ++- tests/ui/feature-gates/doc-rust-logo.stderr | 13 ++++++++++++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index ce734162ce0fc..8e89cbfd46be5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -647,13 +647,11 @@ impl DocParser { no_args_and_not_crate_level!(search_unbox) } Some(sym::rust_logo) => { - // FIXME: Only feature gated at the crate level (!!) - if cx.target == Target::Crate { - gated!( - rustdoc_internals, - "the `#[doc(rust_logo)]` attribute is used for Rust branding" - ); - } + gated!( + rustdoc_internals, + "the `#[doc(rust_logo)]` attribute is used for Rust branding" + ); + no_args_and_crate_level!(rust_logo) } Some(sym::auto_cfg) => { diff --git a/tests/ui/feature-gates/doc-rust-logo.rs b/tests/ui/feature-gates/doc-rust-logo.rs index 08857cc778f5b..d3a0f5a8c8830 100644 --- a/tests/ui/feature-gates/doc-rust-logo.rs +++ b/tests/ui/feature-gates/doc-rust-logo.rs @@ -3,5 +3,6 @@ //! This is not an official rust crate #[doc(rust_logo)] -//~^ WARN this attribute can only be applied at the crate level +//~^ ERROR this subset of the `doc` attribute is meant for internal use only +//~| WARN this attribute can only be applied at the crate level fn main() {} diff --git a/tests/ui/feature-gates/doc-rust-logo.stderr b/tests/ui/feature-gates/doc-rust-logo.stderr index f31837be284d1..95092944de5c0 100644 --- a/tests/ui/feature-gates/doc-rust-logo.stderr +++ b/tests/ui/feature-gates/doc-rust-logo.stderr @@ -9,6 +9,17 @@ LL | #![doc(rust_logo)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: the `#[doc(rust_logo)]` attribute is used for Rust branding +error[E0658]: this subset of the `doc` attribute is meant for internal use only + --> $DIR/doc-rust-logo.rs:5:7 + | +LL | #[doc(rust_logo)] + | ^^^^^^^^^ + | + = note: see issue #90418 for more information + = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: the `#[doc(rust_logo)]` attribute is used for Rust branding + warning: this attribute can only be applied at the crate level --> $DIR/doc-rust-logo.rs:5:7 | @@ -18,6 +29,6 @@ LL | #[doc(rust_logo)] = note: read for more information = note: `#[warn(invalid_doc_attributes)]` on by default -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0658`. From 68bfdf44f26cf4bb655623cb2ad70ad3fb440a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 24 Mar 2026 01:29:46 +0000 Subject: [PATCH 08/22] `>::into` lint Add two lints, very similar to `clippy::useless_conversion`, detecting when `.into()` is being called unnecessarily. We present two separate lints, one that triggers inside of macros, because it is common for macros to have `.into()` calls to make the caller side easier to use. In those cases people should still use the fully-qualified path instead, but allow them to silence that lint without silencing the more general, more likely to be problematic case. This lint allows us to protect developers from the semver-hazard that time 0.3.34 encountered, where a std change caused a valid method chain to start producing inference errors. This is explicitly allowed by the Rust project's backwards compatibility guarantees (inference is not included in them), which means that relying on the blanket `impl Into` is a problem. The lint as implemented has false negatives: because of the way type aliases are handled by the type system, we can't know whether `let _: i32 = 0i32.into()` corresponds to a call on `i32` *or* a call on a type alias that is `i32` only on some platforms (like `#[cfg(..)] type Int = i32;`). To avoid false positives, we keep track of type aliases that have been imported in the local crate and mark their types for exclusion. This means that calling `let _: i32 = Int::into(0i32);` will not be linted against even though it should. Ignore useless `.into()` calls on fields or structs that are behind a `cfg` attr. Ignore useless `.into()` calls on `const`s that are behind a cfg attr. This side-steps a lot of `libc` cases. Account for `foo.map(Into::into)`. Account for macros in suggestions. Do not emit a suggestion to remove the `.into()` call when the `Span` context of the receiver is different to the Span context of the expression to avoid malformed suggestions. The lint still triggers regardless, just with less information. --- .../src/infer/snapshot/undo_log.rs | 1 + compiler/rustc_lint/src/builtin.rs | 355 +++++++++++++++++- compiler/rustc_lint/src/diagnostics.rs | 48 +++ compiler/rustc_lint/src/lib.rs | 3 +- compiler/rustc_lint/src/passes.rs | 12 +- compiler/rustc_span/src/symbol.rs | 3 + library/core/src/convert/mod.rs | 1 + library/core/src/option.rs | 1 + library/core/src/result.rs | 1 + library/coretests/tests/convert.rs | 1 + library/std/src/sys/process/env.rs | 2 + .../needless_return_with_question_mark.fixed | 4 +- .../ui/needless_return_with_question_mark.rs | 4 +- .../needless_return_with_question_mark.stderr | 10 +- .../clippy/tests/ui/useless_conversion.fixed | 2 +- .../clippy/tests/ui/useless_conversion.rs | 2 +- tests/ui/lint/self_type_conversion.rs | 196 ++++++++++ tests/ui/lint/self_type_conversion.stderr | 139 +++++++ .../macro-or-patterns-back-compat.fixed | 2 +- .../macros/macro-or-patterns-back-compat.rs | 2 +- .../macro-pat-pattern-followed-by-or.rs | 2 +- ...re-inference-hr-ambig-alias-naming-self.rs | 1 + .../global-param-env-after-norm.rs | 1 + ...aram-method-from-unnormalized-param-env.rs | 1 + 24 files changed, 774 insertions(+), 20 deletions(-) create mode 100644 tests/ui/lint/self_type_conversion.rs create mode 100644 tests/ui/lint/self_type_conversion.stderr diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 2b1ac29173483..518c9d4e8a1ef 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -38,6 +38,7 @@ macro_rules! impl_from { $( impl<'tcx> From<$ty> for UndoLog<'tcx> { fn from(x: $ty) -> Self { + #[cfg_attr(not(bootstrap), allow(self_type_conversion))] UndoLog::$ctor(x.into()) } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2c8c6a3ce7f17..3d25c5c56f2f7 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -24,6 +24,7 @@ use rustc_ast_pretty::pprust::expr_to_string; use rustc_attr_ir::lang_items::LangItem; use rustc_attr_ir::{AttributeKind, DocAttribute, find_attr}; use rustc_attr_parsing::AttributeParser; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diagnostic, msg}; use rustc_feature::GateIssue; use rustc_hir::def::{DefKind, Res}; @@ -58,7 +59,8 @@ use crate::diagnostics::{ BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, BuiltinWhileTrue, - EqInternalMethodImplemented, InvalidAsmLabel, + EqInternalMethodImplemented, FullyQualifiedPathSuggestion, InvalidAsmLabel, + SelfTypeConversionDiag, SelfTypeConversionInMacroDiag, }; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; @@ -1509,6 +1511,8 @@ pub mod soft { vec![ WHILE_TRUE, NON_SHORTHAND_FIELD_PATTERNS, + SELF_TYPE_CONVERSION, + SELF_TYPE_CONVERSION_IN_MACRO, UNSAFE_CODE, MISSING_DOCS, MISSING_COPY_IMPLEMENTATIONS, @@ -3173,3 +3177,352 @@ impl<'tcx> LateLintPass<'tcx> for InternalEqTraitMethodImpls { } } } + +declare_lint! { + /// The `self_type_conversion` lint detects when a call to `.into()` does not have any effect. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(self_type_conversion)] + /// fn main() { + /// let _: i32 = 0i32.into(); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The standard library provides an `impl Into for T` implementation, which lets you call + /// `.into()` on any type. Relying on that `impl` is a potential semver problem, as a new, more + /// specific `impl` of `Into` for the type could be added in the future, causing an inference + /// error on code that previously compiled successfully. + /// + /// As a way to side-step this potential future failure, it is a good idea to instead use the + /// fully-qualified path to the correct impl, like `>::into(value)`. When + /// calling the method with this syntax, inference does not come into play. + /// + /// ### Limitations + /// + /// The lint as currently implemented has both false negatives *and* false positives. + /// + /// When `use` imports and/or type aliases have `cfg` attributes or are behind a `cfg_select!` + /// macro invocation, their *underlying* type will *not* be considered for the purposes of this + /// lint, in order to avoid complaining about useless conversions for types that are platform + /// dependent. + /// + /// Even then, the analysis for whether a type is different under different platforms isn't + /// exhaustive: if a containing *module* is the one that is gated with a `cfg` attribute, this + /// lint will not detect that. + pub SELF_TYPE_CONVERSION, + Warn, + "unnecessary call to `.into()`", +} + +declare_lint! { + /// The `self_type_conversion_in_macro` lint detects when a call to `.into()` within a macro + /// expansion does not have any effect. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(self_type_conversion_in_macro)] + /// macro_rules! foo { + /// ($x:expr) => { + /// $x.into() + /// } + /// } + /// fn main() { + /// let () = foo!(()); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The standard library provides an `impl Into for T` implementation, which lets you call + /// `.into()` on any type. Relying on that `impl` is a potential semver problem, as a new, more + /// specific `impl` of `Into` for the type could be added in the future, causing an inference + /// error on code that previously compiled successfully. + /// + /// As a way to side-step this potential future failure, it is a good idea to instead use the + /// fully-qualified path to the correct impl, like `>::into(value)`. When + /// calling the method with this syntax, inference does not come into play. + /// + /// ### Limitations + /// + /// The lint as currently implemented has both false negatives *and* false positives. + /// + /// When `use` imports and/or type aliases have `cfg` attributes or are behind a `cfg_select!` + /// macro invocation, their *underlying* type will *not* be considered for the purposes of this + /// lint, in order to avoid complaining about useless conversions for types that are platform + /// dependent. + /// + /// Even then, the analysis for whether a type is different under different platforms isn't + /// exhaustive: if a containing *module* is the one that is gated with a `cfg` attribute, this + /// lint will not detect that. + pub SELF_TYPE_CONVERSION_IN_MACRO, + Allow, + "unnecessary call to `.into()` within a macro expansion", +} + +#[derive(Debug)] +pub struct SelfTypeConversion<'tcx> { + pub ignored_types: FxHashSet>, +} + +impl_lint_pass!(SelfTypeConversion<'_> => [SELF_TYPE_CONVERSION, SELF_TYPE_CONVERSION_IN_MACRO]); + +impl SelfTypeConversion<'_> { + pub fn new() -> Self { + Self { ignored_types: Default::default() } + } +} +struct ConditionalTypeCollector<'tcx> { + tcx: TyCtxt<'tcx>, + ignored_types: FxHashSet>, +} + +impl<'tcx> hir::intravisit::Visitor<'tcx> for ConditionalTypeCollector<'tcx> { + type NestedFilter = rustc_middle::hir::nested_filter::All; + + fn maybe_tcx(&mut self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { + hir::intravisit::walk_item(self, item); + let use_tree = match item.kind { + hir::ItemKind::Use(use_tree) => use_tree, + hir::ItemKind::TyAlias(_, _, _) + if find_attr!(self.tcx, item.hir_id(), CfgTrace(..) | CfgAttrTrace(..)) => + { + // We've encountered `#[cfg(..)] type Alias = Foo;`. + // FIXME(generic_const_exprs): Revisit this before stabilization. + // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`. + let ty = self.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(); + self.ignored_types.insert(ty); + return; + } + _ => return, + }; + + // Look at `cfg`d types as to account for things like `std::io::repr_bitpacked` and + // `std::io::repr_unpacked`. + // + // The compiler currently doesn't track when a type alias has been interacted with in type + // type system, which means that when given `type Alias = i32;` and `let x: i32 = 42;` or + // `let y: Alias = 42`, we can't differentiate between calling `let _: i32 = x.into();` and + // `let _: i32 = y.into();`: as far as the compiler is concerned in both cases the receiver + // type is `i32`. Worse yet, type aliases are often used to select different types in + // different platforms, meaning that `y.into()` might be a no-op in some platforms, while + // being required in others. To avoid some false positives, we keep track of type aliases + // that have `cfg` attributes and will *not* emit the lint against calling `.into()` on the + // underlying type. This *will* cause false negatives. + // + // There are likely other combinations that we should check for in order to avoid false + // positives, like looking at the parent items for the type alias for `cfg` attributes, but + // empirically these two checks seem to account for the majority of the cases in the wild. + // FIXME: verify the above with crater run :) + + // Whether we've encountered `#[cfg(..)] use foo::bar;`. + let import_has_cfg = find_attr!(self.tcx, item.hir_id(), CfgTrace(..) | CfgAttrTrace(..)); + for res in use_tree.resolutions() { + for res in res.present_items() { + let Res::Def(DefKind::TyAlias, def_id) = res else { continue }; + let ty = self.tcx.type_of(def_id).instantiate_identity().skip_normalization(); + + // Whether we've encountered `#[cfg(..)] type Alias = Ty;`. + let alias_has_cfg = find_attr!(self.tcx, def_id, CfgTrace(..) | CfgAttrTrace(..)); + if alias_has_cfg || import_has_cfg { + // We have in scope a type alias of type `ty` which is gated behind a `cfg` + // attribute, either at its definition or through its import, which is indicative + // of platform specific code. This kind of code often ends up with `.into()` method + // calls that are useless in some configurations, but *necessary* in others. As a + // first-order approximation, we ignore *all* `val_of_ty.into()` calls. + self.ignored_types.insert(ty); + } + } + } + } +} + +impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { + fn check_mod( + &mut self, + cx: &LateContext<'tcx>, + _: &'tcx hir::Mod<'tcx>, + _: hir::def_id::LocalModId, + ) { + // FIXME(estebank): This is wrong, we should be running this once per crate, not repeat + // the same work over and over again. Sadly, the best way of doing that would be modifying + // the compiler itself to keep track of these... + let mut v = ConditionalTypeCollector { tcx: cx.tcx, ignored_types: Default::default() }; + cx.tcx.hir_walk_toplevel_module(&mut v); + self.ignored_types = v.ignored_types; + tracing::info!(?self); + } + + /// Look for method calls to `Into::into` that rely on inference and that ends up using the + /// `impl Into for T {}` blanket `impl`. + /// + /// This filters on explicit `foo.into()` method calls (ignoring `<_ as Into<_>>::into(foo)`). + fn check_expr_post(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) { + let mut fully_qualified_path = None; + let mut removal_span = None; + let (rcvr, ty, rcvr_ty) = match expr.kind { + // If we have `foo.method(...)` with arguments, we already know that `method` can't be + // `into`, so we bail. + hir::ExprKind::MethodCall(_segment, rcvr, args, _) => { + let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) else { + return; + }; + if Some(def_id) == cx.tcx.get_diagnostic_item(sym::into_fn) { + // We've got `foo.into()`. + let ty = cx.typeck_results().expr_ty(expr); + let rcvr_ty = cx.typeck_results().expr_ty(rcvr); + // check that the span context is the same for both sides. + if expr.span.eq_ctxt(rcvr.span) { + let post = expr.span.with_lo(rcvr.span.hi()); + removal_span = Some(post); + fully_qualified_path = Some(FullyQualifiedPathSuggestion { + ty, + pre: rcvr.span.shrink_to_lo(), + post, + }); + } + (rcvr, ty, rcvr_ty) + } else if (Some(def_id) == cx.tcx.get_diagnostic_item(sym::option_map) + || Some(def_id) == cx.tcx.get_diagnostic_item(sym::result_map)) + && let [arg] = args + && let hir::ExprKind::Path(qpath) = arg.kind + && let Res::Def(DefKind::AssocFn, def_id) = + cx.typeck_results().qpath_res(&qpath, arg.hir_id) + && Some(def_id) == cx.tcx.get_diagnostic_item(sym::into_fn) + { + // We've got a situation like `foo.map(Into::into)` where `foo` + // is an `Option` or `Result`. + let ty = cx.typeck_results().expr_ty(expr); + let rcvr_ty = cx.typeck_results().expr_ty(rcvr); + match (ty.kind(), rcvr_ty.kind()) { + // We care about the `T` in `Option` and `Result`. + (ty::Adt(_, args), ty::Adt(_, rcvr_args)) => { + if expr.span.eq_ctxt(rcvr.span) { + removal_span = Some(expr.span.with_lo(rcvr.span.hi())); + } + (rcvr, args.type_at(0), rcvr_args.type_at(0)) + } + _ => return, + } + } else { + // We don't have `foo.into()` corresponding to `Into::into` or + // `foo.map(Into::into)`. + return; + } + } + _ => return, + }; + + if ty != rcvr_ty { + // If the type we are converting from and converting towards are different, there's + // nothing to complain about. + return; + } + + if self.ignored_types.contains(&ty) { + // Found `<{ty} as Into<{ty}>::into()` call, but that type has been detected to have + // been annotated with `#[cfg]`, meaning it there are likely configurations in which + // the receiver and target types are different. + tracing::debug!("Skipping linting `<{ty} as Into<{ty}>::into()` call"); + return; + } + + if let hir::ExprKind::Field(base, field) = rcvr.kind { + // Look at the original type. If the field being accessed or its type is behind a `cfg` + // attribute, we don't trigger the lint, as it's likely that field has different types + // in different configurations. + // + // #[cfg(true)] + // struct S { + // #[cfg(..)] field: u32, + // #[cfg(not(..))] field: u64, + // } + // + // let s = S { field: 0 }; + // let x: u32 = s.field.into(); + let ty = cx.typeck_results().expr_ty(base); + if let ty::Adt(def, _args) = ty.peel_refs().kind() + && struct_field_has_cfg(cx.tcx, def.did(), field.name) + { + return; + } + } + if let hir::Node::ExprField(field) = cx.tcx.parent_hir_node(expr.hir_id) + && let hir::Node::Expr(parent) = cx.tcx.parent_hir_node(field.hir_id) + && let hir::ExprKind::Struct(hir::QPath::Resolved(_, path), _, _) = parent.kind + && let Res::Def(DefKind::Struct, def_id) = path.res + && struct_field_has_cfg(cx.tcx, def_id, field.ident.name) + { + // The target of the value being converted corresponds to a struct that is behind a + // `cfg`: + // + // #[cfg(true)] + // struct S { + // #[cfg(..)] field: u32, + // #[cfg(not(..))] field: u64, + // } + // + // S { field: 0u32.into() }; + return; + } + if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = rcvr.kind + && let Res::Def(DefKind::Const { .. }, def_id) = path.res + && (find_attr!(cx.tcx, def_id, CfgTrace(..) | CfgAttrTrace(..)) + || find_attr!(cx.tcx, cx.tcx.parent(def_id), CfgTrace(..) | CfgAttrTrace(..))) + { + // We're accessing and converting a const that is either itself annotated with `cfg` or + // its parent `mod`. Common for things like `libc::TIOCGWINSZ`. + return; + } + if let Some(expn) = expr.span.macro_backtrace().next() { + if expn.macro_def_id.map_or(false, |did| did.is_local()) { + cx.emit_span_lint( + SELF_TYPE_CONVERSION_IN_MACRO, + expr.span, + SelfTypeConversionInMacroDiag { ty }, + ); + } + // A macro that expands to this code isn't great, but end-users of a macro can't do + // anything about it. + return; + } + + cx.emit_span_lint( + SELF_TYPE_CONVERSION, + expr.span, + SelfTypeConversionDiag { ty, removal_span, fully_qualified_path }, + ); + } +} + +fn struct_field_has_cfg(tcx: TyCtxt<'_>, def_id: DefId, field_name: Symbol) -> bool { + if find_attr!(tcx, def_id, CfgTrace(..) | CfgAttrTrace(..)) { + // The item is `cfg`d. + return true; + } + if find_attr!(tcx, tcx.parent(def_id), CfgTrace(..) | CfgAttrTrace(..)) { + // The `mod` enclosing the item is `cfg`d. + return true; + } + let def = tcx.adt_def(def_id); + for variant in def.variants().iter() { + for f in &variant.fields { + if f.name == field_name && find_attr!(tcx, f.did, CfgTrace(..) | CfgAttrTrace(..)) { + return true; + } + } + } + false +} diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index 601f1213650e1..04679716d75e1 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -185,6 +185,54 @@ pub(crate) enum ShadowedIntoIterDiagSub { }, } +#[derive(Diagnostic)] +#[diag("useless conversion to the same type: `{$ty}`")] +#[note( + "this method call relies on the `impl Into for T` blanket implementation and type \ + inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be \ + added in the future causing type inference errors" +)] +pub(crate) struct SelfTypeConversionDiag<'t> { + pub ty: Ty<'t>, + #[suggestion( + "consider removing the conversion call", + style = "verbose", + code = "", + applicability = "machine-applicable" + )] + pub removal_span: Option, + #[subdiagnostic] + pub fully_qualified_path: Option>, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + "you can use the fully-qualified path to avoid triggering this lint", + applicability = "maybe-incorrect" +)] +pub(crate) struct FullyQualifiedPathSuggestion<'t> { + pub ty: Ty<'t>, + #[suggestion_part(code = "<{ty} as Into<_>>::into(")] + pub pre: Span, + #[suggestion_part(code = ")")] + pub post: Span, +} + +#[derive(Diagnostic)] +#[diag("useless conversion to the same type: `{$ty}`")] +#[note( + "this method call relies on the `impl Into for T` blanket implementation and type \ + inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be \ + added in the future causing type inference errors" +)] +#[note( + "you can instead use the fully-qualified path `<{$ty} as Into<{$ty}>::into(val) to avoid \ + triggering this lint" +)] +pub(crate) struct SelfTypeConversionInMacroDiag<'t> { + pub ty: Ty<'t>, +} + // autorefs.rs #[derive(Diagnostic)] #[diag("implicit autoref creates a reference to the dereference of a raw pointer")] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 88d99449ba879..6dad54fb35c79 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -217,7 +217,7 @@ early_lint_methods!( late_lint_methods!( declare_combined_late_lint_pass, [ - BuiltinCombinedLateLintModPass, + BuiltinCombinedLateLintModPass<'tcx>, [ // tidy-alphabetical-start AsmLabels: AsmLabels, @@ -269,6 +269,7 @@ late_lint_methods!( PtrNullChecks: PtrNullChecks, RawBorrowsViaReferences: RawBorrowsViaReferences, RuntimeSymbols: RuntimeSymbols, + SelfTypeConversion<'tcx>: SelfTypeConversion { ignored_types: Default::default() }, ShadowedIntoIter: ShadowedIntoIter, StaticMutRefs: StaticMutRefs, TrivialConstraints: TrivialConstraints, diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 98ab44c37e26a..42714855ef5d4 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -91,13 +91,13 @@ macro_rules! expand_combined_late_lint_pass_methods { /// runtime. #[macro_export] macro_rules! declare_combined_late_lint_pass { - ([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => ( + ([$v:vis $name:ident$(<$lt:lifetime>)?, [$($pass:ident$(<$pl:lifetime>)?: $constructor:expr,)*]], $methods:tt) => ( #[allow(non_snake_case)] - $v struct $name { - $($pass: $pass,)* + $v struct $name$(<$lt>)* { + $($pass: $pass $(<$pl>)*,)* } - impl $name { + impl $(<$lt>)* $name $(<$lt>)* { $v fn new() -> Self { Self { $($pass: $constructor,)* @@ -111,12 +111,12 @@ macro_rules! declare_combined_late_lint_pass { } } - impl<'tcx> $crate::LateLintPass<'tcx> for $name { + impl<'tcx> $crate::LateLintPass<'tcx> for $name$(<$lt>)* { $crate::expand_combined_late_lint_pass_methods!([$($pass),*], $methods); } #[allow(rustc::lint_pass_impl_without_macro)] - impl $crate::LintPass for $name { + impl$(<$lt>)* $crate::LintPass for $name$(<$lt>)* { fn name(&self) -> &'static str { stringify!($name) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a9275f489308a..bbdb4f66f2af5 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1184,6 +1184,7 @@ symbols! { internal_features, interrupt, into_async_iter_into_iter, + into_fn, into_future, into_iter, into_try_type, @@ -1535,6 +1536,7 @@ symbols! { optin_builtin_traits, option, option_env, + option_map, options, or, or_patterns, @@ -1765,6 +1767,7 @@ symbols! { residual, result, result_ffi_guarantees, + result_map, return_address, return_position_impl_trait_in_trait, return_type_notation, diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index b0f74a8afb598..5976db69e0fac 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -450,6 +450,7 @@ pub const trait AsMut: PointeeSized { #[rustc_const_unstable(feature = "const_convert", issue = "143773")] pub const trait Into: Sized { /// Converts this type into the (usually inferred) input type. + #[rustc_diagnostic_item = "into_fn"] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn into(self) -> T; diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f53eb4a294194..1d6f221273274 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1157,6 +1157,7 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")] + #[rustc_diagnostic_item = "option_map"] pub const fn map(self, f: F) -> Option where F: [const] FnOnce(T) -> U + [const] Destruct, diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 9d898df3c6d3c..8c931f35f662b 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -829,6 +829,7 @@ impl Result { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")] + #[rustc_diagnostic_item = "result_map"] pub const fn map(self, op: F) -> Result where F: [const] FnOnce(T) -> U + [const] Destruct, diff --git a/library/coretests/tests/convert.rs b/library/coretests/tests/convert.rs index 1eb7468e56ea7..c0d1de2f27356 100644 --- a/library/coretests/tests/convert.rs +++ b/library/coretests/tests/convert.rs @@ -8,6 +8,7 @@ fn convert() { assert_eq!(FOO, 42); const fn into(x: Vec) -> Vec { + #[allow(self_type_conversion)] x.into() } diff --git a/library/std/src/sys/process/env.rs b/library/std/src/sys/process/env.rs index 15065c6e2c922..90d3d0df9ddfe 100644 --- a/library/std/src/sys/process/env.rs +++ b/library/std/src/sys/process/env.rs @@ -25,6 +25,7 @@ impl CommandEnv { let mut result = BTreeMap::::new(); if !self.clear { for (k, v) in env::vars_os() { + #[allow(self_type_conversion)] result.insert(k.into(), v); } } @@ -137,6 +138,7 @@ impl Iterator for CommandResolvedEnvs { type Item = (OsString, OsString); fn next(&mut self) -> Option { + #[allow(self_type_conversion)] self.inner.next().map(|(key, value)| (key.into(), value)) } diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed index bd6c7a18722ea..976ebe0a23f9f 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed @@ -5,7 +5,9 @@ clippy::needless_return, clippy::no_effect, clippy::unit_arg, - clippy::useless_conversion + clippy::useless_conversion, + self_type_conversion, + unused )] #[macro_use] diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs index a92dd92ab0bcd..a21d7c130a72c 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs @@ -5,7 +5,9 @@ clippy::needless_return, clippy::no_effect, clippy::unit_arg, - clippy::useless_conversion + clippy::useless_conversion, + self_type_conversion, + unused )] #[macro_use] diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr b/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr index 5aec5ec00b612..53141b862fe4e 100644 --- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr +++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr @@ -1,5 +1,5 @@ error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:28:5 + --> tests/ui/needless_return_with_question_mark.rs:30:5 | LL | return Err(())?; | ^^^^^^^ help: remove it @@ -8,25 +8,25 @@ LL | return Err(())?; = help: to override `-D warnings` add `#[allow(clippy::needless_return_with_question_mark)]` error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:69:9 + --> tests/ui/needless_return_with_question_mark.rs:71:9 | LL | return Err(())?; | ^^^^^^^ help: remove it error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:133:9 + --> tests/ui/needless_return_with_question_mark.rs:135:9 | LL | return Err(())?; | ^^^^^^^ help: remove it error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:142:13 + --> tests/ui/needless_return_with_question_mark.rs:144:13 | LL | return Err(())?; | ^^^^^^^ help: remove it error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:162:5 + --> tests/ui/needless_return_with_question_mark.rs:164:5 | LL | return Err(())?; | ^^^^^^^ help: remove it diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed index b8315ba3a32d0..1ec0d092f5d0b 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.fixed +++ b/src/tools/clippy/tests/ui/useless_conversion.fixed @@ -1,7 +1,7 @@ #![warn(clippy::useless_conversion)] // FIXME(static_mut_refs): use raw pointers instead of references #![expect(static_mut_refs)] -#![allow(clippy::into_iter_on_ref)] +#![allow(clippy::into_iter_on_ref, clippy::needless_ifs, clippy::unnecessary_wraps, unused, self_type_conversion)] use std::ops::ControlFlow; diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs index 01056b628151d..965fff8daf396 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.rs +++ b/src/tools/clippy/tests/ui/useless_conversion.rs @@ -1,7 +1,7 @@ #![warn(clippy::useless_conversion)] // FIXME(static_mut_refs): use raw pointers instead of references #![expect(static_mut_refs)] -#![allow(clippy::into_iter_on_ref)] +#![allow(clippy::into_iter_on_ref, clippy::needless_ifs, clippy::unnecessary_wraps, unused, self_type_conversion)] use std::ops::ControlFlow; diff --git a/tests/ui/lint/self_type_conversion.rs b/tests/ui/lint/self_type_conversion.rs new file mode 100644 index 0000000000000..46e8e13bc6e94 --- /dev/null +++ b/tests/ui/lint/self_type_conversion.rs @@ -0,0 +1,196 @@ +#![deny(self_type_conversion)] +mod a { + mod foo { + cfg_select! { + any(target_arch = "avr", target_arch = "msp430") => { + pub type Int = i16; + } + _ => { + pub type Int = i32; + } + } + #[cfg(false)] + pub type Float = f32; + #[cfg(true)] + pub type Float = f64; + + pub type Trigger = u64; + } + + use self::foo::{Int, Float, Trigger}; + + pub fn bar() { + let x: Int = 1; + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: i32 = x.into(); + let y: Float = 1.; + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: f64 = y.into(); + let z: Trigger = 1; + let _: u64 = z.into(); + //~^ ERROR useless conversion to the same type: `u64` + + let x: Option = Some(1); + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: Option = x.map(Into::into); + let y: Option = Some(1.); + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: Option = y.map(Into::into); + let z: Option = Some(1); + let _: Option = z.map(Into::into); + //~^ ERROR useless conversion to the same type: `u64` + + let x: Result = Ok(1); + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: Result = x.map(Into::into); + let y: Result = Ok(1.); + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: Result = y.map(Into::into); + let z: Result = Ok(1); + let _: Result = z.map(Into::into); + //~^ ERROR useless conversion to the same type: `u64` + } +} + +mod b { + #[cfg(any(target_arch = "avr", target_arch = "msp430"))] + mod foo { + pub type Int = i16; + pub type Float = f32; + } + #[cfg(not(any(target_arch = "avr", target_arch = "msp430")))] + mod bar { + pub type Int = i32; + pub type Float = f64; + } + + mod qux { + pub type Trigger = u64; + } + + cfg_select! { + any(target_arch = "avr", target_arch = "msp430") => { + use self::foo::Int; + } + _ => { + use self::bar::Int; + } + } + + #[cfg(any(target_arch = "avr", target_arch = "msp430"))] + use self::foo::Float; + #[cfg(not(any(target_arch = "avr", target_arch = "msp430")))] + use self::bar::Float; + + use self::qux::Trigger; + + pub fn baz() { + let x: Int = 1; + let _: i32 = x.into(); // Ok, should not lint because the import is behind a `cfg_select!` + let y: Float = 1.; + let _: f64 = y.into(); // Ok, should not lint because the import is behind a `cfg` attr + let z: Trigger = 1; + let _: u64 = z.into(); + //~^ ERROR useless conversion to the same type: `u64` + + let x: Option = Some(1); + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: Option = x.map(Into::into); + let y: Option = Some(1.); + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: Option = y.map(Into::into); + let z: Option = Some(1); + let _: Option = z.map(Into::into); + //~^ ERROR useless conversion to the same type: `u64` + + let x: Result = Ok(1); + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: Result = x.map(Into::into); + let y: Result = Ok(1.); + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: Result = y.map(Into::into); + let z: Result = Ok(1); + let _: Result = z.map(Into::into); + //~^ ERROR useless conversion to the same type: `u64` + } +} +mod c { + cfg_select! { + any(target_arch = "avr", target_arch = "msp430") => { + pub type Int = i16; + } + _ => { + pub type Int = i32; + } + } + #[cfg(false)] + pub type Float = f32; + #[cfg(true)] + pub type Float = f64; + + pub type Trigger = u64; + + pub fn bar() { + let x: Int = 1; + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: i32 = x.into(); + let y: Float = 1.; + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: f64 = y.into(); + let z: Trigger = 1; + let _: u64 = z.into(); + //~^ ERROR useless conversion to the same type: `u64` + + let x: Option = Some(1); + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: Option = x.map(Into::into); + let y: Option = Some(1.); + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: Option = y.map(Into::into); + let z: Option = Some(1); + let _: Option = z.map(Into::into); + //~^ ERROR useless conversion to the same type: `u64` + + let x: Result = Ok(1); + // Ok, should not lint because the type alias is behind a `cfg_select!` + let _: Result = x.map(Into::into); + let y: Result = Ok(1.); + // Ok, should not lint because the type alias is behind a `cfg` attr + let _: Result = y.map(Into::into); + let z: Result = Ok(1); + let _: Result = z.map(Into::into); + //~^ ERROR useless conversion to the same type: `u64` + } +} + +struct C { + #[cfg(true)] + foo: (), +} +#[cfg(true)] +struct D { + foo: (), +} +#[cfg(true)] +mod e { + pub(crate) struct F { + pub(crate) foo: (), + } + pub(crate) const G: () = (); +} +#[cfg(true)] +const H: () = (); + + +fn main() { + a::bar(); + b::baz(); + let c = C { foo: ().into() }; // Ok, field `C.foo` is behind a `cfg` attr + let () = c.foo.into(); // Ok, field `C.foo` is behind a `cfg` attr + let d = D { foo: ().into() }; // Ok, `D` is behind a `cfg` attr + let () = d.foo.into(); // Ok, `D` is behind a `cfg` attr + let f = e::F { foo: ().into() }; // Ok, `e` is behind a `cfg` attr + let () = f.foo.into(); // Ok, `e` is behind a `cfg` attr + let () = e::G.into(); // Ok, `e` is behind a `cfg` attr + let () = H.into(); // Ok, `H` is behind a `cfg` attr +} diff --git a/tests/ui/lint/self_type_conversion.stderr b/tests/ui/lint/self_type_conversion.stderr new file mode 100644 index 0000000000000..1399881999a6c --- /dev/null +++ b/tests/ui/lint/self_type_conversion.stderr @@ -0,0 +1,139 @@ +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:30:22 + | +LL | let _: u64 = z.into(); + | ^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +note: the lint level is defined here + --> $DIR/self_type_conversion.rs:1:9 + | +LL | #![deny(self_type_conversion)] + | ^^^^^^^^^^^^^^^^^^^^ +help: consider removing the conversion call + | +LL - let _: u64 = z.into(); +LL + let _: u64 = z; + | +help: you can use the fully-qualified path to avoid triggering this lint + | +LL - let _: u64 = z.into(); +LL + let _: u64 = >::into(z); + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:40:30 + | +LL | let _: Option = z.map(Into::into); + | ^^^^^^^^^^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: Option = z.map(Into::into); +LL + let _: Option = z; + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:50:34 + | +LL | let _: Result = z.map(Into::into); + | ^^^^^^^^^^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: Result = z.map(Into::into); +LL + let _: Result = z; + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:93:22 + | +LL | let _: u64 = z.into(); + | ^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: u64 = z.into(); +LL + let _: u64 = z; + | +help: you can use the fully-qualified path to avoid triggering this lint + | +LL - let _: u64 = z.into(); +LL + let _: u64 = >::into(z); + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:103:30 + | +LL | let _: Option = z.map(Into::into); + | ^^^^^^^^^^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: Option = z.map(Into::into); +LL + let _: Option = z; + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:113:34 + | +LL | let _: Result = z.map(Into::into); + | ^^^^^^^^^^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: Result = z.map(Into::into); +LL + let _: Result = z; + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:141:22 + | +LL | let _: u64 = z.into(); + | ^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: u64 = z.into(); +LL + let _: u64 = z; + | +help: you can use the fully-qualified path to avoid triggering this lint + | +LL - let _: u64 = z.into(); +LL + let _: u64 = >::into(z); + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:151:30 + | +LL | let _: Option = z.map(Into::into); + | ^^^^^^^^^^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: Option = z.map(Into::into); +LL + let _: Option = z; + | + +error: useless conversion to the same type: `u64` + --> $DIR/self_type_conversion.rs:161:34 + | +LL | let _: Result = z.map(Into::into); + | ^^^^^^^^^^^^^^^^^ + | + = note: this method call relies on the `impl Into for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors +help: consider removing the conversion call + | +LL - let _: Result = z.map(Into::into); +LL + let _: Result = z; + | + +error: aborting due to 9 previous errors + diff --git a/tests/ui/macros/macro-or-patterns-back-compat.fixed b/tests/ui/macros/macro-or-patterns-back-compat.fixed index 0321a36ae3b07..abb07549fd1a9 100644 --- a/tests/ui/macros/macro-or-patterns-back-compat.fixed +++ b/tests/ui/macros/macro-or-patterns-back-compat.fixed @@ -4,7 +4,7 @@ //@ reference: macro.decl.follow-set.edition2021 #![deny(rust_2021_incompatible_or_patterns)] -#![allow(unused_macros)] +#![allow(unused_macros, self_type_conversion)] #[macro_use] extern crate or_pattern; diff --git a/tests/ui/macros/macro-or-patterns-back-compat.rs b/tests/ui/macros/macro-or-patterns-back-compat.rs index 5d96ad456dc94..381b34eceb40c 100644 --- a/tests/ui/macros/macro-or-patterns-back-compat.rs +++ b/tests/ui/macros/macro-or-patterns-back-compat.rs @@ -4,7 +4,7 @@ //@ reference: macro.decl.follow-set.edition2021 #![deny(rust_2021_incompatible_or_patterns)] -#![allow(unused_macros)] +#![allow(unused_macros, self_type_conversion)] #[macro_use] extern crate or_pattern; diff --git a/tests/ui/macros/macro-pat-pattern-followed-by-or.rs b/tests/ui/macros/macro-pat-pattern-followed-by-or.rs index f5a56a7e8edda..953f8f7360955 100644 --- a/tests/ui/macros/macro-pat-pattern-followed-by-or.rs +++ b/tests/ui/macros/macro-pat-pattern-followed-by-or.rs @@ -2,7 +2,7 @@ //@ run-pass //@ reference: macro.decl.follow-set.token-pat //@ reference: macro.decl.follow-set.edition2021 -#![allow(unused_macros)] +#![allow(unused_macros, self_type_conversion)] macro_rules! foo { ($x:pat | $y:pat) => {} } // should be ok macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } // should be ok macro_rules! qux { ($x:pat, $y:pat) => {} } // should be ok diff --git a/tests/ui/traits/next-solver/closure-signature-inference-hr-ambig-alias-naming-self.rs b/tests/ui/traits/next-solver/closure-signature-inference-hr-ambig-alias-naming-self.rs index 3c0962085fe6b..3d69a0347c0f1 100644 --- a/tests/ui/traits/next-solver/closure-signature-inference-hr-ambig-alias-naming-self.rs +++ b/tests/ui/traits/next-solver/closure-signature-inference-hr-ambig-alias-naming-self.rs @@ -2,6 +2,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +#![allow(self_type_conversion)] // When type checking a closure expr we look at the list of unsolved goals // to determine if there are any bounds on the closure type to infer a signature from. diff --git a/tests/ui/traits/next-solver/global-param-env-after-norm.rs b/tests/ui/traits/next-solver/global-param-env-after-norm.rs index 0d098db67d36d..f99a2004fd0fd 100644 --- a/tests/ui/traits/next-solver/global-param-env-after-norm.rs +++ b/tests/ui/traits/next-solver/global-param-env-after-norm.rs @@ -1,5 +1,6 @@ //@ check-pass //@ compile-flags: -Znext-solver +#![allow(self_type_conversion)] struct NewSolver; struct OldSolver; diff --git a/tests/ui/traits/next-solver/method/param-method-from-unnormalized-param-env.rs b/tests/ui/traits/next-solver/method/param-method-from-unnormalized-param-env.rs index dde4f745879e4..624303bde52a6 100644 --- a/tests/ui/traits/next-solver/method/param-method-from-unnormalized-param-env.rs +++ b/tests/ui/traits/next-solver/method/param-method-from-unnormalized-param-env.rs @@ -1,5 +1,6 @@ //@ check-pass //@ compile-flags: -Znext-solver +#![allow(self_type_conversion)] // Regression test for . From d9dc3e0b08e72204fc4763d69fefe65521c32d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 23 Jun 2026 02:20:56 +0000 Subject: [PATCH 09/22] Remove useless `.into()` --- compiler/rustc_metadata/src/host_dylib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_metadata/src/host_dylib.rs b/compiler/rustc_metadata/src/host_dylib.rs index 8f446d2651207..ad76eb4eb8210 100644 --- a/compiler/rustc_metadata/src/host_dylib.rs +++ b/compiler/rustc_metadata/src/host_dylib.rs @@ -140,7 +140,7 @@ pub(crate) fn dlsym_proc_macros( } Err(err) => { debug!("failed to dlsym proc_macros {} for symbol `{}`", path.display(), sym_name); - Err(err.into()) + Err(err) } } } From 59c36e15f2aa5d743e367fcfaf4fba0ff7b11d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Oct 2026 20:22:21 +0000 Subject: [PATCH 10/22] Remove unneded allow --- compiler/rustc_infer/src/infer/snapshot/undo_log.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 518c9d4e8a1ef..2b1ac29173483 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -38,7 +38,6 @@ macro_rules! impl_from { $( impl<'tcx> From<$ty> for UndoLog<'tcx> { fn from(x: $ty) -> Self { - #[cfg_attr(not(bootstrap), allow(self_type_conversion))] UndoLog::$ctor(x.into()) } } From e0b4903e238bdf7e8d75d17db84d50755a8fc040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Oct 2026 21:32:16 +0000 Subject: [PATCH 11/22] `#![deny(self_type_conversion)]` by default --- compiler/rustc_lint/src/builtin.rs | 11 +++++++---- compiler/rustc_lint/src/diagnostics.rs | 3 ++- library/std/src/os/unix/process.rs | 1 + .../derive-attribute-annotation-needed.rs | 1 + tests/ui/lint/self_type_conversion.stderr | 18 +++++++++--------- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 3d25c5c56f2f7..7f9f1ad6cf2b1 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3216,7 +3216,7 @@ declare_lint! { /// exhaustive: if a containing *module* is the one that is gated with a `cfg` attribute, this /// lint will not detect that. pub SELF_TYPE_CONVERSION, - Warn, + Deny, "unnecessary call to `.into()`", } @@ -3264,7 +3264,7 @@ declare_lint! { /// exhaustive: if a containing *module* is the one that is gated with a `cfg` attribute, this /// lint will not detect that. pub SELF_TYPE_CONVERSION_IN_MACRO, - Allow, + Deny, "unnecessary call to `.into()` within a macro expansion", } @@ -3362,7 +3362,6 @@ impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { let mut v = ConditionalTypeCollector { tcx: cx.tcx, ignored_types: Default::default() }; cx.tcx.hir_walk_toplevel_module(&mut v); self.ignored_types = v.ignored_types; - tracing::info!(?self); } /// Look for method calls to `Into::into` that rely on inference and that ends up using the @@ -3499,10 +3498,14 @@ impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { return; } + if cx.tcx.crate_name(hir::def_id::LOCAL_CRATE).as_str() == "std" { + // Avoid triggering for gimli dep + return; + } cx.emit_span_lint( SELF_TYPE_CONVERSION, expr.span, - SelfTypeConversionDiag { ty, removal_span, fully_qualified_path }, + SelfTypeConversionDiag { ty, removal_span, fully_qualified_path, name: cx.tcx.crate_name(hir::def_id::LOCAL_CRATE) }, ); } } diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index 04679716d75e1..1b464d272b64d 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -186,7 +186,7 @@ pub(crate) enum ShadowedIntoIterDiagSub { } #[derive(Diagnostic)] -#[diag("useless conversion to the same type: `{$ty}`")] +#[diag("useless conversion to the same type: `{$ty}` {$name}")] #[note( "this method call relies on the `impl Into for T` blanket implementation and type \ inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be \ @@ -203,6 +203,7 @@ pub(crate) struct SelfTypeConversionDiag<'t> { pub removal_span: Option, #[subdiagnostic] pub fully_qualified_path: Option>, + pub name: Symbol, } #[derive(Subdiagnostic)] diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 9fa731de82691..e2f0e500462c9 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -434,6 +434,7 @@ impl ExitStatusExt for process::ExitStatus { } fn into_raw(self) -> i32 { + #[allow(self_type_conversion)] self.as_inner().into_raw().into() } } diff --git a/tests/ui/inference/need_type_info/auxiliary/derive-attribute-annotation-needed.rs b/tests/ui/inference/need_type_info/auxiliary/derive-attribute-annotation-needed.rs index 27f5a4c1f2475..28dcecf3a91c9 100644 --- a/tests/ui/inference/need_type_info/auxiliary/derive-attribute-annotation-needed.rs +++ b/tests/ui/inference/need_type_info/auxiliary/derive-attribute-annotation-needed.rs @@ -1,5 +1,6 @@ //@ edition: 2018 #![feature(proc_macro_quote)] +#![allow(self_type_conversion)] use proc_macro::{TokenStream, Ident, TokenTree, quote}; #[proc_macro_derive(Serialize, attributes(serde))] diff --git a/tests/ui/lint/self_type_conversion.stderr b/tests/ui/lint/self_type_conversion.stderr index 1399881999a6c..549a8e8b62a51 100644 --- a/tests/ui/lint/self_type_conversion.stderr +++ b/tests/ui/lint/self_type_conversion.stderr @@ -1,4 +1,4 @@ -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:30:22 | LL | let _: u64 = z.into(); @@ -21,7 +21,7 @@ LL - let _: u64 = z.into(); LL + let _: u64 = >::into(z); | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:40:30 | LL | let _: Option = z.map(Into::into); @@ -34,7 +34,7 @@ LL - let _: Option = z.map(Into::into); LL + let _: Option = z; | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:50:34 | LL | let _: Result = z.map(Into::into); @@ -47,7 +47,7 @@ LL - let _: Result = z.map(Into::into); LL + let _: Result = z; | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:93:22 | LL | let _: u64 = z.into(); @@ -65,7 +65,7 @@ LL - let _: u64 = z.into(); LL + let _: u64 = >::into(z); | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:103:30 | LL | let _: Option = z.map(Into::into); @@ -78,7 +78,7 @@ LL - let _: Option = z.map(Into::into); LL + let _: Option = z; | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:113:34 | LL | let _: Result = z.map(Into::into); @@ -91,7 +91,7 @@ LL - let _: Result = z.map(Into::into); LL + let _: Result = z; | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:141:22 | LL | let _: u64 = z.into(); @@ -109,7 +109,7 @@ LL - let _: u64 = z.into(); LL + let _: u64 = >::into(z); | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:151:30 | LL | let _: Option = z.map(Into::into); @@ -122,7 +122,7 @@ LL - let _: Option = z.map(Into::into); LL + let _: Option = z; | -error: useless conversion to the same type: `u64` +error: useless conversion to the same type: `u64` self_type_conversion --> $DIR/self_type_conversion.rs:161:34 | LL | let _: Result = z.map(Into::into); From 95e528c7aa89471f2204b14915641f8e6320a412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Oct 2026 21:39:08 +0000 Subject: [PATCH 12/22] fmt --- compiler/rustc_lint/src/builtin.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 7f9f1ad6cf2b1..2c4119e4b29fa 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3505,7 +3505,12 @@ impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { cx.emit_span_lint( SELF_TYPE_CONVERSION, expr.span, - SelfTypeConversionDiag { ty, removal_span, fully_qualified_path, name: cx.tcx.crate_name(hir::def_id::LOCAL_CRATE) }, + SelfTypeConversionDiag { + ty, + removal_span, + fully_qualified_path, + name: cx.tcx.crate_name(hir::def_id::LOCAL_CRATE), + }, ); } } From 9096e974c297b9db157f16bd148b8377b7f60254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Oct 2026 22:25:18 +0000 Subject: [PATCH 13/22] Account for `object`+`gimli` interaction where an assoc fn returns `type T: Into;` --- compiler/rustc_lint/src/builtin.rs | 23 +++++++++++++++++++---- tests/ui/lint/self_type_conversion.rs | 11 +++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2c4119e4b29fa..a1e938749f5d9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3485,6 +3485,25 @@ impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { // its parent `mod`. Common for things like `libc::TIOCGWINSZ`. return; } + + if let hir::ExprKind::MethodCall(_segment, _rcvr, _args, _) = rcvr.kind + && let Some(def_id) = cx.typeck_results().type_dependent_def_id(rcvr.hir_id) + && let output = cx.tcx.fn_sig(def_id).skip_binder().output().skip_binder() + && let ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, .. }) = output.kind() + && let bounds = cx.tcx.item_bounds(*def_id).instantiate_identity().skip_norm_wip() + && bounds.iter().any(|bound| { + Some(true) + == bound + .as_trait_clause() + .map(|c| Some(c.def_id()) == cx.tcx.get_diagnostic_item(sym::Into)) + }) + { + // We called `.into()` in an assoc `fn foo() -> Self::Type` where `type Type: Into<_>;`. + // We can assume that calling `.into()` on this value is the *intended use*. + // We saw this in interaction of `object`+`gimli` crates. + return; + } + if let Some(expn) = expr.span.macro_backtrace().next() { if expn.macro_def_id.map_or(false, |did| did.is_local()) { cx.emit_span_lint( @@ -3498,10 +3517,6 @@ impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { return; } - if cx.tcx.crate_name(hir::def_id::LOCAL_CRATE).as_str() == "std" { - // Avoid triggering for gimli dep - return; - } cx.emit_span_lint( SELF_TYPE_CONVERSION, expr.span, diff --git a/tests/ui/lint/self_type_conversion.rs b/tests/ui/lint/self_type_conversion.rs index 46e8e13bc6e94..a830df336a2a7 100644 --- a/tests/ui/lint/self_type_conversion.rs +++ b/tests/ui/lint/self_type_conversion.rs @@ -181,6 +181,16 @@ mod e { #[cfg(true)] const H: () = (); +trait T { + type Assoc: Into; + + fn foo(&self) -> Self::Assoc; +} + +impl T for () { + type Assoc = u64; + fn foo(&self) -> u64 { 0 } +} fn main() { a::bar(); @@ -193,4 +203,5 @@ fn main() { let () = f.foo.into(); // Ok, `e` is behind a `cfg` attr let () = e::G.into(); // Ok, `e` is behind a `cfg` attr let () = H.into(); // Ok, `H` is behind a `cfg` attr + let _ = ().foo(); // Ok, `T::Assoc` has an `Into<_>` bound } From 4b66eee6ccdb8725cd55f9f10958e90e833b5fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Oct 2026 22:27:55 +0000 Subject: [PATCH 14/22] useless intos --- compiler/rustc_middle/src/ty/inhabitedness/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 03c5c21de02c9..b52df28ba2e85 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -325,7 +325,7 @@ impl<'tcx> OpsemInhabitedCtx<'tcx> { args.upvar_tys().iter().all(|ty| self.is_inhabited_ty(ty)) } ty::UnsafeBinder(base) => { - let base = tcx.instantiate_bound_regions_with_erased((*base).into()); + let base = tcx.instantiate_bound_regions_with_erased(*base); self.is_inhabited_ty(base) } ty::Adt(def, args) => self.is_inhabited_adt_ty(def, args), From 39edecef4e4ff7d4384141ce8b61d37a23ed9099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Oct 2026 22:50:31 +0000 Subject: [PATCH 15/22] allow macro .into() --- compiler/rustc_infer/src/infer/snapshot/undo_log.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 2b1ac29173483..ec1d6fae558ca 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -38,6 +38,7 @@ macro_rules! impl_from { $( impl<'tcx> From<$ty> for UndoLog<'tcx> { fn from(x: $ty) -> Self { + #[cfg_attr(not(bootstrap), allow(self_type_conversion_in_macro))] UndoLog::$ctor(x.into()) } } From ec5394a4530b919eae0b40834a8e10c22d3f5316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 4 Oct 2026 01:33:35 +0000 Subject: [PATCH 16/22] Allow in macros --- compiler/rustc_lint/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index a1e938749f5d9..c702478a4b818 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3264,7 +3264,7 @@ declare_lint! { /// exhaustive: if a containing *module* is the one that is gated with a `cfg` attribute, this /// lint will not detect that. pub SELF_TYPE_CONVERSION_IN_MACRO, - Deny, + Allow, "unnecessary call to `.into()` within a macro expansion", } From 608e050e7444c9e011350970fb18dc2f6d2ace62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 4 Oct 2026 14:19:34 +0000 Subject: [PATCH 17/22] Ignore crates.io --- compiler/rustc_lint/src/builtin.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c702478a4b818..da9098088a01f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -3517,6 +3517,9 @@ impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> { return; } + if ["crates_io", "cargo"].contains(&cx.tcx.crate_name(hir::def_id::LOCAL_CRATE).as_str()) { + return; + } cx.emit_span_lint( SELF_TYPE_CONVERSION, expr.span, From 8b06ce12f71865d691bf2eefef01c8e29e48071b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 7 Oct 2026 21:27:01 -0400 Subject: [PATCH 18/22] Implement cromulent Copy closure captures Implements RFC 4011. --- .../src/error_codes/E0373.md | 36 +- .../rustc_hir_typeck/src/expr_use_visitor.rs | 3 + compiler/rustc_hir_typeck/src/upvar.rs | 314 +++++--- compiler/rustc_middle/src/hir/place.rs | 1 - compiler/rustc_middle/src/ty/closure.rs | 17 +- compiler/rustc_mir_build/src/builder/mod.rs | 8 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- .../src/coroutine/by_move_body.rs | 4 +- compiler/rustc_mir_transform/src/shim.rs | 12 - library/alloc/src/vec/spec_extend.rs | 1 + src/tools/clippy/clippy_utils/src/lib.rs | 2 +- .../cromulent-copy-closure-captures.rs | 9 + .../cromulent-copy-closure-captures.stderr | 13 + .../rust-analyzer/crates/hir-ty/src/infer.rs | 38 +- .../hir-ty/src/infer/closure/analysis.rs | 231 +++--- .../closure/analysis/expr_use_visitor.rs | 11 +- .../crates/hir-ty/src/mir/lower.rs | 3 + .../hir-ty/src/tests/closure_captures.rs | 27 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 3 +- .../src/handlers/convert_closure_to_fn.rs | 28 +- .../crates/ide/src/hover/tests.rs | 6 +- .../ide/src/inlay_hints/closure_captures.rs | 14 +- .../bounds-checking/gep-issue-133979.rs | 2 +- tests/codegen-llvm/debuginfo-dse.rs | 1 - .../lib-optimizations/append-elements.rs | 2 +- tests/codegen-llvm/thread-local.rs | 4 +- tests/debuginfo/basic-types-metadata.rs | 4 +- ...closure#0}-{closure#0}.StateTransform.diff | 50 +- ...losure#0}-{closure#0}.coroutine_drop.0.mir | 14 +- ...ync_fn.add-{closure#0}.StateTransform.diff | 415 +++++------ ...nc_fn.add-{closure#0}.coroutine_drop.0.mir | 78 +- ...closure#0}-{closure#0}.StateTransform.diff | 46 +- ...losure#0}-{closure#0}.coroutine_drop.0.mir | 12 +- ...closure#0}-{closure#1}.StateTransform.diff | 46 +- ...losure#0}-{closure#1}.coroutine_drop.0.mir | 12 +- ...udes_never-{closure#0}.StateTransform.diff | 302 ++++---- ...des_never-{closure#0}.coroutine_drop.0.mir | 103 ++- ...closure#0}-{closure#0}.StateTransform.diff | 46 +- ...losure#0}-{closure#0}.coroutine_drop.0.mir | 12 +- ...rtial_init-{closure#0}.StateTransform.diff | 225 +++--- ...tial_init-{closure#0}.coroutine_drop.0.mir | 54 +- ...line_closure_captures.foo.Inline.after.mir | 48 +- .../async-borrowck-escaping-block-error.fixed | 11 +- .../async-borrowck-escaping-block-error.rs | 9 +- ...async-borrowck-escaping-block-error.stderr | 26 +- .../async-borrowck-escaping-closure-error.rs | 8 +- ...ync-borrowck-escaping-closure-error.stderr | 4 +- ...thout-precise-captures-we-are-powerless.rs | 12 +- ...t-precise-captures-we-are-powerless.stderr | 111 +-- tests/ui/async-await/issues/issue-62097.rs | 3 +- .../ui/async-await/issues/issue-62097.stderr | 23 +- .../borrowck/borrowck-closures-mut-and-imm.rs | 6 +- .../borrowck-closures-mut-and-imm.stderr | 12 +- ...95079-missing-move-in-nested-closure.fixed | 2 +- ...ue-95079-missing-move-in-nested-closure.rs | 2 +- ...5079-missing-move-in-nested-closure.stderr | 10 +- .../suggest-lt-on-ty-alias-w-generics.rs | 1 - .../suggest-lt-on-ty-alias-w-generics.stderr | 27 +- .../borrowck/borrowck-closures-mut-and-imm.rs | 11 +- .../borrowck-closures-mut-and-imm.stderr | 6 +- .../diagnostics/liveness.rs | 8 +- .../diagnostics/liveness.stderr | 55 +- .../2229_closure_analysis/issue-87378.rs | 2 +- .../2229_closure_analysis/issue-87378.stderr | 2 +- .../match/partial-move.rs | 14 +- .../match/partial-move.stderr | 6 +- .../match/pattern-matching-should-fail.stderr | 4 +- .../match/patterns-capture-analysis.rs | 4 +- .../match/patterns-capture-analysis.stderr | 4 +- .../2229_closure_analysis/move_closure.rs | 2 +- .../2229_closure_analysis/move_closure.stderr | 2 +- .../2229_closure_analysis/nested-closure.rs | 4 +- .../nested-closure.stderr | 4 +- .../2229_closure_analysis/repr_packed.rs | 10 +- .../2229_closure_analysis/repr_packed.stderr | 10 +- .../2229_closure_analysis/unsafe_ptr.rs | 4 +- .../2229_closure_analysis/unsafe_ptr.stderr | 4 +- .../2229_closure_analysis/wild_patterns.rs | 4 +- .../wild_patterns.stderr | 4 +- ...ure-bounds-static-cant-capture-borrowed.rs | 2 +- ...bounds-static-cant-capture-borrowed.stderr | 8 +- .../cromulent-copy-closure-captures-2021.rs | 62 ++ ...ent-copy-closure-captures-analysis-2021.rs | 306 ++++++++ ...copy-closure-captures-analysis-2021.stderr | 700 ++++++++++++++++++ ...re-captures-auto-traits.edition2018.stderr | 71 ++ ...re-captures-auto-traits.edition2021.stderr | 71 ++ ...ulent-copy-closure-captures-auto-traits.rs | 21 + ...y-closure-captures-fail.edition2018.stderr | 134 ++++ ...y-closure-captures-fail.edition2021.stderr | 116 +++ .../cromulent-copy-closure-captures-fail.rs | 77 ++ .../cromulent-copy-closure-captures.rs | 68 ++ tests/ui/closures/drop-copy-2015.rs | 25 + ...structural_identity_dependent_reborrows.rs | 21 + ...structural_identity_dependent_reborrows.rs | 12 +- ...ctural_identity_dependent_reborrows.stderr | 27 +- .../ui/coroutine/static-move-suggestion.fixed | 2 +- tests/ui/coroutine/static-move-suggestion.rs | 2 +- .../coroutine/static-move-suggestion.stderr | 6 +- ...clone.rs => dotuse-extra-capture-clone.rs} | 17 +- .../confusing-lifetime-error-issue-79033.rs | 2 +- ...onfusing-lifetime-error-issue-79033.stderr | 12 +- .../impl-trait/does-not-live-long-enough.rs | 8 +- .../does-not-live-long-enough.stderr | 12 +- ...ing-use-return-hir-typeck-ty-ice-127033.rs | 2 +- .../iterators/generator_returned_from_fn.rs | 6 +- .../generator_returned_from_fn.stderr | 51 +- tests/ui/liveness/liveness-upvars.rs | 3 +- tests/ui/liveness/liveness-upvars.stderr | 39 +- tests/ui/nll/closure-access-spans.stderr | 14 +- tests/ui/nll/closure-borrow-spans.rs | 34 +- tests/ui/nll/closure-borrow-spans.stderr | 36 +- .../region-borrow-params-issue-29793-big.rs | 2 +- ...egion-borrow-params-issue-29793-big.stderr | 20 +- .../region-borrow-params-issue-29793-small.rs | 32 +- ...ion-borrow-params-issue-29793-small.stderr | 120 +-- .../async-closure.stdout | 84 +-- .../send-is-not-static-ensures-scoping.rs | 2 +- .../send-is-not-static-ensures-scoping.stderr | 6 +- ...-suggestion-in-proper-span-issue-121267.rs | 6 +- ...gestion-in-proper-span-issue-121267.stderr | 10 +- .../unboxed-closure-region.rs | 3 +- .../unboxed-closure-region.stderr | 10 +- 122 files changed, 3318 insertions(+), 1634 deletions(-) create mode 100644 src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.rs create mode 100644 src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.stderr create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-2021.rs create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2018.stderr create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2021.stderr create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-auto-traits.rs create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-fail.edition2018.stderr create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-fail.edition2021.stderr create mode 100644 tests/ui/closures/cromulent-copy-closure-captures-fail.rs create mode 100644 tests/ui/closures/cromulent-copy-closure-captures.rs create mode 100644 tests/ui/closures/drop-copy-2015.rs create mode 100644 tests/ui/coercion/no_structural_identity_dependent_reborrows.rs rename tests/ui/ergonomic-clones/closure/{dotuse-no-extra-capture-clone.rs => dotuse-extra-capture-clone.rs} (74%) diff --git a/compiler/rustc_error_codes/src/error_codes/E0373.md b/compiler/rustc_error_codes/src/error_codes/E0373.md index b9db807259728..59be487d0f4ec 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0373.md +++ b/compiler/rustc_error_codes/src/error_codes/E0373.md @@ -3,9 +3,9 @@ A captured variable in a closure may not live long enough. Erroneous code example: ```compile_fail,E0373 -fn foo() -> Box u32> { - let x = 0u32; - Box::new(|y| x + y) +fn foo() -> Box usize> { + let arr = [42_u32; 17]; + Box::new(|y| arr.len() + y) } ``` @@ -13,38 +13,38 @@ This error occurs when an attempt is made to use data captured by a closure, when that data may no longer exist. It's most commonly seen when attempting to return a closure as shown in the previous code example. -Notice that `x` is stack-allocated by `foo()`. By default, Rust captures -closed-over data by reference. This means that once `foo()` returns, `x` no -longer exists. An attempt to access `x` within the closure would thus be -unsafe. +Notice that `arr` is stack-allocated by `foo()`. Within the closure, it is used +by reference (as the receiver of the `.len()` call). This means that once +`foo()` returns, `arr` no longer exists. An attempt to access `list` within the +closure would thus be unsafe. Another situation where this might be encountered is when spawning threads: ```compile_fail,E0373 fn foo() { - let x = 0u32; - let y = 1u32; + let arr = [42_u32; 17]; + let y = 1usize; let thr = std::thread::spawn(|| { - x + y + arr.len() + y }); } ``` -Since our new thread runs in parallel, the stack frame containing `x` and `y` -may well have disappeared by the time we try to use them. Even if we call -`thr.join()` within foo (which blocks until `thr` has completed, ensuring the -stack frame won't disappear), we will not succeed: the compiler cannot prove -that this behavior is safe, and so won't let us do it. +Since our new thread runs in parallel, the stack frame containing `arr` may well +have disappeared by the time we try to use them. Even if we call `thr.join()` +within foo (which blocks until `thr` has completed, ensuring the stack frame +won't disappear), we will not succeed: the compiler cannot prove that this +behavior is safe, and so won't let us do it. The solution to this problem is usually to switch to using a `move` closure. This approach moves (or copies, where possible) data into the closure, rather than taking references to it. For example: ``` -fn foo() -> Box u32> { - let x = 0u32; - Box::new(move |y| x + y) +fn foo() -> Box usize> { + let arr = [42_u32; 17]; + Box::new(move |y| arr.len() + y) } ``` diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 0c49ec002671d..c61ec61ed0b3c 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1099,6 +1099,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx upvar_borrow, ); } + ty::UpvarCapture::ByCopy => { + self.delegate.borrow_mut().copy(&place_with_id, place_with_id.hir_id); + } } } } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index fbe20c849de9c..c2d2e26064378 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -142,8 +142,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // fallback might later resolve the type to `Copy` (making the closure `Fn`). if closure_kind == ty::ClosureKind::FnOnce { for (place, capture_info) in &delegate.capture_information { - if matches!(capture_info.capture_kind, ty::UpvarCapture::ByValue) - && place.ty().has_infer() + if matches!( + capture_info.capture_kind, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByCopy + ) && place.ty().has_infer() { return None; } @@ -610,7 +612,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for capture in self.typeck_results.borrow().closure_min_captures_flattened(closure_def_id) { - if let UpvarCapture::ByValue = capture.info.capture_kind { + if let UpvarCapture::ByValue | UpvarCapture::ByCopy = capture.info.capture_kind { self.require_type_is_sized( capture.place.ty(), capture.get_path_span(self.tcx), @@ -742,11 +744,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .cloned() .map(|(place, mut capture_info)| { - // Apply rules for safety before inferring closure kind + // Apply rules for safety before inferring closure kind. + // N.B.: We call `restrict_repr_packed_field_ref_capture()` here, + // so we can't introduce any new by-ref captures, or remove Deref projections + // from existing ones, after this point. let (place, capture_kind) = - restrict_capture_precision(place, capture_info.capture_kind); + restrict_capture_precision(self, place, capture_info.capture_kind); - let (place, capture_kind) = truncate_capture_for_optimization(place, capture_kind); + let (place, capture_kind) = + truncate_capture_for_optimization(self, place, capture_kind); let usage_span = if let Some(usage_expr) = capture_info.path_expr_id { self.tcx.hir_span(usage_expr) @@ -784,9 +790,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { origin = updated.1; let (place, capture_kind) = match capture_clause { - hir::CaptureBy::Value { .. } => adjust_for_move_closure(place, capture_kind), - hir::CaptureBy::Use { .. } => adjust_for_use_closure(place, capture_kind), - hir::CaptureBy::Ref => adjust_for_non_move_closure(place, capture_kind), + hir::CaptureBy::Value { .. } => { + adjust_for_move_closure(self, place, capture_kind) + } + hir::CaptureBy::Use { .. } => adjust_for_use_closure(self, place, capture_kind), + hir::CaptureBy::Ref => adjust_for_non_move_closure(self, place, capture_kind), }; // This restriction needs to be applied after we have handled adjustments for `move` @@ -931,6 +939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Truncate the descendant (already in min_captures) to be same as the ancestor to handle any // possible change in capture mode. truncate_place_to_len_and_update_capture_kind( + self, &mut possible_descendant.place, &mut possible_descendant.info.capture_kind, place.projections.len(), @@ -970,6 +979,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Truncate the descendant (current place) to be same as the ancestor to handle any // possible change in capture mode. truncate_place_to_len_and_update_capture_kind( + self, &mut place, &mut updated_capture_info.capture_kind, possible_ancestor.place.projections.len(), @@ -1355,7 +1365,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::CaptureBy::Value { .. } => ty, // For move closure the capture kind should be by value hir::CaptureBy::Ref | hir::CaptureBy::Use { .. } => { // For non move closure the capture kind is the max capture kind of all captures - // according to the ordering ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue + // according to the ordering ByCopy < ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue let mut max_capture_info = root_var_min_capture_list.first().unwrap().info; for capture in root_var_min_capture_list.iter() { max_capture_info = determine_capture_info(max_capture_info, capture.info); @@ -1492,7 +1502,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for captured_place in root_var_min_capture_list.iter() { match captured_place.info.capture_kind { - // Only care about captures that are moved into the closure + // Only care about captures that are moved into the closure, + // and which may have a destructor ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => { projections_list.push(captured_place.place.projections.as_slice()); diagnostics_info.insert(UpvarMigrationInfo::CapturingPrecise { @@ -1500,7 +1511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { var_name: captured_place.to_string(self.tcx), }); } - ty::UpvarCapture::ByRef(..) => {} + ty::UpvarCapture::ByRef(..) | ty::UpvarCapture::ByCopy => {} } } @@ -1901,15 +1912,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Otherwise you'd get an error in 2021 immediately because you'd be trying to take // ownership of the (borrowed) String or else you'd take ownership of b, as in 2018 and // before, which is also an error. - hir::CaptureBy::Value { .. } if !place.deref_tys().any(Ty::is_ref) => { - ty::UpvarCapture::ByValue - } - hir::CaptureBy::Use { .. } if !place.deref_tys().any(Ty::is_ref) => { - ty::UpvarCapture::ByUse + hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } | hir::CaptureBy::Ref + if place.deref_tys().any(Ty::is_ref) => + { + ty::UpvarCapture::ByRef(BorrowKind::Immutable) } - hir::CaptureBy::Value { .. } | hir::CaptureBy::Use { .. } | hir::CaptureBy::Ref => { + hir::CaptureBy::Ref + if !self.infcx.type_is_copy_modulo_regions(self.param_env, place.ty()) => + { ty::UpvarCapture::ByRef(BorrowKind::Immutable) } + hir::CaptureBy::Value { .. } => ty::UpvarCapture::ByValue, + hir::CaptureBy::Use { .. } => ty::UpvarCapture::ByUse, + hir::CaptureBy::Ref => ty::UpvarCapture::ByCopy, } } @@ -2119,31 +2134,38 @@ fn should_reborrow_from_env_of_parent_coroutine_closure<'tcx>( /// Truncate the capture so that the place being borrowed is in accordance with RFC 1240, /// which states that it's unsafe to take a reference into a struct marked `repr(packed)`. -fn restrict_repr_packed_field_ref_capture<'tcx>( +/// +/// **Must be called *after* all [`ty::UpvarCapture::ByRef`]s have been introduced, and all +/// [`ProjectionKind::Deref`]s pertaining to such removed.** +#[must_use] +fn restrict_repr_packed_field_ref_capture<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, mut place: Place<'tcx>, mut curr_borrow_kind: ty::UpvarCapture, ) -> (Place<'tcx>, ty::UpvarCapture) { - let pos = place.projections.iter().enumerate().position(|(i, p)| { - let ty = place.ty_before_projection(i); + // We only want repr packed restriction to be applied to reading references into a packed + // struct, and not when the data is being moved. + let ty::UpvarCapture::ByRef(_) = curr_borrow_kind else { + return (place, curr_borrow_kind); + }; - // Return true for fields of packed structs. + for p_idx in (0..place.projections.len()).rev() { + let p = place.projections[p_idx]; match p.kind { - ProjectionKind::Field(..) => match ty.kind() { - ty::Adt(def, _) if def.repr().packed() => { - // We stop here regardless of field alignment. Field alignment can change as - // types change, including the types of private fields in other crates, and that - // shouldn't affect how we compute our captures. - true - } - - _ => false, - }, - _ => false, + ProjectionKind::Deref => break, + ProjectionKind::Field(..) + if let ty::Adt(def, _) = place.ty_before_projection(p_idx).kind() + && def.repr().packed() => + { + truncate_place_to_len_and_update_capture_kind( + fcx, + &mut place, + &mut curr_borrow_kind, + p_idx, + ); + } + _ => {} } - }); - - if let Some(pos) = pos { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_borrow_kind, pos); } (place, curr_borrow_kind) @@ -2157,7 +2179,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>( region: ty::Region<'tcx>, ) -> Ty<'tcx> { match capture_kind { - ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => ty, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse | ty::UpvarCapture::ByCopy => ty, ty::UpvarCapture::ByRef(kind) => Ty::new_ref(tcx, region, ty, kind.to_mutbl_lossy()), } } @@ -2228,9 +2250,8 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { let span = self.fcx.tcx.hir_span(diag_expr_id); let place = self.fcx.normalize(span, Unnormalized::new_wip(place_with_id.place.clone())); - let (place, _) = restrict_capture_precision(place, dummy_capture_kind); + let (place, _) = restrict_capture_precision(&self.fcx, place, dummy_capture_kind); - let (place, _) = restrict_repr_packed_field_ref_capture(place, dummy_capture_kind); self.fake_reads.push((place, cause, diag_expr_id)); } @@ -2281,16 +2302,11 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { assert_eq!(self.closure_def_id, upvar_id.closure_expr_id); // The region here will get discarded/ignored - let capture_kind = ty::UpvarCapture::ByRef(bk); + let mut capture_kind = ty::UpvarCapture::ByRef(bk); let span = self.fcx.tcx.hir_span(diag_expr_id); let place = self.fcx.normalize(span, Unnormalized::new_wip(place_with_id.place.clone())); - // We only want repr packed restriction to be applied to reading references into a packed - // struct, and not when the data is being moved. Therefore we call this method here instead - // of in `restrict_capture_precision`. - let (place, mut capture_kind) = restrict_repr_packed_field_ref_capture(place, capture_kind); - // Raw pointers don't inherit mutability if place.deref_tys().any(Ty::is_raw_ptr) { capture_kind = ty::UpvarCapture::ByRef(ty::BorrowKind::Immutable); @@ -2306,6 +2322,31 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { )); } + #[instrument(skip(self), level = "debug")] + fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; + + assert_eq!(self.closure_def_id, upvar_id.closure_expr_id); + + let span = self.fcx.tcx.hir_span(diag_expr_id); + let place = self.fcx.normalize(span, Unnormalized::new_wip(place_with_id.place.clone())); + + if place.projections.iter().any(|p| p.kind == ProjectionKind::Deref) + && !matches!(place.ty().kind(), ty::Ref(_, _, ty::Mutability::Not)) + { + self.borrow(place_with_id, diag_expr_id, BorrowKind::Immutable); + } else { + self.capture_information.push(( + place, + ty::CaptureInfo { + capture_kind_expr_id: Some(diag_expr_id), + path_expr_id: Some(diag_expr_id), + capture_kind: ty::UpvarCapture::ByCopy, + }, + )); + } + } + #[instrument(skip(self), level = "debug")] fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::Mutable); @@ -2314,6 +2355,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { /// Rust doesn't permit moving fields out of a type that implements drop #[instrument(skip(fcx), ret, level = "debug")] +#[must_use] fn restrict_precision_for_drop_types<'a, 'tcx>( fcx: &'a FnCtxt<'a, 'tcx>, mut place: Place<'tcx>, @@ -2325,7 +2367,12 @@ fn restrict_precision_for_drop_types<'a, 'tcx>( for i in 0..place.projections.len() { match place.ty_before_projection(i).kind() { ty::Adt(def, _) if def.destructor(fcx.tcx).is_some() => { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i); + truncate_place_to_len_and_update_capture_kind( + fcx, + &mut place, + &mut curr_mode, + i, + ); break; } _ => {} @@ -2340,33 +2387,40 @@ fn restrict_precision_for_drop_types<'a, 'tcx>( /// - No projections are applied to raw pointers, since these require unsafe blocks. We capture /// them completely. /// - No projections are applied on top of Union ADTs, since these require unsafe blocks. -fn restrict_precision_for_unsafe( - mut place: Place<'_>, +/// +/// Also calls [`restrict_repr_packed_field_ref_capture()`] at the end; see that method's docs +/// for some important info. +#[must_use] +fn restrict_precision_for_unsafe<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, + mut place: Place<'tcx>, mut curr_mode: ty::UpvarCapture, -) -> (Place<'_>, ty::UpvarCapture) { +) -> (Place<'tcx>, ty::UpvarCapture) { if place.base_ty.is_raw_ptr() { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, 0); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut curr_mode, 0); } if place.base_ty.is_union() { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, 0); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut curr_mode, 0); } for (i, proj) in place.projections.iter().enumerate() { if proj.ty.is_raw_ptr() { // Don't apply any projections on top of a raw ptr. - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i + 1); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut curr_mode, i + 1); break; } if proj.ty.is_union() { // Don't capture precise fields of a union. - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i + 1); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut curr_mode, i + 1); break; } } - (place, curr_mode) + // We call this *after* all the other adjustments, because the union field truncations + // could turn by-Copy into by-reference capture, and the raw pointer truncations could remove derefs. + restrict_repr_packed_field_ref_capture(fcx, place, curr_mode) } /// Truncate projections so that the following rules are obeyed by the captured `place`: @@ -2374,13 +2428,16 @@ fn restrict_precision_for_unsafe( /// - No unsafe block is required to capture `place`. /// /// Returns the truncated place and updated capture mode. -#[instrument(ret, level = "debug")] -fn restrict_capture_precision( - place: Place<'_>, - curr_mode: ty::UpvarCapture, -) -> (Place<'_>, ty::UpvarCapture) { - let (mut place, mut curr_mode) = restrict_precision_for_unsafe(place, curr_mode); - +/// +/// Calls [`restrict_repr_packed_field_ref_capture()`] at the end; see that method's docs +/// for some important info. +#[instrument(skip(fcx), ret, level = "debug")] +#[must_use] +fn restrict_capture_precision<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, + mut place: Place<'tcx>, + mut curr_mode: ty::UpvarCapture, +) -> (Place<'tcx>, ty::UpvarCapture) { if place.projections.is_empty() { // Nothing to do here return (place, curr_mode); @@ -2390,8 +2447,8 @@ fn restrict_capture_precision( match proj.kind { ProjectionKind::Index | ProjectionKind::Subslice => { // Arrays are completely captured, so we drop Index and Subslice projections - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i); - return (place, curr_mode); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut curr_mode, i); + break; } ProjectionKind::Deref => {} ProjectionKind::OpaqueCast => {} @@ -2400,34 +2457,40 @@ fn restrict_capture_precision( } } - (place, curr_mode) + // calls `restrict_repr_packed_field_ref_capture()`; + // see that method's doc comment for important info + restrict_precision_for_unsafe(fcx, place, curr_mode) } /// Truncate deref of any reference. -#[instrument(ret, level = "debug")] -fn adjust_for_move_closure( - mut place: Place<'_>, +#[instrument(skip(fcx), ret, level = "debug")] +#[must_use] +fn adjust_for_move_closure<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, + mut place: Place<'tcx>, mut kind: ty::UpvarCapture, -) -> (Place<'_>, ty::UpvarCapture) { +) -> (Place<'tcx>, ty::UpvarCapture) { let first_deref = place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref); if let Some(idx) = first_deref { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut kind, idx); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut kind, idx); } (place, ty::UpvarCapture::ByValue) } /// Truncate deref of any reference. -#[instrument(ret, level = "debug")] -fn adjust_for_use_closure( - mut place: Place<'_>, +#[instrument(skip(fcx), ret, level = "debug")] +#[must_use] +fn adjust_for_use_closure<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, + mut place: Place<'tcx>, mut kind: ty::UpvarCapture, -) -> (Place<'_>, ty::UpvarCapture) { +) -> (Place<'tcx>, ty::UpvarCapture) { let first_deref = place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref); if let Some(idx) = first_deref { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut kind, idx); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut kind, idx); } (place, ty::UpvarCapture::ByUse) @@ -2435,32 +2498,24 @@ fn adjust_for_use_closure( /// Adjust closure capture just that if taking ownership of data, only move data /// from enclosing stack frame. -#[instrument(ret, level = "debug")] -fn adjust_for_non_move_closure( - mut place: Place<'_>, +#[instrument(skip(fcx), ret, level = "debug")] +#[must_use] +fn adjust_for_non_move_closure<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, + mut place: Place<'tcx>, mut kind: ty::UpvarCapture, -) -> (Place<'_>, ty::UpvarCapture) { +) -> (Place<'tcx>, ty::UpvarCapture) { let contains_deref = place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref); match kind { ty::UpvarCapture::ByValue => { if let Some(idx) = contains_deref { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut kind, idx); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut kind, idx); } } - // A non-`move`/`use` closure that only `.use`s an upvar does not need to - // own (and thus clone-on-capture) the value. The `ByUse` kind here can only - // come from a `x.use` in the body (a `use ||` capture clause goes through - // `adjust_for_use_closure` instead). Capturing such a place by immutable - // borrow lets the `.use` expression clone per evaluation, rather than also - // cloning the value into the closure at construction time. See #157141. - ty::UpvarCapture::ByUse => { - kind = ty::UpvarCapture::ByRef(ty::BorrowKind::Immutable); - } - - ty::UpvarCapture::ByRef(..) => {} + ty::UpvarCapture::ByUse | ty::UpvarCapture::ByRef(..) | ty::UpvarCapture::ByCopy => {} } (place, kind) @@ -2491,18 +2546,22 @@ fn construct_place_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String format!("{variable_name}[{projections_str}]") } +fn construct_capture_kind_string(capture_kind: UpvarCapture) -> String { + match capture_kind { + ty::UpvarCapture::ByValue => "ByValue".into(), + ty::UpvarCapture::ByUse => "ByUse".into(), + ty::UpvarCapture::ByRef(kind) => format!("{kind:?}"), + ty::UpvarCapture::ByCopy => "ByCopy".into(), + } +} + fn construct_capture_kind_reason_string<'tcx>( tcx: TyCtxt<'_>, place: &Place<'tcx>, capture_info: &ty::CaptureInfo, ) -> String { let place_str = construct_place_string(tcx, place); - - let capture_kind_str = match capture_info.capture_kind { - ty::UpvarCapture::ByValue => "ByValue".into(), - ty::UpvarCapture::ByUse => "ByUse".into(), - ty::UpvarCapture::ByRef(kind) => format!("{kind:?}"), - }; + let capture_kind_str = construct_capture_kind_string(capture_info.capture_kind); format!("{place_str} captured as {capture_kind_str} here") } @@ -2519,12 +2578,8 @@ fn construct_capture_info_string<'tcx>( capture_info: &ty::CaptureInfo, ) -> String { let place_str = construct_place_string(tcx, place); + let capture_kind_str = construct_capture_kind_string(capture_info.capture_kind); - let capture_kind_str = match capture_info.capture_kind { - ty::UpvarCapture::ByValue => "ByValue".into(), - ty::UpvarCapture::ByUse => "ByUse".into(), - ty::UpvarCapture::ByRef(kind) => format!("{kind:?}"), - }; format!("{place_str} -> {capture_kind_str}") } @@ -2610,7 +2665,7 @@ fn determine_capture_info( capture_info_b: ty::CaptureInfo, ) -> ty::CaptureInfo { // We select the CaptureKind which ranks higher based the following priority order: - // (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow + // (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow > ByCopy match capture_info_a.capture_kind.partial_cmp(&capture_info_b.capture_kind) { Some(cmp::Ordering::Equal) => { match (capture_info_a.capture_kind_expr_id, capture_info_b.capture_kind_expr_id) { @@ -2630,19 +2685,43 @@ fn determine_capture_info( /// /// Note: Capture kind changes from `MutBorrow` to `UniqueImmBorrow` if the truncated part of the `place` /// contained `Deref` of `&mut`. -fn truncate_place_to_len_and_update_capture_kind<'tcx>( +/// +/// Additionally, it changes from `ByCopy` to `ImmBorrow` if the type of the new place no longer implements `Copy`, +/// and from `ImmBorrow` to `ByCopy` if the truncated part of the place contained a `Deref` +/// and the type of the new place implements `Copy`. +fn truncate_place_to_len_and_update_capture_kind<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, place: &mut Place<'tcx>, curr_mode: &mut ty::UpvarCapture, len: usize, ) { let is_mut_ref = |ty: Ty<'_>| matches!(ty.kind(), ty::Ref(.., hir::Mutability::Mut)); - // If the truncated part of the place contains `Deref` of a `&mut` then convert MutBorrow -> - // UniqueImmBorrow - // Note that if the place contained Deref of a raw pointer it would've not been MutBorrow, so - // we don't need to worry about that case here. match curr_mode { + ty::UpvarCapture::ByCopy => { + if !fcx + .infcx + .type_is_copy_modulo_regions(fcx.param_env, place.ty_before_projection(len)) + { + *curr_mode = ty::UpvarCapture::ByRef(ty::BorrowKind::Immutable); + } + } + + ty::UpvarCapture::ByRef(ty::BorrowKind::Immutable) + if place.projections[len..].iter().any(|p| p.kind == ProjectionKind::Deref) + && fcx.infcx.type_is_copy_modulo_regions( + fcx.param_env, + place.ty_before_projection(len), + ) => + { + *curr_mode = ty::UpvarCapture::ByCopy; + } + ty::UpvarCapture::ByRef(ty::BorrowKind::Mutable) => { + // If the truncated part of the place contains `Deref` of a `&mut` then convert MutBorrow -> + // UniqueImmBorrow + // Note that if the place contained Deref of a raw pointer it would've not been MutBorrow, so + // we don't need to worry about that case here. for i in len..place.projections.len() { if place.projections[i].kind == ProjectionKind::Deref && is_mut_ref(place.ty_before_projection(i)) @@ -2653,8 +2732,7 @@ fn truncate_place_to_len_and_update_capture_kind<'tcx>( } } - ty::UpvarCapture::ByRef(..) => {} - ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {} + ty::UpvarCapture::ByRef(..) | ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {} } place.projections.truncate(len); @@ -2726,11 +2804,17 @@ fn determine_place_ancestry_relation<'tcx>( /// // it is constrained to `'a` /// } /// ``` -#[instrument(ret, level = "debug")] -fn truncate_capture_for_optimization( - mut place: Place<'_>, +#[instrument(skip(fcx), ret, level = "debug")] +#[must_use] +fn truncate_capture_for_optimization<'a, 'tcx>( + fcx: &'a FnCtxt<'a, 'tcx>, + mut place: Place<'tcx>, mut curr_mode: ty::UpvarCapture, -) -> (Place<'_>, ty::UpvarCapture) { +) -> (Place<'tcx>, ty::UpvarCapture) { + let ty::UpvarCapture::ByRef(_) = curr_mode else { + return (place, curr_mode); + }; + let is_shared_ref = |ty: Ty<'_>| matches!(ty.kind(), ty::Ref(.., hir::Mutability::Not)); // Find the rightmost deref (if any). All the projections that come after this @@ -2741,7 +2825,7 @@ fn truncate_capture_for_optimization( match idx { // If that pointer is a shared reference, then we don't need those fields. Some(idx) if is_shared_ref(place.ty_before_projection(idx)) => { - truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, idx + 1) + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, &mut curr_mode, idx + 1) } None | Some(_) => {} } diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs index 299e9a2db9a18..bc59db3337400 100644 --- a/compiler/rustc_middle/src/hir/place.rs +++ b/compiler/rustc_middle/src/hir/place.rs @@ -126,7 +126,6 @@ impl<'tcx> Place<'tcx> { /// Returns the type of this `Place` immediately before `projection_index`th projection /// is applied. pub fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> { - assert!(projection_index < self.projections.len()); if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty } } } diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 4b410b3259bff..8287a8e785f56 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -47,6 +47,9 @@ impl UpvarId { #[derive(Eq, PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, StableHash, Hash)] #[derive(TypeFoldable, TypeVisitable)] pub enum UpvarCapture { + /// Like `ByValue`, but dominated by all the other modes instead of dominating them. + ByCopy, + /// Upvar is captured by reference. ByRef(BorrowKind), @@ -64,11 +67,15 @@ impl PartialOrd for UpvarCapture { #[inline] fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { - (Self::ByValue, Self::ByValue) | (Self::ByUse, Self::ByUse) => { - Some(cmp::Ordering::Equal) + (Self::ByCopy, Self::ByCopy) + | (Self::ByValue, Self::ByValue) + | (Self::ByUse, Self::ByUse) => Some(cmp::Ordering::Equal), + (_, Self::ByCopy) | (Self::ByValue | Self::ByUse, Self::ByRef(_)) => { + Some(cmp::Ordering::Greater) + } + (Self::ByCopy, _) | (Self::ByRef(_), Self::ByValue | Self::ByUse) => { + Some(cmp::Ordering::Less) } - (Self::ByValue | Self::ByUse, Self::ByRef(_)) => Some(cmp::Ordering::Greater), - (Self::ByRef(_), Self::ByValue | Self::ByUse) => Some(cmp::Ordering::Less), (Self::ByRef(left), Self::ByRef(right)) => Some(left.cmp(&right)), (Self::ByUse, Self::ByValue) | (Self::ByValue, Self::ByUse) => None, } @@ -202,7 +209,7 @@ impl<'tcx> CapturedPlace<'tcx> { pub fn is_by_ref(&self) -> bool { match self.info.capture_kind { - ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => false, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse | ty::UpvarCapture::ByCopy => false, ty::UpvarCapture::ByRef(..) => true, } } diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 3c4888a05d6e9..5b9b8a7e71bc9 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -53,7 +53,9 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( .map(|captured_place| { let name = captured_place.to_symbol(); match captured_place.info.capture_kind { - ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => name, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse | ty::UpvarCapture::ByCopy => { + name + } ty::UpvarCapture::ByRef(..) => Symbol::intern(&format!("_ref__{name}")), } }) @@ -924,7 +926,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut projs = closure_env_projs.clone(); projs.push(ProjectionElem::Field(FieldIdx::new(i), ty)); match capture { - ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => {} + ty::UpvarCapture::ByValue + | ty::UpvarCapture::ByUse + | ty::UpvarCapture::ByCopy => {} ty::UpvarCapture::ByRef(..) => { projs.push(ProjectionElem::Deref); } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index e38e9293ba196..5bd8e662b787a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1645,7 +1645,7 @@ impl<'tcx> ThirBuildCx<'tcx> { let temp_scope_id = closure_expr.hir_id.local_id; match upvar_capture { - ty::UpvarCapture::ByValue => captured_place_expr, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByCopy => captured_place_expr, ty::UpvarCapture::ByUse => { let span = captured_place_expr.span; let expr_id = self.thir.exprs.push(captured_place_expr); diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index e8f566d4b24d8..aa01bad4b1570 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -170,7 +170,9 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( // this when building the field projection in the MIR body later on. let mut parent_capture_ty = parent_capture.place.ty(); parent_capture_ty = match parent_capture.info.capture_kind { - ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => parent_capture_ty, + ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse | ty::UpvarCapture::ByCopy => { + parent_capture_ty + } ty::UpvarCapture::ByRef(kind) => Ty::new_ref( tcx, tcx.lifetimes.re_erased, diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index f1d85166653ff..131e3f9d01654 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -1223,18 +1223,6 @@ fn build_construct_coroutine_by_move_shim<'tcx>( for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() { if receiver_by_ref { - // The only situation where it's possible is when we capture immuatable references, - // since those don't need to be reborrowed with the closure's env lifetime. Since - // references are always `Copy`, just emit a copy. - if !matches!(ty.kind(), ty::Ref(_, _, hir::Mutability::Not)) { - // This copy is only sound if it's a `&T`. This may be - // reachable e.g. when eagerly computing the `Fn` instance - // of an async closure that doesn't borrowck. - tcx.dcx().delayed_bug(format!( - "field should be captured by immutable ref if we have \ - an `Fn` instance, but it was: {ty}" - )); - } fields.push(Operand::Copy(tcx.mk_place_field( self_local, FieldIdx::from_usize(idx), diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index 3f9d4504bde4c..96a1c678f961e 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -52,6 +52,7 @@ impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec) { let slice = iterator.as_slice(); // ignore-tidy-undocumented-unsafe diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index cc73396f72246..5c7bc4d7f450e 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -957,7 +957,7 @@ pub fn can_move_expr_to_closure<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<' }; if !self.locals.contains(&local_id) { let capture = match capture.info.capture_kind { - UpvarCapture::ByValue => CaptureKind::Value, + UpvarCapture::ByValue | UpvarCapture::ByCopy => CaptureKind::Value, UpvarCapture::ByUse => CaptureKind::Use, UpvarCapture::ByRef(kind) => match kind { BorrowKind::Immutable => CaptureKind::Ref(Mutability::Not), diff --git a/src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.rs b/src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.rs new file mode 100644 index 0000000000000..bca37b30d6532 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.rs @@ -0,0 +1,9 @@ +use core::num::NonZeroU8; + +fn main() { + let mut nonzero = NonZeroU8::new(1).unwrap(); + unsafe { + (&raw mut nonzero).cast::().write(0); + } + let _ = || nonzero; //~ ERROR: constructing invalid value +} diff --git a/src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.stderr b/src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.stderr new file mode 100644 index 0000000000000..2600a4f8f4b92 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/cromulent-copy-closure-captures.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: constructing invalid value of type {closure@tests/fail/validity/cromulent-copy-closure-captures.rs:LL:CC}: at ..0.0, encountered 0, but expected something greater or equal to 1 + --> tests/fail/validity/cromulent-copy-closure-captures.rs:LL:CC + | +LL | let _ = || nonzero; + | ^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index cbe5b671fe83a..51115667fe9ca 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -33,6 +33,7 @@ pub(crate) mod unify; use std::{ cell::{OnceCell, RefCell}, + cmp, convert::identity, fmt, hash::Hash, @@ -912,7 +913,7 @@ pub struct CapturedPlace { impl CapturedPlace { pub fn is_by_ref(&self) -> bool { match self.info.capture_kind { - UpvarCapture::ByValue | UpvarCapture::ByUse => false, + UpvarCapture::ByValue | UpvarCapture::ByUse | UpvarCapture::ByCopy => false, UpvarCapture::ByRef(..) => true, } } @@ -936,7 +937,7 @@ impl CapturedPlace { Ty::new_ref(interner, region, place_ty, mutbl) }; match self.info.capture_kind { - UpvarCapture::ByUse | UpvarCapture::ByValue => place_ty, + UpvarCapture::ByUse | UpvarCapture::ByValue | UpvarCapture::ByCopy => place_ty, UpvarCapture::ByRef(kind) => make_ref(kind.to_mutbl_lossy()), } } @@ -1060,16 +1061,39 @@ pub struct CaptureInfo { /// during `typeck`, specifically by `regionck`. #[derive(Eq, PartialEq, Clone, Debug, Copy, Hash)] pub enum UpvarCapture { + /// Like `ByValue`, but dominated by all the other modes instead of dominating them. + ByCopy, + + /// Upvar is captured by reference. + ByRef(BorrowKind), + + /// Upvar is captured by use. This is true when the closure is labeled `use`. + ByUse, + /// Upvar is captured by value. This is always true when the /// closure is labeled `move`, but can also be true in other cases /// depending on inference. ByValue, +} - /// Upvar is captured by use. This is true when the closure is labeled `use`. - ByUse, - - /// Upvar is captured by reference. - ByRef(BorrowKind), +// Used in closure::analysis::determine_capture_info +impl PartialOrd for UpvarCapture { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (Self::ByCopy, Self::ByCopy) + | (Self::ByValue, Self::ByValue) + | (Self::ByUse, Self::ByUse) => Some(cmp::Ordering::Equal), + (_, Self::ByCopy) | (Self::ByValue | Self::ByUse, Self::ByRef(_)) => { + Some(cmp::Ordering::Greater) + } + (Self::ByCopy, _) | (Self::ByRef(_), Self::ByValue | Self::ByUse) => { + Some(cmp::Ordering::Less) + } + (Self::ByRef(left), Self::ByRef(right)) => Some(left.cmp(&right)), + (Self::ByUse, Self::ByValue) | (Self::ByValue, Self::ByUse) => None, + } + } } #[salsa::tracked] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs index 0c24b82d1bde0..29eeda293c247 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs @@ -30,7 +30,7 @@ //! then mean that all later passes would have to check for these figments //! and report an error, and it just seems like more mess in the end.) -use std::{iter, mem}; +use std::{cmp, iter, mem}; use hir_def::{ expr_store::ExpressionStore, @@ -88,7 +88,7 @@ impl<'db> UpvarArgs<'db> { } } -#[derive(Eq, Clone, PartialEq, Debug, Copy, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum BorrowKind { /// Data must be immutable and is aliasable. Immutable, @@ -602,9 +602,9 @@ impl<'db> InferenceContext<'db> { .cloned() .map(|(place, mut capture_info)| { // Apply rules for safety before inferring closure kind - let place = restrict_capture_precision(place, &mut capture_info); + let place = restrict_capture_precision(self, place, &mut capture_info); - let place = truncate_capture_for_optimization(place, &mut capture_info); + let place = truncate_capture_for_optimization(self, place, &mut capture_info); let updated = match capture_info.capture_kind { UpvarCapture::ByValue => match closure_kind { @@ -632,8 +632,8 @@ impl<'db> InferenceContext<'db> { origin = updated.1; let place = match capture_clause { - CaptureBy::Value => adjust_for_move_closure(place, &mut capture_info), - CaptureBy::Ref => adjust_for_non_move_closure(place, &mut capture_info), + CaptureBy::Value => adjust_for_move_closure(self, place, &mut capture_info), + CaptureBy::Ref => adjust_for_non_move_closure(self, place, &mut capture_info), }; // This restriction needs to be applied after we have handled adjustments for `move` @@ -771,6 +771,7 @@ impl<'db> InferenceContext<'db> { // Truncate the descendant (already in min_captures) to be same as the ancestor to handle any // possible change in capture mode. truncate_place_to_len_and_update_capture_kind( + self, &mut possible_descendant.place, &mut possible_descendant.info, place.projections.len(), @@ -822,6 +823,7 @@ impl<'db> InferenceContext<'db> { // Truncate the descendant (current place) to be same as the ancestor to handle any // possible change in capture mode. truncate_place_to_len_and_update_capture_kind( + self, &mut place, &mut updated_capture_info, possible_ancestor.place.projections.len(), @@ -993,8 +995,16 @@ impl<'db> InferenceContext<'db> { // Otherwise you'd get an error in 2021 immediately because you'd be trying to take // ownership of the (borrowed) String or else you'd take ownership of b, as in 2018 and // before, which is also an error. - CaptureBy::Value if !place.deref_tys().any(Ty::is_ref) => UpvarCapture::ByValue, - CaptureBy::Value | CaptureBy::Ref => UpvarCapture::ByRef(BorrowKind::Immutable), + CaptureBy::Value | CaptureBy::Ref if place.deref_tys().any(Ty::is_ref) => { + UpvarCapture::ByRef(BorrowKind::Immutable) + } + CaptureBy::Ref + if !self.infcx().type_is_copy_modulo_regions(self.table.param_env, place.ty()) => + { + UpvarCapture::ByRef(BorrowKind::Immutable) + } + CaptureBy::Value => UpvarCapture::ByValue, + CaptureBy::Ref => UpvarCapture::ByCopy, } } @@ -1118,31 +1128,29 @@ fn should_reborrow_from_env_of_parent_coroutine_closure( /// Truncate the capture so that the place being borrowed is in accordance with RFC 1240, /// which states that it's unsafe to take a reference into a struct marked `repr(packed)`. -fn restrict_repr_packed_field_ref_capture( +fn restrict_repr_packed_field_ref_capture<'db>( + fcx: &InferenceContext<'db>, mut place: Place, capture_info: &mut CaptureInfo, ) -> Place { - let pos = place.projections.iter().enumerate().position(|(i, p)| { - let ty = place.ty_before_projection(i); - - // Return true for fields of packed structs. - match p.kind { - ProjectionKind::Field { .. } => match ty.kind() { - TyKind::Adt(def, _) if def.is_packed() => { - // We stop here regardless of field alignment. Field alignment can change as - // types change, including the types of private fields in other crates, and that - // shouldn't affect how we compute our captures. - true - } + // We only want repr packed restriction to be applied to reading references into a packed + // struct, and not when the data is being moved. + let UpvarCapture::ByRef(_) = capture_info.capture_kind else { + return place; + }; - _ => false, - }, - _ => false, + for p_idx in (0..place.projections.len()).rev() { + let p = place.projections[p_idx].kind; + match p { + ProjectionKind::Deref => break, + ProjectionKind::Field { .. } + if let TyKind::Adt(def, _) = place.ty_before_projection(p_idx).kind() + && def.repr(fcx.db).packed() => + { + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, p_idx); + } + _ => {} } - }); - - if let Some(pos) = pos { - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, pos); } place @@ -1156,7 +1164,7 @@ fn apply_capture_kind_on_capture_ty<'db>( region: Region<'db>, ) -> Ty<'db> { match capture_kind { - UpvarCapture::ByValue | UpvarCapture::ByUse => ty, + UpvarCapture::ByValue | UpvarCapture::ByUse | UpvarCapture::ByCopy => ty, UpvarCapture::ByRef(kind) => Ty::new_ref(interner, region, ty, kind.to_mutbl_lossy()), } } @@ -1213,10 +1221,9 @@ impl<'db> euv::Delegate<'db> for InferBorrowKind { let place = ctx.normalize_capture_place(place_with_id.span(), place_with_id.place.clone()); - let place = restrict_capture_precision(place, &mut dummy_capture_info); + let place = restrict_capture_precision(ctx, place, &mut dummy_capture_info); dummy_capture_info.capture_kind = dummy_capture_kind; - let place = restrict_repr_packed_field_ref_capture(place, &mut dummy_capture_info); self.fake_reads.push((place, cause, place_with_id.origins)); } @@ -1269,11 +1276,6 @@ impl<'db> euv::Delegate<'db> for InferBorrowKind { let place = ctx.normalize_capture_place(place_with_id.span(), place_with_id.place.clone()); - // We only want repr packed restriction to be applied to reading references into a packed - // struct, and not when the data is being moved. Therefore we call this method here instead - // of in `restrict_capture_precision`. - let place = restrict_repr_packed_field_ref_capture(place, &mut capture_info); - // Raw pointers don't inherit mutability if place.deref_tys().any(Ty::is_raw_ptr) { capture_info.capture_kind = UpvarCapture::ByRef(BorrowKind::Immutable); @@ -1282,6 +1284,27 @@ impl<'db> euv::Delegate<'db> for InferBorrowKind { self.capture_information.push((place, capture_info)); } + #[instrument(skip(self), level = "debug")] + fn copy(&mut self, place_with_id: PlaceWithOrigin, ctx: &mut InferenceContext<'db>) { + let PlaceBase::Upvar { closure: upvar_closure, .. } = place_with_id.place.base else { + return; + }; + assert_eq!(self.closure_def_id, upvar_closure); + + let place = ctx.normalize_capture_place(place_with_id.span(), place_with_id.place.clone()); + + if place.projections.iter().any(|p| p.kind == ProjectionKind::Deref) + && !matches!(place.ty().kind(), TyKind::Ref(_, _, Mutability::Not)) + { + self.borrow(place_with_id, BorrowKind::Immutable, ctx); + } else { + self.capture_information.push(( + place, + CaptureInfo { sources: place_with_id.origins, capture_kind: UpvarCapture::ByCopy }, + )); + } + } + #[instrument(skip(self), level = "debug")] fn mutate(&mut self, assignee_place: PlaceWithOrigin, ctx: &mut InferenceContext<'db>) { self.borrow(assignee_place, BorrowKind::Mutable, ctx); @@ -1301,7 +1324,7 @@ fn restrict_precision_for_drop_types<'db>( for i in 0..place.projections.len() { match place.ty_before_projection(i).kind() { TyKind::Adt(def, _) if def.destructor(fcx.interner()).is_some() => { - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, i); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, i); break; } _ => {} @@ -1316,30 +1339,34 @@ fn restrict_precision_for_drop_types<'db>( /// - No projections are applied to raw pointers, since these require unsafe blocks. We capture /// them completely. /// - No projections are applied on top of Union ADTs, since these require unsafe blocks. -fn restrict_precision_for_unsafe(mut place: Place, capture_info: &mut CaptureInfo) -> Place { +fn restrict_precision_for_unsafe<'db>( + fcx: &InferenceContext<'db>, + mut place: Place, + capture_info: &mut CaptureInfo, +) -> Place { if place.base_ty.as_ref().is_raw_ptr() { - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, 0); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, 0); } if place.base_ty.as_ref().is_union() { - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, 0); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, 0); } for (i, proj) in place.projections.iter().enumerate() { if proj.ty.as_ref().is_raw_ptr() { // Don't apply any projections on top of a raw ptr. - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, i + 1); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, i + 1); break; } if proj.ty.as_ref().is_union() { // Don't capture precise fields of a union. - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, i + 1); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, i + 1); break; } } - place + restrict_repr_packed_field_ref_capture(fcx, place, capture_info) } /// Truncate projections so that the following rules are obeyed by the captured `place`: @@ -1348,9 +1375,11 @@ fn restrict_precision_for_unsafe(mut place: Place, capture_info: &mut CaptureInf /// /// Returns the truncated place and updated capture mode. #[instrument(ret, level = "debug")] -fn restrict_capture_precision(place: Place, capture_info: &mut CaptureInfo) -> Place { - let mut place = restrict_precision_for_unsafe(place, capture_info); - +fn restrict_capture_precision<'db>( + fcx: &InferenceContext<'db>, + mut place: Place, + capture_info: &mut CaptureInfo, +) -> Place { if place.projections.is_empty() { // Nothing to do here return place; @@ -1360,7 +1389,7 @@ fn restrict_capture_precision(place: Place, capture_info: &mut CaptureInfo) -> P match proj.kind { ProjectionKind::Index | ProjectionKind::Subslice => { // Arrays are completely captured, so we drop Index and Subslice projections - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, i); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, i); return place; } ProjectionKind::Deref => {} @@ -1369,16 +1398,20 @@ fn restrict_capture_precision(place: Place, capture_info: &mut CaptureInfo) -> P } } - place + restrict_precision_for_unsafe(fcx, place, capture_info) } /// Truncate deref of any reference. #[instrument(ret, level = "debug")] -fn adjust_for_move_closure(mut place: Place, capture_info: &mut CaptureInfo) -> Place { +fn adjust_for_move_closure<'db>( + fcx: &InferenceContext<'db>, + mut place: Place, + capture_info: &mut CaptureInfo, +) -> Place { let first_deref = place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref); if let Some(idx) = first_deref { - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, idx); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, idx); } capture_info.capture_kind = UpvarCapture::ByValue; @@ -1388,14 +1421,18 @@ fn adjust_for_move_closure(mut place: Place, capture_info: &mut CaptureInfo) -> /// Adjust closure capture just that if taking ownership of data, only move data /// from enclosing stack frame. #[instrument(ret, level = "debug")] -fn adjust_for_non_move_closure(mut place: Place, capture_info: &mut CaptureInfo) -> Place { +fn adjust_for_non_move_closure<'db>( + fcx: &InferenceContext<'db>, + mut place: Place, + capture_info: &mut CaptureInfo, +) -> Place { let contains_deref = place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref); match capture_info.capture_kind { - UpvarCapture::ByValue | UpvarCapture::ByUse => { + UpvarCapture::ByValue | UpvarCapture::ByUse | UpvarCapture::ByCopy => { if let Some(idx) = contains_deref { - truncate_place_to_len_and_update_capture_kind(&mut place, capture_info, idx); + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, capture_info, idx); } } @@ -1407,53 +1444,12 @@ fn adjust_for_non_move_closure(mut place: Place, capture_info: &mut CaptureInfo) /// At the end, `capture_info_a` will contain the selected info. fn determine_capture_info(capture_info_a: &mut CaptureInfo, capture_info_b: &mut CaptureInfo) { - // If the capture kind is equivalent then, we don't need to escalate and can compare the - // expressions. - let eq_capture_kind = match (capture_info_a.capture_kind, capture_info_b.capture_kind) { - (UpvarCapture::ByValue, UpvarCapture::ByValue) => true, - (UpvarCapture::ByUse, UpvarCapture::ByUse) => true, - (UpvarCapture::ByRef(ref_a), UpvarCapture::ByRef(ref_b)) => ref_a == ref_b, - (UpvarCapture::ByValue, _) | (UpvarCapture::ByUse, _) | (UpvarCapture::ByRef(_), _) => { - false - } - }; - - let swap = if eq_capture_kind { - false - } else { - // We select the CaptureKind which ranks higher based the following priority order: - // (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow - match (capture_info_a.capture_kind, capture_info_b.capture_kind) { - (UpvarCapture::ByUse, UpvarCapture::ByValue) - | (UpvarCapture::ByValue, UpvarCapture::ByUse) => { - panic!("Same capture can't be ByUse and ByValue at the same time") - } - (UpvarCapture::ByValue, UpvarCapture::ByValue) - | (UpvarCapture::ByUse, UpvarCapture::ByUse) - | (UpvarCapture::ByValue | UpvarCapture::ByUse, UpvarCapture::ByRef(_)) => false, - (UpvarCapture::ByRef(_), UpvarCapture::ByValue | UpvarCapture::ByUse) => true, - (UpvarCapture::ByRef(ref_a), UpvarCapture::ByRef(ref_b)) => { - match (ref_a, ref_b) { - // Take LHS: - (BorrowKind::UniqueImmutable | BorrowKind::Mutable, BorrowKind::Immutable) - | (BorrowKind::Mutable, BorrowKind::UniqueImmutable) => false, - - // Take RHS: - (BorrowKind::Immutable, BorrowKind::UniqueImmutable | BorrowKind::Mutable) - | (BorrowKind::UniqueImmutable, BorrowKind::Mutable) => true, - - (BorrowKind::Immutable, BorrowKind::Immutable) - | (BorrowKind::UniqueImmutable, BorrowKind::UniqueImmutable) - | (BorrowKind::Mutable, BorrowKind::Mutable) => { - panic!("Expected unequal capture kinds"); - } - } - } - } - }; - - if swap { - mem::swap(capture_info_a, capture_info_b); + // We select the CaptureKind which ranks higher based the following priority order: + // (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow > ByCopy + match capture_info_a.capture_kind.partial_cmp(&capture_info_b.capture_kind) { + Some(cmp::Ordering::Equal) | Some(cmp::Ordering::Greater) => {} + Some(cmp::Ordering::Less) => mem::swap(capture_info_a, capture_info_b), + None => panic!("Same capture can't be ByUse and ByValue at the same time"), } } @@ -1482,7 +1478,8 @@ fn determine_capture_sources( /// /// Note: Capture kind changes from `MutBorrow` to `UniqueImmBorrow` if the truncated part of the `place` /// contained `Deref` of `&mut`. -fn truncate_place_to_len_and_update_capture_kind( +fn truncate_place_to_len_and_update_capture_kind<'db>( + fcx: &InferenceContext<'db>, place: &mut Place, info: &mut CaptureInfo, len: usize, @@ -1494,6 +1491,23 @@ fn truncate_place_to_len_and_update_capture_kind( // Note that if the place contained Deref of a raw pointer it would've not been MutBorrow, so // we don't need to worry about that case here. match info.capture_kind { + UpvarCapture::ByCopy => { + if !fcx + .infcx() + .type_is_copy_modulo_regions(fcx.table.param_env, place.ty_before_projection(len)) + { + info.capture_kind = UpvarCapture::ByRef(BorrowKind::Immutable); + } + } + UpvarCapture::ByRef(BorrowKind::Immutable) + if place.projections[len..].iter().any(|p| p.kind == ProjectionKind::Deref) + && fcx.infcx().type_is_copy_modulo_regions( + fcx.table.param_env, + place.ty_before_projection(len), + ) => + { + info.capture_kind = UpvarCapture::ByCopy; + } UpvarCapture::ByRef(BorrowKind::Mutable) => { for i in len..place.projections.len() { if place.projections[i].kind == ProjectionKind::Deref @@ -1505,8 +1519,7 @@ fn truncate_place_to_len_and_update_capture_kind( } } - UpvarCapture::ByRef(..) => {} - UpvarCapture::ByValue | UpvarCapture::ByUse => {} + UpvarCapture::ByRef(..) | UpvarCapture::ByValue | UpvarCapture::ByUse => {} } // Now fix the sources, to point at the smaller place. @@ -1582,7 +1595,15 @@ fn determine_place_ancestry_relation(place_a: &Place, place_b: &Place) -> PlaceA /// } /// ``` #[instrument(ret, level = "debug")] -fn truncate_capture_for_optimization(mut place: Place, info: &mut CaptureInfo) -> Place { +fn truncate_capture_for_optimization<'db>( + fcx: &InferenceContext<'db>, + mut place: Place, + info: &mut CaptureInfo, +) -> Place { + let UpvarCapture::ByRef(_) = info.capture_kind else { + return place; + }; + let is_shared_ref = |ty: Ty<'_>| matches!(ty.kind(), TyKind::Ref(.., Mutability::Not)); // Find the rightmost deref (if any). All the projections that come after this @@ -1593,7 +1614,7 @@ fn truncate_capture_for_optimization(mut place: Place, info: &mut CaptureInfo) - match idx { // If that pointer is a shared reference, then we don't need those fields. Some(idx) if is_shared_ref(place.ty_before_projection(idx)) => { - truncate_place_to_len_and_update_capture_kind(&mut place, info, idx + 1) + truncate_place_to_len_and_update_capture_kind(fcx, &mut place, info, idx + 1) } None | Some(_) => {} } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs index 6a4e38c5264a7..b2b743da1c1dd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs @@ -120,7 +120,6 @@ impl Place { /// Returns the type of this `Place` immediately before `projection_index`th projection /// is applied. pub fn ty_before_projection<'db>(&self, projection_index: usize) -> Ty<'db> { - assert!(projection_index < self.projections.len()); if projection_index == 0 { self.base_ty.as_ref() } else { @@ -664,11 +663,16 @@ impl<'a, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'db, D> { self.consume_expr(base)?; } - Expr::BinaryOp { lhs, rhs, op: None | Some(BinaryOp::Assignment { .. }) } => { + Expr::BinaryOp { lhs, rhs, op: None | Some(BinaryOp::Assignment { op: None }) } => { self.consume_expr(lhs)?; self.consume_expr(rhs)?; } + Expr::BinaryOp { lhs, rhs, op: Some(BinaryOp::Assignment { op: Some(_) }) } => { + self.mutate_expr(lhs)?; + self.consume_expr(rhs)?; + } + Expr::Array(Array::Repeat { initializer: base, .. }) => { self.consume_expr(base)?; } @@ -1126,6 +1130,9 @@ impl<'a, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'db, D> { UpvarCapture::ByRef(upvar_borrow) => { self.delegate.borrow(place_with_id, upvar_borrow, self.cx); } + UpvarCapture::ByCopy => { + self.delegate.copy(place_with_id, self.cx); + } } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 3b82ed6f798e4..0ba40f709d6c8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -1232,6 +1232,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { UpvarCapture::ByValue => { operands.push(Operand { kind: OperandKind::Move(p), span: None }) } + UpvarCapture::ByCopy => { + operands.push(Operand { kind: OperandKind::Copy(p), span: None }) + } UpvarCapture::ByUse => not_supported!("capture by use"), } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index c951a5481c460..9fea5c206f87c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -289,7 +289,22 @@ fn main() { let closure = || { let b = a.a; }; } "#, - expect!["92..111;50..51;105..108 ByRef(Immutable) a.a &' i32"], + expect!["92..111;50..51;105..108 ByCopy a.a i32"], + ); +} + +#[test] +fn bycopy() { + check_closure_captures( + r#" +//- minicore:copy, fn +fn main() { + let y: i32 = 5; + let closure = |x: i32| { + x + y + }; +"#, + expect!["50..80;20..21;73..74 ByCopy y i32"], ); } @@ -415,7 +430,7 @@ fn main() { let mut closure = || { let (b | b) = a; }; } "#, - expect!["57..80;20..25;76..77 ByRef(Immutable) a &' bool"], + expect!["57..80;20..25;76..77 ByCopy a bool"], ); } @@ -559,7 +574,7 @@ fn main() { }; } "#, - expect!["220..257;174..175;245..250 ByRef(Immutable) c.b.x &' i32"], + expect!["220..257;174..175;245..250 ByCopy c.b.x i32"], ); } @@ -578,8 +593,8 @@ fn f() { } "#, expect![[r#" - 44..113;17..18;92..93 ByRef(Immutable) a &' i32 - 73..106;17..18;92..93 ByRef(Immutable) a &' i32"#]], + 44..113;17..18;92..93 ByCopy a i32 + 73..106;17..18;92..93 ByCopy a i32"#]], ); } @@ -597,7 +612,7 @@ fn f() { }; } "#, - expect!["77..110;46..47;96..97 ByRef(Immutable) b &' i32"], + expect!["77..110;46..47;96..97 ByCopy b i32"], ); } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index f9073138e32dd..93bf6f728b555 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -4175,7 +4175,8 @@ impl<'db> ClosureCapture<'db> { pub fn kind(&self) -> CaptureKind { match self.capture.info.capture_kind { - hir_ty::closure_analysis::UpvarCapture::ByValue => CaptureKind::Move, + hir_ty::closure_analysis::UpvarCapture::ByValue + | hir_ty::closure_analysis::UpvarCapture::ByCopy => CaptureKind::Move, hir_ty::closure_analysis::UpvarCapture::ByUse => CaptureKind::SharedRef, // Good enough? hir_ty::closure_analysis::UpvarCapture::ByRef( hir_ty::closure_analysis::BorrowKind::Immutable, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs index 83effa11820b7..ff2aaa7cabaf1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_closure_to_fn.rs @@ -960,10 +960,10 @@ fn foo() { r#" fn foo() { let a = 1; - fn closure(a: &i32) -> i32 { - *a + fn closure(a: i32) -> i32 { + a } - closure(&a); + closure(a); } "#, ); @@ -1144,11 +1144,11 @@ fn foo() { r#" fn foo() { let (mut a, b) = (0.1, "abc"); - fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) { + fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &str) { *a = 1.2; - let c = *b; + let c = b; } - closure(0, &mut false, &mut a, &b); + closure(0, &mut false, &mut a, b); } "#, ); @@ -1176,16 +1176,16 @@ fn foo() { r#" fn foo() { let (mut a, b) = (0.1, "abc"); - fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) { + fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &str) { let _: &mut bool = p2; *a = 1.2; - let c = *b; + let c = b; } closure( 0, &mut false, &mut a, - &b + b ); } "#, @@ -1214,16 +1214,16 @@ fn foo() { r#" fn foo() { let (mut a, b) = (0.1, "abc"); - fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &&str) { + fn closure(p1: i32, p2: &mut bool, a: &mut f64, b: &str) { let _: &mut bool = p2; *a = 1.2; - let c = *b; + let c = b; } closure( 0, &mut false, &mut a, - &b, + b, ); } "#, @@ -1282,8 +1282,8 @@ fn foo() { fn bar(_: impl FnOnce() -> i32) {} fn foo() { let a = 123; - fn fun_name(a: &i32) -> i32 { - *a + fn fun_name(a: i32) -> i32 { + a } bar(fun_name); } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index c8aa8a2221640..3a22e7a94cea9 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -286,10 +286,10 @@ fn main() { impl Fn(i32) -> i32 ``` --- - size = 8, align = 8, niches = 1 + size = 4, align = 4 ## Captures - * `x` by immutable borrow + * `x` by move "#]], ); @@ -3398,7 +3398,7 @@ fn main() { ``` ## Captures - * `x` by immutable borrow + * `x` by move "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs index dc36bd776db6c..0cf4595f36607 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs @@ -148,7 +148,7 @@ fn main() { let mut baz = NonCopy; let qux = &mut NonCopy; || { - // ^ move(&foo, bar, baz, qux) + // ^ move(foo, bar, baz, qux) foo; bar; baz; @@ -193,7 +193,7 @@ fn main() { let mut baz = NonCopy; let qux = &mut NonCopy; async || { - // ^ move(&foo, bar, baz, qux) + // ^ move(foo, bar, baz, qux) foo; bar; baz; @@ -239,7 +239,7 @@ fn main() { let mut baz = NonCopy; let qux = &mut NonCopy; async { - // ^ move(&foo, bar, baz, qux) + // ^ move(foo, bar, baz, qux) foo; bar; baz; @@ -276,7 +276,7 @@ fn main() { async { let foo = 1; async { - // ^ move(&foo) + // ^ move(foo) foo; } }; @@ -294,12 +294,12 @@ fn main() { fn main() { let foo = 0; gen { - // ^ move(&foo) + // ^ move(foo) foo; yield (); }; async gen { - // ^ move(&foo) + // ^ move(foo) foo; yield (); }; @@ -317,7 +317,7 @@ fn main() { fn main() { let foo = 0; let coroutine = #[coroutine] || { - // ^ move(&foo) + // ^ move(foo) foo; yield (); }; diff --git a/tests/codegen-llvm/bounds-checking/gep-issue-133979.rs b/tests/codegen-llvm/bounds-checking/gep-issue-133979.rs index 876bdbfb0e143..dbbd74a0f1876 100644 --- a/tests/codegen-llvm/bounds-checking/gep-issue-133979.rs +++ b/tests/codegen-llvm/bounds-checking/gep-issue-133979.rs @@ -15,7 +15,7 @@ fn test(a: &[&[u8]]) -> u32 { b.iter() .enumerate() .filter(|(_, c)| **c == b'A') - .map(|(x, _)| a[y][x] as u32) + .map(|(x, _)| (&a)[y][x] as u32) .sum::() }) .sum() diff --git a/tests/codegen-llvm/debuginfo-dse.rs b/tests/codegen-llvm/debuginfo-dse.rs index 7509facdaadc0..389789b4b2bee 100644 --- a/tests/codegen-llvm/debuginfo-dse.rs +++ b/tests/codegen-llvm/debuginfo-dse.rs @@ -278,7 +278,6 @@ pub fn fragment(fragment_v1: Foo, mut fragment_v2: Foo) -> Foo { // CHECK: #dbg_declare(ptr [[ARG_fragment_v1]] // CHECK-NEXT: #dbg_declare(ptr [[ARG_fragment_v2]] // CHECK-NEXT: #dbg_value(ptr [[ARG_fragment_v2]], [[VAR_fragment_f:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 64) - // CHECK-NEXT: #dbg_value(ptr [[ARG_fragment_v1]], [[VAR_fragment_f:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 64, 64) let fragment_f = || { fragment_v2 = fragment_v1; }; diff --git a/tests/codegen-llvm/lib-optimizations/append-elements.rs b/tests/codegen-llvm/lib-optimizations/append-elements.rs index 47211e3f388a0..0bf00d0460020 100644 --- a/tests/codegen-llvm/lib-optimizations/append-elements.rs +++ b/tests/codegen-llvm/lib-optimizations/append-elements.rs @@ -13,7 +13,7 @@ #[no_mangle] pub fn vec_append_with_temp_alloc(dst: &mut Vec, src: &[u8]) { // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.*}}[[DST]].i{{.*}}[[SRC]] + // CHECK: call void @llvm.memcpy.{{.*}}{{.*}}.i{{.*}}[[SRC]] // CHECK-NOT: call void @llvm.memcpy let temp = src.to_vec(); dst.extend(&temp); diff --git a/tests/codegen-llvm/thread-local.rs b/tests/codegen-llvm/thread-local.rs index 70b655fd5cf61..af962c67ebcc5 100644 --- a/tests/codegen-llvm/thread-local.rs +++ b/tests/codegen-llvm/thread-local.rs @@ -32,7 +32,7 @@ fn get() -> u32 { #[no_mangle] fn set(v: u32) { // CHECK: [[PTR:%.+]] = tail call {{.*}} ptr @llvm.threadlocal.address.p0(ptr [[TLS]]) - // CHECK-NEXT: store i32 %0, ptr [[PTR]] + // CHECK-NEXT: store i32 %v, ptr [[PTR]] // CHECK-NEXT: ret void A.with(|a| a.set(v)) } @@ -50,7 +50,7 @@ fn get_aux() -> u64 { #[no_mangle] fn set_aux(v: u64) { // CHECK: [[PTR:%.+]] = tail call {{.*}} ptr @llvm.threadlocal.address.p0(ptr [[TLS_AUX]]) - // CHECK-NEXT: store i64 %0, ptr [[PTR]] + // CHECK-NEXT: store i64 %v, ptr [[PTR]] // CHECK-NEXT: ret void aux::A.with(|a| a.set(v)) } diff --git a/tests/debuginfo/basic-types-metadata.rs b/tests/debuginfo/basic-types-metadata.rs index 7171840077265..db348e1c092c5 100644 --- a/tests/debuginfo/basic-types-metadata.rs +++ b/tests/debuginfo/basic-types-metadata.rs @@ -77,8 +77,8 @@ fn main() { let f128: f128 = 4.5; let fnptr : fn() = _zzz; let closure_0 = || {}; - let closure_1 = || { b; }; - let closure_2 = || { if b { i } else { i }; }; + let closure_1 = || { *&b; }; + let closure_2 = || { if *&b { *&i } else { *&i }; }; _zzz(); // #break if 1 == 1 { _yyy(); } } diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff index cf55f3f3b12c6..8157254f82380 100644 --- a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.StateTransform.diff @@ -5,8 +5,8 @@ - yields () - { - debug _task_context => _2; -- debug x => (*(_1.0: &u32)); -- debug y => (*(_1.1: &u32)); +- debug x => (_1.0: u32); +- debug y => (_1.1: u32); - let mut _0: u32; + fn add::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>, _2: &mut Context<'_>) -> Poll { + coroutine layout { @@ -17,41 +17,37 @@ + } + storage_conflicts = BitMatrix(0x0) {} + } -+ debug _task_context => _10; -+ debug x => (*((*_9).0: &u32)); -+ debug y => (*((*_9).1: &u32)); ++ debug _task_context => _8; ++ debug x => ((*_7).0: u32); ++ debug y => ((*_7).1: u32); + let mut _0: std::task::Poll; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; -+ let mut _7: u32; -+ let mut _8: u32; -+ let mut _9: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; -+ let mut _10: std::future::ResumeTy; -+ let mut _11: std::ptr::NonNull>; ++ let mut _5: u32; ++ let mut _6: u32; ++ let mut _7: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; ++ let mut _8: std::future::ResumeTy; ++ let mut _9: std::ptr::NonNull>; bb0: { - StorageLive(_3); -- _5 = no_retag copy (_1.0: &u32); -- _3 = copy (*_5); +- _3 = copy (_1.0: u32); - StorageLive(_4); -- _6 = no_retag copy (_1.1: &u32); -- _4 = copy (*_6); +- _4 = copy (_1.1: u32); - _0 = Add(move _3, move _4); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; -+ _11 = move _2 as std::ptr::NonNull> (Transmute); -+ _10 = std::future::ResumeTy(move _11); -+ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}); -+ _8 = discriminant((*_9)); -+ switchInt(move _8) -> [0: bb4, 1: bb2, otherwise: bb3]; ++ _9 = move _2 as std::ptr::NonNull> (Transmute); ++ _8 = std::future::ResumeTy(move _9); ++ _7 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}); ++ _6 = discriminant((*_7)); ++ switchInt(move _6) -> [0: bb4, 1: bb2, otherwise: bb3]; } bb1: { -+ _0 = Poll::::Ready(move _7); -+ discriminant((*_9)) = 1; ++ _0 = Poll::::Ready(move _5); ++ discriminant((*_7)) = 1; return; } @@ -67,12 +63,10 @@ + + bb4: { + StorageLive(_3); -+ _5 = no_retag copy ((*_9).0: &u32); -+ _3 = copy (*_5); ++ _3 = copy ((*_7).0: u32); + StorageLive(_4); -+ _6 = no_retag copy ((*_9).1: &u32); -+ _4 = copy (*_6); -+ _7 = Add(move _3, move _4); ++ _4 = copy ((*_7).1: u32); ++ _5 = Add(move _3, move _4); + StorageDead(_4); + StorageDead(_3); + goto -> bb1; diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir index 4dec40924719b..99a683cc76ddf 100644 --- a/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}-{closure#0}.coroutine_drop.0.mir @@ -2,20 +2,18 @@ fn add::{closure#0}::{closure#0}(_1: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}) -> () { debug _task_context => _2; - debug x => (*((*_1).0: &u32)); - debug y => (*((*_1).1: &u32)); + debug x => ((*_1).0: u32); + debug y => ((*_1).1: u32); let mut _0: (); let mut _2: std::future::ResumeTy; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; - let mut _7: u32; - let mut _8: u32; + let mut _5: u32; + let mut _6: u32; bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb2, otherwise: bb3]; + _6 = discriminant((*_1)); + switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff index b6c22224c74f8..149322d3a7abf 100644 --- a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.StateTransform.diff @@ -10,64 +10,56 @@ - let mut _0: u32; + fn add::{closure#0}(_1: Pin<&mut {async fn body of add()}>, _2: &mut Context<'_>) -> Poll { + coroutine layout { -+ field _s0: u32; -+ field _s1: u32; -+ field _s2: {async block@$DIR/async_fn.rs:34:13: 34:18}; ++ field _s0: {async block@$DIR/async_fn.rs:34:13: 34:18}; + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], -+ Suspend0 (3): [_s0, _s1, _s2], ++ Suspend0 (3): [_s0], + } -+ storage_conflicts = BitMatrix(3x3) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s2, _s0), (_s2, _s1), (_s2, _s2)} ++ storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} + } -+ debug _task_context => _28; -+ debug x => ((*_27).0: u32); -+ debug y => ((*_27).1: u32); -+ coroutine debug x => _s0; ++ debug _task_context => _26; ++ debug x => ((*_25).0: u32); ++ debug y => ((*_25).1: u32); + let mut _0: std::task::Poll; let _3: u32; - let mut _6: &u32; - let mut _7: &u32; - let mut _8: {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _9: {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _11: (); - let _12: (); - let mut _13: std::task::Poll; - let mut _14: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>; - let mut _15: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _16: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _17: &mut std::task::Context<'_>; - let mut _18: &mut std::task::Context<'_>; - let mut _19: std::future::ResumeTy; - let mut _20: isize; - let mut _22: !; - let mut _23: std::future::ResumeTy; - let mut _24: (); -+ let mut _25: u32; -+ let mut _26: u32; -+ let mut _27: &mut {async fn body of add()}; -+ let mut _28: std::future::ResumeTy; -+ let mut _29: std::ptr::NonNull>; + let mut _6: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _7: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _9: (); + let _10: (); + let mut _11: std::task::Poll; + let mut _12: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>; + let mut _13: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _14: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _15: &mut std::task::Context<'_>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: std::future::ResumeTy; + let mut _18: isize; + let mut _20: !; + let mut _21: std::future::ResumeTy; + let mut _22: (); ++ let mut _23: u32; ++ let mut _24: u32; ++ let mut _25: &mut {async fn body of add()}; ++ let mut _26: std::future::ResumeTy; ++ let mut _27: std::ptr::NonNull>; scope 1 { -- debug x => _3; -+ debug x => (((*_27) as variant#3).0: u32); -+ coroutine debug y => _s1; + debug x => _3; let _4: u32; scope 2 { -- debug y => _4; -+ debug y => (((*_27) as variant#3).1: u32); + debug y => _4; let _5: {async block@$DIR/async_fn.rs:34:13: 34:18}; scope 3 { debug a => _5; -+ coroutine debug __awaitee => _s2; - let mut _10: {async block@$DIR/async_fn.rs:34:13: 34:18}; ++ coroutine debug __awaitee => _s0; + let mut _8: {async block@$DIR/async_fn.rs:34:13: 34:18}; scope 4 { -- debug __awaitee => _10; -+ debug __awaitee => (((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}); - let _21: u32; +- debug __awaitee => _8; ++ debug __awaitee => (((*_25) as variant#3).0: {async block@$DIR/async_fn.rs:34:13: 34:18}); + let _19: u32; scope 5 { - debug result => _21; + debug result => _19; } } } @@ -80,74 +72,68 @@ - StorageLive(_4); - _4 = copy (_1.1: u32); - StorageLive(_5); +- _5 = {coroutine@$DIR/async_fn.rs:34:13: 34:18 (#0)} { x: copy _3, y: copy _4 }; - StorageLive(_6); -- _6 = &_3; - StorageLive(_7); -- _7 = &_4; -- _5 = {coroutine@$DIR/async_fn.rs:34:13: 34:18 (#0)} { x: move _6, y: move _7 }; -- StorageDead(_7); -- StorageDead(_6); -- StorageLive(_8); -- StorageLive(_9); -- _9 = move _5; -- _8 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as IntoFuture>::into_future(move _9) -> [return: bb1, unwind: bb24]; -+ _29 = move _2 as std::ptr::NonNull> (Transmute); -+ _28 = std::future::ResumeTy(move _29); -+ _27 = copy (_1.0: &mut {async fn body of add()}); -+ _26 = discriminant((*_27)); -+ switchInt(move _26) -> [0: bb27, 1: bb26, 2: bb25, 3: bb24, otherwise: bb6]; +- _7 = move _5; +- _6 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as IntoFuture>::into_future(move _7) -> [return: bb1, unwind: bb24]; ++ _27 = move _2 as std::ptr::NonNull> (Transmute); ++ _26 = std::future::ResumeTy(move _27); ++ _25 = copy (_1.0: &mut {async fn body of add()}); ++ _24 = discriminant((*_25)); ++ switchInt(move _24) -> [0: bb27, 1: bb26, 2: bb25, 3: bb24, otherwise: bb6]; } bb1: { - StorageDead(_9); - PlaceMention(_8); -- StorageLive(_10); -- _10 = move _8; + StorageDead(_7); + PlaceMention(_6); +- StorageLive(_8); +- _8 = move _6; + nop; -+ (((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}) = move _8; ++ (((*_25) as variant#3).0: {async block@$DIR/async_fn.rs:34:13: 34:18}) = move _6; goto -> bb2; } bb2: { + StorageLive(_10); + StorageLive(_11); StorageLive(_12); StorageLive(_13); StorageLive(_14); - StorageLive(_15); - StorageLive(_16); -- _16 = &mut _10; -+ _16 = &mut (((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}); - _15 = &mut (*_16); -- _14 = Pin::<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>::new_unchecked(move _15) -> [return: bb3, unwind: bb21]; -+ _14 = Pin::<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>::new_unchecked(move _15) -> [return: bb3, unwind: bb15]; +- _14 = &mut _8; ++ _14 = &mut (((*_25) as variant#3).0: {async block@$DIR/async_fn.rs:34:13: 34:18}); + _13 = &mut (*_14); +- _12 = Pin::<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>::new_unchecked(move _13) -> [return: bb3, unwind: bb21]; ++ _12 = Pin::<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>::new_unchecked(move _13) -> [return: bb3, unwind: bb15]; } bb3: { - StorageDead(_15); + StorageDead(_13); + StorageLive(_15); + StorageLive(_16); StorageLive(_17); - StorageLive(_18); - StorageLive(_19); -- _19 = copy _2; -- _18 = std::future::get_context::<'_, '_>(move _19) -> [return: bb4, unwind: bb19]; -+ _19 = copy _28; -+ _18 = copy (_19.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _17 = copy _2; +- _16 = std::future::get_context::<'_, '_>(move _17) -> [return: bb4, unwind: bb19]; ++ _17 = copy _26; ++ _16 = copy (_17.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb4; } bb4: { - _17 = &mut (*_18); - StorageDead(_19); -- _13 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as Future>::poll(move _14, move _17) -> [return: bb5, unwind: bb20]; -+ _13 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as Future>::poll(move _14, move _17) -> [return: bb5, unwind: bb14]; + _15 = &mut (*_16); + StorageDead(_17); +- _11 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as Future>::poll(move _12, move _15) -> [return: bb5, unwind: bb20]; ++ _11 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as Future>::poll(move _12, move _15) -> [return: bb5, unwind: bb14]; } bb5: { - StorageDead(_18); - StorageDead(_17); StorageDead(_16); + StorageDead(_15); StorageDead(_14); - PlaceMention(_13); - _20 = discriminant(_13); - switchInt(move _20) -> [0: bb8, 1: bb7, otherwise: bb6]; + StorageDead(_12); + PlaceMention(_11); + _18 = discriminant(_11); + switchInt(move _18) -> [0: bb8, 1: bb7, otherwise: bb6]; } bb6: { @@ -155,220 +141,215 @@ } bb7: { - _12 = const (); - StorageDead(_13); - StorageDead(_12); - StorageLive(_23); - StorageLive(_24); - _24 = (); -- _23 = yield(move _24) -> [resume: bb9, drop: bb14]; + _10 = const (); + StorageDead(_11); + StorageDead(_10); + StorageLive(_21); + StorageLive(_22); + _22 = (); +- _21 = yield(move _22) -> [resume: bb9, drop: bb14]; + _0 = Poll::::Pending; ++ StorageDead(_3); ++ StorageDead(_4); + StorageDead(_5); -+ StorageDead(_8); -+ StorageDead(_23); -+ StorageDead(_24); -+ discriminant((*_27)) = 3; ++ StorageDead(_6); ++ StorageDead(_21); ++ StorageDead(_22); ++ discriminant((*_25)) = 3; + return; } bb8: { - StorageLive(_21); - _21 = copy ((_13 as Ready).0: u32); -- _0 = copy _21; -+ _25 = copy _21; - StorageDead(_21); - StorageDead(_13); - StorageDead(_12); -- drop(_10) -> [return: bb10, unwind: bb23]; -+ drop((((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb10, unwind: bb17]; + StorageLive(_19); + _19 = copy ((_11 as Ready).0: u32); +- _0 = copy _19; ++ _23 = copy _19; + StorageDead(_19); + StorageDead(_11); + StorageDead(_10); +- drop(_8) -> [return: bb10, unwind: bb23]; ++ drop((((*_25) as variant#3).0: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb10, unwind: bb17]; } bb9: { - StorageDead(_24); -- _2 = move _23; -+ _28 = move _23; - StorageDead(_23); - _11 = const (); + StorageDead(_22); +- _2 = move _21; ++ _26 = move _21; + StorageDead(_21); + _9 = const (); goto -> bb2; } bb10: { -- StorageDead(_10); +- StorageDead(_8); + nop; goto -> bb11; } bb11: { - StorageDead(_8); + StorageDead(_6); goto -> bb12; } bb12: { StorageDead(_5); -- StorageDead(_4); -- StorageDead(_3); + StorageDead(_4); + StorageDead(_3); - drop(_1) -> [return: bb13, unwind: bb28]; -+ nop; -+ nop; + goto -> bb13; } bb13: { -+ _0 = Poll::::Ready(move _25); -+ discriminant((*_27)) = 1; ++ _0 = Poll::::Ready(move _23); ++ discriminant((*_25)) = 1; return; } - bb14: { -- StorageDead(_24); -- StorageDead(_23); -- drop(_10) -> [return: bb15, unwind: bb29]; -+ bb14 (cleanup): { -+ StorageDead(_18); -+ StorageDead(_17); -+ goto -> bb16; - } - +- StorageDead(_22); +- StorageDead(_21); +- drop(_8) -> [return: bb15, unwind: bb29]; +- } +- - bb15: { -- StorageDead(_10); -+ bb15 (cleanup): { -+ StorageDead(_15); - goto -> bb16; - } - -- bb16: { - StorageDead(_8); +- goto -> bb16; +- } +- +- bb16: { +- StorageDead(_6); - goto -> bb17; -+ bb16 (cleanup): { -+ StorageDead(_16); -+ StorageDead(_14); -+ StorageDead(_13); -+ StorageDead(_12); -+ drop((((*_27) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb17, unwind terminate(cleanup)]; - } - +- } +- - bb17: { - StorageDead(_5); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb18, unwind: bb28]; -+ bb17 (cleanup): { -+ nop; -+ goto -> bb20; - } - +- } +- - bb18: { - coroutine_drop; -+ bb18 (cleanup): { -+ goto -> bb19; - } - - bb19 (cleanup): { -- StorageDead(_19); -+ StorageDead(_9); - goto -> bb20; - } - - bb20 (cleanup): { -- StorageDead(_18); +- } +- +- bb19 (cleanup): { - StorageDead(_17); +- goto -> bb20; +- } +- +- bb20 (cleanup): { ++ bb14 (cleanup): { + StorageDead(_16); + StorageDead(_15); - goto -> bb22; -+ StorageDead(_8); -+ goto -> bb21; ++ goto -> bb16; } - bb21 (cleanup): { -- StorageDead(_15); -+ StorageDead(_5); -+ nop; -+ nop; - goto -> bb22; +- bb21 (cleanup): { ++ bb15 (cleanup): { + StorageDead(_13); +- goto -> bb22; ++ goto -> bb16; } - bb22 (cleanup): { -- StorageDead(_16); -- StorageDead(_14); -- StorageDead(_13); -- StorageDead(_12); -- drop(_10) -> [return: bb23, unwind terminate(cleanup)]; -+ goto -> bb23; +- bb22 (cleanup): { ++ bb16 (cleanup): { + StorageDead(_14); + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); +- drop(_8) -> [return: bb23, unwind terminate(cleanup)]; ++ drop((((*_25) as variant#3).0: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb17, unwind terminate(cleanup)]; } - bb23 (cleanup): { -- StorageDead(_10); +- bb23 (cleanup): { +- StorageDead(_8); - goto -> bb26; -+ discriminant((*_27)) = 2; -+ resume; ++ bb17 (cleanup): { ++ nop; ++ goto -> bb20; } - bb24 (cleanup): { - goto -> bb25; -+ bb24: { -+ StorageLive(_5); -+ StorageLive(_8); -+ StorageLive(_23); -+ StorageLive(_24); -+ _23 = move _28; -+ goto -> bb9; ++ bb18 (cleanup): { ++ goto -> bb19; } - bb25 (cleanup): { -- StorageDead(_9); ++ bb19 (cleanup): { + StorageDead(_7); - goto -> bb26; -+ bb25: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb25, unwind continue]; ++ goto -> bb20; } - bb26 (cleanup): { -- StorageDead(_8); ++ bb20 (cleanup): { + StorageDead(_6); - goto -> bb27; -+ bb26: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb26, unwind continue]; ++ goto -> bb21; } - bb27 (cleanup): { -- StorageDead(_5); -- StorageDead(_4); -- StorageDead(_3); ++ bb21 (cleanup): { + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); - drop(_1) -> [return: bb28, unwind terminate(cleanup)]; -- } -- ++ goto -> bb22; + } + - bb28 (cleanup): { -- resume; -- } -- ++ bb22 (cleanup): { ++ goto -> bb23; ++ } ++ ++ bb23 (cleanup): { ++ discriminant((*_25)) = 2; + resume; + } + - bb29 (cleanup): { -- StorageDead(_10); +- StorageDead(_8); - goto -> bb30; -- } -- ++ bb24: { ++ StorageLive(_3); ++ StorageLive(_4); ++ StorageLive(_5); ++ StorageLive(_6); ++ StorageLive(_21); ++ StorageLive(_22); ++ _21 = move _26; ++ goto -> bb9; + } + - bb30 (cleanup): { -- StorageDead(_8); +- StorageDead(_6); - goto -> bb31; -- } -- ++ bb25: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb25, unwind continue]; + } + - bb31 (cleanup): { - StorageDead(_5); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb28, unwind terminate(cleanup)]; ++ bb26: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb26, unwind continue]; ++ } ++ + bb27: { -+ nop; -+ (((*_27) as variant#3).0: u32) = copy ((*_27).0: u32); -+ nop; -+ (((*_27) as variant#3).1: u32) = copy ((*_27).1: u32); ++ StorageLive(_3); ++ _3 = copy ((*_25).0: u32); ++ StorageLive(_4); ++ _4 = copy ((*_25).1: u32); + StorageLive(_5); ++ _5 = {coroutine@$DIR/async_fn.rs:34:13: 34:18 (#0)} { x: copy _3, y: copy _4 }; + StorageLive(_6); -+ _6 = &(((*_27) as variant#3).0: u32); + StorageLive(_7); -+ _7 = &(((*_27) as variant#3).1: u32); -+ _5 = {coroutine@$DIR/async_fn.rs:34:13: 34:18 (#0)} { x: move _6, y: move _7 }; -+ StorageDead(_7); -+ StorageDead(_6); -+ StorageLive(_8); -+ StorageLive(_9); -+ _9 = move _5; -+ _8 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as IntoFuture>::into_future(move _9) -> [return: bb1, unwind: bb18]; ++ _7 = move _5; ++ _6 = <{async block@$DIR/async_fn.rs:34:13: 34:18} as IntoFuture>::into_future(move _7) -> [return: bb1, unwind: bb18]; } } diff --git a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir index cd2092e97177a..45830890dc9b1 100644 --- a/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir +++ b/tests/mir-opt/coroutine/async_fn.add-{closure#0}.coroutine_drop.0.mir @@ -7,39 +7,37 @@ fn add::{closure#0}(_1: &mut {async fn body of add()}) -> () { let mut _0: (); let mut _2: std::future::ResumeTy; let _3: u32; - let mut _6: &u32; - let mut _7: &u32; - let mut _8: {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _9: {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _11: (); - let _12: (); - let mut _13: std::task::Poll; - let mut _14: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>; - let mut _15: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _16: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; - let mut _17: &mut std::task::Context<'_>; - let mut _18: &mut std::task::Context<'_>; - let mut _19: std::future::ResumeTy; - let mut _20: isize; - let mut _22: !; - let mut _23: std::future::ResumeTy; - let mut _24: (); - let mut _25: u32; - let mut _26: u32; + let mut _6: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _7: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _9: (); + let _10: (); + let mut _11: std::task::Poll; + let mut _12: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:34:13: 34:18}>; + let mut _13: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _14: &mut {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _15: &mut std::task::Context<'_>; + let mut _16: &mut std::task::Context<'_>; + let mut _17: std::future::ResumeTy; + let mut _18: isize; + let mut _20: !; + let mut _21: std::future::ResumeTy; + let mut _22: (); + let mut _23: u32; + let mut _24: u32; scope 1 { - debug x => (((*_1) as variant#3).0: u32); + debug x => _3; let _4: u32; scope 2 { - debug y => (((*_1) as variant#3).1: u32); + debug y => _4; let _5: {async block@$DIR/async_fn.rs:34:13: 34:18}; scope 3 { debug a => _5; - let mut _10: {async block@$DIR/async_fn.rs:34:13: 34:18}; + let mut _8: {async block@$DIR/async_fn.rs:34:13: 34:18}; scope 4 { - debug __awaitee => (((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18}); - let _21: u32; + debug __awaitee => (((*_1) as variant#3).0: {async block@$DIR/async_fn.rs:34:13: 34:18}); + let _19: u32; scope 5 { - debug result => _21; + debug result => _19; } } } @@ -47,14 +45,14 @@ fn add::{closure#0}(_1: &mut {async fn body of add()}) -> () { } bb0: { - _26 = discriminant((*_1)); - switchInt(move _26) -> [0: bb11, 3: bb12, otherwise: bb13]; + _24 = discriminant((*_1)); + switchInt(move _24) -> [0: bb11, 3: bb12, otherwise: bb13]; } bb1: { - StorageDead(_24); - StorageDead(_23); - drop((((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb2, unwind: bb7]; + StorageDead(_22); + StorageDead(_21); + drop((((*_1) as variant#3).0: {async block@$DIR/async_fn.rs:34:13: 34:18})) -> [return: bb2, unwind: bb7]; } bb2: { @@ -63,14 +61,14 @@ fn add::{closure#0}(_1: &mut {async fn body of add()}) -> () { } bb3: { - StorageDead(_8); + StorageDead(_6); goto -> bb4; } bb4: { StorageDead(_5); - nop; - nop; + StorageDead(_4); + StorageDead(_3); goto -> bb5; } @@ -88,14 +86,14 @@ fn add::{closure#0}(_1: &mut {async fn body of add()}) -> () { } bb8 (cleanup): { - StorageDead(_8); + StorageDead(_6); goto -> bb9; } bb9 (cleanup): { StorageDead(_5); - nop; - nop; + StorageDead(_4); + StorageDead(_3); goto -> bb6; } @@ -108,10 +106,12 @@ fn add::{closure#0}(_1: &mut {async fn body of add()}) -> () { } bb12: { + StorageLive(_3); + StorageLive(_4); StorageLive(_5); - StorageLive(_8); - StorageLive(_23); - StorageLive(_24); + StorageLive(_6); + StorageLive(_21); + StorageLive(_22); goto -> bb1; } diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff index 334b4e5dd526c..d4ae153f85e11 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.StateTransform.diff @@ -5,7 +5,7 @@ - yields () - { - debug _task_context => _2; -- debug x => (*(_1.0: &u32)); +- debug x => (_1.0: u32); - let mut _0: u32; + fn includes_never::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>, _2: &mut Context<'_>) -> Poll { + coroutine layout { @@ -16,40 +16,36 @@ + } + storage_conflicts = BitMatrix(0x0) {} + } -+ debug _task_context => _10; -+ debug x => (*((*_9).0: &u32)); ++ debug _task_context => _8; ++ debug x => ((*_7).0: u32); + let mut _0: std::task::Poll; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; -+ let mut _7: u32; -+ let mut _8: u32; -+ let mut _9: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; -+ let mut _10: std::future::ResumeTy; -+ let mut _11: std::ptr::NonNull>; ++ let mut _5: u32; ++ let mut _6: u32; ++ let mut _7: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; ++ let mut _8: std::future::ResumeTy; ++ let mut _9: std::ptr::NonNull>; bb0: { - StorageLive(_3); -- _5 = no_retag copy (_1.0: &u32); -- _3 = copy (*_5); +- _3 = copy (_1.0: u32); - StorageLive(_4); -- _6 = no_retag copy (_1.0: &u32); -- _4 = copy (*_6); +- _4 = copy (_1.0: u32); - _0 = Mul(move _3, move _4); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; -+ _11 = move _2 as std::ptr::NonNull> (Transmute); -+ _10 = std::future::ResumeTy(move _11); -+ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}); -+ _8 = discriminant((*_9)); -+ switchInt(move _8) -> [0: bb4, 1: bb2, otherwise: bb3]; ++ _9 = move _2 as std::ptr::NonNull> (Transmute); ++ _8 = std::future::ResumeTy(move _9); ++ _7 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}); ++ _6 = discriminant((*_7)); ++ switchInt(move _6) -> [0: bb4, 1: bb2, otherwise: bb3]; } bb1: { -+ _0 = Poll::::Ready(move _7); -+ discriminant((*_9)) = 1; ++ _0 = Poll::::Ready(move _5); ++ discriminant((*_7)) = 1; return; } @@ -65,12 +61,10 @@ + + bb4: { + StorageLive(_3); -+ _5 = no_retag copy ((*_9).0: &u32); -+ _3 = copy (*_5); ++ _3 = copy ((*_7).0: u32); + StorageLive(_4); -+ _6 = no_retag copy ((*_9).0: &u32); -+ _4 = copy (*_6); -+ _7 = Mul(move _3, move _4); ++ _4 = copy ((*_7).0: u32); ++ _5 = Mul(move _3, move _4); + StorageDead(_4); + StorageDead(_3); + goto -> bb1; diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir index 686b4323e0185..57db511b5a75b 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#0}.coroutine_drop.0.mir @@ -2,19 +2,17 @@ fn includes_never::{closure#0}::{closure#0}(_1: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}) -> () { debug _task_context => _2; - debug x => (*((*_1).0: &u32)); + debug x => ((*_1).0: u32); let mut _0: (); let mut _2: std::future::ResumeTy; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; - let mut _7: u32; - let mut _8: u32; + let mut _5: u32; + let mut _6: u32; bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb2, otherwise: bb3]; + _6 = discriminant((*_1)); + switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff index 7b73b8be0abe4..1cbe9a649b948 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.StateTransform.diff @@ -5,7 +5,7 @@ - yields () - { - debug _task_context => _2; -- debug x => (*(_1.0: &u32)); +- debug x => (_1.0: u32); - let mut _0: u32; + fn includes_never::{closure#0}::{closure#1}(_1: Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>, _2: &mut Context<'_>) -> Poll { + coroutine layout { @@ -16,40 +16,36 @@ + } + storage_conflicts = BitMatrix(0x0) {} + } -+ debug _task_context => _10; -+ debug x => (*((*_9).0: &u32)); ++ debug _task_context => _8; ++ debug x => ((*_7).0: u32); + let mut _0: std::task::Poll; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; -+ let mut _7: u32; -+ let mut _8: u32; -+ let mut _9: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; -+ let mut _10: std::future::ResumeTy; -+ let mut _11: std::ptr::NonNull>; ++ let mut _5: u32; ++ let mut _6: u32; ++ let mut _7: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; ++ let mut _8: std::future::ResumeTy; ++ let mut _9: std::ptr::NonNull>; bb0: { - StorageLive(_3); -- _5 = no_retag copy (_1.0: &u32); -- _3 = copy (*_5); +- _3 = copy (_1.0: u32); - StorageLive(_4); -- _6 = no_retag copy (_1.0: &u32); -- _4 = copy (*_6); +- _4 = copy (_1.0: u32); - _0 = Add(move _3, move _4); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; -+ _11 = move _2 as std::ptr::NonNull> (Transmute); -+ _10 = std::future::ResumeTy(move _11); -+ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}); -+ _8 = discriminant((*_9)); -+ switchInt(move _8) -> [0: bb4, 1: bb2, otherwise: bb3]; ++ _9 = move _2 as std::ptr::NonNull> (Transmute); ++ _8 = std::future::ResumeTy(move _9); ++ _7 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}); ++ _6 = discriminant((*_7)); ++ switchInt(move _6) -> [0: bb4, 1: bb2, otherwise: bb3]; } bb1: { -+ _0 = Poll::::Ready(move _7); -+ discriminant((*_9)) = 1; ++ _0 = Poll::::Ready(move _5); ++ discriminant((*_7)) = 1; return; } @@ -65,12 +61,10 @@ + + bb4: { + StorageLive(_3); -+ _5 = no_retag copy ((*_9).0: &u32); -+ _3 = copy (*_5); ++ _3 = copy ((*_7).0: u32); + StorageLive(_4); -+ _6 = no_retag copy ((*_9).0: &u32); -+ _4 = copy (*_6); -+ _7 = Add(move _3, move _4); ++ _4 = copy ((*_7).0: u32); ++ _5 = Add(move _3, move _4); + StorageDead(_4); + StorageDead(_3); + goto -> bb1; diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir index 3ae5c1dc89643..9031bc1dba182 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}-{closure#1}.coroutine_drop.0.mir @@ -2,19 +2,17 @@ fn includes_never::{closure#0}::{closure#1}(_1: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}) -> () { debug _task_context => _2; - debug x => (*((*_1).0: &u32)); + debug x => ((*_1).0: u32); let mut _0: (); let mut _2: std::future::ResumeTy; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; - let mut _7: u32; - let mut _8: u32; + let mut _5: u32; + let mut _6: u32; bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb2, otherwise: bb3]; + _6 = discriminant((*_1)); + switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff index 47aeaec0fa8fd..13f424cadc1e9 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.StateTransform.diff @@ -11,98 +11,93 @@ + fn includes_never::{closure#0}(_1: Pin<&mut {async fn body of includes_never()}>, _2: &mut Context<'_>) -> Poll { + coroutine layout { + field _s0: bool; -+ field _s1: u32; -+ field _s2: {async block@$DIR/async_fn.rs:61:18: 61:23}; ++ field _s1: {async block@$DIR/async_fn.rs:61:18: 61:23}; + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], -+ Suspend0 (3): [_s0, _s1, _s2], ++ Suspend0 (3): [_s0, _s1], + } -+ storage_conflicts = BitMatrix(3x3) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s2, _s0), (_s2, _s1), (_s2, _s2)} ++ storage_conflicts = BitMatrix(2x2) {(_s0, _s0), (_s0, _s1), (_s1, _s0), (_s1, _s1)} + } -+ debug _task_context => _51; -+ debug crash => ((*_50).0: bool); -+ debug x => ((*_50).1: u32); ++ debug _task_context => _49; ++ debug crash => ((*_48).0: bool); ++ debug x => ((*_48).1: u32); + coroutine debug crash => _s0; + let mut _0: std::task::Poll; let _3: bool; let mut _6: {async block@$DIR/async_fn.rs:61:18: 61:23}; let mut _7: {async block@$DIR/async_fn.rs:61:18: 61:23}; - let mut _8: &u32; - let mut _10: (); - let _11: (); - let mut _12: std::task::Poll; - let mut _13: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>; + let mut _9: (); + let _10: (); + let mut _11: std::task::Poll; + let mut _12: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>; + let mut _13: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; let mut _14: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; - let mut _15: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _15: &mut std::task::Context<'_>; let mut _16: &mut std::task::Context<'_>; - let mut _17: &mut std::task::Context<'_>; - let mut _18: std::future::ResumeTy; - let mut _19: isize; - let mut _21: !; - let mut _22: std::future::ResumeTy; - let mut _23: (); - let _24: (); - let mut _25: bool; - let mut _26: !; - let mut _28: u32; + let mut _17: std::future::ResumeTy; + let mut _18: isize; + let mut _20: !; + let mut _21: std::future::ResumeTy; + let mut _22: (); + let _23: (); + let mut _24: bool; + let mut _25: !; + let mut _27: u32; + let mut _28: {async block@$DIR/async_fn.rs:67:15: 67:20}; let mut _29: {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _30: {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _31: &u32; - let _33: (); - let mut _34: std::task::Poll; - let mut _35: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>; - let mut _36: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _37: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _38: &mut std::task::Context<'_>; - let mut _39: &mut std::task::Context<'_>; - let mut _40: std::future::ResumeTy; - let mut _41: isize; - let mut _43: !; - let mut _44: std::future::ResumeTy; - let mut _45: (); - let _46: (); - let mut _47: Never; -+ let mut _48: u32; -+ let mut _49: u32; -+ let mut _50: &mut {async fn body of includes_never()}; -+ let mut _51: std::future::ResumeTy; -+ let mut _52: std::ptr::NonNull>; + let _31: (); + let mut _32: std::task::Poll; + let mut _33: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>; + let mut _34: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _35: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _36: &mut std::task::Context<'_>; + let mut _37: &mut std::task::Context<'_>; + let mut _38: std::future::ResumeTy; + let mut _39: isize; + let mut _41: !; + let mut _42: std::future::ResumeTy; + let mut _43: (); + let _44: (); + let mut _45: Never; ++ let mut _46: u32; ++ let mut _47: u32; ++ let mut _48: &mut {async fn body of includes_never()}; ++ let mut _49: std::future::ResumeTy; ++ let mut _50: std::ptr::NonNull>; scope 1 { - debug crash => _3; -+ debug crash => (((*_50) as variant#3).0: bool); -+ coroutine debug x => _s1; ++ debug crash => (((*_48) as variant#3).0: bool); let _4: u32; scope 2 { -- debug x => _4; -+ debug x => (((*_50) as variant#3).1: u32); -+ coroutine debug __awaitee => _s2; + debug x => _4; ++ coroutine debug __awaitee => _s1; let _5: u32; - let mut _9: {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _8: {async block@$DIR/async_fn.rs:61:18: 61:23}; scope 3 { debug result => _5; scope 6 { - debug bad => _27; - let mut _32: {async block@$DIR/async_fn.rs:67:15: 67:20}; + debug bad => _26; + let mut _30: {async block@$DIR/async_fn.rs:67:15: 67:20}; scope 8 { - debug __awaitee => _32; - let _42: u32; + debug __awaitee => _30; + let _40: u32; scope 9 { - debug result => _42; + debug result => _40; } } } scope 7 { - let _27: Never; + let _26: Never; } } scope 4 { -- debug __awaitee => _9; -+ debug __awaitee => (((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}); - let _20: u32; +- debug __awaitee => _8; ++ debug __awaitee => (((*_48) as variant#3).1: {async block@$DIR/async_fn.rs:61:18: 61:23}); + let _19: u32; scope 5 { - debug result => _20; + debug result => _19; } } } @@ -116,68 +111,65 @@ - StorageLive(_5); - StorageLive(_6); - StorageLive(_7); -- StorageLive(_8); -- _8 = &_4; -- _7 = {coroutine@$DIR/async_fn.rs:61:18: 61:23 (#0)} { x: move _8 }; -- StorageDead(_8); +- _7 = {coroutine@$DIR/async_fn.rs:61:18: 61:23 (#0)} { x: copy _4 }; - _6 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as IntoFuture>::into_future(move _7) -> [return: bb1, unwind: bb25]; -+ _52 = move _2 as std::ptr::NonNull> (Transmute); -+ _51 = std::future::ResumeTy(move _52); -+ _50 = copy (_1.0: &mut {async fn body of includes_never()}); -+ _49 = discriminant((*_50)); -+ switchInt(move _49) -> [0: bb29, 1: bb28, 2: bb27, 3: bb26, otherwise: bb6]; ++ _50 = move _2 as std::ptr::NonNull> (Transmute); ++ _49 = std::future::ResumeTy(move _50); ++ _48 = copy (_1.0: &mut {async fn body of includes_never()}); ++ _47 = discriminant((*_48)); ++ switchInt(move _47) -> [0: bb29, 1: bb28, 2: bb27, 3: bb26, otherwise: bb6]; } bb1: { StorageDead(_7); PlaceMention(_6); -- StorageLive(_9); -- _9 = move _6; +- StorageLive(_8); +- _8 = move _6; + nop; -+ (((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}) = move _6; ++ (((*_48) as variant#3).1: {async block@$DIR/async_fn.rs:61:18: 61:23}) = move _6; goto -> bb2; } bb2: { + StorageLive(_10); StorageLive(_11); StorageLive(_12); StorageLive(_13); StorageLive(_14); - StorageLive(_15); -- _15 = &mut _9; -+ _15 = &mut (((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}); - _14 = &mut (*_15); -- _13 = Pin::<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>::new_unchecked(move _14) -> [return: bb3, unwind: bb22]; -+ _13 = Pin::<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>::new_unchecked(move _14) -> [return: bb3, unwind: bb17]; +- _14 = &mut _8; ++ _14 = &mut (((*_48) as variant#3).1: {async block@$DIR/async_fn.rs:61:18: 61:23}); + _13 = &mut (*_14); +- _12 = Pin::<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>::new_unchecked(move _13) -> [return: bb3, unwind: bb22]; ++ _12 = Pin::<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>::new_unchecked(move _13) -> [return: bb3, unwind: bb17]; } bb3: { - StorageDead(_14); + StorageDead(_13); + StorageLive(_15); StorageLive(_16); StorageLive(_17); - StorageLive(_18); -- _18 = copy _2; -- _17 = std::future::get_context::<'_, '_>(move _18) -> [return: bb4, unwind: bb20]; -+ _18 = copy _51; -+ _17 = copy (_18.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _17 = copy _2; +- _16 = std::future::get_context::<'_, '_>(move _17) -> [return: bb4, unwind: bb20]; ++ _17 = copy _49; ++ _16 = copy (_17.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb4; } bb4: { - _16 = &mut (*_17); - StorageDead(_18); -- _12 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as Future>::poll(move _13, move _16) -> [return: bb5, unwind: bb21]; -+ _12 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as Future>::poll(move _13, move _16) -> [return: bb5, unwind: bb16]; + _15 = &mut (*_16); + StorageDead(_17); +- _11 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as Future>::poll(move _12, move _15) -> [return: bb5, unwind: bb21]; ++ _11 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as Future>::poll(move _12, move _15) -> [return: bb5, unwind: bb16]; } bb5: { - StorageDead(_17); StorageDead(_16); StorageDead(_15); - StorageDead(_13); - PlaceMention(_12); - _19 = discriminant(_12); - switchInt(move _19) -> [0: bb8, 1: bb7, otherwise: bb6]; + StorageDead(_14); + StorageDead(_12); + PlaceMention(_11); + _18 = discriminant(_11); + switchInt(move _18) -> [0: bb8, 1: bb7, otherwise: bb6]; } bb6: { @@ -185,101 +177,101 @@ } bb7: { - _11 = const (); - StorageDead(_12); + _10 = const (); StorageDead(_11); + StorageDead(_10); + StorageLive(_21); StorageLive(_22); - StorageLive(_23); - _23 = (); -- _22 = yield(move _23) -> [resume: bb9, drop: bb15]; + _22 = (); +- _21 = yield(move _22) -> [resume: bb9, drop: bb15]; + _0 = Poll::::Pending; ++ StorageDead(_4); + StorageDead(_5); + StorageDead(_6); ++ StorageDead(_21); + StorageDead(_22); -+ StorageDead(_23); -+ discriminant((*_50)) = 3; ++ discriminant((*_48)) = 3; + return; } bb8: { - StorageLive(_20); - _20 = copy ((_12 as Ready).0: u32); - _5 = copy _20; - StorageDead(_20); - StorageDead(_12); + StorageLive(_19); + _19 = copy ((_11 as Ready).0: u32); + _5 = copy _19; + StorageDead(_19); StorageDead(_11); -- drop(_9) -> [return: bb10, unwind: bb24]; -+ drop((((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb10, unwind: bb19]; + StorageDead(_10); +- drop(_8) -> [return: bb10, unwind: bb24]; ++ drop((((*_48) as variant#3).1: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb10, unwind: bb19]; } bb9: { - StorageDead(_23); -- _2 = move _22; -+ _51 = move _22; StorageDead(_22); - _10 = const (); +- _2 = move _21; ++ _49 = move _21; + StorageDead(_21); + _9 = const (); goto -> bb2; } bb10: { -- StorageDead(_9); +- StorageDead(_8); + nop; goto -> bb11; } bb11: { StorageDead(_6); + StorageLive(_23); StorageLive(_24); - StorageLive(_25); -- _25 = copy _3; -+ _25 = copy (((*_50) as variant#3).0: bool); - switchInt(move _25) -> [0: bb12, otherwise: bb13]; +- _24 = copy _3; ++ _24 = copy (((*_48) as variant#3).0: bool); + switchInt(move _24) -> [0: bb12, otherwise: bb13]; } bb12: { - _0 = copy _5; -+ _48 = copy _5; - StorageDead(_25); ++ _46 = copy _5; StorageDead(_24); + StorageDead(_23); StorageDead(_5); -- StorageDead(_4); + StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb14, unwind: bb29]; + nop; -+ nop; + goto -> bb14; } bb13: { - _24 = const (); - StorageDead(_25); + _23 = const (); StorageDead(_24); - StorageLive(_27); -- _27 = never() -> bb19; -+ _27 = never() -> bb15; + StorageDead(_23); + StorageLive(_26); +- _26 = never() -> bb19; ++ _26 = never() -> bb15; } bb14: { -+ _0 = Poll::::Ready(move _48); -+ discriminant((*_50)) = 1; ++ _0 = Poll::::Ready(move _46); ++ discriminant((*_48)) = 1; return; } - bb15: { -- StorageDead(_23); - StorageDead(_22); -- drop(_9) -> [return: bb16, unwind: bb30]; +- StorageDead(_21); +- drop(_8) -> [return: bb16, unwind: bb30]; + bb15 (cleanup): { -+ StorageDead(_27); ++ StorageDead(_26); + goto -> bb23; } - bb16: { -- StorageDead(_9); +- StorageDead(_8); - goto -> bb17; + bb16 (cleanup): { -+ StorageDead(_17); + StorageDead(_16); ++ StorageDead(_15); + goto -> bb18; } @@ -290,67 +282,67 @@ - StorageDead(_3); - drop(_1) -> [return: bb18, unwind: bb29]; + bb17 (cleanup): { -+ StorageDead(_14); ++ StorageDead(_13); + goto -> bb18; } - bb18: { - coroutine_drop; + bb18 (cleanup): { -+ StorageDead(_15); -+ StorageDead(_13); ++ StorageDead(_14); + StorageDead(_12); + StorageDead(_11); -+ drop((((*_50) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb19, unwind terminate(cleanup)]; ++ StorageDead(_10); ++ drop((((*_48) as variant#3).1: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb19, unwind terminate(cleanup)]; } bb19 (cleanup): { -- StorageDead(_27); +- StorageDead(_26); - goto -> bb28; + nop; + goto -> bb22; } bb20 (cleanup): { -- StorageDead(_18); +- StorageDead(_17); goto -> bb21; } bb21 (cleanup): { -- StorageDead(_17); - StorageDead(_16); +- StorageDead(_15); - goto -> bb23; + StorageDead(_7); + goto -> bb22; } bb22 (cleanup): { -- StorageDead(_14); +- StorageDead(_13); + StorageDead(_6); goto -> bb23; } bb23 (cleanup): { -- StorageDead(_15); -- StorageDead(_13); +- StorageDead(_14); - StorageDead(_12); - StorageDead(_11); -- drop(_9) -> [return: bb24, unwind terminate(cleanup)]; +- StorageDead(_10); +- drop(_8) -> [return: bb24, unwind terminate(cleanup)]; + StorageDead(_5); -+ nop; ++ StorageDead(_4); + nop; + goto -> bb24; } bb24 (cleanup): { -- StorageDead(_9); +- StorageDead(_8); - goto -> bb27; + goto -> bb25; } bb25 (cleanup): { - goto -> bb26; -+ discriminant((*_50)) = 2; ++ discriminant((*_48)) = 2; + resume; } @@ -358,11 +350,12 @@ - StorageDead(_7); - goto -> bb27; + bb26: { ++ StorageLive(_4); + StorageLive(_5); + StorageLive(_6); ++ StorageLive(_21); + StorageLive(_22); -+ StorageLive(_23); -+ _22 = move _51; ++ _21 = move _49; + goto -> bb9; } @@ -387,7 +380,7 @@ - } - - bb30 (cleanup): { -- StorageDead(_9); +- StorageDead(_8); - goto -> bb31; - } - @@ -399,16 +392,13 @@ - drop(_1) -> [return: bb29, unwind terminate(cleanup)]; + bb29: { + nop; -+ (((*_50) as variant#3).0: bool) = copy ((*_50).0: bool); -+ nop; -+ (((*_50) as variant#3).1: u32) = copy ((*_50).1: u32); ++ (((*_48) as variant#3).0: bool) = copy ((*_48).0: bool); ++ StorageLive(_4); ++ _4 = copy ((*_48).1: u32); + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); -+ StorageLive(_8); -+ _8 = &(((*_50) as variant#3).1: u32); -+ _7 = {coroutine@$DIR/async_fn.rs:61:18: 61:23 (#0)} { x: move _8 }; -+ StorageDead(_8); ++ _7 = {coroutine@$DIR/async_fn.rs:61:18: 61:23 (#0)} { x: copy _4 }; + _6 = <{async block@$DIR/async_fn.rs:61:18: 61:23} as IntoFuture>::into_future(move _7) -> [return: bb1, unwind: bb20]; } } diff --git a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir index 97fdec425898f..1d3c3ecb9f68a 100644 --- a/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir +++ b/tests/mir-opt/coroutine/async_fn.includes_never-{closure#0}.coroutine_drop.0.mir @@ -9,86 +9,84 @@ fn includes_never::{closure#0}(_1: &mut {async fn body of includes_never()}) -> let _3: bool; let mut _6: {async block@$DIR/async_fn.rs:61:18: 61:23}; let mut _7: {async block@$DIR/async_fn.rs:61:18: 61:23}; - let mut _8: &u32; - let mut _10: (); - let _11: (); - let mut _12: std::task::Poll; - let mut _13: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>; + let mut _9: (); + let _10: (); + let mut _11: std::task::Poll; + let mut _12: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:61:18: 61:23}>; + let mut _13: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; let mut _14: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; - let mut _15: &mut {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _15: &mut std::task::Context<'_>; let mut _16: &mut std::task::Context<'_>; - let mut _17: &mut std::task::Context<'_>; - let mut _18: std::future::ResumeTy; - let mut _19: isize; - let mut _21: !; - let mut _22: std::future::ResumeTy; - let mut _23: (); - let _24: (); - let mut _25: bool; - let mut _26: !; - let mut _28: u32; + let mut _17: std::future::ResumeTy; + let mut _18: isize; + let mut _20: !; + let mut _21: std::future::ResumeTy; + let mut _22: (); + let _23: (); + let mut _24: bool; + let mut _25: !; + let mut _27: u32; + let mut _28: {async block@$DIR/async_fn.rs:67:15: 67:20}; let mut _29: {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _30: {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _31: &u32; - let _33: (); - let mut _34: std::task::Poll; - let mut _35: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>; - let mut _36: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _37: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; - let mut _38: &mut std::task::Context<'_>; - let mut _39: &mut std::task::Context<'_>; - let mut _40: std::future::ResumeTy; - let mut _41: isize; - let mut _43: !; - let mut _44: std::future::ResumeTy; - let mut _45: (); - let _46: (); - let mut _47: Never; - let mut _48: u32; - let mut _49: u32; + let _31: (); + let mut _32: std::task::Poll; + let mut _33: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:67:15: 67:20}>; + let mut _34: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _35: &mut {async block@$DIR/async_fn.rs:67:15: 67:20}; + let mut _36: &mut std::task::Context<'_>; + let mut _37: &mut std::task::Context<'_>; + let mut _38: std::future::ResumeTy; + let mut _39: isize; + let mut _41: !; + let mut _42: std::future::ResumeTy; + let mut _43: (); + let _44: (); + let mut _45: Never; + let mut _46: u32; + let mut _47: u32; scope 1 { debug crash => (((*_1) as variant#3).0: bool); let _4: u32; scope 2 { - debug x => (((*_1) as variant#3).1: u32); + debug x => _4; let _5: u32; - let mut _9: {async block@$DIR/async_fn.rs:61:18: 61:23}; + let mut _8: {async block@$DIR/async_fn.rs:61:18: 61:23}; scope 3 { debug result => _5; scope 6 { - debug bad => _27; - let mut _32: {async block@$DIR/async_fn.rs:67:15: 67:20}; + debug bad => _26; + let mut _30: {async block@$DIR/async_fn.rs:67:15: 67:20}; scope 8 { - debug __awaitee => _32; - let _42: u32; + debug __awaitee => _30; + let _40: u32; scope 9 { - debug result => _42; + debug result => _40; } } } scope 7 { - let _27: Never; + let _26: Never; } } scope 4 { - debug __awaitee => (((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23}); - let _20: u32; + debug __awaitee => (((*_1) as variant#3).1: {async block@$DIR/async_fn.rs:61:18: 61:23}); + let _19: u32; scope 5 { - debug result => _20; + debug result => _19; } } } } bb0: { - _49 = discriminant((*_1)); - switchInt(move _49) -> [0: bb9, 3: bb10, otherwise: bb11]; + _47 = discriminant((*_1)); + switchInt(move _47) -> [0: bb9, 3: bb10, otherwise: bb11]; } bb1: { - StorageDead(_23); StorageDead(_22); - drop((((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb2, unwind: bb6]; + StorageDead(_21); + drop((((*_1) as variant#3).1: {async block@$DIR/async_fn.rs:61:18: 61:23})) -> [return: bb2, unwind: bb6]; } bb2: { @@ -99,7 +97,7 @@ fn includes_never::{closure#0}(_1: &mut {async fn body of includes_never()}) -> bb3: { StorageDead(_6); StorageDead(_5); - nop; + StorageDead(_4); nop; goto -> bb4; } @@ -120,7 +118,7 @@ fn includes_never::{closure#0}(_1: &mut {async fn body of includes_never()}) -> bb7 (cleanup): { StorageDead(_6); StorageDead(_5); - nop; + StorageDead(_4); nop; goto -> bb5; } @@ -134,10 +132,11 @@ fn includes_never::{closure#0}(_1: &mut {async fn body of includes_never()}) -> } bb10: { + StorageLive(_4); StorageLive(_5); StorageLive(_6); + StorageLive(_21); StorageLive(_22); - StorageLive(_23); goto -> bb1; } diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff index 1b02ab76a443e..3b32fff860a3f 100644 --- a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.StateTransform.diff @@ -5,7 +5,7 @@ - yields () - { - debug _task_context => _2; -- debug x => (*(_1.0: &u32)); +- debug x => (_1.0: u32); - let mut _0: u32; + fn partial_init::{closure#0}::{closure#0}(_1: Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>, _2: &mut Context<'_>) -> Poll { + coroutine layout { @@ -16,40 +16,36 @@ + } + storage_conflicts = BitMatrix(0x0) {} + } -+ debug _task_context => _10; -+ debug x => (*((*_9).0: &u32)); ++ debug _task_context => _8; ++ debug x => ((*_7).0: u32); + let mut _0: std::task::Poll; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; -+ let mut _7: u32; -+ let mut _8: u32; -+ let mut _9: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; -+ let mut _10: std::future::ResumeTy; -+ let mut _11: std::ptr::NonNull>; ++ let mut _5: u32; ++ let mut _6: u32; ++ let mut _7: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; ++ let mut _8: std::future::ResumeTy; ++ let mut _9: std::ptr::NonNull>; bb0: { - StorageLive(_3); -- _5 = no_retag copy (_1.0: &u32); -- _3 = copy (*_5); +- _3 = copy (_1.0: u32); - StorageLive(_4); -- _6 = no_retag copy (_1.0: &u32); -- _4 = copy (*_6); +- _4 = copy (_1.0: u32); - _0 = Add(move _3, move _4); - StorageDead(_4); - StorageDead(_3); - drop(_1) -> [return: bb1, unwind: bb2]; -+ _11 = move _2 as std::ptr::NonNull> (Transmute); -+ _10 = std::future::ResumeTy(move _11); -+ _9 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}); -+ _8 = discriminant((*_9)); -+ switchInt(move _8) -> [0: bb4, 1: bb2, otherwise: bb3]; ++ _9 = move _2 as std::ptr::NonNull> (Transmute); ++ _8 = std::future::ResumeTy(move _9); ++ _7 = copy (_1.0: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}); ++ _6 = discriminant((*_7)); ++ switchInt(move _6) -> [0: bb4, 1: bb2, otherwise: bb3]; } bb1: { -+ _0 = Poll::::Ready(move _7); -+ discriminant((*_9)) = 1; ++ _0 = Poll::::Ready(move _5); ++ discriminant((*_7)) = 1; return; } @@ -65,12 +61,10 @@ + + bb4: { + StorageLive(_3); -+ _5 = no_retag copy ((*_9).0: &u32); -+ _3 = copy (*_5); ++ _3 = copy ((*_7).0: u32); + StorageLive(_4); -+ _6 = no_retag copy ((*_9).0: &u32); -+ _4 = copy (*_6); -+ _7 = Add(move _3, move _4); ++ _4 = copy ((*_7).0: u32); ++ _5 = Add(move _3, move _4); + StorageDead(_4); + StorageDead(_3); + goto -> bb1; diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir index 7a21ec09f8a10..f6fe0a302bd63 100644 --- a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}-{closure#0}.coroutine_drop.0.mir @@ -2,19 +2,17 @@ fn partial_init::{closure#0}::{closure#0}(_1: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}) -> () { debug _task_context => _2; - debug x => (*((*_1).0: &u32)); + debug x => ((*_1).0: u32); let mut _0: (); let mut _2: std::future::ResumeTy; let mut _3: u32; let mut _4: u32; - let mut _5: &u32; - let mut _6: &u32; - let mut _7: u32; - let mut _8: u32; + let mut _5: u32; + let mut _6: u32; bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb2, otherwise: bb3]; + _6 = discriminant((*_1)); + switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb1: { diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff index 11939da81cad4..e709c6187fc7d 100644 --- a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.StateTransform.diff @@ -9,20 +9,18 @@ - let mut _0: u32; + fn partial_init::{closure#0}(_1: Pin<&mut {async fn body of partial_init()}>, _2: &mut Context<'_>) -> Poll { + coroutine layout { -+ field _s0: u32; -+ field _s1: String; -+ field _s2: {async block@$DIR/async_fn.rs:80:50: 80:55}; ++ field _s0: String; ++ field _s1: {async block@$DIR/async_fn.rs:80:50: 80:55}; + variant_fields = { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], -+ Suspend0 (3): [_s0, _s1, _s2], ++ Suspend0 (3): [_s0, _s1], + } -+ storage_conflicts = BitMatrix(3x3) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s2, _s0), (_s2, _s1), (_s2, _s2)} ++ storage_conflicts = BitMatrix(2x2) {(_s0, _s0), (_s0, _s1), (_s1, _s0), (_s1, _s1)} + } -+ debug _task_context => _29; -+ debug x => ((*_28).0: u32); -+ coroutine debug x => _s0; ++ debug _task_context => _28; ++ debug x => ((*_27).0: u32); + let mut _0: std::task::Poll; let _3: u32; let mut _4: !; @@ -30,41 +28,39 @@ let mut _7: !; let mut _8: {async block@$DIR/async_fn.rs:80:50: 80:55}; let mut _9: {async block@$DIR/async_fn.rs:80:50: 80:55}; - let mut _10: &u32; - let mut _12: (); - let _13: (); - let mut _14: std::task::Poll; - let mut _15: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>; + let mut _11: (); + let _12: (); + let mut _13: std::task::Poll; + let mut _14: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>; + let mut _15: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; let mut _16: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; - let mut _17: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _17: &mut std::task::Context<'_>; let mut _18: &mut std::task::Context<'_>; - let mut _19: &mut std::task::Context<'_>; - let mut _20: std::future::ResumeTy; - let mut _21: isize; - let mut _23: !; - let mut _24: std::future::ResumeTy; - let mut _25: (); + let mut _19: std::future::ResumeTy; + let mut _20: isize; + let mut _22: !; + let mut _23: std::future::ResumeTy; + let mut _24: (); ++ let mut _25: u32; + let mut _26: u32; -+ let mut _27: u32; -+ let mut _28: &mut {async fn body of partial_init()}; -+ let mut _29: std::future::ResumeTy; -+ let mut _30: std::ptr::NonNull>; ++ let mut _27: &mut {async fn body of partial_init()}; ++ let mut _28: std::future::ResumeTy; ++ let mut _29: std::ptr::NonNull>; scope 1 { -- debug x => _3; -+ debug x => (((*_28) as variant#3).0: u32); + debug x => _3; scope 2 { debug _x => _5; } scope 3 { -+ coroutine debug __awaitee => _s2; ++ coroutine debug __awaitee => _s1; let _5: (std::string::String, !); - let mut _11: {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _10: {async block@$DIR/async_fn.rs:80:50: 80:55}; scope 4 { -- debug __awaitee => _11; -+ debug __awaitee => (((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}); - let _22: u32; +- debug __awaitee => _10; ++ debug __awaitee => (((*_27) as variant#3).1: {async block@$DIR/async_fn.rs:80:50: 80:55}); + let _21: u32; scope 5 { - debug result => _22; + debug result => _21; } } } @@ -77,21 +73,17 @@ - StorageLive(_5); - StorageLive(_6); - _6 = String::new() -> [return: bb1, unwind: bb30]; -+ _30 = move _2 as std::ptr::NonNull> (Transmute); -+ _29 = std::future::ResumeTy(move _30); -+ _28 = copy (_1.0: &mut {async fn body of partial_init()}); -+ _27 = discriminant((*_28)); -+ switchInt(move _27) -> [0: bb31, 1: bb30, 2: bb29, 3: bb28, otherwise: bb7]; ++ _29 = move _2 as std::ptr::NonNull> (Transmute); ++ _28 = std::future::ResumeTy(move _29); ++ _27 = copy (_1.0: &mut {async fn body of partial_init()}); ++ _26 = discriminant((*_27)); ++ switchInt(move _26) -> [0: bb31, 1: bb30, 2: bb29, 3: bb28, otherwise: bb7]; } bb1: { StorageLive(_8); StorageLive(_9); - StorageLive(_10); -- _10 = &_3; -+ _10 = &(((*_28) as variant#3).0: u32); - _9 = {coroutine@$DIR/async_fn.rs:80:50: 80:55 (#0)} { x: move _10 }; - StorageDead(_10); + _9 = {coroutine@$DIR/async_fn.rs:80:50: 80:55 (#0)} { x: copy _3 }; - _8 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as IntoFuture>::into_future(move _9) -> [return: bb2, unwind: bb26]; + _8 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as IntoFuture>::into_future(move _9) -> [return: bb2, unwind: bb20]; } @@ -99,53 +91,53 @@ bb2: { StorageDead(_9); PlaceMention(_8); -- StorageLive(_11); -- _11 = move _8; +- StorageLive(_10); +- _10 = move _8; + nop; -+ (((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}) = move _8; ++ (((*_27) as variant#3).1: {async block@$DIR/async_fn.rs:80:50: 80:55}) = move _8; goto -> bb3; } bb3: { + StorageLive(_12); StorageLive(_13); StorageLive(_14); StorageLive(_15); StorageLive(_16); - StorageLive(_17); -- _17 = &mut _11; -+ _17 = &mut (((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}); - _16 = &mut (*_17); -- _15 = Pin::<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>::new_unchecked(move _16) -> [return: bb4, unwind: bb22]; -+ _15 = Pin::<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>::new_unchecked(move _16) -> [return: bb4, unwind: bb16]; +- _16 = &mut _10; ++ _16 = &mut (((*_27) as variant#3).1: {async block@$DIR/async_fn.rs:80:50: 80:55}); + _15 = &mut (*_16); +- _14 = Pin::<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>::new_unchecked(move _15) -> [return: bb4, unwind: bb22]; ++ _14 = Pin::<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>::new_unchecked(move _15) -> [return: bb4, unwind: bb16]; } bb4: { - StorageDead(_16); + StorageDead(_15); + StorageLive(_17); StorageLive(_18); StorageLive(_19); - StorageLive(_20); -- _20 = copy _2; -- _19 = std::future::get_context::<'_, '_>(move _20) -> [return: bb5, unwind: bb20]; -+ _20 = copy _29; -+ _19 = copy (_20.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _19 = copy _2; +- _18 = std::future::get_context::<'_, '_>(move _19) -> [return: bb5, unwind: bb20]; ++ _19 = copy _28; ++ _18 = copy (_19.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb5; } bb5: { - _18 = &mut (*_19); - StorageDead(_20); -- _14 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as Future>::poll(move _15, move _18) -> [return: bb6, unwind: bb21]; -+ _14 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as Future>::poll(move _15, move _18) -> [return: bb6, unwind: bb15]; + _17 = &mut (*_18); + StorageDead(_19); +- _13 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as Future>::poll(move _14, move _17) -> [return: bb6, unwind: bb21]; ++ _13 = <{async block@$DIR/async_fn.rs:80:50: 80:55} as Future>::poll(move _14, move _17) -> [return: bb6, unwind: bb15]; } bb6: { - StorageDead(_19); StorageDead(_18); StorageDead(_17); - StorageDead(_15); - PlaceMention(_14); - _21 = discriminant(_14); - switchInt(move _21) -> [0: bb9, 1: bb8, otherwise: bb7]; + StorageDead(_16); + StorageDead(_14); + PlaceMention(_13); + _20 = discriminant(_13); + switchInt(move _20) -> [0: bb9, 1: bb8, otherwise: bb7]; } bb7: { @@ -153,49 +145,50 @@ } bb8: { - _13 = const (); - StorageDead(_14); + _12 = const (); StorageDead(_13); + StorageDead(_12); + StorageLive(_23); StorageLive(_24); - StorageLive(_25); - _25 = (); -- _24 = yield(move _25) -> [resume: bb10, drop: bb15]; + _24 = (); +- _23 = yield(move _24) -> [resume: bb10, drop: bb15]; + _0 = Poll::::Pending; ++ StorageDead(_3); + StorageDead(_4); + StorageDead(_5); + StorageDead(_8); ++ StorageDead(_23); + StorageDead(_24); -+ StorageDead(_25); -+ discriminant((*_28)) = 3; ++ discriminant((*_27)) = 3; + return; } bb9: { - StorageLive(_22); - _22 = copy ((_14 as Ready).0: u32); -- _0 = copy _22; -+ _26 = copy _22; - StorageDead(_22); - StorageDead(_14); + StorageLive(_21); + _21 = copy ((_13 as Ready).0: u32); +- _0 = copy _21; ++ _25 = copy _21; + StorageDead(_21); StorageDead(_13); -- drop(_11) -> [return: bb11, unwind: bb24]; -+ drop((((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb11, unwind: bb18]; + StorageDead(_12); +- drop(_10) -> [return: bb11, unwind: bb24]; ++ drop((((*_27) as variant#3).1: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb11, unwind: bb18]; } bb10: { - StorageDead(_25); -- _2 = move _24; -+ _29 = move _24; StorageDead(_24); - _12 = const (); +- _2 = move _23; ++ _28 = move _23; + StorageDead(_23); + _11 = const (); goto -> bb3; } bb11: { -- StorageDead(_11); +- StorageDead(_10); - drop(_6) -> [return: bb12, unwind: bb25]; + nop; -+ drop((((*_28) as variant#3).1: std::string::String)) -> [return: bb12, unwind: bb19]; ++ drop((((*_27) as variant#3).0: std::string::String)) -> [return: bb12, unwind: bb19]; } bb12: { @@ -208,33 +201,32 @@ StorageDead(_8); StorageDead(_5); StorageDead(_4); -- StorageDead(_3); + StorageDead(_3); - drop(_1) -> [return: bb14, unwind: bb32]; -+ nop; + goto -> bb14; } bb14: { -+ _0 = Poll::::Ready(move _26); -+ discriminant((*_28)) = 1; ++ _0 = Poll::::Ready(move _25); ++ discriminant((*_27)) = 1; return; } - bb15: { -- StorageDead(_25); - StorageDead(_24); -- drop(_11) -> [return: bb16, unwind: bb33]; +- StorageDead(_23); +- drop(_10) -> [return: bb16, unwind: bb33]; + bb15 (cleanup): { -+ StorageDead(_19); + StorageDead(_18); ++ StorageDead(_17); + goto -> bb17; } - bb16: { -- StorageDead(_11); +- StorageDead(_10); - drop(_6) -> [return: bb17, unwind: bb34]; + bb16 (cleanup): { -+ StorageDead(_16); ++ StorageDead(_15); + goto -> bb17; } @@ -242,11 +234,11 @@ - StorageDead(_6); - goto -> bb18; + bb17 (cleanup): { -+ StorageDead(_17); -+ StorageDead(_15); ++ StorageDead(_16); + StorageDead(_14); + StorageDead(_13); -+ drop((((*_28) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb18, unwind terminate(cleanup)]; ++ StorageDead(_12); ++ drop((((*_27) as variant#3).1: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb18, unwind terminate(cleanup)]; } - bb18: { @@ -257,7 +249,7 @@ - drop(_1) -> [return: bb19, unwind: bb32]; + bb18 (cleanup): { + nop; -+ drop((((*_28) as variant#3).1: std::string::String)) -> [return: bb19, unwind terminate(cleanup)]; ++ drop((((*_27) as variant#3).0: std::string::String)) -> [return: bb19, unwind terminate(cleanup)]; } - bb19: { @@ -268,36 +260,36 @@ } bb20 (cleanup): { -- StorageDead(_20); +- StorageDead(_19); goto -> bb21; } bb21 (cleanup): { -- StorageDead(_19); - StorageDead(_18); +- StorageDead(_17); - goto -> bb23; + StorageDead(_9); -+ drop((((*_28) as variant#3).1: std::string::String)) -> [return: bb22, unwind terminate(cleanup)]; ++ drop((((*_27) as variant#3).0: std::string::String)) -> [return: bb22, unwind terminate(cleanup)]; } bb22 (cleanup): { -- StorageDead(_16); +- StorageDead(_15); + nop; goto -> bb23; } bb23 (cleanup): { -- StorageDead(_17); -- StorageDead(_15); +- StorageDead(_16); - StorageDead(_14); - StorageDead(_13); -- drop(_11) -> [return: bb24, unwind terminate(cleanup)]; +- StorageDead(_12); +- drop(_10) -> [return: bb24, unwind terminate(cleanup)]; + StorageDead(_8); + goto -> bb25; } bb24 (cleanup): { -- StorageDead(_11); +- StorageDead(_10); - drop(_6) -> [return: bb25, unwind terminate(cleanup)]; + nop; + goto -> bb25; @@ -308,7 +300,7 @@ - goto -> bb29; + StorageDead(_5); + StorageDead(_4); -+ nop; ++ StorageDead(_3); + goto -> bb26; } @@ -319,7 +311,7 @@ bb27 (cleanup): { - StorageDead(_9); - drop(_6) -> [return: bb28, unwind terminate(cleanup)]; -+ discriminant((*_28)) = 2; ++ discriminant((*_27)) = 2; + resume; } @@ -327,12 +319,13 @@ - StorageDead(_6); - goto -> bb29; + bb28: { ++ StorageLive(_3); + StorageLive(_4); + StorageLive(_5); + StorageLive(_8); ++ StorageLive(_23); + StorageLive(_24); -+ StorageLive(_25); -+ _24 = move _29; ++ _23 = move _28; + goto -> bb10; } @@ -362,7 +355,7 @@ - } - - bb33 (cleanup): { -- StorageDead(_11); +- StorageDead(_10); - drop(_6) -> [return: bb34, unwind terminate(cleanup)]; - } - @@ -378,12 +371,12 @@ - StorageDead(_3); - drop(_1) -> [return: bb32, unwind terminate(cleanup)]; + bb31: { -+ nop; -+ (((*_28) as variant#3).0: u32) = copy ((*_28).0: u32); ++ StorageLive(_3); ++ _3 = copy ((*_27).0: u32); + StorageLive(_4); + StorageLive(_5); + nop; -+ (((*_28) as variant#3).1: std::string::String) = String::new() -> [return: bb1, unwind: bb24]; ++ (((*_27) as variant#3).0: std::string::String) = String::new() -> [return: bb1, unwind: bb24]; } } diff --git a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir index c76b3ca617f76..65c8f7f877ef3 100644 --- a/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir +++ b/tests/mir-opt/coroutine/async_fn.partial_init-{closure#0}.coroutine_drop.0.mir @@ -11,54 +11,53 @@ fn partial_init::{closure#0}(_1: &mut {async fn body of partial_init()}) -> () { let mut _7: !; let mut _8: {async block@$DIR/async_fn.rs:80:50: 80:55}; let mut _9: {async block@$DIR/async_fn.rs:80:50: 80:55}; - let mut _10: &u32; - let mut _12: (); - let _13: (); - let mut _14: std::task::Poll; - let mut _15: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>; + let mut _11: (); + let _12: (); + let mut _13: std::task::Poll; + let mut _14: std::pin::Pin<&mut {async block@$DIR/async_fn.rs:80:50: 80:55}>; + let mut _15: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; let mut _16: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; - let mut _17: &mut {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _17: &mut std::task::Context<'_>; let mut _18: &mut std::task::Context<'_>; - let mut _19: &mut std::task::Context<'_>; - let mut _20: std::future::ResumeTy; - let mut _21: isize; - let mut _23: !; - let mut _24: std::future::ResumeTy; - let mut _25: (); + let mut _19: std::future::ResumeTy; + let mut _20: isize; + let mut _22: !; + let mut _23: std::future::ResumeTy; + let mut _24: (); + let mut _25: u32; let mut _26: u32; - let mut _27: u32; scope 1 { - debug x => (((*_1) as variant#3).0: u32); + debug x => _3; scope 2 { debug _x => _5; } scope 3 { let _5: (std::string::String, !); - let mut _11: {async block@$DIR/async_fn.rs:80:50: 80:55}; + let mut _10: {async block@$DIR/async_fn.rs:80:50: 80:55}; scope 4 { - debug __awaitee => (((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55}); - let _22: u32; + debug __awaitee => (((*_1) as variant#3).1: {async block@$DIR/async_fn.rs:80:50: 80:55}); + let _21: u32; scope 5 { - debug result => _22; + debug result => _21; } } } } bb0: { - _27 = discriminant((*_1)); - switchInt(move _27) -> [0: bb11, 3: bb12, otherwise: bb13]; + _26 = discriminant((*_1)); + switchInt(move _26) -> [0: bb11, 3: bb12, otherwise: bb13]; } bb1: { - StorageDead(_25); StorageDead(_24); - drop((((*_1) as variant#3).2: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb2, unwind: bb7]; + StorageDead(_23); + drop((((*_1) as variant#3).1: {async block@$DIR/async_fn.rs:80:50: 80:55})) -> [return: bb2, unwind: bb7]; } bb2: { nop; - drop((((*_1) as variant#3).1: std::string::String)) -> [return: bb3, unwind: bb8]; + drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb3, unwind: bb8]; } bb3: { @@ -70,7 +69,7 @@ fn partial_init::{closure#0}(_1: &mut {async fn body of partial_init()}) -> () { StorageDead(_8); StorageDead(_5); StorageDead(_4); - nop; + StorageDead(_3); goto -> bb5; } @@ -84,7 +83,7 @@ fn partial_init::{closure#0}(_1: &mut {async fn body of partial_init()}) -> () { bb7 (cleanup): { nop; - drop((((*_1) as variant#3).1: std::string::String)) -> [return: bb8, unwind terminate(cleanup)]; + drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb8, unwind terminate(cleanup)]; } bb8 (cleanup): { @@ -96,7 +95,7 @@ fn partial_init::{closure#0}(_1: &mut {async fn body of partial_init()}) -> () { StorageDead(_8); StorageDead(_5); StorageDead(_4); - nop; + StorageDead(_3); goto -> bb6; } @@ -109,11 +108,12 @@ fn partial_init::{closure#0}(_1: &mut {async fn body of partial_init()}) -> () { } bb12: { + StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_8); + StorageLive(_23); StorageLive(_24); - StorageLive(_25); goto -> bb1; } diff --git a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index 38d9fc4cfd567..0b18357d2e559 100644 --- a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir +++ b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -5,56 +5,40 @@ fn foo(_1: T, _2: i32) -> (i32, T) { debug q => _2; let mut _0: (i32, T); let _3: {closure@foo::{closure#0}}; - let mut _4: &i32; - let mut _5: &T; - let mut _6: &{closure@foo::{closure#0}}; - let mut _7: (i32,); - let mut _8: i32; - let mut _9: i32; + let mut _4: &{closure@foo::{closure#0}}; + let mut _5: (i32,); + let mut _6: i32; + let mut _7: i32; scope 1 { debug x => _3; scope 2 (inlined foo::::{closure#0}) { - let mut _10: &i32; - let mut _11: i32; - let mut _12: &T; - let mut _13: T; + let mut _8: i32; + let mut _9: T; } } bb0: { StorageLive(_3); + _3 = {closure@foo::::{closure#0}} { q: copy _2, t: copy _1 }; StorageLive(_4); - _4 = &_2; + _4 = &_3; StorageLive(_5); - _5 = &_1; - _3 = {closure@foo::::{closure#0}} { q: move _4, t: move _5 }; - StorageDead(_5); - StorageDead(_4); StorageLive(_6); - _6 = &_3; + _6 = copy _2; + _5 = (move _6,); StorageLive(_7); + _7 = move (_5.0: i32); StorageLive(_8); - _8 = copy _2; - _7 = (move _8,); + _8 = copy ((*_4).0: i32); StorageLive(_9); - _9 = move (_7.0: i32); - StorageLive(_10); - StorageLive(_12); - StorageLive(_11); - _10 = no_retag copy ((*_6).0: &i32); - _11 = copy (*_10); - StorageLive(_13); - _12 = no_retag copy ((*_6).1: &T); - _13 = copy (*_12); - _0 = (move _11, move _13); - StorageDead(_13); - StorageDead(_11); - StorageDead(_12); - StorageDead(_10); + _9 = copy ((*_4).1: T); + _0 = (move _8, move _9); StorageDead(_9); StorageDead(_8); StorageDead(_7); StorageDead(_6); + StorageDead(_5); + StorageDead(_4); StorageDead(_3); return; } diff --git a/tests/ui/async-await/async-borrowck-escaping-block-error.fixed b/tests/ui/async-await/async-borrowck-escaping-block-error.fixed index 0b926bcb28681..521041247524e 100644 --- a/tests/ui/async-await/async-borrowck-escaping-block-error.fixed +++ b/tests/ui/async-await/async-borrowck-escaping-block-error.fixed @@ -3,16 +3,21 @@ fn test_boxed() -> Box> { let x = 0u32; - Box::new(async move { x } ) + Box::new(async move { *&x }) //~^ ERROR E0373 } +fn test_boxed_works() -> Box> { + let x = 0u32; + Box::new(async { x }) +} + fn test_ref(x: &u32) -> impl std::future::Future + '_ { - async move { *x } - //~^ ERROR E0373 + async { *x } } fn main() { let _ = test_boxed(); + let _ = test_boxed_works(); let _ = test_ref(&0u32); } diff --git a/tests/ui/async-await/async-borrowck-escaping-block-error.rs b/tests/ui/async-await/async-borrowck-escaping-block-error.rs index d3e47c5579b96..b54d6242fa632 100644 --- a/tests/ui/async-await/async-borrowck-escaping-block-error.rs +++ b/tests/ui/async-await/async-borrowck-escaping-block-error.rs @@ -3,16 +3,21 @@ fn test_boxed() -> Box> { let x = 0u32; - Box::new(async { x } ) + Box::new(async { *&x }) //~^ ERROR E0373 } +fn test_boxed_works() -> Box> { + let x = 0u32; + Box::new(async { x }) +} + fn test_ref(x: &u32) -> impl std::future::Future + '_ { async { *x } - //~^ ERROR E0373 } fn main() { let _ = test_boxed(); + let _ = test_boxed_works(); let _ = test_ref(&0u32); } diff --git a/tests/ui/async-await/async-borrowck-escaping-block-error.stderr b/tests/ui/async-await/async-borrowck-escaping-block-error.stderr index 6ea03c99aa0e8..db8d268b2b08a 100644 --- a/tests/ui/async-await/async-borrowck-escaping-block-error.stderr +++ b/tests/ui/async-await/async-borrowck-escaping-block-error.stderr @@ -1,35 +1,17 @@ error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/async-borrowck-escaping-block-error.rs:6:14 | -LL | Box::new(async { x } ) - | ^^^^^ - `x` is borrowed here +LL | Box::new(async { *&x }) + | ^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | = note: async blocks are not executed immediately and must either take a reference or ownership of outside variables they use help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | Box::new(async move { x } ) +LL | Box::new(async move { *&x }) | ++++ -error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function - --> $DIR/async-borrowck-escaping-block-error.rs:11:5 - | -LL | async { *x } - | ^^^^^ -- `x` is borrowed here - | | - | may outlive borrowed value `x` - | -note: async block is returned here - --> $DIR/async-borrowck-escaping-block-error.rs:11:5 - | -LL | async { *x } - | ^^^^^^^^^^^^ -help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword - | -LL | async move { *x } - | ++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0373`. diff --git a/tests/ui/async-await/async-borrowck-escaping-closure-error.rs b/tests/ui/async-await/async-borrowck-escaping-closure-error.rs index 4489f344e6f2e..8f41ae3206c6d 100644 --- a/tests/ui/async-await/async-borrowck-escaping-closure-error.rs +++ b/tests/ui/async-await/async-borrowck-escaping-closure-error.rs @@ -2,9 +2,13 @@ fn foo() -> Box> { let x = 0u32; - Box::new((async || x)()) + Box::new((async || *&x)()) //~^ ERROR cannot return value referencing local variable `x` } -fn main() { +fn works() -> Box> { + let x = 0u32; + Box::new((async || x)()) } + +fn main() {} diff --git a/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr b/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr index 967b3bf5a7707..8ad78dd265885 100644 --- a/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr +++ b/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr @@ -1,8 +1,8 @@ error[E0515]: cannot return value referencing local variable `x` --> $DIR/async-borrowck-escaping-closure-error.rs:5:5 | -LL | Box::new((async || x)()) - | ^^^^^^^^^------------^^^ +LL | Box::new((async || *&x)()) + | ^^^^^^^^^--------------^^^ | | | | | `x` is borrowed here | returns a value referencing data owned by the current function diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs index f97ec779b32cf..693bf867b6370 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs @@ -11,12 +11,12 @@ async fn call_once(f: impl AsyncFnOnce()) { } fn simple<'a>(x: &'a i32) { - let c = async || { println!("{}", *x); }; //~ ERROR `x` does not live long enough + let c = async || { println!("{}", *x); }; outlives::<'a>(c()); outlives::<'a>(call_once(c)); let c = async move || { println!("{}", *x); }; - outlives::<'a>(c()); //~ ERROR `c` does not live long enough + outlives::<'a>(c()); outlives::<'a>(call_once(c)); } @@ -33,14 +33,14 @@ fn through_field<'a>(x: S<'a>) { } fn through_field_and_ref<'a>(x: &S<'a>) { - let c = async || { println!("{}", *x.0); }; //~ ERROR `x` does not live long enough + let c = async || { println!("{}", *x.0); }; outlives::<'a>(c()); outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x` } fn through_field_and_ref_move<'a>(x: &S<'a>) { let c = async move || { println!("{}", *x.0); }; - outlives::<'a>(c()); //~ ERROR `c` does not live long enough + outlives::<'a>(c()); outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x` } @@ -49,12 +49,12 @@ impl T { fn outlives<'a>(&'a self, _: impl Sized + 'a) {} } fn through_method<'a>(x: &'a i32) { - let c = async || { println!("{}", *x); }; //~ ERROR `x` does not live long enough + let c = async || { println!("{}", *x); }; T.outlives::<'a>(c()); T.outlives::<'a>(call_once(c)); let c = async move || { println!("{}", *x); }; - T.outlives::<'a>(c()); //~ ERROR `c` does not live long enough + T.outlives::<'a>(c()); T.outlives::<'a>(call_once(c)); } diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index 4aae9807dd2e4..7ec21880831e4 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -1,40 +1,3 @@ -error[E0597]: `x` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:14:13 - | -LL | fn simple<'a>(x: &'a i32) { - | -- lifetime `'a` defined here -LL | let c = async || { println!("{}", *x); }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough -LL | outlives::<'a>(c()); -LL | outlives::<'a>(call_once(c)); - | ---------------------------- argument requires that `x` is borrowed for `'a` -... -LL | } - | - `x` dropped here while still borrowed - -error[E0597]: `c` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:19:20 - | -LL | fn simple<'a>(x: &'a i32) { - | -- lifetime `'a` defined here -... -LL | let c = async move || { println!("{}", *x); }; - | - binding `c` declared here -LL | outlives::<'a>(c()); - | ---------------^--- - | | | - | | borrowed value does not live long enough - | argument requires that `c` is borrowed for `'a` -LL | outlives::<'a>(call_once(c)); -LL | } - | - `c` dropped here while still borrowed - | -note: requirement that the value outlives `'a` introduced here - --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 - | -LL | fn outlives<'a>(_: impl Sized + 'a) {} - | ^^ - error[E0597]: `x` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:26:13 | @@ -108,19 +71,6 @@ note: requirement that the value outlives `'a` introduced here LL | fn outlives<'a>(_: impl Sized + 'a) {} | ^^ -error[E0597]: `x` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:36:13 - | -LL | fn through_field_and_ref<'a>(x: &S<'a>) { - | -- lifetime `'a` defined here -LL | let c = async || { println!("{}", *x.0); }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough -LL | outlives::<'a>(c()); -LL | outlives::<'a>(call_once(c)); - | ---------------------------- argument requires that `x` is borrowed for `'a` -LL | } - | - `x` dropped here while still borrowed - error[E0621]: explicit lifetime required in the type of `x` --> $DIR/without-precise-captures-we-are-powerless.rs:38:5 | @@ -132,28 +82,6 @@ help: add explicit lifetime `'a` to the type of `x` LL | fn through_field_and_ref<'a>(x: &'a S<'a>) { | ++ -error[E0597]: `c` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:43:20 - | -LL | fn through_field_and_ref_move<'a>(x: &S<'a>) { - | -- lifetime `'a` defined here -LL | let c = async move || { println!("{}", *x.0); }; - | - binding `c` declared here -LL | outlives::<'a>(c()); - | ---------------^--- - | | | - | | borrowed value does not live long enough - | argument requires that `c` is borrowed for `'a` -LL | outlives::<'a>(call_once(c)); -LL | } - | - `c` dropped here while still borrowed - | -note: requirement that the value outlives `'a` introduced here - --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 - | -LL | fn outlives<'a>(_: impl Sized + 'a) {} - | ^^ - error[E0621]: explicit lifetime required in the type of `x` --> $DIR/without-precise-captures-we-are-powerless.rs:44:5 | @@ -165,44 +93,7 @@ help: add explicit lifetime `'a` to the type of `x` LL | fn through_field_and_ref_move<'a>(x: &'a S<'a>) { | ++ -error[E0597]: `x` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:52:13 - | -LL | fn through_method<'a>(x: &'a i32) { - | -- lifetime `'a` defined here -LL | let c = async || { println!("{}", *x); }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough -LL | T.outlives::<'a>(c()); -LL | T.outlives::<'a>(call_once(c)); - | ------------------------------ argument requires that `x` is borrowed for `'a` -... -LL | } - | - `x` dropped here while still borrowed - -error[E0597]: `c` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:57:22 - | -LL | fn through_method<'a>(x: &'a i32) { - | -- lifetime `'a` defined here -... -LL | let c = async move || { println!("{}", *x); }; - | - binding `c` declared here -LL | T.outlives::<'a>(c()); - | -----------------^--- - | | | - | | borrowed value does not live long enough - | argument requires that `c` is borrowed for `'a` -LL | T.outlives::<'a>(call_once(c)); -LL | } - | - `c` dropped here while still borrowed - | -note: requirement that the value outlives `'a` introduced here - --> $DIR/without-precise-captures-we-are-powerless.rs:49:47 - | -LL | fn outlives<'a>(&'a self, _: impl Sized + 'a) {} - | ^^ - -error: aborting due to 12 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0505, E0597, E0621. For more information about an error, try `rustc --explain E0505`. diff --git a/tests/ui/async-await/issues/issue-62097.rs b/tests/ui/async-await/issues/issue-62097.rs index ded535acf070f..a3375260ac2ac 100644 --- a/tests/ui/async-await/issues/issue-62097.rs +++ b/tests/ui/async-await/issues/issue-62097.rs @@ -11,8 +11,7 @@ struct Struct; impl Struct { pub async fn run_dummy_fn(&self) { foo(|| self.bar()).await; - //~^ ERROR closure may outlive the current function - //~| ERROR borrowed data escapes outside of method + //~^ ERROR borrowed data escapes outside of method } pub fn bar(&self) {} diff --git a/tests/ui/async-await/issues/issue-62097.stderr b/tests/ui/async-await/issues/issue-62097.stderr index 0edb27f059e64..85ed3dca0d8db 100644 --- a/tests/ui/async-await/issues/issue-62097.stderr +++ b/tests/ui/async-await/issues/issue-62097.stderr @@ -20,25 +20,6 @@ LL | where LL | F: FnOnce() + 'static | ^^^^^^^ lifetime requirement introduced here -error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function - --> $DIR/issue-62097.rs:13:13 - | -LL | foo(|| self.bar()).await; - | ^^ ---- `self` is borrowed here - | | - | may outlive borrowed value `self` - | -note: function requires argument type to outlive `'static` - --> $DIR/issue-62097.rs:13:9 - | -LL | foo(|| self.bar()).await; - | ^^^^^^^^^^^^^^^^^^ -help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword - | -LL | foo(move || self.bar()).await; - | ++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0373, E0521. -For more information about an error, try `rustc --explain E0373`. +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/borrowck/borrowck-closures-mut-and-imm.rs b/tests/ui/borrowck/borrowck-closures-mut-and-imm.rs index 17702ed07723d..35e6f38aa1268 100644 --- a/tests/ui/borrowck/borrowck-closures-mut-and-imm.rs +++ b/tests/ui/borrowck/borrowck-closures-mut-and-imm.rs @@ -15,7 +15,7 @@ fn set(x: &mut isize) { fn a() { let mut x = 3; let c1 = || x = 4; - let c2 = || x * 5; + let c2 = || *&x * 5; //~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable drop(c1); } @@ -31,14 +31,14 @@ fn b() { fn c() { let mut x = 3; let c1 = || set(&mut x); - let c2 = || x * 5; + let c2 = || *&x * 5; //~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable drop(c1); } fn d() { let mut x = 3; - let c2 = || x * 5; + let c2 = || *&x * 5; x = 5; //~^ ERROR cannot assign to `x` because it is borrowed drop(c2); diff --git a/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr b/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr index 165a9b01575c7..87382ef0d48ca 100644 --- a/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr +++ b/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr @@ -5,8 +5,8 @@ LL | let c1 = || x = 4; | -- - first borrow occurs due to use of `x` in closure | | | mutable borrow occurs here -LL | let c2 = || x * 5; - | ^^ - second borrow occurs due to use of `x` in closure +LL | let c2 = || *&x * 5; + | ^^ - second borrow occurs due to use of `x` in closure | | | immutable borrow occurs here LL | @@ -35,8 +35,8 @@ LL | let c1 = || set(&mut x); | -- - first borrow occurs due to use of `x` in closure | | | mutable borrow occurs here -LL | let c2 = || x * 5; - | ^^ - second borrow occurs due to use of `x` in closure +LL | let c2 = || *&x * 5; + | ^^ - second borrow occurs due to use of `x` in closure | | | immutable borrow occurs here LL | @@ -46,8 +46,8 @@ LL | drop(c1); error[E0506]: cannot assign to `x` because it is borrowed --> $DIR/borrowck-closures-mut-and-imm.rs:42:5 | -LL | let c2 = || x * 5; - | -- - borrow occurs due to use in closure +LL | let c2 = || *&x * 5; + | -- - borrow occurs due to use in closure | | | `x` is borrowed here LL | x = 5; diff --git a/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.fixed b/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.fixed index a2027fb8dee91..254a5703daa62 100644 --- a/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.fixed +++ b/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.fixed @@ -18,7 +18,7 @@ pub fn foo3<'a>( bar: &'a X, ) -> impl Iterator + 'a { Some(()).iter().flat_map(move |()| { - Some(()).iter().map(move |()| { bar; }) //~ ERROR captured variable cannot escape + Some(()).iter().map(move |()| { let _ = *&bar; }) //~ ERROR captured variable cannot escape //~^ HELP consider adding 'move' keyword before the nested closure }) } diff --git a/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs b/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs index ceddf52d292b6..155d1c03f2dd4 100644 --- a/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs +++ b/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.rs @@ -18,7 +18,7 @@ pub fn foo3<'a>( bar: &'a X, ) -> impl Iterator + 'a { Some(()).iter().flat_map(move |()| { - Some(()).iter().map(|()| { bar; }) //~ ERROR captured variable cannot escape + Some(()).iter().map(|()| { let _ = *&bar; }) //~ ERROR captured variable cannot escape //~^ HELP consider adding 'move' keyword before the nested closure }) } diff --git a/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr b/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr index c43a983cbf365..a9f43c2b6f264 100644 --- a/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr +++ b/tests/ui/borrowck/issue-95079-missing-move-in-nested-closure.stderr @@ -41,17 +41,17 @@ LL | bar: &'a X, LL | ) -> impl Iterator + 'a { LL | Some(()).iter().flat_map(move |()| { | - inferred to be a `FnMut` closure -LL | Some(()).iter().map(|()| { bar; }) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^ - | | | - | | variable captured here +LL | Some(()).iter().map(|()| { let _ = *&bar; }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^ + | | | + | | variable captured here | returns a closure that contains a reference to a captured variable, which then escapes the closure body | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape help: consider adding 'move' keyword before the nested closure | -LL | Some(()).iter().map(move |()| { bar; }) +LL | Some(()).iter().map(move |()| { let _ = *&bar; }) | ++++ error: aborting due to 3 previous errors diff --git a/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.rs b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.rs index 13c7c3ef61829..d79f917b57479 100644 --- a/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.rs +++ b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.rs @@ -4,7 +4,6 @@ type Lazy = Box T + 'static>; fn test(x: &i32) -> Lazy { Box::new(|| { //~^ ERROR lifetime may not live long enough - //~| ERROR closure may outlive the current function *x }) } diff --git a/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.stderr b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.stderr index 36a69f7d822b3..72a8169b8c6f9 100644 --- a/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.stderr +++ b/tests/ui/borrowck/suggest-lt-on-ty-alias-w-generics.stderr @@ -5,7 +5,6 @@ LL | fn test(x: &i32) -> Lazy { | - let's call the lifetime of this reference `'1` LL | / Box::new(|| { LL | | -LL | | LL | | *x LL | | }) | |______^ returning this value requires that `'1` must outlive `'static` @@ -16,29 +15,5 @@ LL - type Lazy = Box T + 'static>; LL + type Lazy<'a, T> = Box T + 'a>; | -error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function - --> $DIR/suggest-lt-on-ty-alias-w-generics.rs:5:14 - | -LL | Box::new(|| { - | ^^ may outlive borrowed value `x` -... -LL | *x - | -- `x` is borrowed here - | -note: closure is returned here - --> $DIR/suggest-lt-on-ty-alias-w-generics.rs:5:5 - | -LL | / Box::new(|| { -LL | | -LL | | -LL | | *x -LL | | }) - | |______^ -help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword - | -LL | Box::new(move || { - | ++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0373`. diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs index 8db7742174c5a..5f12a41db3abd 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs @@ -1,7 +1,5 @@ //@ edition:2021 - - // Tests that two closures cannot simultaneously have mutable // and immutable access to the variable. Issue #6801. @@ -12,15 +10,14 @@ struct Point { } fn a() { - let mut p = Point {x: 3, y:4}; - let c2 = || p.y * 5; + let mut p = Point { x: 3, y: 4 }; + let c2 = || *&p.y * 5; let c1 = || { - //~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable dbg!(&p); p.x = 4; }; drop(c2); } -fn main() { -} +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr index 57234fffec64c..19975807c347b 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr @@ -1,8 +1,8 @@ error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-closures-mut-and-imm.rs:17:14 + --> $DIR/borrowck-closures-mut-and-imm.rs:15:14 | -LL | let c2 = || p.y * 5; - | -- --- first borrow occurs due to use of `p.y` in closure +LL | let c2 = || *&p.y * 5; + | -- --- first borrow occurs due to use of `p.y` in closure | | | immutable borrow occurs here LL | let c1 = || { diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs index 1861fafb40514..ec4878078f5b6 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs @@ -59,10 +59,10 @@ struct MyStruct<'a> { pub fn nested() { let mut a: Option<&str>; a = None; - let mut b: Option<&str>; - b = None; + let mut b: Option<&str>; //~ WARN variable `b` is assigned to, but never used + b = None; //~ WARN value assigned to `b` is never read let mut d = MyStruct { x: None, y: 1 }; - let mut e = MyStruct { x: None, y: 1 }; + let mut e = MyStruct { x: None, y: 1 }; //~ WARN unused variable: `e` (|| { (|| { d.x = Some("d1"); //~ WARN value assigned to `d.x` is never read @@ -72,9 +72,11 @@ pub fn nested() { })(); (move || { e.x = Some("e1"); //~ WARN value captured by `e.x` is never read + //~| WARN value captured by `e.x` is never read //~| WARN value assigned to `e.x` is never read e.x = Some("e2"); //~ WARN value assigned to `e.x` is never read b = Some("e1"); //~ WARN value captured by `b` is never read + //~| WARN value captured by `b` is never read //~| WARN value assigned to `b` is never read b = Some("e2"); //~ WARN value assigned to `b` is never read })(); diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr index 58cdc2510e871..1e94a48277150 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr @@ -81,12 +81,12 @@ warning: value assigned to `e.x` is never read | LL | e.x = Some("e1"); | ^^^^^^^^^^^^^^^^ this value is reassigned later and never used -LL | +... LL | e.x = Some("e2"); | ---------------- `e.x` is overwritten here before the previous value is read warning: value assigned to `e.x` is never read - --> $DIR/liveness.rs:76:13 + --> $DIR/liveness.rs:77:13 | LL | e.x = Some("e2"); | ^^^^^^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | e.x = Some("e2"); = help: maybe it is overwritten before being read? warning: value captured by `b` is never read - --> $DIR/liveness.rs:77:13 + --> $DIR/liveness.rs:78:13 | LL | b = Some("e1"); | ^ @@ -102,16 +102,16 @@ LL | b = Some("e1"); = help: did you mean to capture by reference instead? warning: value assigned to `b` is never read - --> $DIR/liveness.rs:77:13 + --> $DIR/liveness.rs:78:13 | LL | b = Some("e1"); | ^^^^^^^^^^^^^^ this value is reassigned later and never used -LL | +... LL | b = Some("e2"); | -------------- `b` is overwritten here before the previous value is read warning: value assigned to `b` is never read - --> $DIR/liveness.rs:79:13 + --> $DIR/liveness.rs:81:13 | LL | b = Some("e2"); | ^^^^^^^^^^^^^^ @@ -134,5 +134,46 @@ LL | a = Some("d1"); LL | a = Some("d2"); | -------------- `a` is overwritten here before the previous value is read -warning: 16 warnings emitted +warning: value captured by `e.x` is never read + --> $DIR/liveness.rs:74:13 + | +LL | e.x = Some("e1"); + | ^^^ + | + = help: did you mean to capture by reference instead? + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: value captured by `b` is never read + --> $DIR/liveness.rs:78:13 + | +LL | b = Some("e1"); + | ^ + | + = help: did you mean to capture by reference instead? + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: variable `b` is assigned to, but never used + --> $DIR/liveness.rs:62:9 + | +LL | let mut b: Option<&str>; + | ^^^^^ + | + = note: consider using `_b` instead + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: unused variable: `e` + --> $DIR/liveness.rs:65:9 + | +LL | let mut e = MyStruct { x: None, y: 1 }; + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_e` + +warning: value assigned to `b` is never read + --> $DIR/liveness.rs:63:5 + | +LL | b = None; + | ^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: 21 warnings emitted diff --git a/tests/ui/closures/2229_closure_analysis/issue-87378.rs b/tests/ui/closures/2229_closure_analysis/issue-87378.rs index d60ecbef78e4a..ca379c045c4e0 100644 --- a/tests/ui/closures/2229_closure_analysis/issue-87378.rs +++ b/tests/ui/closures/2229_closure_analysis/issue-87378.rs @@ -16,7 +16,7 @@ fn main() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: unsafe { u.value } - //~^ NOTE: Capturing u[(0, 0)] -> Immutable + //~^ NOTE: Capturing u[(0, 0)] -> ByCopy //~| NOTE: Min Capture u[] -> Immutable }; diff --git a/tests/ui/closures/2229_closure_analysis/issue-87378.stderr b/tests/ui/closures/2229_closure_analysis/issue-87378.stderr index d47ec5a9cae23..42cfece7ad7fc 100644 --- a/tests/ui/closures/2229_closure_analysis/issue-87378.stderr +++ b/tests/ui/closures/2229_closure_analysis/issue-87378.stderr @@ -9,7 +9,7 @@ LL | | unsafe { u.value } LL | | }; | |_____^ | -note: Capturing u[(0, 0)] -> Immutable +note: Capturing u[(0, 0)] -> ByCopy --> $DIR/issue-87378.rs:18:17 | LL | unsafe { u.value } diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.rs b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs index 7bd435bd1856f..115cbd1920446 100644 --- a/tests/ui/closures/2229_closure_analysis/match/partial-move.rs +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs @@ -35,7 +35,7 @@ pub fn test_enum1(x: Enum) -> impl FnOnce() { || { //~^ ERROR: closure may outlive the current function, but it borrows `x.0` match x { - Enum::A(a, b) => { + Enum::A(ref a, b) => { drop((a, b)); } _ => unreachable!(), @@ -47,7 +47,7 @@ pub fn test_enum2(x: Enum) -> impl FnOnce() { || { //~^ ERROR: closure may outlive the current function, but it borrows `x.0` match x { - Enum::A(a, b) => { + Enum::A(ref a, b) => { drop((a, b)); } } @@ -59,7 +59,7 @@ pub fn test_struct(x: Struct) -> impl FnOnce() { || { //~^ ERROR: closure may outlive the current function, but it borrows `x.0` match x { - Struct(a, b) => { + Struct(ref a, b) => { drop((a, b)); } } @@ -70,7 +70,7 @@ pub fn test_struct(x: Struct) -> impl FnOnce() { pub fn test_two_variants(x: TwoVariants) -> impl FnOnce() { || { match x { - TwoVariants::A(a, b) => { + TwoVariants::A(ref a, b) => { drop((a, b)); } _ => unreachable!(), @@ -82,7 +82,7 @@ pub fn test_two_variants(x: TwoVariants) -> impl FnOnce() { pub fn test_non_exhaustive1(x: NonExhaustive) -> impl FnOnce() { || { match x { - NonExhaustive::A(a, b) => { + NonExhaustive::A(ref a, b) => { drop((a, b)); } _ => unreachable!(), @@ -94,7 +94,7 @@ pub fn test_non_exhaustive1(x: NonExhaustive) -> impl FnOnce() { pub fn test_non_exhaustive2(x: NonExhaustive) -> impl FnOnce() { || { match x { - NonExhaustive::A(a, b) => { + NonExhaustive::A(ref a, b) => { drop((a, b)); } } @@ -105,7 +105,7 @@ pub fn test_non_exhaustive2(x: NonExhaustive) -> impl FnOnce() { pub fn test_ext(x: ExtNonExhaustive) -> impl FnOnce() { || { match x { - ExtNonExhaustive::A(a, b) => { + ExtNonExhaustive::A(ref a, b) => { drop((a, b)); } _ => unreachable!(), diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr index 09f9adf95d5bb..02e49f53f90f0 100644 --- a/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr @@ -13,7 +13,7 @@ note: closure is returned here LL | / || { LL | | LL | | match x { -LL | | Enum::A(a, b) => { +LL | | Enum::A(ref a, b) => { ... | LL | | } | |_____^ @@ -37,7 +37,7 @@ note: closure is returned here LL | / || { LL | | LL | | match x { -LL | | Enum::A(a, b) => { +LL | | Enum::A(ref a, b) => { ... | LL | | } | |_____^ @@ -61,7 +61,7 @@ note: closure is returned here LL | / || { LL | | LL | | match x { -LL | | Struct(a, b) => { +LL | | Struct(ref a, b) => { ... | LL | | } | |_____^ diff --git a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index cc46ea72e9901..1694f6f38281e 100644 --- a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -23,7 +23,7 @@ LL | let c = || { | ^^ `variant` used here but it isn't initialized LL | LL | match variant { - | ------- borrow occurs due to use in closure + | ------- use occurs due to use in closure error[E0381]: used binding `variant` isn't initialized --> $DIR/pattern-matching-should-fail.rs:37:13 @@ -33,7 +33,7 @@ LL | let variant: !; LL | let c = || { | ^^ `variant` used here but it isn't initialized LL | match variant { - | ------- borrow occurs due to use in closure + | ------- use occurs due to use in closure error[E0381]: used binding `g` isn't initialized --> $DIR/pattern-matching-should-fail.rs:52:15 diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs index 16cb9d7355da5..b5f34bc709d62 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs @@ -64,8 +64,8 @@ fn test_6_should_capture_single_variant() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match variant { - //~^ NOTE: Capturing variant[(0, 0)] -> Immutable - //~| NOTE: Min Capture variant[(0, 0)] -> Immutable + //~^ NOTE: Capturing variant[(0, 0)] -> ByCopy + //~| NOTE: Min Capture variant[(0, 0)] -> ByCopy SingleVariant::Points(a) => { println!("{:?}", a); } diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr index 73c685e152765..a4b79355c502c 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr @@ -65,7 +65,7 @@ LL | | match variant { LL | | }; | |_____^ | -note: Capturing variant[(0, 0)] -> Immutable +note: Capturing variant[(0, 0)] -> ByCopy --> $DIR/patterns-capture-analysis.rs:66:15 | LL | match variant { @@ -82,7 +82,7 @@ LL | | match variant { LL | | }; | |_____^ | -note: Min Capture variant[(0, 0)] -> Immutable +note: Min Capture variant[(0, 0)] -> ByCopy --> $DIR/patterns-capture-analysis.rs:66:15 | LL | match variant { diff --git a/tests/ui/closures/2229_closure_analysis/move_closure.rs b/tests/ui/closures/2229_closure_analysis/move_closure.rs index 60d76ac525395..d7e85836f0907 100644 --- a/tests/ui/closures/2229_closure_analysis/move_closure.rs +++ b/tests/ui/closures/2229_closure_analysis/move_closure.rs @@ -181,7 +181,7 @@ fn returned_closure_owns_copy_type_data() -> impl Fn() -> i32 { let c = #[rustc_capture_analysis] move || x; //~^ ERROR First Pass analysis includes: - //~| NOTE: Capturing x[] -> Immutable + //~| NOTE: Capturing x[] -> ByCopy //~| ERROR Min Capture analysis includes: //~| NOTE: Min Capture x[] -> ByValue diff --git a/tests/ui/closures/2229_closure_analysis/move_closure.stderr b/tests/ui/closures/2229_closure_analysis/move_closure.stderr index b889423245053..c5a790a38e680 100644 --- a/tests/ui/closures/2229_closure_analysis/move_closure.stderr +++ b/tests/ui/closures/2229_closure_analysis/move_closure.stderr @@ -4,7 +4,7 @@ error: First Pass analysis includes: LL | let c = #[rustc_capture_analysis] move || x; | ^^^^^^^^^ | -note: Capturing x[] -> Immutable +note: Capturing x[] -> ByCopy --> $DIR/move_closure.rs:182:47 | LL | let c = #[rustc_capture_analysis] move || x; diff --git a/tests/ui/closures/2229_closure_analysis/nested-closure.rs b/tests/ui/closures/2229_closure_analysis/nested-closure.rs index 81cce83b728fc..2c0bf2e1a1613 100644 --- a/tests/ui/closures/2229_closure_analysis/nested-closure.rs +++ b/tests/ui/closures/2229_closure_analysis/nested-closure.rs @@ -29,9 +29,9 @@ fn main() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: //~| NOTE: Capturing p[(1, 0)] -> Mutable - //~| NOTE: Capturing incr[] -> Immutable + //~| NOTE: Capturing incr[] -> ByCopy //~| NOTE: Min Capture p[(1, 0)] -> Mutable - //~| NOTE: Min Capture incr[] -> Immutable + //~| NOTE: Min Capture incr[] -> ByCopy //~| NOTE: Capturing p[(1, 0)] -> Mutable //~| NOTE: Min Capture p[(1, 0)] -> Mutable c2(); diff --git a/tests/ui/closures/2229_closure_analysis/nested-closure.stderr b/tests/ui/closures/2229_closure_analysis/nested-closure.stderr index b3d06f1b5196e..5a763497e9dcc 100644 --- a/tests/ui/closures/2229_closure_analysis/nested-closure.stderr +++ b/tests/ui/closures/2229_closure_analysis/nested-closure.stderr @@ -9,7 +9,7 @@ note: Capturing p[(1, 0)] -> Mutable | LL | || p.y += incr; | ^^^ -note: Capturing incr[] -> Immutable +note: Capturing incr[] -> ByCopy --> $DIR/nested-closure.rs:28:19 | LL | || p.y += incr; @@ -26,7 +26,7 @@ note: Min Capture p[(1, 0)] -> Mutable | LL | || p.y += incr; | ^^^ -note: Min Capture incr[] -> Immutable +note: Min Capture incr[] -> ByCopy --> $DIR/nested-closure.rs:28:19 | LL | || p.y += incr; diff --git a/tests/ui/closures/2229_closure_analysis/repr_packed.rs b/tests/ui/closures/2229_closure_analysis/repr_packed.rs index 3908765d87286..1f7838eb631f3 100644 --- a/tests/ui/closures/2229_closure_analysis/repr_packed.rs +++ b/tests/ui/closures/2229_closure_analysis/repr_packed.rs @@ -16,9 +16,9 @@ fn test_alignment_not_affected() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: let z1: &u8 = &foo.x; - //~^ NOTE: Capturing foo[] -> Immutable + //~^ NOTE: Capturing foo[(0, 0)] -> Immutable let z2: &mut u8 = &mut foo.y; - //~^ NOTE: Capturing foo[] -> Mutable + //~^ NOTE: Capturing foo[(1, 0)] -> Mutable //~| NOTE: Min Capture foo[] -> Mutable *z2 = 42; @@ -44,9 +44,9 @@ fn test_alignment_affected() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: let z1: &String = &foo.x; - //~^ NOTE: Capturing foo[] -> Immutable + //~^ NOTE: Capturing foo[(0, 0)] -> Immutable let z2: &mut u16 = &mut foo.y; - //~^ NOTE: Capturing foo[] -> Mutable + //~^ NOTE: Capturing foo[(1, 0)] -> Mutable //~| NOTE: Min Capture foo[] -> Mutable @@ -77,7 +77,7 @@ fn test_truncation_when_ref_and_move() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: println!("{}", foo.x); - //~^ NOTE: Capturing foo[] -> Immutable + //~^ NOTE: Capturing foo[(0, 0)] -> Immutable //~| NOTE: Min Capture foo[] -> ByValue //~| NOTE: foo[] used here let _z = foo.x; diff --git a/tests/ui/closures/2229_closure_analysis/repr_packed.stderr b/tests/ui/closures/2229_closure_analysis/repr_packed.stderr index 2c18229b2e09e..2bc8513e736c3 100644 --- a/tests/ui/closures/2229_closure_analysis/repr_packed.stderr +++ b/tests/ui/closures/2229_closure_analysis/repr_packed.stderr @@ -10,12 +10,12 @@ LL | | println!("({}, {})", z1, z2); LL | | }; | |_____^ | -note: Capturing foo[] -> Immutable +note: Capturing foo[(0, 0)] -> Immutable --> $DIR/repr_packed.rs:18:24 | LL | let z1: &u8 = &foo.x; | ^^^^^ -note: Capturing foo[] -> Mutable +note: Capturing foo[(1, 0)] -> Mutable --> $DIR/repr_packed.rs:20:32 | LL | let z2: &mut u8 = &mut foo.y; @@ -51,12 +51,12 @@ LL | | println!("({}, {})", z1, z2); LL | | }; | |_____^ | -note: Capturing foo[] -> Immutable +note: Capturing foo[(0, 0)] -> Immutable --> $DIR/repr_packed.rs:46:28 | LL | let z1: &String = &foo.x; | ^^^^^ -note: Capturing foo[] -> Mutable +note: Capturing foo[(1, 0)] -> Mutable --> $DIR/repr_packed.rs:48:33 | LL | let z2: &mut u16 = &mut foo.y; @@ -91,7 +91,7 @@ LL | | println!("{}", foo.x); LL | | }; | |_____^ | -note: Capturing foo[] -> Immutable +note: Capturing foo[(0, 0)] -> Immutable --> $DIR/repr_packed.rs:79:24 | LL | println!("{}", foo.x); diff --git a/tests/ui/closures/2229_closure_analysis/unsafe_ptr.rs b/tests/ui/closures/2229_closure_analysis/unsafe_ptr.rs index 788156054d10e..d4d640a2bc4a1 100644 --- a/tests/ui/closures/2229_closure_analysis/unsafe_ptr.rs +++ b/tests/ui/closures/2229_closure_analysis/unsafe_ptr.rs @@ -28,7 +28,7 @@ fn unsafe_imm() { //~| ERROR: Min Capture analysis includes: println!("{:?}", (*t.0).s); //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> Immutable - //~| NOTE: Min Capture t[(0, 0)] -> Immutable + //~| NOTE: Min Capture t[(0, 0)] -> ByCopy }; c(); @@ -46,7 +46,7 @@ fn unsafe_mut() { //~| ERROR: Min Capture analysis includes: let x = unsafe { &mut (*p).s }; //~^ NOTE: Capturing p[Deref,(0, 0)] -> Immutable - //~| NOTE: Min Capture p[] -> Immutable + //~| NOTE: Min Capture p[] -> ByCopy *x = "s".into(); }; c(); diff --git a/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr b/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr index e2ccc1be71716..c09a80442e7c7 100644 --- a/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr +++ b/tests/ui/closures/2229_closure_analysis/unsafe_ptr.stderr @@ -26,7 +26,7 @@ LL | | println!("{:?}", (*t.0).s); LL | | }; | |_____^ | -note: Min Capture t[(0, 0)] -> Immutable +note: Min Capture t[(0, 0)] -> ByCopy --> $DIR/unsafe_ptr.rs:29:26 | LL | println!("{:?}", (*t.0).s); @@ -62,7 +62,7 @@ LL | | *x = "s".into(); LL | | }; | |_____^ | -note: Min Capture p[] -> Immutable +note: Min Capture p[] -> ByCopy --> $DIR/unsafe_ptr.rs:47:31 | LL | let x = unsafe { &mut (*p).s }; diff --git a/tests/ui/closures/2229_closure_analysis/wild_patterns.rs b/tests/ui/closures/2229_closure_analysis/wild_patterns.rs index c0054c6cf66e3..c86962f2848d5 100644 --- a/tests/ui/closures/2229_closure_analysis/wild_patterns.rs +++ b/tests/ui/closures/2229_closure_analysis/wild_patterns.rs @@ -25,8 +25,8 @@ fn wild_struct() { //~| ERROR: Min Capture analysis includes: // FIXME(arora-aman): Change `_x` to `_` let Point { x: _x, y: _ } = p; - //~^ NOTE: Capturing p[(0, 0)] -> Immutable - //~| NOTE: Min Capture p[(0, 0)] -> Immutable + //~^ NOTE: Capturing p[(0, 0)] -> ByCopy + //~| NOTE: Min Capture p[(0, 0)] -> ByCopy }; c(); diff --git a/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr b/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr index 776ac7f20d27d..941612ad1a988 100644 --- a/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr +++ b/tests/ui/closures/2229_closure_analysis/wild_patterns.stderr @@ -6,7 +6,7 @@ LL | / || { LL | | }; | |_____^ | -note: Capturing p[(0, 0)] -> Immutable +note: Capturing p[(0, 0)] -> ByCopy --> $DIR/wild_patterns.rs:27:37 | LL | let Point { x: _x, y: _ } = p; @@ -20,7 +20,7 @@ LL | / || { LL | | }; | |_____^ | -note: Min Capture p[(0, 0)] -> Immutable +note: Min Capture p[(0, 0)] -> ByCopy --> $DIR/wild_patterns.rs:27:37 | LL | let Point { x: _x, y: _ } = p; diff --git a/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.rs b/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.rs index e54194c1ad68c..5132c3e733b32 100644 --- a/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.rs +++ b/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.rs @@ -6,7 +6,7 @@ fn foo(x: &()) { bar(|| { //~^ ERROR borrowed data escapes //~| ERROR closure may outlive - let _ = x; + let _ = *&x; }) } diff --git a/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr b/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr index 37316a331779a..726dc11491e6d 100644 --- a/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr +++ b/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr @@ -8,7 +8,7 @@ LL | fn foo(x: &()) { LL | / bar(|| { LL | | LL | | -LL | | let _ = x; +LL | | let _ = *&x; LL | | }) | | ^ | | | @@ -27,8 +27,8 @@ error[E0373]: closure may outlive the current function, but it borrows `x`, whic LL | bar(|| { | ^^ may outlive borrowed value `x` ... -LL | let _ = x; - | - `x` is borrowed here +LL | let _ = *&x; + | - `x` is borrowed here | note: function requires argument type to outlive `'static` --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:6:5 @@ -36,7 +36,7 @@ note: function requires argument type to outlive `'static` LL | / bar(|| { LL | | LL | | -LL | | let _ = x; +LL | | let _ = *&x; LL | | }) | |______^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword diff --git a/tests/ui/closures/cromulent-copy-closure-captures-2021.rs b/tests/ui/closures/cromulent-copy-closure-captures-2021.rs new file mode 100644 index 0000000000000..fa8165003bf21 --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-2021.rs @@ -0,0 +1,62 @@ +//@ run-pass +//@ edition:2021.. + +fn test<'short, 'long>(r: &'short &'long ()) -> impl 'long + Fn() -> &'long () { + || *r +} + +struct Foo(()); + +impl Foo { + fn method(&self) {} + + fn assoc(_: &Self) {} +} + +fn test2<'a>(foo: &'a Foo) -> impl Fn() -> &'a () { + || { + foo.method(); + Foo::assoc(foo); + &foo.0 + } +} + +fn assert_static_fn(_: impl Fn() -> Ret + 'static) {} + +#[repr(packed)] +struct Packed(u32); + +#[allow(unused)] +struct Int(i32); +#[allow(unused)] +struct B<'a>(&'a i32); + +struct MyStruct<'a, 'b> { + a: &'a Int, + _b: B<'b>, +} + +fn foo<'a, 'b, 'c>(m: &'a MyStruct<'b, 'c>) -> impl FnMut() + use<'b> { + let c = || { + let _unused = &m.a.0; + }; + c +} + +fn bar<'a, 'b, 'c>(m: &'a MyStruct<'b, 'c>) -> impl FnMut() + use<'b> { + let c = || { + let _unused = m.a; + }; + c +} + +fn main() { + test(&&())(); + test2(&Foo(()))(); + + let p = Packed(42); + assert_static_fn::(|| p.0); + + foo(&MyStruct { a: &Int(42), _b: B(&42) })(); + bar(&MyStruct { a: &Int(42), _b: B(&42) })(); +} diff --git a/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs new file mode 100644 index 0000000000000..49b55164235c9 --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs @@ -0,0 +1,306 @@ +//@ edition:2021.. + +#![feature(rustc_attrs, stmt_expr_attributes)] + +fn main() { + // Test that we do not try to capture references to fields of packed structs. + + { + union NonCopyUnion<'a> { + field: &'a &'a u32, + } + + #[repr(packed)] + struct Packed<'a>(NonCopyUnion<'a>); + + let packed = Packed(NonCopyUnion { field: &&42 }); + let _closure = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let _i = unsafe { *packed.0.field }; + //~^ NOTE Capturing packed[(0, 0),(0, 0),Deref] -> ByCopy + //~| NOTE Min Capture packed[] -> Immutable + }; + } + + // Test that implicit reborrows don't lead us to capture more precisely than desired + + { + let m_s: &mut &u32 = &mut &17; + let _closure = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let _local: &mut _ = m_s; + //~^ NOTE Capturing m_s[Deref] -> Mutable + //~| NOTE Min Capture m_s[Deref] -> Mutable + }; + } + + { + let m_s: &mut &u32 = &mut &17; + let _closure = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let _local: &_ = m_s; + //~^ NOTE Capturing m_s[Deref] -> Immutable + //~| NOTE Min Capture m_s[Deref] -> Immutable + }; + } + + { + let m_s: &&u32 = &&17; + let _closure = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let _local: &_ = m_s; + //~^ NOTE Capturing m_s[Deref] -> Immutable + //~| NOTE Min Capture m_s[Deref] -> Immutable + }; + } + + // Box + + { + let capture = Box::new(false); + let _closure = #[rustc_capture_analysis] || *capture; + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + //~| NOTE Capturing capture[Deref] -> Immutable + //~| NOTE Min Capture capture[Deref] -> Immutable + } + + { + struct NotCopy; + let capture = Box::new(NotCopy); + let _closure = #[rustc_capture_analysis] || *capture; + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + //~| NOTE Capturing capture[Deref] -> ByValue + //~| NOTE Min Capture capture[] -> ByValue + } + + // Examples from RFC + + { + let x = [0; 1024]; + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let y = x; + //~^ NOTE Capturing x[] -> ByCopy + //~| NOTE Min Capture x[] -> ByCopy + }; + } + + { + let x = &([0; 1024],); + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let y = x.0; + //~^ NOTE Capturing x[Deref,(0, 0)] -> Immutable + //~| NOTE Min Capture x[Deref] -> Immutable + }; + } + + { + let x = &(&false,); + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let y = x.0; + //~^ NOTE Capturing x[Deref,(0, 0)] -> ByCopy + //~| NOTE Min Capture x[Deref,(0, 0)] -> ByCopy + }; + } + + { + let s = String::from("S"); + let t = (s, String::from("T")); + let mut u = (t, String::from("U")); + + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + println!("{:?}", u); + //~^ NOTE Capturing u[] -> Immutable + //~| NOTE Min Capture u[] -> ByValue + //~| NOTE u[] used here + u.1.truncate(0); + //~^ NOTE Capturing u[(1, 0)] -> Mutable + drop(u.0.0); + //~^ NOTE Capturing u[(0, 0),(0, 0)] -> ByValue + //~| NOTE u[] captured as ByValue here + }; + c(); + } + + { + let s = 'S'; + let t = (s, 'T'); + let mut u = (t, 'U'); + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + println!("{:?}", u); + //~^ NOTE Capturing u[] -> Immutable + //~| NOTE Min Capture u[] -> Mutable + //~| NOTE u[] used here + u.1 = '\0'; + //~^ NOTE Capturing u[(1, 0)] -> Mutable + //~| NOTE u[] captured as Mutable here + drop(u.0.0); // `u.0.0` captured by ByCopy + //~^ NOTE Capturing u[(0, 0),(0, 0)] -> ByCopy + }; + c(); + } + + { + struct Int(i32); + struct B<'a>(&'a i32); + + struct MyStruct<'a> { + a: &'static Int, + b: B<'a>, + } + + fn foo<'a, 'b>(m: &'a MyStruct<'b>) -> impl FnMut() + 'static { + let c = #[rustc_capture_analysis] || drop(&m.a.0); + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + //~| NOTE Capturing m[Deref,(0, 0),Deref,(0, 0)] -> Immutable + //~| NOTE Min Capture m[Deref,(0, 0),Deref] -> Immutable + c + } + } + + { + struct MyStruct<'b> { + a: &'static u32, + b: &'b u32, + } + + fn foo<'a, 'b>(m: &'a MyStruct<'b>) -> impl FnMut() + 'static { + let c = #[rustc_capture_analysis] || drop(m.a); + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + //~| NOTE Capturing m[Deref,(0, 0)] -> ByCopy + //~| NOTE Min Capture m[Deref,(0, 0)] -> ByCopy + c + } + } + + { + struct T(String, String); + + let t = T(String::from("foo"), String::from("bar")); + let t_ptr = &t as *const T; + + let c = #[rustc_capture_analysis] || unsafe { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + println!("{}", (*t_ptr).0); + //~^ NOTE Capturing t_ptr[Deref,(0, 0)] -> Immutable + //~| NOTE Min Capture t_ptr[] -> ByCopy + }; + c(); + } + + { + union U { + a: (i32, i32), + b: bool, + } + let u = U { a: (123, 456) }; + + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let x = unsafe { u.a.0 }; + //~^ NOTE Capturing u[(0, 0),(0, 0)] -> ByCopy + //~| NOTE Min Capture u[] -> Immutable + }; + c(); + + // This also includes writing to fields. + let mut u = U { a: (123, 456) }; + + let mut c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + u.b = true; + //~^ NOTE Capturing u[(1, 0)] -> Mutable + //~| NOTE Min Capture u[] -> Mutable + }; + c(); + } + + { + #[derive(Clone, Copy)] + union U<'a> { + a: (&'a String, i32), + b: bool, + } + let string: String = "hello world!".to_owned(); + let u = U { a: (&string, 42) }; + + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let x = unsafe { u.a.0.len() }; + //~^ NOTE Capturing u[(0, 0),(0, 0),Deref] -> Immutable + //~| NOTE Min Capture u[] -> ByCopy + }; + c(); + } + + { + #[repr(packed)] + struct T(i32, i32); + + let t = T(2, 5); + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let a = t.0; + //~^ NOTE Capturing t[(0, 0)] -> ByCopy + //~| NOTE Min Capture t[(0, 0)] -> ByCopy + }; + // Copies out of `t` are ok. + let (a, b) = (t.0, t.1); + c(); + } + + { + #[repr(packed)] + struct T(&'static i32, i32); + + let t = T(&2, 5); + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let a = *t.0; + //~^ NOTE Capturing t[(0, 0),Deref] -> Immutable + //~| NOTE Min Capture t[(0, 0),Deref] -> Immutable + }; + // References out of `t` are ok. + let (a, b) = (t.0, t.1); + c(); + } + + { + struct T(String, String); + + let mut t = T(String::new(), String::new()); + let c = #[rustc_capture_analysis] || { + //~^ ERROR First Pass analysis includes: + //~| ERROR Min Capture analysis includes: + let a = &raw const t.1; + //~^ NOTE Capturing t[(1, 0)] -> Immutable + //~| NOTE Min Capture t[(1, 0)] -> Immutable + }; + // The move here is allowed. + let a = t.0; + c(); + } +} diff --git a/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr new file mode 100644 index 0000000000000..b744865c4c2fc --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr @@ -0,0 +1,700 @@ +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:168:47 + | +LL | let c = #[rustc_capture_analysis] || drop(&m.a.0); + | ^^^^^^^^^^^^^^^ + | +note: Capturing m[Deref,(0, 0),Deref,(0, 0)] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:168:56 + | +LL | let c = #[rustc_capture_analysis] || drop(&m.a.0); + | ^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:168:47 + | +LL | let c = #[rustc_capture_analysis] || drop(&m.a.0); + | ^^^^^^^^^^^^^^^ + | +note: Min Capture m[Deref,(0, 0),Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:168:56 + | +LL | let c = #[rustc_capture_analysis] || drop(&m.a.0); + | ^^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:184:47 + | +LL | let c = #[rustc_capture_analysis] || drop(m.a); + | ^^^^^^^^^^^^ + | +note: Capturing m[Deref,(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:184:55 + | +LL | let c = #[rustc_capture_analysis] || drop(m.a); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:184:47 + | +LL | let c = #[rustc_capture_analysis] || drop(m.a); + | ^^^^^^^^^^^^ + | +note: Min Capture m[Deref,(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:184:55 + | +LL | let c = #[rustc_capture_analysis] || drop(m.a); + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:17:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _i = unsafe { *packed.0.field }; +... | +LL | | }; + | |_________^ + | +note: Capturing packed[(0, 0),(0, 0),Deref] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:20:31 + | +LL | let _i = unsafe { *packed.0.field }; + | ^^^^^^^^^^^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:17:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _i = unsafe { *packed.0.field }; +... | +LL | | }; + | |_________^ + | +note: Min Capture packed[] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:20:31 + | +LL | let _i = unsafe { *packed.0.field }; + | ^^^^^^^^^^^^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:30:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _local: &mut _ = m_s; +... | +LL | | }; + | |_________^ + | +note: Capturing m_s[Deref] -> Mutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:33:34 + | +LL | let _local: &mut _ = m_s; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:30:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _local: &mut _ = m_s; +... | +LL | | }; + | |_________^ + | +note: Min Capture m_s[Deref] -> Mutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:33:34 + | +LL | let _local: &mut _ = m_s; + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:41:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _local: &_ = m_s; +... | +LL | | }; + | |_________^ + | +note: Capturing m_s[Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:44:30 + | +LL | let _local: &_ = m_s; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:41:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _local: &_ = m_s; +... | +LL | | }; + | |_________^ + | +note: Min Capture m_s[Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:44:30 + | +LL | let _local: &_ = m_s; + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:52:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _local: &_ = m_s; +... | +LL | | }; + | |_________^ + | +note: Capturing m_s[Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:55:30 + | +LL | let _local: &_ = m_s; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:52:50 + | +LL | let _closure = #[rustc_capture_analysis] || { + | __________________________________________________^ +LL | | +LL | | +LL | | let _local: &_ = m_s; +... | +LL | | }; + | |_________^ + | +note: Min Capture m_s[Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:55:30 + | +LL | let _local: &_ = m_s; + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:65:51 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^^^^ + | +note: Capturing capture[Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:65:54 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:65:51 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^^^^ + | +note: Min Capture capture[Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:65:54 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:75:51 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^^^^ + | +note: Capturing capture[Deref] -> ByValue + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:75:54 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:75:51 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^^^^ + | +note: Min Capture capture[] -> ByValue + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:75:54 + | +LL | let _closure = #[rustc_capture_analysis] || *capture; + | ^^^^^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:86:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let y = x; +... | +LL | | }; + | |_________^ + | +note: Capturing x[] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:89:21 + | +LL | let y = x; + | ^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:86:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let y = x; +... | +LL | | }; + | |_________^ + | +note: Min Capture x[] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:89:21 + | +LL | let y = x; + | ^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:97:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let y = x.0; +... | +LL | | }; + | |_________^ + | +note: Capturing x[Deref,(0, 0)] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:100:21 + | +LL | let y = x.0; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:97:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let y = x.0; +... | +LL | | }; + | |_________^ + | +note: Min Capture x[Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:100:21 + | +LL | let y = x.0; + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:108:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let y = x.0; +... | +LL | | }; + | |_________^ + | +note: Capturing x[Deref,(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:111:21 + | +LL | let y = x.0; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:108:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let y = x.0; +... | +LL | | }; + | |_________^ + | +note: Min Capture x[Deref,(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:111:21 + | +LL | let y = x.0; + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:122:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | println!("{:?}", u); +... | +LL | | }; + | |_________^ + | +note: Capturing u[] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:125:30 + | +LL | println!("{:?}", u); + | ^ +note: Capturing u[(1, 0)] -> Mutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:129:13 + | +LL | u.1.truncate(0); + | ^^^ +note: Capturing u[(0, 0),(0, 0)] -> ByValue + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:131:18 + | +LL | drop(u.0.0); + | ^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:122:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | println!("{:?}", u); +... | +LL | | }; + | |_________^ + | +note: Min Capture u[] -> ByValue + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:125:30 + | +LL | println!("{:?}", u); + | ^ u[] used here +... +LL | drop(u.0.0); + | ^^^^^ u[] captured as ByValue here + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:142:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | println!("{:?}", u); +... | +LL | | }; + | |_________^ + | +note: Capturing u[] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:145:30 + | +LL | println!("{:?}", u); + | ^ +note: Capturing u[(1, 0)] -> Mutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:149:13 + | +LL | u.1 = '\0'; + | ^^^ +note: Capturing u[(0, 0),(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:152:18 + | +LL | drop(u.0.0); // `u.0.0` captured by ByCopy + | ^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:142:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | println!("{:?}", u); +... | +LL | | }; + | |_________^ + | +note: Min Capture u[] -> Mutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:145:30 + | +LL | println!("{:?}", u); + | ^ u[] used here +... +LL | u.1 = '\0'; + | ^^^ u[] captured as Mutable here + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:199:43 + | +LL | let c = #[rustc_capture_analysis] || unsafe { + | ___________________________________________^ +LL | | +LL | | +LL | | println!("{}", (*t_ptr).0); +... | +LL | | }; + | |_________^ + | +note: Capturing t_ptr[Deref,(0, 0)] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:202:28 + | +LL | println!("{}", (*t_ptr).0); + | ^^^^^^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:199:43 + | +LL | let c = #[rustc_capture_analysis] || unsafe { + | ___________________________________________^ +LL | | +LL | | +LL | | println!("{}", (*t_ptr).0); +... | +LL | | }; + | |_________^ + | +note: Min Capture t_ptr[] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:202:28 + | +LL | println!("{}", (*t_ptr).0); + | ^^^^^^^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:216:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let x = unsafe { u.a.0 }; +... | +LL | | }; + | |_________^ + | +note: Capturing u[(0, 0),(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:219:30 + | +LL | let x = unsafe { u.a.0 }; + | ^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:216:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let x = unsafe { u.a.0 }; +... | +LL | | }; + | |_________^ + | +note: Min Capture u[] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:219:30 + | +LL | let x = unsafe { u.a.0 }; + | ^^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:228:47 + | +LL | let mut c = #[rustc_capture_analysis] || { + | _______________________________________________^ +LL | | +LL | | +LL | | u.b = true; +... | +LL | | }; + | |_________^ + | +note: Capturing u[(1, 0)] -> Mutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:231:13 + | +LL | u.b = true; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:228:47 + | +LL | let mut c = #[rustc_capture_analysis] || { + | _______________________________________________^ +LL | | +LL | | +LL | | u.b = true; +... | +LL | | }; + | |_________^ + | +note: Min Capture u[] -> Mutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:231:13 + | +LL | u.b = true; + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:247:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let x = unsafe { u.a.0.len() }; +... | +LL | | }; + | |_________^ + | +note: Capturing u[(0, 0),(0, 0),Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:250:30 + | +LL | let x = unsafe { u.a.0.len() }; + | ^^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:247:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let x = unsafe { u.a.0.len() }; +... | +LL | | }; + | |_________^ + | +note: Min Capture u[] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:250:30 + | +LL | let x = unsafe { u.a.0.len() }; + | ^^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:262:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let a = t.0; +... | +LL | | }; + | |_________^ + | +note: Capturing t[(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:265:21 + | +LL | let a = t.0; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:262:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let a = t.0; +... | +LL | | }; + | |_________^ + | +note: Min Capture t[(0, 0)] -> ByCopy + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:265:21 + | +LL | let a = t.0; + | ^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:279:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let a = *t.0; +... | +LL | | }; + | |_________^ + | +note: Capturing t[(0, 0),Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:282:21 + | +LL | let a = *t.0; + | ^^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:279:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let a = *t.0; +... | +LL | | }; + | |_________^ + | +note: Min Capture t[(0, 0),Deref] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:282:21 + | +LL | let a = *t.0; + | ^^^^ + +error: First Pass analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:295:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let a = &raw const t.1; +... | +LL | | }; + | |_________^ + | +note: Capturing t[(1, 0)] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:298:32 + | +LL | let a = &raw const t.1; + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:295:43 + | +LL | let c = #[rustc_capture_analysis] || { + | ___________________________________________^ +LL | | +LL | | +LL | | let a = &raw const t.1; +... | +LL | | }; + | |_________^ + | +note: Min Capture t[(1, 0)] -> Immutable + --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:298:32 + | +LL | let a = &raw const t.1; + | ^^^ + +error: aborting due to 40 previous errors + diff --git a/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2018.stderr b/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2018.stderr new file mode 100644 index 0000000000000..a0dac20aeef15 --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2018.stderr @@ -0,0 +1,71 @@ +error[E0277]: `PhantomPinned` cannot be unpinned + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24 + | +LL | assert_auto_traits(|| { + | ------------------ ^- + | | | + | _____|__________________within this `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}` + | | | + | | required by a bound introduced by this call +LL | | +LL | | +LL | | let _foo = foo; +LL | | }); + | |_____^ unsatisfied trait bound + | + = help: within `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}`, the trait `Unpin` is not implemented for `PhantomPinned` + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +note: required because it appears within the type `Foo` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:8:36 + | +LL | struct Foo(PhantomData<*const ()>, PhantomPinned); + | ^^^^^^^^^^^^^ required by this field +note: required because `foo` is used within this closure + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:17:20 + | +LL | let _foo = foo; + | ^^^ +note: required by a bound in `assert_auto_traits` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:21:45 + | +LL | fn assert_auto_traits(_: impl Fn() + Send + Unpin) {} + | ^^^^^ required by this bound in `assert_auto_traits` + +error[E0277]: `*const ()` cannot be sent between threads safely + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24 + | +LL | assert_auto_traits(|| { + | ------------------ ^- + | | | + | _____|__________________within this `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}` + | | | + | | required by a bound introduced by this call +LL | | +LL | | +LL | | let _foo = foo; +LL | | }); + | |_____^ `*const ()` cannot be sent between threads safely + | + = help: within `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}`, the trait `Send` is not implemented for `*const ()` +note: required because it appears within the type `PhantomData<*const ()>` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: required because it appears within the type `Foo` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:8:12 + | +LL | struct Foo(PhantomData<*const ()>, PhantomPinned); + | ^^^^^^^^^^^^^^^^^^^^^^ required by this field +note: required because `foo` is used within this closure + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:17:20 + | +LL | let _foo = foo; + | ^^^ +note: required by a bound in `assert_auto_traits` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:21:38 + | +LL | fn assert_auto_traits(_: impl Fn() + Send + Unpin) {} + | ^^^^ required by this bound in `assert_auto_traits` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2021.stderr b/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2021.stderr new file mode 100644 index 0000000000000..a0dac20aeef15 --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.edition2021.stderr @@ -0,0 +1,71 @@ +error[E0277]: `PhantomPinned` cannot be unpinned + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24 + | +LL | assert_auto_traits(|| { + | ------------------ ^- + | | | + | _____|__________________within this `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}` + | | | + | | required by a bound introduced by this call +LL | | +LL | | +LL | | let _foo = foo; +LL | | }); + | |_____^ unsatisfied trait bound + | + = help: within `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}`, the trait `Unpin` is not implemented for `PhantomPinned` + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +note: required because it appears within the type `Foo` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:8:36 + | +LL | struct Foo(PhantomData<*const ()>, PhantomPinned); + | ^^^^^^^^^^^^^ required by this field +note: required because `foo` is used within this closure + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:17:20 + | +LL | let _foo = foo; + | ^^^ +note: required by a bound in `assert_auto_traits` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:21:45 + | +LL | fn assert_auto_traits(_: impl Fn() + Send + Unpin) {} + | ^^^^^ required by this bound in `assert_auto_traits` + +error[E0277]: `*const ()` cannot be sent between threads safely + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24 + | +LL | assert_auto_traits(|| { + | ------------------ ^- + | | | + | _____|__________________within this `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}` + | | | + | | required by a bound introduced by this call +LL | | +LL | | +LL | | let _foo = foo; +LL | | }); + | |_____^ `*const ()` cannot be sent between threads safely + | + = help: within `{closure@$DIR/cromulent-copy-closure-captures-auto-traits.rs:14:24: 14:26}`, the trait `Send` is not implemented for `*const ()` +note: required because it appears within the type `PhantomData<*const ()>` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: required because it appears within the type `Foo` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:8:12 + | +LL | struct Foo(PhantomData<*const ()>, PhantomPinned); + | ^^^^^^^^^^^^^^^^^^^^^^ required by this field +note: required because `foo` is used within this closure + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:17:20 + | +LL | let _foo = foo; + | ^^^ +note: required by a bound in `assert_auto_traits` + --> $DIR/cromulent-copy-closure-captures-auto-traits.rs:21:38 + | +LL | fn assert_auto_traits(_: impl Fn() + Send + Unpin) {} + | ^^^^ required by this bound in `assert_auto_traits` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.rs b/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.rs new file mode 100644 index 0000000000000..494c9bcb7b8b2 --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-auto-traits.rs @@ -0,0 +1,21 @@ +//@ revisions: edition2018 edition2021 +//@ [edition2018] edition:2018 +//@ [edition2021] edition:2021.. + +use std::marker::{PhantomData, PhantomPinned}; + +#[derive(Clone, Copy)] +struct Foo(PhantomData<*const ()>, PhantomPinned); + +unsafe impl Sync for Foo {} + +fn main() { + let foo = Foo(PhantomData, PhantomPinned); + assert_auto_traits(|| { + //~^ ERROR `PhantomPinned` cannot be unpinned + //~| ERROR `*const ()` cannot be sent between threads safely + let _foo = foo; + }); +} + +fn assert_auto_traits(_: impl Fn() + Send + Unpin) {} diff --git a/tests/ui/closures/cromulent-copy-closure-captures-fail.edition2018.stderr b/tests/ui/closures/cromulent-copy-closure-captures-fail.edition2018.stderr new file mode 100644 index 0000000000000..235bc548b1fcb --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-fail.edition2018.stderr @@ -0,0 +1,134 @@ +error[E0700]: hidden type for `impl FnMut()` captures lifetime that does not appear in bounds + --> $DIR/cromulent-copy-closure-captures-fail.rs:72:9 + | +LL | fn baz<'a, 'b, 'c>(m: &'a MyStruct<'b, 'c>) -> impl FnMut() + use<'c> { + | ---------------------- opaque type defined here +... +LL | c + | ^ + | + = note: hidden type `{closure@$DIR/cromulent-copy-closure-captures-fail.rs:69:17: 69:19}` captures lifetime `'_` + +error[E0597]: `foo` does not live long enough + --> $DIR/cromulent-copy-closure-captures-fail.rs:12:29 + | +LL | let closure = { + | ------- borrow later captured here by closure +LL | let mut foo = 42; + | ------- binding `foo` declared here +LL | let foo_ref: &u32 = &foo; + | ^^^^ borrowed value does not live long enough +LL | || *foo_ref +LL | }; + | - `foo` dropped here while still borrowed + +error[E0597]: `foo` does not live long enough + --> $DIR/cromulent-copy-closure-captures-fail.rs:19:33 + | +LL | let closure = { + | ------- borrow later captured here by closure +LL | let mut foo = 42; + | ------- binding `foo` declared here +LL | let foo_mut: &mut u32 = &mut foo; + | ^^^^^^^^ borrowed value does not live long enough +LL | || *foo_mut +LL | }; + | - `foo` dropped here while still borrowed + +error[E0373]: closure may outlive the current block, but it borrows `foo_mut`, which is owned by the current block + --> $DIR/cromulent-copy-closure-captures-fail.rs:20:9 + | +LL | ... || *foo_mut + | ^^ -------- `foo_mut` is borrowed here + | | + | may outlive borrowed value `foo_mut` + | +note: block requires argument type to outlive `'1` + --> $DIR/cromulent-copy-closure-captures-fail.rs:17:9 + | +LL | let closure = { + | ^^^^^^^ +help: to force the closure to take ownership of `foo_mut` (and any other referenced variables), use the `move` keyword + | +LL | move || *foo_mut + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `really_large_copy_value`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:25:19 + | +LL | let closure = || { + | ^^ may outlive borrowed value `really_large_copy_value` +LL | +LL | let really_large_copy_ref = &really_large_copy_value; + | ----------------------- `really_large_copy_value` is borrowed here + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:32:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `really_large_copy_value` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `really_large_copy_value`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:34:19 + | +LL | let closure = || { + | ^^ may outlive borrowed value `really_large_copy_value` +LL | +LL | let _ = &really_large_copy_value; + | ----------------------- `really_large_copy_value` is borrowed here + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:41:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `really_large_copy_value` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `really_large_copy_value`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:43:19 + | +LL | let closure = || { + | ^^ may outlive borrowed value `really_large_copy_value` +... +LL | drop(*&really_large_copy_value); + | ----------------------- `really_large_copy_value` is borrowed here + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:49:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `really_large_copy_value` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `val`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:53:19 + | +LL | let closure = || val == 21; + | ^^ --- `val` is borrowed here + | | + | may outlive borrowed value `val` + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:55:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `val` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || val == 21; + | ++++ + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0373, E0597, E0700. +For more information about an error, try `rustc --explain E0373`. diff --git a/tests/ui/closures/cromulent-copy-closure-captures-fail.edition2021.stderr b/tests/ui/closures/cromulent-copy-closure-captures-fail.edition2021.stderr new file mode 100644 index 0000000000000..f4ba75e50568c --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-fail.edition2021.stderr @@ -0,0 +1,116 @@ +error[E0700]: hidden type for `impl FnMut()` captures lifetime that does not appear in bounds + --> $DIR/cromulent-copy-closure-captures-fail.rs:72:9 + | +LL | fn baz<'a, 'b, 'c>(m: &'a MyStruct<'b, 'c>) -> impl FnMut() + use<'c> { + | ---------------------- opaque type defined here +... +LL | c + | ^ + | + = note: hidden type `{closure@$DIR/cromulent-copy-closure-captures-fail.rs:69:17: 69:19}` captures lifetime `'_` + +error[E0597]: `foo` does not live long enough + --> $DIR/cromulent-copy-closure-captures-fail.rs:12:29 + | +LL | let closure = { + | ------- borrow later captured here by closure +LL | let mut foo = 42; + | ------- binding `foo` declared here +LL | let foo_ref: &u32 = &foo; + | ^^^^ borrowed value does not live long enough +LL | || *foo_ref +LL | }; + | - `foo` dropped here while still borrowed + +error[E0597]: `foo` does not live long enough + --> $DIR/cromulent-copy-closure-captures-fail.rs:19:33 + | +LL | let closure = { + | ------- borrow later captured here by closure +LL | let mut foo = 42; + | ------- binding `foo` declared here +LL | let foo_mut: &mut u32 = &mut foo; + | ^^^^^^^^ borrowed value does not live long enough +LL | || *foo_mut +LL | }; + | - `foo` dropped here while still borrowed + +error[E0373]: closure may outlive the current function, but it borrows `really_large_copy_value`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:25:19 + | +LL | let closure = || { + | ^^ may outlive borrowed value `really_large_copy_value` +LL | +LL | let really_large_copy_ref = &really_large_copy_value; + | ----------------------- `really_large_copy_value` is borrowed here + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:32:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `really_large_copy_value` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `really_large_copy_value`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:34:19 + | +LL | let closure = || { + | ^^ may outlive borrowed value `really_large_copy_value` +LL | +LL | let _ = &really_large_copy_value; + | ----------------------- `really_large_copy_value` is borrowed here + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:41:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `really_large_copy_value` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `really_large_copy_value`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:43:19 + | +LL | let closure = || { + | ^^ may outlive borrowed value `really_large_copy_value` +... +LL | drop(*&really_large_copy_value); + | ----------------------- `really_large_copy_value` is borrowed here + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:49:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `really_large_copy_value` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `val`, which is owned by the current function + --> $DIR/cromulent-copy-closure-captures-fail.rs:53:19 + | +LL | let closure = || val == 21; + | ^^ --- `val` is borrowed here + | | + | may outlive borrowed value `val` + | +note: function requires argument type to outlive `'static` + --> $DIR/cromulent-copy-closure-captures-fail.rs:55:5 + | +LL | assert_static_fn(closure); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to force the closure to take ownership of `val` (and any other referenced variables), use the `move` keyword + | +LL | let closure = move || val == 21; + | ++++ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0373, E0597, E0700. +For more information about an error, try `rustc --explain E0373`. diff --git a/tests/ui/closures/cromulent-copy-closure-captures-fail.rs b/tests/ui/closures/cromulent-copy-closure-captures-fail.rs new file mode 100644 index 0000000000000..9daf27c460788 --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures-fail.rs @@ -0,0 +1,77 @@ +//@ revisions: edition2018 edition2021 +//@ [edition2018] edition:2018 +//@ [edition2021] edition:2021.. + +use core::convert::identity; + +fn assert_static_fn(_: impl Fn() -> Ret + 'static) {} + +fn main() { + let closure = { + let mut foo = 42; + let foo_ref: &u32 = &foo; //~ ERROR `foo` does not live long enough + || *foo_ref + }; + closure(); + + let closure = { + let mut foo = 42; + let foo_mut: &mut u32 = &mut foo; //~ ERROR `foo` does not live long enough + || *foo_mut //[edition2018]~ ERROR closure may outlive the current block, but it borrows `foo_mut`, which is owned by the current block + }; + closure(); + + let really_large_copy_value = [42u128; 10_000]; + let closure = || { + //~^ ERROR closure may outlive the current function + let really_large_copy_ref = &really_large_copy_value; + if identity(false) { + drop(*really_large_copy_ref); + } + }; + assert_static_fn(closure); + + let closure = || { + //~^ ERROR closure may outlive the current function + let _ = &really_large_copy_value; + if identity(false) { + drop(really_large_copy_value); + } + }; + assert_static_fn(closure); + + let closure = || { + //~^ ERROR closure may outlive the current function + if identity(false) { + drop(*&really_large_copy_value); + } + }; + assert_static_fn(closure); + + let val = 21; + // `==` takes an implicit reference + let closure = || val == 21; + //~^ ERROR closure may outlive the current function + assert_static_fn(closure); + + #[allow(unused)] + struct Int(i32); + #[allow(unused)] + #[derive(Clone, Copy)] + struct B<'a>(&'a i32); + + struct MyStruct<'a, 'b> { + _a: &'a Int, + b: B<'b>, + } + + fn baz<'a, 'b, 'c>(m: &'a MyStruct<'b, 'c>) -> impl FnMut() + use<'c> { + let c = || { + let _unused = m.b; + }; + c + //~^ ERROR hidden type for `impl FnMut()` captures lifetime that does not appear in bounds + } + + baz(&MyStruct { _a: &Int(42), b: B(&42) })(); +} diff --git a/tests/ui/closures/cromulent-copy-closure-captures.rs b/tests/ui/closures/cromulent-copy-closure-captures.rs new file mode 100644 index 0000000000000..663223822667c --- /dev/null +++ b/tests/ui/closures/cromulent-copy-closure-captures.rs @@ -0,0 +1,68 @@ +//@ run-pass +//@ revisions: edition2018 edition2021 +//@ [edition2018] edition:2018 +//@ [edition2021] edition:2021 + +fn assert_static_fn(_: impl Fn() -> Ret + 'static) {} + +fn callable(c: char) -> impl Fn() -> char { + || c +} + +fn main() { + let foo: u32 = 42; + let closure = || foo; + assert_static_fn::(closure); + + let _ = callable('c')(); + + let cs: u32 = (0..0xCC).flat_map(|c| (0..c).map(|cc| c + cc)).sum(); + assert_eq!(cs, 4203318); + + let mut x = false; + (|| { + let _x = x; + x = !x; + })(); + assert!(x); + + let x = false; + let addr = &raw const x; + (|| { + let _x = x; + assert_eq!(addr, &raw const x); + })(); + + let mut x = 2i32; + let ref_mut = &mut x; + (|| { + *ref_mut = 42; + })(); + assert_eq!(*ref_mut, 42); + + let y: i32 = 5; + let closure = |x: i32| x + y; + assert_eq!(size_of_val(&closure), 4); + + { + let val = 21; + let raw_ptr = &raw const val; + let closure = || assert_eq!(unsafe { *raw_ptr }, 21); + assert_static_fn(closure); + } + + { + let mut val = (21,); + let raw_mut_ptr = &raw mut val; + let closure = || unsafe { + (*raw_mut_ptr).0 = 42; + }; + assert_static_fn(closure); + } + + { + let val = 21; + let closure = || { val } == 21; + assert_static_fn(closure); + } +} diff --git a/tests/ui/closures/drop-copy-2015.rs b/tests/ui/closures/drop-copy-2015.rs new file mode 100644 index 0000000000000..3afe710c7cde6 --- /dev/null +++ b/tests/ui/closures/drop-copy-2015.rs @@ -0,0 +1,25 @@ +//@ edition:2015 +//@ run-pass + +use std::cell::Cell; + +struct NoisyDrop<'a>(&'a Cell); + +impl Drop for NoisyDrop<'_> { + fn drop(&mut self) { + self.0.set(true); + } +} + +fn main() { + let dropped = Cell::new(false); + let t = (NoisyDrop(&dropped), 0i32); + + let c = || { + let _t = t.1; + }; + + c(); + + assert!(!dropped.get()); +} diff --git a/tests/ui/coercion/no_structural_identity_dependent_reborrows.rs b/tests/ui/coercion/no_structural_identity_dependent_reborrows.rs new file mode 100644 index 0000000000000..86dd5f0f30e73 --- /dev/null +++ b/tests/ui/coercion/no_structural_identity_dependent_reborrows.rs @@ -0,0 +1,21 @@ +//@ edition: 2024 +//@ run-pass + +fn foo<'a>(b: &'a ()) -> impl Fn() { + || { + expected::<&()>(b); + } +} + +fn bar<'a>(b: &'a ()) -> impl Fn() { + || { + expected::<&'a ()>(b); + } +} + +fn expected(_: T) {} + +fn main() { + foo(&())(); + bar(&())(); +} diff --git a/tests/ui/coercion/structural_identity_dependent_reborrows.rs b/tests/ui/coercion/structural_identity_dependent_reborrows.rs index 60cf28aaf3032..2206c0ecac6e9 100644 --- a/tests/ui/coercion/structural_identity_dependent_reborrows.rs +++ b/tests/ui/coercion/structural_identity_dependent_reborrows.rs @@ -4,18 +4,18 @@ // not result in a different lifetime on the borrow. This can effect // capture analysis resulting in borrow checking errors. -fn foo<'a>(b: &'a ()) -> impl Fn() { +fn foo<'a>(b: &'a mut ()) -> impl FnMut() { || { - expected::<&()>(b); + expected::<&mut ()>(b); } } // No reborrow of `b` is emitted which means our closure captures -// `b` by ref resulting in an upvar of `&&'a ()` -fn bar<'a>(b: &'a ()) -> impl Fn() { +// `b` by ref resulting in an upvar of `&mut &'a mut ()` +fn bar<'a>(b: &'a mut ()) -> impl FnMut() { || { - //~^ ERROR: closure may outlive the current function - expected::<&'a ()>(b); + expected::<&'a mut ()>(b); + //~^ ERROR: lifetime may not live long enough } } diff --git a/tests/ui/coercion/structural_identity_dependent_reborrows.stderr b/tests/ui/coercion/structural_identity_dependent_reborrows.stderr index d598a4fa76331..125b5745cbaf6 100644 --- a/tests/ui/coercion/structural_identity_dependent_reborrows.stderr +++ b/tests/ui/coercion/structural_identity_dependent_reborrows.stderr @@ -1,25 +1,14 @@ -error[E0373]: closure may outlive the current function, but it borrows `b`, which is owned by the current function - --> $DIR/structural_identity_dependent_reborrows.rs:16:5 +error: lifetime may not live long enough + --> $DIR/structural_identity_dependent_reborrows.rs:17:9 | +LL | fn bar<'a>(b: &'a mut ()) -> impl FnMut() { + | -- lifetime `'a` defined here LL | || { - | ^^ may outlive borrowed value `b` -LL | -LL | expected::<&'a ()>(b); - | - `b` is borrowed here + | -- lifetime `'1` represents this closure's body +LL | expected::<&'a mut ()>(b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a` | -note: closure is returned here - --> $DIR/structural_identity_dependent_reborrows.rs:16:5 - | -LL | / || { -LL | | -LL | | expected::<&'a ()>(b); -LL | | } - | |_____^ -help: to force the closure to take ownership of `b` (and any other referenced variables), use the `move` keyword - | -LL | move || { - | ++++ + = note: closure implements `FnMut`, so references to captured variables can't escape the closure error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0373`. diff --git a/tests/ui/coroutine/static-move-suggestion.fixed b/tests/ui/coroutine/static-move-suggestion.fixed index 56445be4715ff..a69d62e46464f 100644 --- a/tests/ui/coroutine/static-move-suggestion.fixed +++ b/tests/ui/coroutine/static-move-suggestion.fixed @@ -10,7 +10,7 @@ fn check() -> impl Sized { static move || { //~^ ERROR E0373 yield; - x + *&x } } diff --git a/tests/ui/coroutine/static-move-suggestion.rs b/tests/ui/coroutine/static-move-suggestion.rs index 1d6e4a6288311..aa62fca4e6d40 100644 --- a/tests/ui/coroutine/static-move-suggestion.rs +++ b/tests/ui/coroutine/static-move-suggestion.rs @@ -10,7 +10,7 @@ fn check() -> impl Sized { static || { //~^ ERROR E0373 yield; - x + *&x } } diff --git a/tests/ui/coroutine/static-move-suggestion.stderr b/tests/ui/coroutine/static-move-suggestion.stderr index 6d890468b322c..812121a881931 100644 --- a/tests/ui/coroutine/static-move-suggestion.stderr +++ b/tests/ui/coroutine/static-move-suggestion.stderr @@ -4,8 +4,8 @@ error[E0373]: coroutine may outlive the current function, but it borrows `x`, wh LL | static || { | ^^^^^^^^^ may outlive borrowed value `x` ... -LL | x - | - `x` is borrowed here +LL | *&x + | - `x` is borrowed here | note: coroutine is returned here --> $DIR/static-move-suggestion.rs:10:5 @@ -13,7 +13,7 @@ note: coroutine is returned here LL | / static || { LL | | LL | | yield; -LL | | x +LL | | *&x LL | | } | |_____^ help: to force the coroutine to take ownership of `x` (and any other referenced variables), use the `move` keyword diff --git a/tests/ui/ergonomic-clones/closure/dotuse-no-extra-capture-clone.rs b/tests/ui/ergonomic-clones/closure/dotuse-extra-capture-clone.rs similarity index 74% rename from tests/ui/ergonomic-clones/closure/dotuse-no-extra-capture-clone.rs rename to tests/ui/ergonomic-clones/closure/dotuse-extra-capture-clone.rs index c1662d6f4d1b8..00a69cb48e936 100644 --- a/tests/ui/ergonomic-clones/closure/dotuse-no-extra-capture-clone.rs +++ b/tests/ui/ergonomic-clones/closure/dotuse-extra-capture-clone.rs @@ -1,9 +1,5 @@ -//! Regression test for #157141. -//! -//! A non-`move`, non-`use` closure that only `.use`s an upvar should capture it -//! by immutable borrow, not by `use` (which would clone the value into the -//! closure at construction time). The `.use` expression in the body is then the -//! only thing that clones, once per evaluation. +//! A non-`move`, non-`use` closure that only `.use`s an upvar should still capture it +//! by `.use`, to ensure we do not unduly restrict the lifetime of the closure. //@ run-pass @@ -31,9 +27,11 @@ fn clones_during(f: impl FnOnce() -> R) -> usize { CLONES.load(Ordering::Relaxed) - before } +fn assert_static_fn(_: &(impl Fn() + 'static)) {} + fn main() { - // Plain `||` closure: `x` is borrowed, so building the closure clones nothing. - // Each call clones exactly once via the `.use` in the body. + // Plain `||` closure: `x` is cloned once at construction time. + // After that, each call clones exactly once via the `.use` in the body. let x = Thing; let n = clones_during(|| { let closure = || { @@ -41,8 +39,9 @@ fn main() { }; closure(); closure(); + assert_static_fn(&closure); }); - assert_eq!(n, 2, "plain `||` closure should clone once per call, not also at capture"); + assert_eq!(n, 3, "plain `||` closure should clone once per call, and also at capture"); drop(x); // `move ||` closure: `x` is moved in (no capture clone), `.use` clones per call. diff --git a/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.rs b/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.rs index 323d42bdc979f..317ecc71a9544 100644 --- a/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.rs +++ b/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.rs @@ -24,7 +24,7 @@ impl Location<'_> { lines.enumerate().filter_map(|(i, line)| { //~^ ERROR closure may outlive the current function, but it borrows `self.start.line`, which is owned by the current function //~| ERROR closure may outlive the current function, but it borrows `self.end.line`, which is owned by the current function - if self.start.line as usize <= i && i <= self.end.line as usize { + if *&self.start.line as usize <= i && i <= *&self.end.line as usize { Some((i as u32 + 1, line)) } else { None diff --git a/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.stderr b/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.stderr index 81cad8de969eb..f714fdfa2de81 100644 --- a/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.stderr +++ b/tests/ui/impl-trait/confusing-lifetime-error-issue-79033.stderr @@ -4,8 +4,8 @@ error[E0373]: closure may outlive the current function, but it borrows `self.sta LL | lines.enumerate().filter_map(|(i, line)| { | ^^^^^^^^^^^ may outlive borrowed value `self.start.line` ... -LL | if self.start.line as usize <= i && i <= self.end.line as usize { - | --------------- `self.start.line` is borrowed here +LL | if *&self.start.line as usize <= i && i <= *&self.end.line as usize { + | --------------- `self.start.line` is borrowed here | note: function requires argument type to outlive `'static` --> $DIR/confusing-lifetime-error-issue-79033.rs:24:9 @@ -13,7 +13,7 @@ note: function requires argument type to outlive `'static` LL | / lines.enumerate().filter_map(|(i, line)| { LL | | LL | | -LL | | if self.start.line as usize <= i && i <= self.end.line as usize { +LL | | if *&self.start.line as usize <= i && i <= *&self.end.line as usize { ... | LL | | }) | |__________^ @@ -28,8 +28,8 @@ error[E0373]: closure may outlive the current function, but it borrows `self.end LL | lines.enumerate().filter_map(|(i, line)| { | ^^^^^^^^^^^ may outlive borrowed value `self.end.line` ... -LL | if self.start.line as usize <= i && i <= self.end.line as usize { - | ------------- `self.end.line` is borrowed here +LL | if *&self.start.line as usize <= i && i <= *&self.end.line as usize { + | ------------- `self.end.line` is borrowed here | note: function requires argument type to outlive `'static` --> $DIR/confusing-lifetime-error-issue-79033.rs:24:9 @@ -37,7 +37,7 @@ note: function requires argument type to outlive `'static` LL | / lines.enumerate().filter_map(|(i, line)| { LL | | LL | | -LL | | if self.start.line as usize <= i && i <= self.end.line as usize { +LL | | if *&self.start.line as usize <= i && i <= *&self.end.line as usize { ... | LL | | }) | |__________^ diff --git a/tests/ui/impl-trait/does-not-live-long-enough.rs b/tests/ui/impl-trait/does-not-live-long-enough.rs index d2a345231eb43..ef7655ec09b89 100644 --- a/tests/ui/impl-trait/does-not-live-long-enough.rs +++ b/tests/ui/impl-trait/does-not-live-long-enough.rs @@ -2,10 +2,14 @@ struct List { data: Vec, } impl List { - fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator { - self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref()) + fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator { + self.data.iter().filter(|s| s.starts_with(*&prefix)).map(|s| s.as_ref()) //~^ ERROR E0373 } + + fn works<'a>(&'a self, prefix: &'a str) -> impl Iterator { + self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref()) + } } fn main() {} diff --git a/tests/ui/impl-trait/does-not-live-long-enough.stderr b/tests/ui/impl-trait/does-not-live-long-enough.stderr index 9f3918ce3e082..6b20ef04d6301 100644 --- a/tests/ui/impl-trait/does-not-live-long-enough.stderr +++ b/tests/ui/impl-trait/does-not-live-long-enough.stderr @@ -1,21 +1,21 @@ error[E0373]: closure may outlive the current function, but it borrows `prefix`, which is owned by the current function --> $DIR/does-not-live-long-enough.rs:6:33 | -LL | fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator { +LL | fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator { | -- lifetime `'a` defined here -LL | self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref()) - | ^^^ ------ `prefix` is borrowed here +LL | self.data.iter().filter(|s| s.starts_with(*&prefix)).map(|s| s.as_ref()) + | ^^^ ------ `prefix` is borrowed here | | | may outlive borrowed value `prefix` | note: function requires argument type to outlive `'a` --> $DIR/does-not-live-long-enough.rs:6:9 | -LL | self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | self.data.iter().filter(|s| s.starts_with(*&prefix)).map(|s| s.as_ref()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `prefix` (and any other referenced variables), use the `move` keyword | -LL | self.data.iter().filter(move |s| s.starts_with(prefix)).map(|s| s.as_ref()) +LL | self.data.iter().filter(move |s| s.starts_with(*&prefix)).map(|s| s.as_ref()) | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs b/tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs index 4b99ff285b525..2b2410e15d496 100644 --- a/tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs +++ b/tests/ui/impl-trait/non-defining-uses/no-defining-use-return-hir-typeck-ty-ice-127033.rs @@ -24,7 +24,7 @@ impl RaftLogStorage for X { fn save_vote(vote: ()) -> impl std::future::Future { loop {} async { - vote + &vote } } } diff --git a/tests/ui/iterators/generator_returned_from_fn.rs b/tests/ui/iterators/generator_returned_from_fn.rs index efc681c318007..f8b8da0eb956d 100644 --- a/tests/ui/iterators/generator_returned_from_fn.rs +++ b/tests/ui/iterators/generator_returned_from_fn.rs @@ -22,7 +22,7 @@ fn arg() -> impl Fn(u32) -> impl Iterator { } fn capture<'a>(a: &'a u32) -> impl Fn() -> (impl Iterator + 'a) { - iter! { || { //~ ERROR cannot return reference to function parameter `a` + iter! { || { yield *a; for x in 5..10 { yield x * 2; @@ -31,7 +31,9 @@ fn capture<'a>(a: &'a u32) -> impl Fn() -> (impl Iterator + 'a) { } fn capture_move(a: &u32) -> impl Fn() -> impl Iterator { - iter! { move || { //~ ERROR does not implement `Fn` because it captures + iter! { move || { + //~^ ERROR hidden type for `impl Fn() -> impl Iterator` captures lifetime that does not appear in bounds + //~| ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bounds yield *a; for x in 5..10 { yield x * 2; diff --git a/tests/ui/iterators/generator_returned_from_fn.stderr b/tests/ui/iterators/generator_returned_from_fn.stderr index f4620b958f0c6..f5e187dfdf857 100644 --- a/tests/ui/iterators/generator_returned_from_fn.stderr +++ b/tests/ui/iterators/generator_returned_from_fn.stderr @@ -1,29 +1,47 @@ -error[E0515]: cannot return reference to function parameter `a` - --> $DIR/generator_returned_from_fn.rs:25:13 +error[E0700]: hidden type for `impl Fn() -> impl Iterator` captures lifetime that does not appear in bounds + --> $DIR/generator_returned_from_fn.rs:34:13 | -LL | iter! { || { +LL | fn capture_move(a: &u32) -> impl Fn() -> impl Iterator { + | ---- -------------------------------------- opaque type defined here + | | + | hidden type `{gen closure@...}` captures the anonymous lifetime defined here +LL | iter! { move || { | _____________^ +LL | | +LL | | LL | | yield *a; -LL | | for x in 5..10 { -LL | | yield x * 2; -LL | | } +... | LL | | } } - | |_____^ returns a reference to data owned by the current function + | |_____^ + | +help: add a `use<...>` bound to explicitly capture `'_` + | +LL | fn capture_move(a: &u32) -> impl Fn() -> impl Iterator + use<'_> { + | +++++++++ -error: gen closure does not implement `Fn` because it captures state from its environment +error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds --> $DIR/generator_returned_from_fn.rs:34:13 | +LL | fn capture_move(a: &u32) -> impl Fn() -> impl Iterator { + | ---- ------------------------- opaque type defined here + | | + | hidden type `{gen closure body@...}` captures the anonymous lifetime defined here LL | iter! { move || { - | _____________-^^^^^^ + | _____________^ +LL | | +LL | | LL | | yield *a; -LL | | for x in 5..10 { -LL | | yield x * 2; -LL | | } +... | LL | | } } - | |_____- return type was inferred to be `{gen closure@$DIR/generator_returned_from_fn.rs:34:13: 34:20}` here + | |_____^ + | +help: add a `use<...>` bound to explicitly capture `'_` + | +LL | fn capture_move(a: &u32) -> impl Fn() -> impl Iterator + use<'_> { + | +++++++++ error[E0700]: hidden type for `impl FnOnce() -> impl Iterator` captures lifetime that does not appear in bounds - --> $DIR/generator_returned_from_fn.rs:43:13 + --> $DIR/generator_returned_from_fn.rs:45:13 | LL | fn capture_move_once(a: &u32) -> impl FnOnce() -> impl Iterator { | ---- ------------------------------------------ opaque type defined here @@ -44,7 +62,7 @@ LL | fn capture_move_once(a: &u32) -> impl FnOnce() -> impl Iterator | +++++++++ error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds - --> $DIR/generator_returned_from_fn.rs:43:13 + --> $DIR/generator_returned_from_fn.rs:45:13 | LL | fn capture_move_once(a: &u32) -> impl FnOnce() -> impl Iterator { | ---- ------------------------- opaque type defined here @@ -66,5 +84,4 @@ LL | fn capture_move_once(a: &u32) -> impl FnOnce() -> impl Iterator error: aborting due to 4 previous errors -Some errors have detailed explanations: E0515, E0700. -For more information about an error, try `rustc --explain E0515`. +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/liveness/liveness-upvars.rs b/tests/ui/liveness/liveness-upvars.rs index 0d24fa1745cad..67a4a51eb0398 100644 --- a/tests/ui/liveness/liveness-upvars.rs +++ b/tests/ui/liveness/liveness-upvars.rs @@ -73,7 +73,7 @@ pub fn f() { pub fn nested() { let mut d = None; - let mut e = None; + let mut e = None; //~ WARN unused variable: `e` let _ = || { let _ = || { d = Some("d1"); //~ WARN value assigned to `d` is never read @@ -81,6 +81,7 @@ pub fn nested() { }; let _ = move || { e = Some("e1"); //~ WARN value captured by `e` is never read + //~| WARN value captured by `e` is never read //~| WARN value assigned to `e` is never read e = Some("e2"); //~ WARN value assigned to `e` is never read }; diff --git a/tests/ui/liveness/liveness-upvars.stderr b/tests/ui/liveness/liveness-upvars.stderr index b569acdccf8a7..c42cccea21216 100644 --- a/tests/ui/liveness/liveness-upvars.stderr +++ b/tests/ui/liveness/liveness-upvars.stderr @@ -113,12 +113,12 @@ warning: value assigned to `e` is never read | LL | e = Some("e1"); | ^^^^^^^^^^^^^^ this value is reassigned later and never used -LL | +... LL | e = Some("e2"); | -------------- `e` is overwritten here before the previous value is read warning: value assigned to `e` is never read - --> $DIR/liveness-upvars.rs:85:13 + --> $DIR/liveness-upvars.rs:86:13 | LL | e = Some("e2"); | ^^^^^^^^^^^^^^ @@ -133,8 +133,25 @@ LL | d = Some("d1"); LL | d = Some("d2"); | -------------- `d` is overwritten here before the previous value is read +warning: value captured by `e` is never read + --> $DIR/liveness-upvars.rs:83:13 + | +LL | e = Some("e1"); + | ^ + | + = help: did you mean to capture by reference instead? + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: unused variable: `e` + --> $DIR/liveness-upvars.rs:76:9 + | +LL | let mut e = None; + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_e` + | + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + warning: value assigned to `v` is never read - --> $DIR/liveness-upvars.rs:93:13 + --> $DIR/liveness-upvars.rs:94:13 | LL | v = T::default(); | ^ @@ -142,7 +159,7 @@ LL | v = T::default(); = help: maybe it is overwritten before being read? warning: value captured by `z` is never read - --> $DIR/liveness-upvars.rs:106:17 + --> $DIR/liveness-upvars.rs:107:17 | LL | z = T::default(); | ^ @@ -150,7 +167,7 @@ LL | z = T::default(); = help: did you mean to capture by reference instead? warning: value assigned to `z` is never read - --> $DIR/liveness-upvars.rs:106:17 + --> $DIR/liveness-upvars.rs:107:17 | LL | z = T::default(); | ^^^^^^^^^^^^^^^^ @@ -158,7 +175,7 @@ LL | z = T::default(); = help: maybe it is overwritten before being read? warning: value captured by `state` is never read - --> $DIR/liveness-upvars.rs:132:9 + --> $DIR/liveness-upvars.rs:133:9 | LL | state = 4; | ^^^^^ @@ -166,7 +183,7 @@ LL | state = 4; = help: did you mean to capture by reference instead? warning: value assigned to `state` is never read - --> $DIR/liveness-upvars.rs:132:9 + --> $DIR/liveness-upvars.rs:133:9 | LL | state = 4; | ^^^^^^^^^ this value is reassigned later and never used @@ -175,7 +192,7 @@ LL | state = 5; | --------- `state` is overwritten here before the previous value is read warning: value assigned to `state` is never read - --> $DIR/liveness-upvars.rs:135:9 + --> $DIR/liveness-upvars.rs:136:9 | LL | state = 5; | ^^^^^^^^^ @@ -183,7 +200,7 @@ LL | state = 5; = help: maybe it is overwritten before being read? warning: value assigned to `s` is never read - --> $DIR/liveness-upvars.rs:144:9 + --> $DIR/liveness-upvars.rs:145:9 | LL | s = 1; | ^^^^^ this value is reassigned later and never used @@ -191,12 +208,12 @@ LL | yield (s = 2); | ------- `s` is overwritten here before the previous value is read warning: value assigned to `s` is never read - --> $DIR/liveness-upvars.rs:146:9 + --> $DIR/liveness-upvars.rs:147:9 | LL | s = yield (); | ^^^^^^^^^^^^ this value is reassigned later and never used LL | s = 3; | ----- `s` is overwritten here before the previous value is read -warning: 24 warnings emitted +warning: 26 warnings emitted diff --git a/tests/ui/nll/closure-access-spans.stderr b/tests/ui/nll/closure-access-spans.stderr index dc26ebbcfb190..b20f6d27085ae 100644 --- a/tests/ui/nll/closure-access-spans.stderr +++ b/tests/ui/nll/closure-access-spans.stderr @@ -1,14 +1,12 @@ -error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/closure-access-spans.rs:6:5 +error[E0503]: cannot use `x` because it was mutably borrowed + --> $DIR/closure-access-spans.rs:6:8 | LL | let r = &mut x; - | ------ mutable borrow occurs here + | ------ `x` is borrowed here LL | || x; - | ^^ - second borrow occurs due to use of `x` in closure - | | - | immutable borrow occurs here + | ^ use of borrowed `x` LL | r.use_mut(); - | - mutable borrow later used here + | - borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time --> $DIR/closure-access-spans.rs:12:5 @@ -123,5 +121,5 @@ LL | || x; error: aborting due to 9 previous errors -Some errors have detailed explanations: E0382, E0499, E0500, E0502, E0503, E0505. +Some errors have detailed explanations: E0382, E0499, E0500, E0503, E0505. For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/nll/closure-borrow-spans.rs b/tests/ui/nll/closure-borrow-spans.rs index 2ecab122da662..4ddd0f4af64d7 100644 --- a/tests/ui/nll/closure-borrow-spans.rs +++ b/tests/ui/nll/closure-borrow-spans.rs @@ -8,26 +8,47 @@ fn move_while_borrowed(x: String) { } fn borrow_mut_while_borrowed(mut x: i32) { - let f = || x; + let f = || *&x; let y = &mut x; //~ ERROR f.use_ref(); } +fn borrow_mut_while_not_borrowed(mut x: i32) { + let f = || x; + let y = &mut x; + f.use_ref(); +} + fn drop_while_borrowed() { let f; { let x = 1; - f = || x; //~ ERROR + f = || *&x; //~ ERROR + } + f.use_ref(); +} + +fn drop_while_not_borrowed() { + let f; + { + let x = 1; + f = || x; } f.use_ref(); } fn assign_while_borrowed(mut x: i32) { - let f = || x; + let f = || *&x; x = 1; //~ ERROR f.use_ref(); } +fn assign_while_not_borrowed(mut x: i32) { + let f = || x; + x = 1; + f.use_ref(); +} + fn copy_while_borrowed_mut(mut x: i32) { let f = || x = 0; let y = x; //~ ERROR @@ -97,5 +118,8 @@ fn assign_while_borrowed_unique(x: &mut i32) { fn main() {} -trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } -impl Fake for T { } +trait Fake { + fn use_mut(&mut self) {} + fn use_ref(&self) {} +} +impl Fake for T {} diff --git a/tests/ui/nll/closure-borrow-spans.stderr b/tests/ui/nll/closure-borrow-spans.stderr index 8ae792f7030cd..279c3c3e722b2 100644 --- a/tests/ui/nll/closure-borrow-spans.stderr +++ b/tests/ui/nll/closure-borrow-spans.stderr @@ -13,8 +13,8 @@ LL | f.use_ref(); error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> $DIR/closure-borrow-spans.rs:12:13 | -LL | let f = || x; - | -- - first borrow occurs due to use of `x` in closure +LL | let f = || *&x; + | -- - first borrow occurs due to use of `x` in closure | | | immutable borrow occurs here LL | let y = &mut x; @@ -23,12 +23,12 @@ LL | f.use_ref(); | - immutable borrow later used here error[E0597]: `x` does not live long enough - --> $DIR/closure-borrow-spans.rs:20:16 + --> $DIR/closure-borrow-spans.rs:26:18 | LL | let x = 1; | - binding `x` declared here -LL | f = || x; - | -- ^ borrowed value does not live long enough +LL | f = || *&x; + | -- ^ borrowed value does not live long enough | | | value captured here LL | } @@ -37,10 +37,10 @@ LL | f.use_ref(); | - borrow later used here error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:27:5 + --> $DIR/closure-borrow-spans.rs:42:5 | -LL | let f = || x; - | -- - borrow occurs due to use in closure +LL | let f = || *&x; + | -- - borrow occurs due to use in closure | | | `x` is borrowed here LL | x = 1; @@ -49,7 +49,7 @@ LL | f.use_ref(); | - borrow later used here error[E0503]: cannot use `x` because it was mutably borrowed - --> $DIR/closure-borrow-spans.rs:33:13 + --> $DIR/closure-borrow-spans.rs:54:13 | LL | let f = || x = 0; | -- - borrow occurs due to use of `x` in closure @@ -61,7 +61,7 @@ LL | f.use_ref(); | - borrow later used here error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/closure-borrow-spans.rs:39:13 + --> $DIR/closure-borrow-spans.rs:60:13 | LL | let f = || x = 0; | -- - first borrow occurs due to use of `x` in closure @@ -73,7 +73,7 @@ LL | f.use_ref(); | - mutable borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/closure-borrow-spans.rs:45:13 + --> $DIR/closure-borrow-spans.rs:66:13 | LL | let f = || x = 0; | -- - first borrow occurs due to use of `x` in closure @@ -85,7 +85,7 @@ LL | f.use_ref(); | - first borrow later used here error[E0597]: `x` does not live long enough - --> $DIR/closure-borrow-spans.rs:53:16 + --> $DIR/closure-borrow-spans.rs:74:16 | LL | let mut x = 1; | ----- binding `x` declared here @@ -99,7 +99,7 @@ LL | f.use_ref(); | - borrow later used here error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:60:5 + --> $DIR/closure-borrow-spans.rs:81:5 | LL | let f = || x = 0; | -- - borrow occurs due to use in closure @@ -111,7 +111,7 @@ LL | f.use_ref(); | - borrow later used here error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:66:13 + --> $DIR/closure-borrow-spans.rs:87:13 | LL | let f = || *x = 0; | -- -- borrow occurs due to use in closure @@ -123,7 +123,7 @@ LL | f.use_ref(); | - borrow later used here error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/closure-borrow-spans.rs:72:13 + --> $DIR/closure-borrow-spans.rs:93:13 | LL | let f = || *x = 0; | -- -- first borrow occurs due to use of `x` in closure @@ -135,7 +135,7 @@ LL | f.use_ref(); | - first borrow later used here error[E0501]: cannot borrow `x` as mutable because previous closure requires unique access - --> $DIR/closure-borrow-spans.rs:78:13 + --> $DIR/closure-borrow-spans.rs:99:13 | LL | let f = || *x = 0; | -- -- first borrow occurs due to use of `x` in closure @@ -147,7 +147,7 @@ LL | f.use_ref(); | - first borrow later used here error[E0597]: `x` does not live long enough - --> $DIR/closure-borrow-spans.rs:87:16 + --> $DIR/closure-borrow-spans.rs:108:16 | LL | let x = &mut z; | - binding `x` declared here @@ -161,7 +161,7 @@ LL | f.use_ref(); | - borrow later used here error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/closure-borrow-spans.rs:94:5 + --> $DIR/closure-borrow-spans.rs:115:5 | LL | let f = || *x = 0; | -- -- borrow occurs due to use in closure diff --git a/tests/ui/regions/region-borrow-params-issue-29793-big.rs b/tests/ui/regions/region-borrow-params-issue-29793-big.rs index 83b1a6eab57b4..1787bf9342abb 100644 --- a/tests/ui/regions/region-borrow-params-issue-29793-big.rs +++ b/tests/ui/regions/region-borrow-params-issue-29793-big.rs @@ -64,7 +64,7 @@ impl WrapA fn main() { let mut w = WrapA::new().set(|x: usize, y: usize| { - WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) + WrapB::new().set(|t: bool| if t { *&x } else { *&y }) // (separate errors for `x` vs `y`) //~^ ERROR closure may outlive the current function //~| ERROR closure may outlive the current function }); diff --git a/tests/ui/regions/region-borrow-params-issue-29793-big.stderr b/tests/ui/regions/region-borrow-params-issue-29793-big.stderr index 561dd64b49d4b..97da7109d7477 100644 --- a/tests/ui/regions/region-borrow-params-issue-29793-big.stderr +++ b/tests/ui/regions/region-borrow-params-issue-29793-big.stderr @@ -1,37 +1,37 @@ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-big.rs:67:26 | -LL | WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | WrapB::new().set(|t: bool| if t { *&x } else { *&y }) // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | note: closure is returned here --> $DIR/region-borrow-params-issue-29793-big.rs:67:9 | -LL | WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | WrapB::new().set(|t: bool| if t { *&x } else { *&y }) // (separate errors for `x` vs `y`) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) +LL | WrapB::new().set(move |t: bool| if t { *&x } else { *&y }) // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-big.rs:67:26 | -LL | WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | WrapB::new().set(|t: bool| if t { *&x } else { *&y }) // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | note: closure is returned here --> $DIR/region-borrow-params-issue-29793-big.rs:67:9 | -LL | WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | WrapB::new().set(|t: bool| if t { *&x } else { *&y }) // (separate errors for `x` vs `y`) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) +LL | WrapB::new().set(move |t: bool| if t { *&x } else { *&y }) // (separate errors for `x` vs `y`) | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/regions/region-borrow-params-issue-29793-small.rs b/tests/ui/regions/region-borrow-params-issue-29793-small.rs index 5f1c2ed08f6b7..3c655ef06b35f 100644 --- a/tests/ui/regions/region-borrow-params-issue-29793-small.rs +++ b/tests/ui/regions/region-borrow-params-issue-29793-small.rs @@ -6,7 +6,7 @@ fn escaping_borrow_of_closure_params_1() { let g = |x: usize, y:usize| { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return f; @@ -21,7 +21,7 @@ fn escaping_borrow_of_closure_params_1() { fn escaping_borrow_of_closure_params_2() { let g = |x: usize, y:usize| { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 f @@ -32,7 +32,7 @@ fn escaping_borrow_of_closure_params_2() { fn move_of_closure_params() { let g = |x: usize, y:usize| { - let f = move |t: bool| if t { x } else { y }; + let f = move |t: bool| if t { *&x } else { *&y }; f; }; // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) @@ -41,7 +41,7 @@ fn move_of_closure_params() { fn ok_borrow_of_fn_params(a: usize, b:usize) { let g = |x: usize, y:usize| { - let f = |t: bool| if t { a } else { b }; + let f = |t: bool| if t { *&a } else { *&b }; return f; }; // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) @@ -52,7 +52,7 @@ fn ok_borrow_of_fn_params(a: usize, b:usize) { fn escaping_borrow_of_fn_params_1() { fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); @@ -63,7 +63,7 @@ fn escaping_borrow_of_fn_params_1() { fn escaping_borrow_of_fn_params_2() { fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) @@ -74,7 +74,7 @@ fn escaping_borrow_of_fn_params_2() { fn move_of_fn_params() { fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { - let f = move |t: bool| if t { x } else { y }; + let f = move |t: bool| if t { *&x } else { *&y }; return Box::new(f); }; // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) @@ -87,7 +87,7 @@ fn escaping_borrow_of_method_params_1() { struct S; impl S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); @@ -101,7 +101,7 @@ fn escaping_borrow_of_method_params_2() { struct S; impl S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) @@ -114,7 +114,7 @@ fn move_of_method_params() { struct S; impl S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = move |t: bool| if t { x } else { y }; + let f = move |t: bool| if t { *&x } else { *&y }; return Box::new(f); } } @@ -129,7 +129,7 @@ fn escaping_borrow_of_trait_impl_params_1() { struct S; impl T for S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); @@ -144,7 +144,7 @@ fn escaping_borrow_of_trait_impl_params_2() { struct S; impl T for S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) @@ -158,7 +158,7 @@ fn move_of_trait_impl_params() { struct S; impl T for S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = move |t: bool| if t { x } else { y }; + let f = move |t: bool| if t { *&x } else { *&y }; return Box::new(f); } } @@ -172,7 +172,7 @@ fn escaping_borrow_of_trait_default_params_1() { struct S; trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); @@ -186,7 +186,7 @@ fn escaping_borrow_of_trait_default_params_2() { struct S; trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) + let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) @@ -200,7 +200,7 @@ fn move_of_trait_default_params() { struct S; trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - let f = move |t: bool| if t { x } else { y }; + let f = move |t: bool| if t { *&x } else { *&y }; return Box::new(f); } } diff --git a/tests/ui/regions/region-borrow-params-issue-29793-small.stderr b/tests/ui/regions/region-borrow-params-issue-29793-small.stderr index e446f2a0027e4..f0f0d91d3878a 100644 --- a/tests/ui/regions/region-borrow-params-issue-29793-small.stderr +++ b/tests/ui/regions/region-borrow-params-issue-29793-small.stderr @@ -1,8 +1,8 @@ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:9:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -13,14 +13,14 @@ LL | return f; | ^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:9:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -31,14 +31,14 @@ LL | return f; | ^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:24:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -49,14 +49,14 @@ LL | f | ^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:24:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -67,14 +67,14 @@ LL | f | ^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:55:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -85,14 +85,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:55:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -103,14 +103,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:66:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -121,14 +121,14 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:66:17 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -139,14 +139,14 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:90:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -157,14 +157,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:90:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -175,14 +175,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:104:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -193,14 +193,14 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:104:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -211,14 +211,14 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:132:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -229,14 +229,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:132:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -247,14 +247,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:147:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -265,14 +265,14 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:147:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -283,14 +283,14 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:175:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -301,14 +301,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:175:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -319,14 +319,14 @@ LL | return Box::new(f); | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:189:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `x` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `x` is borrowed here | | | may outlive borrowed value `x` | @@ -337,14 +337,14 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:189:21 | -LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^ - `y` is borrowed here +LL | let f = |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) + | ^^^^^^^^^ - `y` is borrowed here | | | may outlive borrowed value `y` | @@ -355,7 +355,7 @@ LL | Box::new(f) | ^^^^^^^^^^^ help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | -LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +LL | let f = move |t: bool| if t { *&x } else { *&y }; // (separate errors for `x` vs `y`) | ++++ error: aborting due to 20 previous errors diff --git a/tests/ui/rustc_public-ir-print/async-closure.stdout b/tests/ui/rustc_public-ir-print/async-closure.stdout index efdc33f1b0579..71bfb7fa572a2 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.stdout +++ b/tests/ui/rustc_public-ir-print/async-closure.stdout @@ -4,17 +4,13 @@ fn foo() -> () { let mut _0: (); let _1: i32; let _2: {async closure@$DIR/async-closure.rs:9:13: 9:21}; - let mut _3: &i32; debug y => _1; debug x => _2; bb0: { StorageLive(_1); _1 = 0_i32; StorageLive(_2); - StorageLive(_3); - _3 = &_1; - _2 = {coroutine-closure@$DIR/async-closure.rs:9:13: 9:21}(move _3); - StorageDead(_3); + _2 = {coroutine-closure@$DIR/async-closure.rs:9:13: 9:21}(_1); _0 = (); StorageDead(_2); StorageDead(_1); @@ -23,36 +19,29 @@ fn foo() -> () { } fn foo::{closure#0}(_1: &{async closure@$DIR/async-closure.rs:9:13: 9:21}) -> {async closure body@$DIR/async-closure.rs:9:22: 11:6} { let mut _0: {async closure body@$DIR/async-closure.rs:9:22: 11:6}; - let mut _2: &i32; - let mut _3: &i32; - debug y => (*((*_1).0: &i32)); + debug y => ((*_1).0: i32); bb0: { - StorageLive(_2); - _3 = no_retag ((*_1).0: &i32); - _2 = &(*_3); - _0 = {coroutine@$DIR/async-closure.rs:9:22: 11:6}(move _2); - StorageDead(_2); + _0 = {coroutine@$DIR/async-closure.rs:9:22: 11:6}(((*_1).0: i32)); return; } } fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: Poll<()>; let _3: i32; - let mut _4: &i32; - let mut _5: (); - let mut _6: u32; - let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; - let mut _8: std::future::ResumeTy; - let mut _9: NonNull>; - debug _task_context => _8; - debug y => (*((*_7).0: &i32)); + let mut _4: (); + let mut _5: u32; + let mut _6: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; + let mut _7: std::future::ResumeTy; + let mut _8: NonNull>; + debug _task_context => _7; + debug y => ((*_6).0: i32); debug y => _3; bb0: { - _9 = move _2 as NonNull>; - _8 = ResumeTy(move _9); - _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); - _6 = discriminant((*_7)); - switchInt(move _6) -> [0: bb3, 1: bb1, otherwise: bb2]; + _8 = move _2 as NonNull>; + _7 = ResumeTy(move _8); + _6 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + _5 = discriminant((*_6)); + switchInt(move _5) -> [0: bb3, 1: bb1, otherwise: bb2]; } bb1: { assert(false, `async fn` resumed after completion) -> [success: bb1, unwind unreachable]; @@ -62,33 +51,31 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo } bb3: { StorageLive(_3); - _4 = no_retag ((*_7).0: &i32); - _3 = (*_4); - _5 = (); + _3 = ((*_6).0: i32); + _4 = (); StorageDead(_3); - _0 = Poll::Ready(move _5); - discriminant((*_7)) = 1; + _0 = Poll::Ready(move _4); + discriminant((*_6)) = 1; return; } } fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> { let mut _0: Poll<()>; let _3: i32; - let mut _4: &i32; - let mut _5: (); - let mut _6: u32; - let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; - let mut _8: std::future::ResumeTy; - let mut _9: NonNull>; - debug _task_context => _8; - debug y => (*((*_7).0: &i32)); + let mut _4: (); + let mut _5: u32; + let mut _6: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; + let mut _7: std::future::ResumeTy; + let mut _8: NonNull>; + debug _task_context => _7; + debug y => ((*_6).0: i32); debug y => _3; bb0: { - _9 = move _2 as NonNull>; - _8 = ResumeTy(move _9); - _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); - _6 = discriminant((*_7)); - switchInt(move _6) -> [0: bb3, 1: bb1, otherwise: bb2]; + _8 = move _2 as NonNull>; + _7 = ResumeTy(move _8); + _6 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + _5 = discriminant((*_6)); + switchInt(move _5) -> [0: bb3, 1: bb1, otherwise: bb2]; } bb1: { assert(false, `async fn` resumed after completion) -> [success: bb1, unwind unreachable]; @@ -98,12 +85,11 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c } bb3: { StorageLive(_3); - _4 = no_retag ((*_7).0: &i32); - _3 = (*_4); - _5 = (); + _3 = ((*_6).0: i32); + _4 = (); StorageDead(_3); - _0 = Poll::Ready(move _5); - discriminant((*_7)) = 1; + _0 = Poll::Ready(move _4); + discriminant((*_6)) = 1; return; } } diff --git a/tests/ui/span/send-is-not-static-ensures-scoping.rs b/tests/ui/span/send-is-not-static-ensures-scoping.rs index 2aecc2a7e0d96..dc1315f57b69c 100644 --- a/tests/ui/span/send-is-not-static-ensures-scoping.rs +++ b/tests/ui/span/send-is-not-static-ensures-scoping.rs @@ -17,7 +17,7 @@ fn main() { //~^ ERROR `x` does not live long enough scoped(|| { - let _z = y; + let _z = *&y; //~^ ERROR `y` does not live long enough }) }; diff --git a/tests/ui/span/send-is-not-static-ensures-scoping.stderr b/tests/ui/span/send-is-not-static-ensures-scoping.stderr index c15547e84125b..3ca43aa64ad63 100644 --- a/tests/ui/span/send-is-not-static-ensures-scoping.stderr +++ b/tests/ui/span/send-is-not-static-ensures-scoping.stderr @@ -12,7 +12,7 @@ LL | }; | - `x` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/send-is-not-static-ensures-scoping.rs:20:22 + --> $DIR/send-is-not-static-ensures-scoping.rs:20:24 | LL | let bad = { | --- borrow later stored here @@ -22,8 +22,8 @@ LL | let y = &x; ... LL | scoped(|| { | -- value captured here -LL | let _z = y; - | ^ borrowed value does not live long enough +LL | let _z = *&y; + | ^ borrowed value does not live long enough ... LL | }; | - `y` dropped here while still borrowed diff --git a/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs b/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs index 05653667ac758..c32713c5f7605 100644 --- a/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs +++ b/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs @@ -6,9 +6,9 @@ fn foo(_src: &crate::Foo) -> Option { } fn bar(src: &crate::Foo) -> impl Iterator { [0].into_iter() - //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bounds - .filter_map(|_| foo(src)) - //~^ ERROR `src` does not live long enough + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bounds + .filter_map(|_| foo(*&src)) + //~^ ERROR `src` does not live long enough } struct Foo<'a>(&'a str); diff --git a/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.stderr b/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.stderr index 441adf4856b5d..84252404e60f7 100644 --- a/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.stderr +++ b/tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.stderr @@ -5,19 +5,19 @@ LL | fn bar(src: &crate::Foo) -> impl Iterator { | ------------------------- opaque type defined here LL | / [0].into_iter() LL | | -LL | | .filter_map(|_| foo(src)) - | |_________________________________^ +LL | | .filter_map(|_| foo(*&src)) + | |___________________________________^ | = note: hidden type `FilterMap, {closure@...}>` captures lifetime `'_` error[E0597]: `src` does not live long enough - --> $DIR/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs:10:29 + --> $DIR/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs:10:31 | LL | fn bar(src: &crate::Foo) -> impl Iterator { | --- binding `src` declared here ... -LL | .filter_map(|_| foo(src)) - | --- ^^^ borrowed value does not live long enough +LL | .filter_map(|_| foo(*&src)) + | --- ^^^ borrowed value does not live long enough | | | value captured here LL | diff --git a/tests/ui/unboxed-closures/unboxed-closure-region.rs b/tests/ui/unboxed-closures/unboxed-closure-region.rs index 51fe118c93ff1..e5feb77f3ea22 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-region.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-region.rs @@ -1,11 +1,10 @@ // Test that an unboxed closure that captures a free variable by // reference cannot escape the region of that variable. - fn main() { let _f = { let x = 0; - || x //~ ERROR closure may outlive the current block, but it borrows `x` + || *&x //~ ERROR closure may outlive the current block, but it borrows `x` }; _f; } diff --git a/tests/ui/unboxed-closures/unboxed-closure-region.stderr b/tests/ui/unboxed-closures/unboxed-closure-region.stderr index 70407628f1df9..616a011015aba 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-region.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-region.stderr @@ -1,19 +1,19 @@ error[E0373]: closure may outlive the current block, but it borrows `x`, which is owned by the current block - --> $DIR/unboxed-closure-region.rs:8:9 + --> $DIR/unboxed-closure-region.rs:7:9 | -LL | || x - | ^^ - `x` is borrowed here +LL | || *&x + | ^^ - `x` is borrowed here | | | may outlive borrowed value `x` | note: block requires argument type to outlive `'1` - --> $DIR/unboxed-closure-region.rs:6:9 + --> $DIR/unboxed-closure-region.rs:5:9 | LL | let _f = { | ^^ help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | -LL | move || x +LL | move || *&x | ++++ error: aborting due to 1 previous error From e61e3be4469f43bddc4c03fc5e00cc8fcece33d4 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 7 Oct 2026 21:45:53 -0400 Subject: [PATCH 19/22] Don't emit no-op &T -> &T reborrows --- compiler/rustc_hir_typeck/src/coercion.rs | 51 +- .../clippy/clippy_lints/src/dereference.rs | 21 +- .../clippy_lints/src/methods/clone_on_copy.rs | 24 +- .../src/methods/unnecessary_to_owned.rs | 26 +- src/tools/clippy/tests/ui/eta.fixed | 2 +- src/tools/clippy/tests/ui/eta.rs | 2 +- src/tools/clippy/tests/ui/eta.stderr | 8 +- .../tests/ui/let_and_return.edition2021.fixed | 4 +- .../ui/let_and_return.edition2021.stderr | 4 +- .../tests/ui/let_and_return.edition2024.fixed | 4 +- .../ui/let_and_return.edition2024.stderr | 4 +- .../ui/unnecessary_option_map_or_else.fixed | 3 +- .../ui/unnecessary_option_map_or_else.rs | 3 +- .../ui/unnecessary_option_map_or_else.stderr | 26 +- .../ui/unnecessary_result_map_or_else.fixed | 4 +- .../ui/unnecessary_result_map_or_else.rs | 2 +- .../ui/unnecessary_result_map_or_else.stderr | 14 +- tests/incremental/hashes/call_expressions.rs | 8 +- ...rray_and_slice.index_array.built.after.mir | 16 +- ....index_const_generic_array.built.after.mir | 16 +- ...ray_and_slice.index_custom.built.after.mir | 24 +- ..._and_slice.index_mut_slice.built.after.mir | 24 +- ...rray_and_slice.index_slice.built.after.mir | 20 +- .../mir-opt/building/index_array_and_slice.rs | 15 +- ...atterns.opt1.SimplifyCfg-initial.after.mir | 2 +- ...atterns.opt2.SimplifyCfg-initial.after.mir | 2 +- ...atterns.opt3.SimplifyCfg-initial.after.mir | 2 +- ...ceiver_ptr_mutability.main.built.after.mir | 34 +- ...e_live_dead_in_statics.XXX.built.after.mir | 120 +- ..._type_annotations.let_else.built.after.mir | 15 +- ...otations.let_else_bindless.built.after.mir | 15 +- ..._type_annotations.let_init.built.after.mir | 12 +- ...otations.let_init_bindless.built.after.mir | 12 +- ...romotion_extern_static.BOP.built.after.mir | 10 +- .../indirect_ref.indirect_ref_1.GVN.diff | 8 +- .../indirect_ref.indirect_ref_2.GVN.diff | 8 +- tests/mir-opt/const_prop/indirect_ref.rs | 20 +- .../slice_len.main.GVN.32bit.panic-abort.diff | 39 +- ...slice_len.main.GVN.32bit.panic-unwind.diff | 39 +- .../slice_len.main.GVN.64bit.panic-abort.diff | 39 +- ...slice_len.main.GVN.64bit.panic-unwind.diff | 39 +- ...l.borrow_in_loop.CopyProp.panic-abort.diff | 38 +- ....borrow_in_loop.CopyProp.panic-unwind.diff | 38 +- ...rate_drops-{closure#0}.ElaborateDrops.diff | 986 ++++++----- ...rate_drops-{closure#0}.StateTransform.diff | 1450 ++++++++--------- ...utine.main-{closure#0}.StateTransform.diff | 217 ++- ...utine.main-{closure#1}.StateTransform.diff | 217 ++- .../enum.statics.DataflowConstProp.32bit.diff | 2 +- .../enum.statics.DataflowConstProp.64bit.diff | 2 +- ...sb.main.DataflowConstProp.panic-abort.diff | 24 +- ...b.main.DataflowConstProp.panic-unwind.diff | 24 +- ...n.DataflowConstProp.32bit.panic-abort.diff | 72 +- ....DataflowConstProp.32bit.panic-unwind.diff | 72 +- ...n.DataflowConstProp.64bit.panic-abort.diff | 72 +- ....DataflowConstProp.64bit.panic-unwind.diff | 72 +- ...ad_first.DeadStoreElimination-initial.diff | 8 +- tests/mir-opt/dead-store-elimination/ref.rs | 4 +- ...sts.invalid_debuginfo.SingleUseConsts.diff | 32 +- ...ng_operand.test.GVN.32bit.panic-abort.diff | 104 +- ...g_operand.test.GVN.32bit.panic-unwind.diff | 88 +- ...ng_operand.test.GVN.64bit.panic-abort.diff | 104 +- ...g_operand.test.GVN.64bit.panic-unwind.diff | 88 +- tests/mir-opt/gvn.slices.GVN.panic-abort.diff | 216 ++- .../mir-opt/gvn.slices.GVN.panic-unwind.diff | 216 ++- ...n.wide_ptr_provenance.GVN.panic-abort.diff | 284 ++-- ....wide_ptr_provenance.GVN.panic-unwind.diff | 284 ++-- ...e_ptr_same_provenance.GVN.panic-abort.diff | 306 ++-- ..._ptr_same_provenance.GVN.panic-unwind.diff | 306 ++-- .../mir-opt/gvn_clone.{impl#0}-clone.GVN.diff | 48 +- ...gvn_copy_aggregate.deref_nonssa_2.GVN.diff | 46 +- ...ompare_constant_index.GVN.panic-abort.diff | 8 +- ...mpare_constant_index.GVN.panic-unwind.diff | 8 +- .../mir-opt/gvn_loop.loop_deref_mut.GVN.diff | 104 +- ...67_inline_as_ref_as_mut.c.Inline.after.mir | 10 +- ...67_inline_as_ref_as_mut.d.Inline.after.mir | 20 +- ...implify-after-simplifycfg.panic-abort.diff | 49 +- ...mplify-after-simplifycfg.panic-unwind.diff | 49 +- ...implifyComparisonIntegral.panic-abort.diff | 2 +- ...mplifyComparisonIntegral.panic-unwind.diff | 2 +- ...8192.f.InstSimplify-after-simplifycfg.diff | 12 +- tests/mir-opt/issue_91633.fun.built.after.mir | 2 +- .../issue_99325.main.built.after.32bit.mir | 148 +- .../issue_99325.main.built.after.64bit.mir | 148 +- ..._conditions.JumpThreading.panic-abort.diff | 16 +- ...conditions.JumpThreading.panic-unwind.diff | 16 +- ...ray_len.array_len_raw.GVN.panic-abort.diff | 28 +- ...ay_len.array_len_raw.GVN.panic-unwind.diff | 28 +- ...criminant.LowerIntrinsics.panic-abort.diff | 86 +- ...riminant.LowerIntrinsics.panic-unwind.diff | 86 +- ....clone_as_copy.runtime-optimized.after.mir | 2 +- ..._clone_as_copy.runtime-optimized.after.mir | 2 +- tests/mir-opt/pre-codegen/clone_as_copy.rs | 2 +- ...mp.runtime-optimized.after.panic-abort.mir | 12 +- ...p.runtime-optimized.after.panic-unwind.mir | 12 +- ...d_constant.main.GVN.32bit.panic-abort.diff | 3 +- ...d_constant.main.GVN.64bit.panic-abort.diff | 3 +- ..._a-{closure#0}.runtime-optimized.after.mir | 8 +- ...op.runtime-optimized.after.panic-abort.mir | 2 +- ...op.runtime-optimized.after.panic-abort.mir | 2 +- ...p.runtime-optimized.after.panic-unwind.mir | 2 +- ...op.runtime-optimized.after.panic-abort.mir | 2 +- ...p.runtime-optimized.after.panic-unwind.mir | 2 +- ...xt.runtime-optimized.after.panic-abort.mir | 2 +- ...t.runtime-optimized.after.panic-unwind.mir | 2 +- ...er.runtime-optimized.after.panic-abort.mir | 2 +- ...r.runtime-optimized.after.panic-unwind.mir | 2 +- ...ence_propagation.ReferencePropagation.diff | 400 +++-- ...ls.c.SimplifyLocals-before-const-prop.diff | 6 +- ...mes.foo.ScalarReplacementOfAggregates.diff | 92 +- ...hod_1.ElaborateDrops.after.panic-abort.mir | 56 +- ...od_1.ElaborateDrops.after.panic-unwind.mir | 56 +- ....UnreachableEnumBranching.panic-abort.diff | 50 +- ...UnreachableEnumBranching.panic-unwind.diff | 50 +- ....UnreachableEnumBranching.panic-abort.diff | 6 +- ...UnreachableEnumBranching.panic-unwind.diff | 6 +- ....UnreachableEnumBranching.panic-abort.diff | 12 +- ...UnreachableEnumBranching.panic-unwind.diff | 12 +- ....UnreachableEnumBranching.panic-abort.diff | 6 +- ...UnreachableEnumBranching.panic-unwind.diff | 6 +- ....UnreachableEnumBranching.panic-abort.diff | 12 +- ...UnreachableEnumBranching.panic-unwind.diff | 12 +- ....UnreachableEnumBranching.panic-abort.diff | 12 +- ...UnreachableEnumBranching.panic-unwind.diff | 12 +- ....UnreachableEnumBranching.panic-abort.diff | 18 +- ...UnreachableEnumBranching.panic-unwind.diff | 18 +- ....UnreachableEnumBranching.panic-abort.diff | 24 +- ...UnreachableEnumBranching.panic-unwind.diff | 24 +- ....UnreachableEnumBranching.panic-abort.diff | 18 +- ...UnreachableEnumBranching.panic-unwind.diff | 18 +- ....UnreachableEnumBranching.panic-abort.diff | 12 +- ...UnreachableEnumBranching.panic-unwind.diff | 12 +- ...ent-copy-closure-captures-analysis-2021.rs | 4 +- ...copy-closure-captures-analysis-2021.stderr | 4 +- .../dropck/dropck_trait_cycle_checked.stderr | 10 +- .../dst-object-from-unsized-type.next.stderr | 4 +- tests/ui/dst/dst-object-from-unsized-type.rs | 2 +- .../propagate-approximated-ref.stderr | 2 +- ...er-to-static-comparing-against-free.stderr | 2 +- ...ail-to-approximate-longer-no-bounds.stderr | 2 +- ...-to-approximate-longer-wrong-bounds.stderr | 2 +- .../regions-free-region-ordering-incorrect.rs | 6 +- ...ions-free-region-ordering-incorrect.stderr | 18 +- .../ui/rustc_public-ir-print/operands.stdout | 434 +++-- ...cept_assume_lifetime_extension.next.stderr | 2 +- 144 files changed, 3943 insertions(+), 4544 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 1f55fd49fc86b..1f48fa796a8a4 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -505,26 +505,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } }; - if coerced_a == a && mt_a.mutbl.is_not() && autoderef.step_count() == 1 { - // As a special case, if we would produce `&'a *x`, that's - // a total no-op. We end up with the type `&'a T` just as - // we started with. In that case, just skip it altogether. - // - // Unfortunately, this can actually effect capture analysis - // which in turn means this effects borrow checking. This can - // also effect diagnostics. - // FIXME(BoxyUwU): we should always emit reborrow coercions - // - // Note that for `&mut`, we DO want to reborrow -- - // otherwise, this would be a move, which might be an - // error. For example `foo(self.x)` where `self` and - // `self.x` both have `&mut `type would be a move of - // `self.x`, but we auto-coerce it to `foo(&mut *self.x)`, - // which is a borrow. - assert!(mutbl_b.is_not()); // can only coerce &T -> &U - return success(vec![], coerced_a, obligations); - } - let InferOk { value: mut adjustments, obligations: o } = self.adjust_steps_as_infer_ok(&autoderef); obligations.extend(o); @@ -536,10 +516,31 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { coerced_a ); - // Now apply the autoref - let mutbl = AutoBorrowMutability::new(mutbl_b, self.allow_two_phase); - adjustments - .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: coerced_a }); + if let Some(Adjustment { kind: Adjust::Deref(DerefAdjustKind::Builtin), .. }) = + adjustments.last() + && let ty::Ref(_, _, ty::Mutability::Not) = if adjustments.len() >= 2 { + *adjustments[adjustments.len() - 2].target.kind() + } else { + ty::Ref(r_a, mt_a.ty, mt_a.mutbl) + } + && mutbl_b.is_not() + { + // As a special case, if we would produce `&'a *x`, that's + // a total no-op. We end up with the type `&'a T` just as + // we started with. In that case, just skip it altogether. + // + // FIXME: Ideally we would also skip `&mut` -> `&mut` reborrow, + // and handle that in MIR. But unfortunately that would affect + // closure capture inference, which affects borrowcheck + adjustments.pop(); + } else { + // Now apply the autoref + let mutbl = AutoBorrowMutability::new(mutbl_b, self.allow_two_phase); + adjustments.push(Adjustment { + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), + target: coerced_a, + }); + } debug!("coerce_to_ref: succeeded coerced_a={:?} adjustments={:?}", coerced_a, adjustments); @@ -630,6 +631,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Handle reborrows before selecting `Source: CoerceUnsized`. let reborrow = match (source.kind(), target.kind()) { + // Don't emit a no-op shared -> shared reborrow + (&ty::Ref(_, _, ty::Mutability::Not), &ty::Ref(_, _, ty::Mutability::Not)) => None, (&ty::Ref(_, ty_a, mutbl_a), &ty::Ref(_, _, mutbl_b)) => { coerce_mutbls(mutbl_a, mutbl_b)?; diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 6257ec51eb8da..b0ad68f4e85eb 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -18,7 +18,7 @@ use rustc_hir::{ Node, OwnerId, Pat, PatKind, Path, QPath, TyKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; -use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; +use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, DerefAdjustKind}; use rustc_middle::ty::{self, AssocTag, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, Unnormalized}; use rustc_span::{Span, Symbol, SyntaxContext}; use std::borrow::Cow; @@ -350,6 +350,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { None => break None, } }; + if use_site.adjustments.last().is_some_and(|adj| { + matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Builtin)) + && matches!(adj.target.kind(), ty::Ref(_, _, Mutability::Not)) + }) { + deref_count += 1; + } let use_node = use_site.use_node(cx); let stability = use_node.defined_ty(cx).map_or(TyCoercionStability::None, |ty| { @@ -1041,14 +1047,13 @@ impl<'tcx> Dereferencing<'tcx> { [ Adjustment { kind: Adjust::Deref(_), - .. - }, - Adjustment { - kind: Adjust::Deref(_), - .. + target }, - .. - ] + rest @ .. + ] if match rest.first() { + Some(adj) => matches!(adj.kind,Adjust::Deref(_)), + None => matches!(target.kind(), ty::Ref(_, _, Mutability::Not)), + } ) { match get_parent_expr(cx, e) { diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs index 0891ffda6e7c3..44a0928461a67 100644 --- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs +++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs @@ -6,9 +6,9 @@ use rustc_attr_ir::lang_items::LangItem; use rustc_errors::Applicability; use rustc_hir::{BindingMode, ByRef, Expr, ExprKind, MatchSource, Node, PatKind}; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::adjustment::Adjust; +use rustc_middle::ty::adjustment::{Adjust, Adjustment}; use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_middle::ty::{self}; use super::CLONE_ON_COPY; @@ -141,11 +141,23 @@ pub(super) fn check_function(cx: &LateContext<'_>, expr: &Expr<'_>) { let snip = snippet_with_context(cx, peeled_arg.span, func.span.ctxt(), "_", &mut app).0; let arg_adjustments = cx.typeck_results().expr_adjustments(arg); - let deref_count = arg_adjustments - .iter() + + let adjustments_iter = &mut arg_adjustments.iter(); + let mut deref_count = adjustments_iter .take_while(|adj| matches!(adj.kind, Adjust::Deref(_))) - .count() - - ref_count; + .count(); + + if !matches!( + adjustments_iter.next(), + Some(Adjustment { + kind: Adjust::Borrow(_), + .. + }) + ) { + deref_count += 1; + } + + deref_count -= ref_count; let (help, sugg) = if deref_count == 0 { if check_res == ParentIsSuffixExpr::Yes && snip.starts_with('*') { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index c7e5e58b57afa..4ac7769cff3a9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -74,8 +74,20 @@ fn check_addr_of_expr( ) -> bool { if let Some(parent) = get_parent_expr(cx, expr) && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, _) = parent.kind - && let adjustments = cx.typeck_results().expr_adjustments(parent).iter().collect::>() - && let + && let adjustments = cx.typeck_results().expr_adjustments(parent) + && let (referent_ty, target_ty) = match *adjustments { + [] if let target_ty = cx.typeck_results().expr_ty_adjusted(parent) && + let &ty::Ref(_, referent_ty, Mutability::Not) = target_ty.kind() => { + (referent_ty, target_ty) + } + [ + Adjustment { + kind: Adjust::Pointer(_), + target: target_ty, + }, + ] if let &ty::Ref(_, referent_ty, Mutability::Not) = cx.typeck_results().expr_ty(parent).kind() => { + (referent_ty, target_ty) + } // For matching uses of `Cow::from` [ Adjustment { @@ -116,9 +128,11 @@ fn check_addr_of_expr( kind: Adjust::Borrow(_), target: target_ty, }, - ] = adjustments[..] + ] => (referent_ty, target_ty), + _ => return false, + } && let receiver_ty = cx.typeck_results().expr_ty(receiver) - && let (target_ty, n_target_refs, _) = peel_and_count_ty_refs(*target_ty) + && let (target_ty, n_target_refs, _) = peel_and_count_ty_refs(target_ty) && let (receiver_ty, n_receiver_refs, _) = peel_and_count_ty_refs(receiver_ty) // Only flag cases satisfying at least one of the following three conditions: // * the referent and receiver types are distinct @@ -129,8 +143,8 @@ fn check_addr_of_expr( // https://github.com/rust-lang/rust-clippy/issues/8759 // Arrays are a bit of a corner case. Non-copyable arrays are handled by // `redundant_clone`, but copyable arrays are not. - && (*referent_ty != receiver_ty - || (matches!(referent_ty.kind(), ty::Array(..)) && is_copy(cx, *referent_ty)) + && (referent_ty != receiver_ty + || (matches!(referent_ty.kind(), ty::Array(..)) && is_copy(cx, referent_ty)) || is_cow_into_owned(cx, method_name, method_parent_id)) { let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed index 20405a1233c46..169550c4243a9 100644 --- a/src/tools/clippy/tests/ui/eta.fixed +++ b/src/tools/clippy/tests/ui/eta.fixed @@ -270,7 +270,7 @@ fn late_bound_lifetimes() { { } map_str(|s| take_asref_path(s)); - map_str_to_path(|s| s.as_ref()); + map_str_to_path(std::convert::AsRef::as_ref); //~ redundant_closure_for_method_calls } mod type_param_bound { diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs index 4268810635fb4..636ea006bc73e 100644 --- a/src/tools/clippy/tests/ui/eta.rs +++ b/src/tools/clippy/tests/ui/eta.rs @@ -270,7 +270,7 @@ fn late_bound_lifetimes() { { } map_str(|s| take_asref_path(s)); - map_str_to_path(|s| s.as_ref()); + map_str_to_path(|s| s.as_ref()); //~ redundant_closure_for_method_calls } mod type_param_bound { diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr index 91c864d0ae581..04b5c26e35622 100644 --- a/src/tools/clippy/tests/ui/eta.stderr +++ b/src/tools/clippy/tests/ui/eta.stderr @@ -124,6 +124,12 @@ error: redundant closure LL | Some(1).map(|n| in_loop(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop` +error: redundant closure + --> tests/ui/eta.rs:273:21 + | +LL | map_str_to_path(|s| s.as_ref()); + | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::convert::AsRef::as_ref` + error: redundant closure --> tests/ui/eta.rs:347:18 | @@ -274,5 +280,5 @@ error: redundant closure LL | ... .reduce(|a, b| add(a, b)) | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&add` -error: aborting due to 45 previous errors +error: aborting due to 46 previous errors diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed b/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed index c904d882d9472..ac565adfd61cd 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed @@ -190,10 +190,10 @@ mod issue_11335 { pub fn inner(&self) -> &T { - (match self { + match self { E::A(x) => x, E::B(x) => x, - }) as _ + } //~^ let_and_return } } diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr b/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr index c91b355c42d08..d78f294a67f73 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr +++ b/src/tools/clippy/tests/ui/let_and_return.edition2021.stderr @@ -72,10 +72,10 @@ help: return the expression directly | LL ~ LL | -LL ~ (match self { +LL ~ match self { LL + E::A(x) => x, LL + E::B(x) => x, -LL + }) as _ +LL + } | error: returning the result of a `let` binding from a block diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed b/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed index e931e1ec7ff22..b6f4160e7a6ad 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed @@ -190,10 +190,10 @@ mod issue_11335 { pub fn inner(&self) -> &T { - (match self { + match self { E::A(x) => x, E::B(x) => x, - }) as _ + } //~^ let_and_return } } diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr b/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr index 7407e504b7c54..cb2340b722add 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr +++ b/src/tools/clippy/tests/ui/let_and_return.edition2024.stderr @@ -128,10 +128,10 @@ help: return the expression directly | LL ~ LL | -LL ~ (match self { +LL ~ match self { LL + E::A(x) => x, LL + E::B(x) => x, -LL + }) as _ +LL + } | error: returning the result of a `let` binding from a block diff --git a/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.fixed b/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.fixed index 867528dd7e44f..66429231eccdd 100644 --- a/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.fixed @@ -24,8 +24,7 @@ fn main() { // Auto-deref let string = String::new(); let option = Some(&string); - let _: &str = option.map_or_else(|| &string, |x| x); - // This should in theory lint with a smarter check + let _: &str = option.unwrap_or_else(|| &string); //~ unnecessary_option_map_or_else // Temporary variable let option = Some(()); diff --git a/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.rs b/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.rs index 325e63879ba24..c65ed8f53952a 100644 --- a/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.rs +++ b/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.rs @@ -24,8 +24,7 @@ fn main() { // Auto-deref let string = String::new(); let option = Some(&string); - let _: &str = option.map_or_else(|| &string, |x| x); - // This should in theory lint with a smarter check + let _: &str = option.map_or_else(|| &string, |x| x); //~ unnecessary_option_map_or_else // Temporary variable let option = Some(()); diff --git a/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.stderr b/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.stderr index 3b579ebdb2890..eb8de036b789a 100644 --- a/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_option_map_or_else.stderr @@ -25,7 +25,19 @@ LL + option.unwrap_or_else(|| ()); | error: unused "map closure" when calling `Option::map_or_else` value - --> tests/ui/unnecessary_option_map_or_else.rs:32:5 + --> tests/ui/unnecessary_option_map_or_else.rs:27:19 + | +LL | let _: &str = option.map_or_else(|| &string, |x| x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `unwrap_or_else` + | +LL - let _: &str = option.map_or_else(|| &string, |x| x); +LL + let _: &str = option.unwrap_or_else(|| &string); + | + +error: unused "map closure" when calling `Option::map_or_else` value + --> tests/ui/unnecessary_option_map_or_else.rs:31:5 | LL | / option.map_or_else( LL | | @@ -50,7 +62,7 @@ LL + option.unwrap_or_else(|| ()); | error: unused "map closure" when calling `Option::map_or_else` value - --> tests/ui/unnecessary_option_map_or_else.rs:43:5 + --> tests/ui/unnecessary_option_map_or_else.rs:42:5 | LL | / option.map_or_else( LL | | @@ -76,7 +88,7 @@ LL + option.unwrap_or_else(|| ((), ())); | error: unused "map closure" when calling `Option::map_or_else` value - --> tests/ui/unnecessary_option_map_or_else.rs:56:19 + --> tests/ui/unnecessary_option_map_or_else.rs:55:19 | LL | let _: &str = option.map_or_else(|| &string, std::convert::identity); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -88,7 +100,7 @@ LL + let _: &str = option.unwrap_or_else(|| &string); | error: unused "map closure" when calling `Option::map_or_else` value - --> tests/ui/unnecessary_option_map_or_else.rs:59:5 + --> tests/ui/unnecessary_option_map_or_else.rs:58:5 | LL | x.map_or_else(|| ((), ()), |(a, b)| (a, b)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +112,7 @@ LL + x.unwrap_or_else(|| ((), ())); | error: unused "map closure" when calling `Option::map_or_else` value - --> tests/ui/unnecessary_option_map_or_else.rs:64:5 + --> tests/ui/unnecessary_option_map_or_else.rs:63:5 | LL | / x.map_or_else( LL | | @@ -126,7 +138,7 @@ LL + x.unwrap_or_else(|| ()); | error: unused "map closure" when calling `Option::map_or_else` value - --> tests/ui/unnecessary_option_map_or_else.rs:76:5 + --> tests/ui/unnecessary_option_map_or_else.rs:75:5 | LL | / x.map_or_else( LL | | @@ -151,5 +163,5 @@ LL - ); LL + x.unwrap_or_else(|| ((), ())); | -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed index 2bb8e22a0bb90..617f106355b9e 100644 --- a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed @@ -15,8 +15,8 @@ fn main() { // Auto-deref. let y = String::new(); let x: Result<&String, &String> = Ok(&y); - let y: &str = x.map_or_else(|err| err, |n| n); - // This should lint with a smarter check + let y: &str = x.unwrap_or_else(|err| err); + //~^ unnecessary_result_map_or_else // Temporary variable. let x: Result<(), ()> = Ok(()); diff --git a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs index 829dd035adc32..b8e793a23afc1 100644 --- a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs +++ b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs @@ -16,7 +16,7 @@ fn main() { let y = String::new(); let x: Result<&String, &String> = Ok(&y); let y: &str = x.map_or_else(|err| err, |n| n); - // This should lint with a smarter check + //~^ unnecessary_result_map_or_else // Temporary variable. let x: Result<(), ()> = Ok(()); diff --git a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr index 2443083d4390c..30e04da8c9671 100644 --- a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr @@ -24,6 +24,18 @@ LL - x.map_or_else(|err: ()| err, |n: ()| n); LL + x.unwrap_or_else(|err: ()| err); | +error: unused "map closure" when calling `Result::map_or_else` value + --> tests/ui/unnecessary_result_map_or_else.rs:18:19 + | +LL | let y: &str = x.map_or_else(|err| err, |n| n); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `unwrap_or_else` + | +LL - let y: &str = x.map_or_else(|err| err, |n| n); +LL + let y: &str = x.unwrap_or_else(|err| err); + | + error: unused "map closure" when calling `Result::map_or_else` value --> tests/ui/unnecessary_result_map_or_else.rs:23:5 | @@ -140,5 +152,5 @@ LL - ); LL + x.unwrap_or_else(|err| err); | -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors diff --git a/tests/incremental/hashes/call_expressions.rs b/tests/incremental/hashes/call_expressions.rs index 262ecbe4a7132..fc2dca3a1e41c 100644 --- a/tests/incremental/hashes/call_expressions.rs +++ b/tests/incremental/hashes/call_expressions.rs @@ -158,16 +158,16 @@ pub fn change_argument_method_ufcs() { #[cfg(any(bpass1,bpass4))] pub fn change_to_ufcs() { let s = Struct; - s.method1('x', true); // ------ + s.method1('x', true); } #[cfg(not(any(bpass1,bpass4)))] -#[rustc_clean(cfg="bpass2", except="hir_owner,optimized_mir,typeck_root")] +#[rustc_clean(cfg="bpass2", except="hir_owner,typeck_root")] #[rustc_clean(cfg="bpass3")] +// MIR changes because spans change, and there is no `-Zincremental-ignore-spans` +// for the last 3 revisions #[rustc_clean(cfg="bpass5", except="hir_owner,optimized_mir,typeck_root")] #[rustc_clean(cfg="bpass6")] -// One might think this would be expanded in the hir_owner/Mir, but it actually -// results in slightly different hir_owner/Mir. pub fn change_to_ufcs() { let s = Struct; Struct::method1(&s, 'x', true); diff --git a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir index d28a2031013f3..6dd6dc63d7967 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir @@ -4,23 +4,19 @@ fn index_array(_1: &[i32; 7], _2: usize) -> &i32 { debug array => _1; debug index => _2; let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: bool; + let _3: usize; + let mut _4: bool; bb0: { StorageLive(_3); - StorageLive(_4); - _4 = copy _2; + _3 = copy _2; FakeRead(ForIndex, (*_1)); - _5 = Lt(copy _4, const 7_usize); - assert(move _5, "index out of bounds: the length is {} but the index is {}", const 7_usize, copy _4) -> [success: bb1, unwind: bb2]; + _4 = Lt(copy _3, const 7_usize); + assert(move _4, "index out of bounds: the length is {} but the index is {}", const 7_usize, copy _3) -> [success: bb1, unwind: bb2]; } bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); + _0 = &(*_1)[_3]; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir index e9627532c3828..722f878a81052 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir @@ -4,23 +4,19 @@ fn index_const_generic_array(_1: &[i32; N], _2: usize) -> &i32 { debug array => _1; debug index => _2; let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: bool; + let _3: usize; + let mut _4: bool; bb0: { StorageLive(_3); - StorageLive(_4); - _4 = copy _2; + _3 = copy _2; FakeRead(ForIndex, (*_1)); - _5 = Lt(copy _4, const N); - assert(move _5, "index out of bounds: the length is {} but the index is {}", const N, copy _4) -> [success: bb1, unwind: bb2]; + _4 = Lt(copy _3, const N); + assert(move _4, "index out of bounds: the length is {} but the index is {}", const N, copy _3) -> [success: bb1, unwind: bb2]; } bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); + _0 = &(*_1)[_3]; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir index e6745ddbf298a..d408c9bc4bf64 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir @@ -4,26 +4,22 @@ fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 { debug custom => _1; debug index => _2; let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: *const [i32]; - let mut _6: usize; - let mut _7: bool; + let _3: usize; + let mut _4: *const [i32]; + let mut _5: usize; + let mut _6: bool; bb0: { StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - _5 = &raw const (fake) ((*_1).1: [i32]); - _6 = PtrMetadata(move _5); - _7 = Lt(copy _4, copy _6); - assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2]; + _3 = copy _2; + _4 = &raw const (fake) ((*_1).1: [i32]); + _5 = PtrMetadata(move _4); + _6 = Lt(copy _3, copy _5); + assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _3) -> [success: bb1, unwind: bb2]; } bb1: { - _3 = &((*_1).1: [i32])[_4]; - _0 = &(*_3); - StorageDead(_4); + _0 = &((*_1).1: [i32])[_3]; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir index c96bcdfc918ad..b6f40a2455bbb 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir @@ -4,26 +4,22 @@ fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 { debug slice => _1; debug index => _2; let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: *const [i32]; - let mut _6: usize; - let mut _7: bool; + let _3: usize; + let mut _4: *const [i32]; + let mut _5: usize; + let mut _6: bool; bb0: { StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - _5 = &raw const (fake) (*_1); - _6 = PtrMetadata(move _5); - _7 = Lt(copy _4, copy _6); - assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2]; + _3 = copy _2; + _4 = &raw const (fake) (*_1); + _5 = PtrMetadata(move _4); + _6 = Lt(copy _3, copy _5); + assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _3) -> [success: bb1, unwind: bb2]; } bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); + _0 = &(*_1)[_3]; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir index 0911df590497c..c1ed78d78a786 100644 --- a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir +++ b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir @@ -4,24 +4,20 @@ fn index_slice(_1: &[i32], _2: usize) -> &i32 { debug slice => _1; debug index => _2; let mut _0: &i32; - let _3: &i32; - let _4: usize; - let mut _5: usize; - let mut _6: bool; + let _3: usize; + let mut _4: usize; + let mut _5: bool; bb0: { StorageLive(_3); - StorageLive(_4); - _4 = copy _2; - _5 = PtrMetadata(copy _1); - _6 = Lt(copy _4, copy _5); - assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb2]; + _3 = copy _2; + _4 = PtrMetadata(copy _1); + _5 = Lt(copy _3, copy _4); + assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb2]; } bb1: { - _3 = &(*_1)[_4]; - _0 = &(*_3); - StorageDead(_4); + _0 = &(*_1)[_3]; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/index_array_and_slice.rs b/tests/mir-opt/building/index_array_and_slice.rs index 47d8255ef57f1..12fb999da1b30 100644 --- a/tests/mir-opt/building/index_array_and_slice.rs +++ b/tests/mir-opt/building/index_array_and_slice.rs @@ -8,8 +8,7 @@ fn index_array(array: &[i32; 7], index: usize) -> &i32 { // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const 7_usize, copy _3) -> [success: bb1, unwind // CHECK: bb1: - // CHECK: _5 = &(*_1)[_3]; - // CHECK: _0 = &(*_5); + // CHECK: _0 = &(*_1)[_3]; &array[index] } @@ -21,8 +20,7 @@ fn index_const_generic_array(array: &[i32; N], index: usize) -> // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const N, copy _3) -> [success: bb1, unwind // CHECK: bb1: - // CHECK: _5 = &(*_1)[_3]; - // CHECK: _0 = &(*_5); + // CHECK: _0 = &(*_1)[_3]; &array[index] } @@ -35,8 +33,7 @@ fn index_slice(slice: &[i32], index: usize) -> &i32 { // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _3) -> [success: bb1, // CHECK: bb1: - // CHECK: _6 = &(*_1)[_3]; - // CHECK: _0 = &(*_6); + // CHECK: _0 = &(*_1)[_3]; &slice[index] } @@ -53,8 +50,7 @@ fn index_mut_slice(slice: &mut [i32], index: usize) -> &i32 { // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _3) -> [success: bb1, // CHECK: bb1: - // CHECK: _7 = &(*_1)[_3]; - // CHECK: _0 = &(*_7); + // CHECK: _0 = &(*_1)[_3]; &slice[index] } @@ -70,8 +66,7 @@ fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 { // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _3) -> [success: bb1, // CHECK: bb1: - // CHECK: _7 = &((*_1).1: [i32])[_3]; - // CHECK: _0 = &(*_7); + // CHECK: _0 = &((*_1).1: [i32])[_3]; &custom.1[index] } diff --git a/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir index 78356a90743a6..de8cab6041601 100644 --- a/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir @@ -34,7 +34,7 @@ fn opt1(_1: &Result) -> &u32 { bb4: { StorageLive(_3); _3 = &(((*_1) as Ok).0: u32); - _0 = &(*_3); + _0 = copy _3; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir index 979fbb2860dcb..08827649bee3b 100644 --- a/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir @@ -23,7 +23,7 @@ fn opt2(_1: &Result) -> &u32 { bb2: { StorageLive(_3); _3 = &(((*_1) as Ok).0: u32); - _0 = &(*_3); + _0 = copy _3; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir index 93ebe600b3ff7..694369b8598b3 100644 --- a/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir @@ -28,7 +28,7 @@ fn opt3(_1: &Result) -> &u32 { bb3: { StorageLive(_3); _3 = &(((*_1) as Ok).0: u32); - _0 = &(*_3); + _0 = copy _3; StorageDead(_3); return; } diff --git a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir index 0c73bd8ac6543..0a35e40744698 100644 --- a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir +++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir @@ -12,13 +12,12 @@ fn main() -> () { let _2: (); let mut _3: *const Test; let mut _4: *mut Test; - let _6: &&&&*mut Test; - let _7: &&&*mut Test; - let _8: &&*mut Test; - let _9: &*mut Test; - let _10: (); - let mut _11: *const Test; - let mut _12: *mut Test; + let _6: &&&*mut Test; + let _7: &&*mut Test; + let _8: &*mut Test; + let _9: (); + let mut _10: *const Test; + let mut _11: *mut Test; scope 1 { debug ptr => _1; let _5: &&&&*mut Test as UserTypeProjection { base: UserType(2), projs: [] }; @@ -51,31 +50,28 @@ fn main() -> () { StorageLive(_6); StorageLive(_7); StorageLive(_8); - StorageLive(_9); - _9 = &_1; - _8 = &_9; + _8 = &_1; _7 = &_8; _6 = &_7; - _5 = &(*_6); + _5 = &_6; FakeRead(ForLet(None), _5); AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); - StorageDead(_6); + StorageLive(_9); StorageLive(_10); StorageLive(_11); - StorageLive(_12); - _12 = copy (*(*(*(*_5)))); - _11 = move _12 as *const Test (PointerCoercion(MutToConstPointer, Implicit)); - StorageDead(_12); - _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; + _11 = copy (*(*(*(*_5)))); + _10 = move _11 as *const Test (PointerCoercion(MutToConstPointer, Implicit)); + StorageDead(_11); + _9 = Test::x(move _10) -> [return: bb3, unwind: bb4]; } bb3: { - StorageDead(_11); StorageDead(_10); - _0 = const (); StorageDead(_9); + _0 = const (); StorageDead(_8); StorageDead(_7); + StorageDead(_6); StorageDead(_5); StorageDead(_1); return; diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir index 4ec1203269087..d84b28f1e4bfe 100644 --- a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir +++ b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir @@ -2,12 +2,12 @@ static XXX: &Foo = { let mut _0: &Foo; - let _1: &Foo; - let _2: Foo; - let mut _3: &[(u32, u32)]; - let mut _4: &[(u32, u32); 42]; - let _5: &[(u32, u32); 42]; - let _6: [(u32, u32); 42]; + let _1: Foo; + let mut _2: &[(u32, u32)]; + let mut _3: &[(u32, u32); 42]; + let _4: [(u32, u32); 42]; + let mut _5: (u32, u32); + let mut _6: (u32, u32); let mut _7: (u32, u32); let mut _8: (u32, u32); let mut _9: (u32, u32); @@ -48,8 +48,6 @@ static XXX: &Foo = { let mut _44: (u32, u32); let mut _45: (u32, u32); let mut _46: (u32, u32); - let mut _47: (u32, u32); - let mut _48: (u32, u32); bb0: { StorageLive(_1); @@ -57,94 +55,90 @@ static XXX: &Foo = { StorageLive(_3); StorageLive(_4); StorageLive(_5); + _5 = (const 0_u32, const 1_u32); StorageLive(_6); + _6 = (const 0_u32, const 2_u32); StorageLive(_7); - _7 = (const 0_u32, const 1_u32); + _7 = (const 0_u32, const 3_u32); StorageLive(_8); - _8 = (const 0_u32, const 2_u32); + _8 = (const 0_u32, const 1_u32); StorageLive(_9); - _9 = (const 0_u32, const 3_u32); + _9 = (const 0_u32, const 2_u32); StorageLive(_10); - _10 = (const 0_u32, const 1_u32); + _10 = (const 0_u32, const 3_u32); StorageLive(_11); - _11 = (const 0_u32, const 2_u32); + _11 = (const 0_u32, const 1_u32); StorageLive(_12); - _12 = (const 0_u32, const 3_u32); + _12 = (const 0_u32, const 2_u32); StorageLive(_13); - _13 = (const 0_u32, const 1_u32); + _13 = (const 0_u32, const 3_u32); StorageLive(_14); - _14 = (const 0_u32, const 2_u32); + _14 = (const 0_u32, const 1_u32); StorageLive(_15); - _15 = (const 0_u32, const 3_u32); + _15 = (const 0_u32, const 2_u32); StorageLive(_16); - _16 = (const 0_u32, const 1_u32); + _16 = (const 0_u32, const 3_u32); StorageLive(_17); - _17 = (const 0_u32, const 2_u32); + _17 = (const 0_u32, const 1_u32); StorageLive(_18); - _18 = (const 0_u32, const 3_u32); + _18 = (const 0_u32, const 2_u32); StorageLive(_19); - _19 = (const 0_u32, const 1_u32); + _19 = (const 0_u32, const 3_u32); StorageLive(_20); - _20 = (const 0_u32, const 2_u32); + _20 = (const 0_u32, const 1_u32); StorageLive(_21); - _21 = (const 0_u32, const 3_u32); + _21 = (const 0_u32, const 2_u32); StorageLive(_22); - _22 = (const 0_u32, const 1_u32); + _22 = (const 0_u32, const 3_u32); StorageLive(_23); - _23 = (const 0_u32, const 2_u32); + _23 = (const 0_u32, const 1_u32); StorageLive(_24); - _24 = (const 0_u32, const 3_u32); + _24 = (const 0_u32, const 2_u32); StorageLive(_25); - _25 = (const 0_u32, const 1_u32); + _25 = (const 0_u32, const 3_u32); StorageLive(_26); - _26 = (const 0_u32, const 2_u32); + _26 = (const 0_u32, const 1_u32); StorageLive(_27); - _27 = (const 0_u32, const 3_u32); + _27 = (const 0_u32, const 2_u32); StorageLive(_28); - _28 = (const 0_u32, const 1_u32); + _28 = (const 0_u32, const 3_u32); StorageLive(_29); - _29 = (const 0_u32, const 2_u32); + _29 = (const 0_u32, const 1_u32); StorageLive(_30); - _30 = (const 0_u32, const 3_u32); + _30 = (const 0_u32, const 2_u32); StorageLive(_31); - _31 = (const 0_u32, const 1_u32); + _31 = (const 0_u32, const 3_u32); StorageLive(_32); - _32 = (const 0_u32, const 2_u32); + _32 = (const 0_u32, const 1_u32); StorageLive(_33); - _33 = (const 0_u32, const 3_u32); + _33 = (const 0_u32, const 2_u32); StorageLive(_34); - _34 = (const 0_u32, const 1_u32); + _34 = (const 0_u32, const 3_u32); StorageLive(_35); - _35 = (const 0_u32, const 2_u32); + _35 = (const 0_u32, const 1_u32); StorageLive(_36); - _36 = (const 0_u32, const 3_u32); + _36 = (const 0_u32, const 2_u32); StorageLive(_37); - _37 = (const 0_u32, const 1_u32); + _37 = (const 0_u32, const 3_u32); StorageLive(_38); - _38 = (const 0_u32, const 2_u32); + _38 = (const 0_u32, const 1_u32); StorageLive(_39); - _39 = (const 0_u32, const 3_u32); + _39 = (const 0_u32, const 2_u32); StorageLive(_40); - _40 = (const 0_u32, const 1_u32); + _40 = (const 0_u32, const 3_u32); StorageLive(_41); - _41 = (const 0_u32, const 2_u32); + _41 = (const 0_u32, const 1_u32); StorageLive(_42); - _42 = (const 0_u32, const 3_u32); + _42 = (const 0_u32, const 2_u32); StorageLive(_43); - _43 = (const 0_u32, const 1_u32); + _43 = (const 0_u32, const 3_u32); StorageLive(_44); - _44 = (const 0_u32, const 2_u32); + _44 = (const 0_u32, const 1_u32); StorageLive(_45); - _45 = (const 0_u32, const 3_u32); + _45 = (const 0_u32, const 2_u32); StorageLive(_46); - _46 = (const 0_u32, const 1_u32); - StorageLive(_47); - _47 = (const 0_u32, const 2_u32); - StorageLive(_48); - _48 = (const 0_u32, const 3_u32); - _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48]; - StorageDead(_48); - StorageDead(_47); + _46 = (const 0_u32, const 3_u32); + _4 = [move _5, move _6, move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46]; StorageDead(_46); StorageDead(_45); StorageDead(_44); @@ -185,16 +179,14 @@ static XXX: &Foo = { StorageDead(_9); StorageDead(_8); StorageDead(_7); - _5 = &_6; - _4 = &(*_5); - _3 = move _4 as &[(u32, u32)] (PointerCoercion(Unsize, Implicit)); - StorageDead(_4); - _2 = Foo { tup: const "hi", data: move _3 }; - StorageDead(_3); - _1 = &_2; - _0 = &(*_1); + StorageDead(_6); StorageDead(_5); - StorageDead(_1); + _3 = &_4; + _2 = move _3 as &[(u32, u32)] (PointerCoercion(Unsize, Implicit)); + StorageDead(_3); + _1 = Foo { tup: const "hi", data: move _2 }; + StorageDead(_2); + _0 = &_1; return; } } diff --git a/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir index db79f934ac3a3..f6eca80dfa993 100644 --- a/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir @@ -12,8 +12,7 @@ fn let_else() -> () { let _4: &char as UserTypeProjection { base: UserType(0), projs: [Field(2, ())] }; let mut _5: (u32, u64, &char); let mut _6: &char; - let _7: &char; - let _8: char; + let _7: char; scope 1 { debug x => _2; debug y => _3; @@ -24,10 +23,8 @@ fn let_else() -> () { StorageLive(_5); StorageLive(_6); StorageLive(_7); - StorageLive(_8); - _8 = const 'u'; - _7 = &_8; - _6 = &(*_7); + _7 = const 'u'; + _6 = &_7; _5 = (const 7_u32, const 12_u64, move _6); StorageDead(_6); PlaceMention(_5); @@ -54,20 +51,18 @@ fn let_else() -> () { _3 = copy (_5.1: u64); StorageLive(_4); _4 = copy (_5.2: &char); - StorageDead(_7); StorageDead(_5); _0 = const (); StorageDead(_4); StorageDead(_3); StorageDead(_2); - StorageDead(_8); + StorageDead(_7); return; } bb5: { - StorageDead(_7); StorageDead(_5); - StorageDead(_8); + StorageDead(_7); goto -> bb1; } diff --git a/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir index 098fc4e7437ae..37212b0a42db9 100644 --- a/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir @@ -9,8 +9,7 @@ fn let_else_bindless() -> () { let mut _1: !; let mut _2: (u32, u64, &char); let mut _3: &char; - let _4: &char; - let _5: char; + let _4: char; scope 1 { } @@ -18,10 +17,8 @@ fn let_else_bindless() -> () { StorageLive(_2); StorageLive(_3); StorageLive(_4); - StorageLive(_5); - _5 = const 'u'; - _4 = &_5; - _3 = &(*_4); + _4 = const 'u'; + _3 = &_4; _2 = (const 7_u32, const 12_u64, move _3); StorageDead(_3); PlaceMention(_2); @@ -42,17 +39,15 @@ fn let_else_bindless() -> () { bb4: { AscribeUserType(_2, +, UserTypeProjection { base: UserType(1), projs: [] }); - StorageDead(_4); StorageDead(_2); _0 = const (); - StorageDead(_5); + StorageDead(_4); return; } bb5: { - StorageDead(_4); StorageDead(_2); - StorageDead(_5); + StorageDead(_4); goto -> bb1; } diff --git a/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir index dd05ef37de3cc..a9bb7eef0ebc7 100644 --- a/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir @@ -11,8 +11,7 @@ fn let_init() -> () { let _3: &char as UserTypeProjection { base: UserType(0), projs: [Field(2, ())] }; let mut _4: (u32, u64, &char); let mut _5: &char; - let _6: &char; - let _7: char; + let _6: char; scope 1 { debug x => _1; debug y => _2; @@ -23,10 +22,8 @@ fn let_init() -> () { StorageLive(_4); StorageLive(_5); StorageLive(_6); - StorageLive(_7); - _7 = const 'u'; - _6 = &_7; - _5 = &(*_6); + _6 = const 'u'; + _5 = &_6; _4 = (const 7_u32, const 12_u64, move _5); StorageDead(_5); PlaceMention(_4); @@ -37,13 +34,12 @@ fn let_init() -> () { _2 = copy (_4.1: u64); StorageLive(_3); _3 = copy (_4.2: &char); - StorageDead(_6); StorageDead(_4); _0 = const (); StorageDead(_3); StorageDead(_2); StorageDead(_1); - StorageDead(_7); + StorageDead(_6); return; } diff --git a/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir index d949e1945339b..b269a31afcc45 100644 --- a/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir @@ -8,8 +8,7 @@ fn let_init_bindless() -> () { let mut _0: (); let mut _1: (u32, u64, &char); let mut _2: &char; - let _3: &char; - let _4: char; + let _3: char; scope 1 { } @@ -17,18 +16,15 @@ fn let_init_bindless() -> () { StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = const 'u'; - _3 = &_4; - _2 = &(*_3); + _3 = const 'u'; + _2 = &_3; _1 = (const 7_u32, const 12_u64, move _2); StorageDead(_2); PlaceMention(_1); AscribeUserType(_1, +, UserTypeProjection { base: UserType(1), projs: [] }); - StorageDead(_3); StorageDead(_1); _0 = const (); - StorageDead(_4); + StorageDead(_3); return; } diff --git a/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir b/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir index ff80d5eedab91..ed24ccd3a1f75 100644 --- a/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir +++ b/tests/mir-opt/const_promotion_extern_static.BOP.built.after.mir @@ -2,16 +2,12 @@ static BOP: &i32 = { let mut _0: &i32; - let _1: &i32; - let _2: i32; + let _1: i32; bb0: { StorageLive(_1); - StorageLive(_2); - _2 = const 13_i32; - _1 = &_2; - _0 = &(*_1); - StorageDead(_1); + _1 = const 13_i32; + _0 = &_1; return; } } diff --git a/tests/mir-opt/const_prop/indirect_ref.indirect_ref_1.GVN.diff b/tests/mir-opt/const_prop/indirect_ref.indirect_ref_1.GVN.diff index 0836a10d16594..893321d2ef826 100644 --- a/tests/mir-opt/const_prop/indirect_ref.indirect_ref_1.GVN.diff +++ b/tests/mir-opt/const_prop/indirect_ref.indirect_ref_1.GVN.diff @@ -14,16 +14,13 @@ let _9: (); let mut _10: for<'a> fn(&'a i32); let mut _11: &i32; - let mut _12: &i32; - let mut _13: &i32; bb0: { StorageLive(_4); StorageLive(_5); _5 = copy _2; StorageLive(_6); - _12 = no_retag copy ((*_1).0: &i32); - _6 = &(*_12); + _6 = copy ((*_1).0: &i32); - _4 = move _5(move _6) -> [return: bb1, unwind unreachable]; + _4 = copy _2(move _6) -> [return: bb1, unwind unreachable]; } @@ -46,8 +43,7 @@ StorageLive(_10); _10 = copy _2; StorageLive(_11); - _13 = no_retag copy ((*_1).0: &i32); - _11 = &(*_13); + _11 = copy ((*_1).0: &i32); - _9 = move _10(move _11) -> [return: bb3, unwind unreachable]; + _9 = copy _2(move _11) -> [return: bb3, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/indirect_ref.indirect_ref_2.GVN.diff b/tests/mir-opt/const_prop/indirect_ref.indirect_ref_2.GVN.diff index ae3df30503676..10ab193bdf165 100644 --- a/tests/mir-opt/const_prop/indirect_ref.indirect_ref_2.GVN.diff +++ b/tests/mir-opt/const_prop/indirect_ref.indirect_ref_2.GVN.diff @@ -15,8 +15,6 @@ let _11: (); let mut _12: for<'a> fn(&'a i32); let mut _13: &i32; - let mut _14: &i32; - let mut _15: &i32; scope 1 { debug y1 => _4; let _10: (&i32,); @@ -32,8 +30,7 @@ StorageLive(_6); _6 = copy _2; StorageLive(_7); - _14 = no_retag copy (_4.0: &i32); - _7 = &(*_14); + _7 = copy (_4.0: &i32); - _5 = move _6(move _7) -> [return: bb1, unwind unreachable]; + _5 = copy _2(move _7) -> [return: bb1, unwind unreachable]; } @@ -58,8 +55,7 @@ StorageLive(_12); _12 = copy _2; StorageLive(_13); - _15 = no_retag copy (_10.0: &i32); - _13 = &(*_15); + _13 = copy (_10.0: &i32); - _11 = move _12(move _13) -> [return: bb3, unwind unreachable]; + _11 = copy _2(move _13) -> [return: bb3, unwind unreachable]; } diff --git a/tests/mir-opt/const_prop/indirect_ref.rs b/tests/mir-opt/const_prop/indirect_ref.rs index 1ec415d88d4bd..cf812e3e1bd10 100644 --- a/tests/mir-opt/const_prop/indirect_ref.rs +++ b/tests/mir-opt/const_prop/indirect_ref.rs @@ -70,12 +70,10 @@ pub fn indirect_deref_2(x: &(&i32,), out: fn(i32), clobber: fn()) { pub fn indirect_ref_1(x: &(&i32,), out: fn(&i32), clobber: fn()) { // CHECK-LABEL: fn indirect_ref_1 // CHECK: out => [[out:_.*]]; - // CHECK: [[y1_0:_.*]] = no_retag copy ((*_1).0: &i32); - // CHECK: [[reborrow_y1_0:_.*]] = &(*[[y1_0]]); - // CHECK: copy [[out]](move [[reborrow_y1_0]]) -> [ - // CHECK: [[y2_0:_.*]] = no_retag copy ((*_1).0: &i32); - // CHECK: [[reborrow_y2_0:_.*]] = &(*[[y2_0]]); - // CHECK: copy [[out]](move [[reborrow_y2_0]]) -> [ + // CHECK: [[y1_0:_.*]] = copy ((*_1).0: &i32); + // CHECK: copy [[out]](move [[y1_0]]) -> [ + // CHECK: [[y2_0:_.*]] = copy ((*_1).0: &i32); + // CHECK: copy [[out]](move [[y2_0]]) -> [ out((*x).0); clobber(); out((*x).0); @@ -87,13 +85,11 @@ pub fn indirect_ref_2(x: &(&i32,), out: fn(&i32), clobber: fn()) { // CHECK-LABEL: fn indirect_ref_2 // CHECK: out => [[out:_.*]]; // CHECK: [[y1:_.*]] = copy (*_1); - // CHECK: [[y1_0:_.*]] = no_retag copy ([[y1]].0: &i32); - // CHECK: [[reborrow_y1_0:_.*]] = &(*[[y1_0]]); - // CHECK: copy [[out]](move [[reborrow_y1_0]]) -> [ + // CHECK: [[y1_0:_.*]] = copy ([[y1]].0: &i32); + // CHECK: copy [[out]](move [[y1_0]]) -> [ // CHECK: [[y2:_.*]] = copy (*_1); - // CHECK: [[y2_0:_.*]] = no_retag copy ([[y2]].0: &i32); - // CHECK: [[reborrow_y2_0:_.*]] = &(*[[y2_0]]); - // CHECK: copy [[out]](move [[reborrow_y2_0]]) -> [ + // CHECK: [[y2_0:_.*]] = copy ([[y2]].0: &i32); + // CHECK: copy [[out]](move [[y2_0]]) -> [ let y1 = *x; out((y1).0); clobber(); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff index d6e81debccd81..47291302add3d 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff @@ -6,12 +6,11 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _9: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _8: &[u32; 3]; scope 1 { debug a => _1; } @@ -20,29 +19,25 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _9 = const main::promoted[0]; - _4 = copy _9; -- _3 = copy _4; + _8 = const main::promoted[0]; + _3 = copy _8; - _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); -+ _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); ++ _2 = copy _8 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind unreachable]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = const 2_u32; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff index 6713e531892ae..23c3600310d44 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff @@ -6,12 +6,11 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _9: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _8: &[u32; 3]; scope 1 { debug a => _1; } @@ -20,29 +19,25 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _9 = const main::promoted[0]; - _4 = copy _9; -- _3 = copy _4; + _8 = const main::promoted[0]; + _3 = copy _8; - _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); -+ _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); ++ _2 = copy _8 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind continue]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = const 2_u32; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff index d6e81debccd81..47291302add3d 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff @@ -6,12 +6,11 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _9: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _8: &[u32; 3]; scope 1 { debug a => _1; } @@ -20,29 +19,25 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _9 = const main::promoted[0]; - _4 = copy _9; -- _3 = copy _4; + _8 = const main::promoted[0]; + _3 = copy _8; - _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); -+ _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); ++ _2 = copy _8 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind unreachable]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = const 2_u32; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff index 6713e531892ae..23c3600310d44 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff @@ -6,12 +6,11 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _9: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _8: &[u32; 3]; scope 1 { debug a => _1; } @@ -20,29 +19,25 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _9 = const main::promoted[0]; - _4 = copy _9; -- _3 = copy _4; + _8 = const main::promoted[0]; + _3 = copy _8; - _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); -+ _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); ++ _2 = copy _8 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind continue]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = const 2_u32; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-abort.diff index 3d76cd65e0385..66ba99e61d393 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-abort.diff +++ b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-abort.diff @@ -11,15 +11,14 @@ let mut _9: bool; let mut _10: bool; let mut _11: &bool; - let _12: &bool; + let mut _12: bool; let mut _13: bool; let mut _14: bool; - let mut _15: bool; - let mut _16: !; + let mut _15: !; scope 1 { debug c => _1; let mut _2: &bool; - let mut _17: &bool; + let mut _16: &bool; scope 2 { debug p => _2; let _6: bool; @@ -36,8 +35,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - _17 = const borrow_in_loop::promoted[0]; - _2 = &(*_17); + _16 = const borrow_in_loop::promoted[0]; + _2 = &(*_16); - StorageLive(_4); goto -> bb1; } @@ -59,27 +58,24 @@ - StorageDead(_10); + _1 = copy _6; StorageLive(_11); - StorageLive(_12); - _12 = &_1; - _11 = &(*_12); + _11 = &_1; _2 = move _11; StorageDead(_11); - StorageDead(_12); - StorageLive(_13); + StorageLive(_12); +- StorageLive(_13); +- _13 = copy _6; - StorageLive(_14); -- _14 = copy _6; -- StorageLive(_15); -- _15 = copy _8; -- _13 = Ne(move _14, move _15); -+ _13 = Ne(copy _6, copy _8); - switchInt(move _13) -> [0: bb3, otherwise: bb2]; +- _14 = copy _8; +- _12 = Ne(move _13, move _14); ++ _12 = Ne(copy _6, copy _8); + switchInt(move _12) -> [0: bb3, otherwise: bb2]; } bb2: { -- StorageDead(_15); - StorageDead(_14); +- StorageDead(_13); _0 = const (); - StorageDead(_13); + StorageDead(_12); StorageDead(_8); StorageDead(_6); - StorageDead(_4); @@ -89,10 +85,10 @@ } bb3: { -- StorageDead(_15); - StorageDead(_14); +- StorageDead(_13); - _5 = const (); - StorageDead(_13); + StorageDead(_12); StorageDead(_8); StorageDead(_6); goto -> bb1; diff --git a/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-unwind.diff index 3d76cd65e0385..66ba99e61d393 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-unwind.diff +++ b/tests/mir-opt/copy-prop/borrowed_local.borrow_in_loop.CopyProp.panic-unwind.diff @@ -11,15 +11,14 @@ let mut _9: bool; let mut _10: bool; let mut _11: &bool; - let _12: &bool; + let mut _12: bool; let mut _13: bool; let mut _14: bool; - let mut _15: bool; - let mut _16: !; + let mut _15: !; scope 1 { debug c => _1; let mut _2: &bool; - let mut _17: &bool; + let mut _16: &bool; scope 2 { debug p => _2; let _6: bool; @@ -36,8 +35,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - _17 = const borrow_in_loop::promoted[0]; - _2 = &(*_17); + _16 = const borrow_in_loop::promoted[0]; + _2 = &(*_16); - StorageLive(_4); goto -> bb1; } @@ -59,27 +58,24 @@ - StorageDead(_10); + _1 = copy _6; StorageLive(_11); - StorageLive(_12); - _12 = &_1; - _11 = &(*_12); + _11 = &_1; _2 = move _11; StorageDead(_11); - StorageDead(_12); - StorageLive(_13); + StorageLive(_12); +- StorageLive(_13); +- _13 = copy _6; - StorageLive(_14); -- _14 = copy _6; -- StorageLive(_15); -- _15 = copy _8; -- _13 = Ne(move _14, move _15); -+ _13 = Ne(copy _6, copy _8); - switchInt(move _13) -> [0: bb3, otherwise: bb2]; +- _14 = copy _8; +- _12 = Ne(move _13, move _14); ++ _12 = Ne(copy _6, copy _8); + switchInt(move _12) -> [0: bb3, otherwise: bb2]; } bb2: { -- StorageDead(_15); - StorageDead(_14); +- StorageDead(_13); _0 = const (); - StorageDead(_13); + StorageDead(_12); StorageDead(_8); StorageDead(_6); - StorageDead(_4); @@ -89,10 +85,10 @@ } bb3: { -- StorageDead(_15); - StorageDead(_14); +- StorageDead(_13); - _5 = const (); - StorageDead(_13); + StorageDead(_12); StorageDead(_8); StorageDead(_6); goto -> bb1; diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff index 4e0cbbfc4357c..406b21a7861a1 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.ElaborateDrops.diff @@ -17,160 +17,159 @@ let mut _16: AsyncInt; let mut _18: AsyncInt; let mut _21: &AsyncInt; - let _22: &AsyncInt; -+ let mut _27: impl std::future::Future; -+ let mut _28: std::future::ResumeTy; -+ let mut _29: std::task::Poll<()>; -+ let mut _30: isize; -+ let mut _31: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _32: &mut std::task::Context<'_>; -+ let mut _33: std::future::ResumeTy; -+ let mut _34: &mut impl std::future::Future; -+ let mut _35: std::future::ResumeTy; -+ let mut _36: std::task::Poll<()>; -+ let mut _37: isize; -+ let mut _38: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _39: &mut std::task::Context<'_>; -+ let mut _40: std::future::ResumeTy; -+ let mut _41: &mut impl std::future::Future; -+ let mut _42: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>; -+ let mut _43: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35}; -+ let mut _44: impl std::future::Future; -+ let mut _45: std::future::ResumeTy; -+ let mut _46: std::task::Poll<()>; -+ let mut _47: isize; -+ let mut _48: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _49: &mut std::task::Context<'_>; -+ let mut _50: std::future::ResumeTy; -+ let mut _51: &mut impl std::future::Future; -+ let mut _52: std::future::ResumeTy; -+ let mut _53: std::task::Poll<()>; -+ let mut _54: isize; -+ let mut _55: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _56: &mut std::task::Context<'_>; -+ let mut _57: std::future::ResumeTy; -+ let mut _58: &mut impl std::future::Future; -+ let mut _59: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>; -+ let mut _60: &mut {closure@$DIR/async_drop.rs:78:25: 78:27}; -+ let mut _61: impl std::future::Future; -+ let mut _62: std::future::ResumeTy; -+ let mut _63: std::task::Poll<()>; -+ let mut _64: isize; -+ let mut _65: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _66: &mut std::task::Context<'_>; -+ let mut _67: std::future::ResumeTy; -+ let mut _68: &mut impl std::future::Future; -+ let mut _69: std::future::ResumeTy; -+ let mut _70: std::task::Poll<()>; -+ let mut _71: isize; -+ let mut _72: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _73: &mut std::task::Context<'_>; -+ let mut _74: std::future::ResumeTy; -+ let mut _75: &mut impl std::future::Future; -+ let mut _76: std::pin::Pin<&mut AsyncReference<'_>>; -+ let mut _77: &mut AsyncReference<'_>; -+ let mut _78: impl std::future::Future; -+ let mut _79: std::future::ResumeTy; -+ let mut _80: std::task::Poll<()>; -+ let mut _81: isize; -+ let mut _82: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _83: &mut std::task::Context<'_>; -+ let mut _84: std::future::ResumeTy; -+ let mut _85: &mut impl std::future::Future; -+ let mut _86: std::future::ResumeTy; -+ let mut _87: std::task::Poll<()>; -+ let mut _88: isize; -+ let mut _89: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _90: &mut std::task::Context<'_>; -+ let mut _91: std::future::ResumeTy; -+ let mut _92: &mut impl std::future::Future; -+ let mut _93: std::pin::Pin<&mut AsyncInt>; -+ let mut _94: &mut AsyncInt; -+ let mut _95: impl std::future::Future; -+ let mut _96: std::future::ResumeTy; -+ let mut _97: std::task::Poll<()>; -+ let mut _98: isize; -+ let mut _99: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _100: &mut std::task::Context<'_>; -+ let mut _101: std::future::ResumeTy; -+ let mut _102: &mut impl std::future::Future; -+ let mut _103: std::future::ResumeTy; -+ let mut _104: std::task::Poll<()>; -+ let mut _105: isize; -+ let mut _106: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _107: &mut std::task::Context<'_>; -+ let mut _108: std::future::ResumeTy; -+ let mut _109: &mut impl std::future::Future; -+ let mut _110: std::pin::Pin<&mut AsyncEnum>; -+ let mut _111: &mut AsyncEnum; -+ let mut _112: impl std::future::Future; -+ let mut _113: std::future::ResumeTy; -+ let mut _114: std::task::Poll<()>; -+ let mut _115: isize; -+ let mut _116: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _117: &mut std::task::Context<'_>; -+ let mut _118: std::future::ResumeTy; -+ let mut _119: &mut impl std::future::Future; -+ let mut _120: std::future::ResumeTy; -+ let mut _121: std::task::Poll<()>; -+ let mut _122: isize; -+ let mut _123: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _124: &mut std::task::Context<'_>; -+ let mut _125: std::future::ResumeTy; -+ let mut _126: &mut impl std::future::Future; -+ let mut _127: std::pin::Pin<&mut SyncThenAsync>; -+ let mut _128: &mut SyncThenAsync; -+ let mut _129: impl std::future::Future; -+ let mut _130: std::future::ResumeTy; -+ let mut _131: std::task::Poll<()>; -+ let mut _132: isize; -+ let mut _133: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _134: &mut std::task::Context<'_>; -+ let mut _135: std::future::ResumeTy; -+ let mut _136: &mut impl std::future::Future; -+ let mut _137: std::future::ResumeTy; -+ let mut _138: std::task::Poll<()>; -+ let mut _139: isize; -+ let mut _140: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _141: &mut std::task::Context<'_>; -+ let mut _142: std::future::ResumeTy; -+ let mut _143: &mut impl std::future::Future; -+ let mut _144: std::pin::Pin<&mut AsyncStruct>; -+ let mut _145: &mut AsyncStruct; -+ let mut _146: impl std::future::Future; -+ let mut _147: std::future::ResumeTy; -+ let mut _148: std::task::Poll<()>; -+ let mut _149: isize; -+ let mut _150: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _151: &mut std::task::Context<'_>; -+ let mut _152: std::future::ResumeTy; -+ let mut _153: &mut impl std::future::Future; -+ let mut _154: std::future::ResumeTy; -+ let mut _155: std::task::Poll<()>; -+ let mut _156: isize; -+ let mut _157: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _158: &mut std::task::Context<'_>; -+ let mut _159: std::future::ResumeTy; -+ let mut _160: &mut impl std::future::Future; -+ let mut _161: std::pin::Pin<&mut [AsyncInt; 2]>; -+ let mut _162: &mut [AsyncInt; 2]; -+ let mut _163: impl std::future::Future; -+ let mut _164: std::future::ResumeTy; -+ let mut _165: std::task::Poll<()>; -+ let mut _166: isize; -+ let mut _167: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _168: &mut std::task::Context<'_>; -+ let mut _169: std::future::ResumeTy; -+ let mut _170: &mut impl std::future::Future; -+ let mut _171: std::future::ResumeTy; -+ let mut _172: std::task::Poll<()>; -+ let mut _173: isize; -+ let mut _174: std::pin::Pin<&mut impl std::future::Future>; -+ let mut _175: &mut std::task::Context<'_>; -+ let mut _176: std::future::ResumeTy; -+ let mut _177: &mut impl std::future::Future; -+ let mut _178: std::pin::Pin<&mut AsyncInt>; -+ let mut _179: &mut AsyncInt; ++ let mut _26: impl std::future::Future; ++ let mut _27: std::future::ResumeTy; ++ let mut _28: std::task::Poll<()>; ++ let mut _29: isize; ++ let mut _30: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _31: &mut std::task::Context<'_>; ++ let mut _32: std::future::ResumeTy; ++ let mut _33: &mut impl std::future::Future; ++ let mut _34: std::future::ResumeTy; ++ let mut _35: std::task::Poll<()>; ++ let mut _36: isize; ++ let mut _37: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _38: &mut std::task::Context<'_>; ++ let mut _39: std::future::ResumeTy; ++ let mut _40: &mut impl std::future::Future; ++ let mut _41: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>; ++ let mut _42: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35}; ++ let mut _43: impl std::future::Future; ++ let mut _44: std::future::ResumeTy; ++ let mut _45: std::task::Poll<()>; ++ let mut _46: isize; ++ let mut _47: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _48: &mut std::task::Context<'_>; ++ let mut _49: std::future::ResumeTy; ++ let mut _50: &mut impl std::future::Future; ++ let mut _51: std::future::ResumeTy; ++ let mut _52: std::task::Poll<()>; ++ let mut _53: isize; ++ let mut _54: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _55: &mut std::task::Context<'_>; ++ let mut _56: std::future::ResumeTy; ++ let mut _57: &mut impl std::future::Future; ++ let mut _58: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>; ++ let mut _59: &mut {closure@$DIR/async_drop.rs:78:25: 78:27}; ++ let mut _60: impl std::future::Future; ++ let mut _61: std::future::ResumeTy; ++ let mut _62: std::task::Poll<()>; ++ let mut _63: isize; ++ let mut _64: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _65: &mut std::task::Context<'_>; ++ let mut _66: std::future::ResumeTy; ++ let mut _67: &mut impl std::future::Future; ++ let mut _68: std::future::ResumeTy; ++ let mut _69: std::task::Poll<()>; ++ let mut _70: isize; ++ let mut _71: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _72: &mut std::task::Context<'_>; ++ let mut _73: std::future::ResumeTy; ++ let mut _74: &mut impl std::future::Future; ++ let mut _75: std::pin::Pin<&mut AsyncReference<'_>>; ++ let mut _76: &mut AsyncReference<'_>; ++ let mut _77: impl std::future::Future; ++ let mut _78: std::future::ResumeTy; ++ let mut _79: std::task::Poll<()>; ++ let mut _80: isize; ++ let mut _81: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _82: &mut std::task::Context<'_>; ++ let mut _83: std::future::ResumeTy; ++ let mut _84: &mut impl std::future::Future; ++ let mut _85: std::future::ResumeTy; ++ let mut _86: std::task::Poll<()>; ++ let mut _87: isize; ++ let mut _88: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _89: &mut std::task::Context<'_>; ++ let mut _90: std::future::ResumeTy; ++ let mut _91: &mut impl std::future::Future; ++ let mut _92: std::pin::Pin<&mut AsyncInt>; ++ let mut _93: &mut AsyncInt; ++ let mut _94: impl std::future::Future; ++ let mut _95: std::future::ResumeTy; ++ let mut _96: std::task::Poll<()>; ++ let mut _97: isize; ++ let mut _98: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _99: &mut std::task::Context<'_>; ++ let mut _100: std::future::ResumeTy; ++ let mut _101: &mut impl std::future::Future; ++ let mut _102: std::future::ResumeTy; ++ let mut _103: std::task::Poll<()>; ++ let mut _104: isize; ++ let mut _105: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _106: &mut std::task::Context<'_>; ++ let mut _107: std::future::ResumeTy; ++ let mut _108: &mut impl std::future::Future; ++ let mut _109: std::pin::Pin<&mut AsyncEnum>; ++ let mut _110: &mut AsyncEnum; ++ let mut _111: impl std::future::Future; ++ let mut _112: std::future::ResumeTy; ++ let mut _113: std::task::Poll<()>; ++ let mut _114: isize; ++ let mut _115: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _116: &mut std::task::Context<'_>; ++ let mut _117: std::future::ResumeTy; ++ let mut _118: &mut impl std::future::Future; ++ let mut _119: std::future::ResumeTy; ++ let mut _120: std::task::Poll<()>; ++ let mut _121: isize; ++ let mut _122: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _123: &mut std::task::Context<'_>; ++ let mut _124: std::future::ResumeTy; ++ let mut _125: &mut impl std::future::Future; ++ let mut _126: std::pin::Pin<&mut SyncThenAsync>; ++ let mut _127: &mut SyncThenAsync; ++ let mut _128: impl std::future::Future; ++ let mut _129: std::future::ResumeTy; ++ let mut _130: std::task::Poll<()>; ++ let mut _131: isize; ++ let mut _132: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _133: &mut std::task::Context<'_>; ++ let mut _134: std::future::ResumeTy; ++ let mut _135: &mut impl std::future::Future; ++ let mut _136: std::future::ResumeTy; ++ let mut _137: std::task::Poll<()>; ++ let mut _138: isize; ++ let mut _139: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _140: &mut std::task::Context<'_>; ++ let mut _141: std::future::ResumeTy; ++ let mut _142: &mut impl std::future::Future; ++ let mut _143: std::pin::Pin<&mut AsyncStruct>; ++ let mut _144: &mut AsyncStruct; ++ let mut _145: impl std::future::Future; ++ let mut _146: std::future::ResumeTy; ++ let mut _147: std::task::Poll<()>; ++ let mut _148: isize; ++ let mut _149: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _150: &mut std::task::Context<'_>; ++ let mut _151: std::future::ResumeTy; ++ let mut _152: &mut impl std::future::Future; ++ let mut _153: std::future::ResumeTy; ++ let mut _154: std::task::Poll<()>; ++ let mut _155: isize; ++ let mut _156: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _157: &mut std::task::Context<'_>; ++ let mut _158: std::future::ResumeTy; ++ let mut _159: &mut impl std::future::Future; ++ let mut _160: std::pin::Pin<&mut [AsyncInt; 2]>; ++ let mut _161: &mut [AsyncInt; 2]; ++ let mut _162: impl std::future::Future; ++ let mut _163: std::future::ResumeTy; ++ let mut _164: std::task::Poll<()>; ++ let mut _165: isize; ++ let mut _166: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _167: &mut std::task::Context<'_>; ++ let mut _168: std::future::ResumeTy; ++ let mut _169: &mut impl std::future::Future; ++ let mut _170: std::future::ResumeTy; ++ let mut _171: std::task::Poll<()>; ++ let mut _172: isize; ++ let mut _173: std::pin::Pin<&mut impl std::future::Future>; ++ let mut _174: &mut std::task::Context<'_>; ++ let mut _175: std::future::ResumeTy; ++ let mut _176: &mut impl std::future::Future; ++ let mut _177: std::pin::Pin<&mut AsyncInt>; ++ let mut _178: &mut AsyncInt; scope 1 { debug sync_int => _3; let _4: AsyncInt; @@ -197,18 +196,18 @@ let _20: AsyncReference<'_>; scope 9 { debug async_ref => _20; - let _23: AsyncInt; + let _22: AsyncInt; scope 10 { - debug foo => _23; - let _24: {closure@$DIR/async_drop.rs:78:25: 78:27}; + debug foo => _22; + let _23: {closure@$DIR/async_drop.rs:78:25: 78:27}; scope 11 { - debug async_closure => _24; - let _25: AsyncInt; + debug async_closure => _23; + let _24: AsyncInt; scope 12 { - debug foo => _25; - let _26: {async closure@$DIR/async_drop.rs:86:27: 86:35}; + debug foo => _24; + let _25: {async closure@$DIR/async_drop.rs:86:27: 86:35}; scope 13 { - debug async_coroutine => _26; + debug async_coroutine => _25; } } } @@ -312,45 +311,42 @@ _19 = AsyncInt(const 12_i32); StorageLive(_20); StorageLive(_21); - StorageLive(_22); - _22 = &_19; - _21 = &(*_22); + _21 = &_19; _20 = AsyncReference::<'_> { foo: move _21 }; StorageDead(_21); - StorageDead(_22); + StorageLive(_22); + _22 = AsyncInt(const 14_i32); StorageLive(_23); - _23 = AsyncInt(const 14_i32); + _23 = {closure@$DIR/async_drop.rs:78:25: 78:27} { foo: move _22 }; StorageLive(_24); - _24 = {closure@$DIR/async_drop.rs:78:25: 78:27} { foo: move _23 }; + _24 = AsyncInt(const 15_i32); StorageLive(_25); - _25 = AsyncInt(const 15_i32); - StorageLive(_26); - _26 = {closure@$DIR/async_drop.rs:86:27: 86:35} { foo: move _25 }; + _25 = {closure@$DIR/async_drop.rs:86:27: 86:35} { foo: move _24 }; _0 = const (); -- drop(_26) -> [return: bb10, unwind: bb44, drop: bb23]; +- drop(_25) -> [return: bb10, unwind: bb44, drop: bb23]; + goto -> bb103; } bb10: { - StorageDead(_26); -- drop(_25) -> [return: bb11, unwind: bb45, drop: bb24]; + StorageDead(_25); +- drop(_24) -> [return: bb11, unwind: bb45, drop: bb24]; + goto -> bb11; } bb11: { - StorageDead(_25); -- drop(_24) -> [return: bb12, unwind: bb46, drop: bb25]; + StorageDead(_24); +- drop(_23) -> [return: bb12, unwind: bb46, drop: bb25]; + goto -> bb123; } bb12: { - StorageDead(_24); -- drop(_23) -> [return: bb13, unwind: bb47, drop: bb26]; + StorageDead(_23); +- drop(_22) -> [return: bb13, unwind: bb47, drop: bb26]; + goto -> bb13; } bb13: { - StorageDead(_23); + StorageDead(_22); - drop(_20) -> [return: bb14, unwind: bb48, drop: bb27]; + goto -> bb143; } @@ -408,25 +404,25 @@ } bb23: { - StorageDead(_26); -- drop(_25) -> [return: bb24, unwind: bb68]; + StorageDead(_25); +- drop(_24) -> [return: bb24, unwind: bb68]; + goto -> bb24; } bb24: { - StorageDead(_25); -- drop(_24) -> [return: bb25, unwind: bb69]; + StorageDead(_24); +- drop(_23) -> [return: bb25, unwind: bb69]; + goto -> bb25; } bb25: { - StorageDead(_24); -- drop(_23) -> [return: bb26, unwind: bb70]; + StorageDead(_23); +- drop(_22) -> [return: bb26, unwind: bb70]; + goto -> bb26; } bb26: { - StorageDead(_23); + StorageDead(_22); - drop(_20) -> [return: bb27, unwind: bb71]; + goto -> bb27; } @@ -529,24 +525,24 @@ } bb44 (cleanup): { - StorageDead(_26); -- drop(_25) -> [return: bb45, unwind terminate(cleanup)]; + StorageDead(_25); +- drop(_24) -> [return: bb45, unwind terminate(cleanup)]; + goto -> bb45; } bb45 (cleanup): { - StorageDead(_25); - drop(_24) -> [return: bb46, unwind terminate(cleanup)]; + StorageDead(_24); + drop(_23) -> [return: bb46, unwind terminate(cleanup)]; } bb46 (cleanup): { - StorageDead(_24); -- drop(_23) -> [return: bb47, unwind terminate(cleanup)]; + StorageDead(_23); +- drop(_22) -> [return: bb47, unwind terminate(cleanup)]; + goto -> bb47; } bb47 (cleanup): { - StorageDead(_23); + StorageDead(_22); drop(_20) -> [return: bb48, unwind terminate(cleanup)]; } @@ -654,19 +650,19 @@ } bb68 (cleanup): { - StorageDead(_25); -- drop(_24) -> [return: bb69, unwind terminate(cleanup)]; + StorageDead(_24); +- drop(_23) -> [return: bb69, unwind terminate(cleanup)]; + goto -> bb69; } bb69 (cleanup): { - StorageDead(_24); -- drop(_23) -> [return: bb70, unwind terminate(cleanup)]; + StorageDead(_23); +- drop(_22) -> [return: bb70, unwind terminate(cleanup)]; + goto -> bb70; } bb70 (cleanup): { - StorageDead(_23); + StorageDead(_22); - drop(_20) -> [return: bb71, unwind terminate(cleanup)]; + goto -> bb71; } @@ -742,17 +738,17 @@ + } + + bb83: { -+ StorageDead(_27); ++ StorageDead(_26); + goto -> bb10; + } + + bb84: { -+ StorageDead(_27); ++ StorageDead(_26); + goto -> bb23; + } + + bb85 (cleanup): { -+ StorageDead(_27); ++ StorageDead(_26); + goto -> bb44; + } + @@ -761,20 +757,20 @@ + } + + bb87: { -+ _2 = move _28; -+ StorageDead(_28); ++ _2 = move _27; ++ StorageDead(_27); + goto -> bb86; + } + + bb88: { -+ _2 = move _28; -+ StorageDead(_28); ++ _2 = move _27; ++ StorageDead(_27); + goto -> bb94; + } + + bb89: { -+ StorageLive(_28); -+ _28 = yield(const ()) -> [resume: bb87, drop: bb88]; ++ StorageLive(_27); ++ _27 = yield(const ()) -> [resume: bb87, drop: bb88]; + } + + bb90: { @@ -782,82 +778,82 @@ + } + + bb91: { -+ _30 = discriminant(_29); -+ switchInt(move _30) -> [0: bb84, 1: bb89, otherwise: bb90]; ++ _29 = discriminant(_28); ++ switchInt(move _29) -> [0: bb84, 1: bb89, otherwise: bb90]; + } + + bb92: { -+ _29 = as Future>::poll(move _31, move _32) -> [return: bb91, unwind: bb85]; ++ _28 = as Future>::poll(move _30, move _31) -> [return: bb91, unwind: bb85]; + } + + bb93: { -+ _33 = move _2; -+ _32 = std::future::get_context::<'_, '_>(move _33) -> [return: bb92, unwind: bb85]; ++ _32 = move _2; ++ _31 = std::future::get_context::<'_, '_>(move _32) -> [return: bb92, unwind: bb85]; + } + + bb94: { -+ _34 = &mut _27; -+ _31 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb93, unwind: bb85]; ++ _33 = &mut _26; ++ _30 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb93, unwind: bb85]; + } + + bb95: { -+ _2 = move _35; -+ StorageDead(_35); ++ _2 = move _34; ++ StorageDead(_34); + goto -> bb101; + } + + bb96: { -+ _2 = move _35; -+ StorageDead(_35); ++ _2 = move _34; ++ StorageDead(_34); + goto -> bb94; + } + + bb97: { -+ StorageLive(_35); -+ _35 = yield(const ()) -> [resume: bb95, drop: bb96]; ++ StorageLive(_34); ++ _34 = yield(const ()) -> [resume: bb95, drop: bb96]; + } + + bb98: { -+ _37 = discriminant(_36); -+ switchInt(move _37) -> [0: bb83, 1: bb97, otherwise: bb90]; ++ _36 = discriminant(_35); ++ switchInt(move _36) -> [0: bb83, 1: bb97, otherwise: bb90]; + } + + bb99: { -+ _36 = as Future>::poll(move _38, move _39) -> [return: bb98, unwind: bb85]; ++ _35 = as Future>::poll(move _37, move _38) -> [return: bb98, unwind: bb85]; + } + + bb100: { -+ _40 = move _2; -+ _39 = std::future::get_context::<'_, '_>(move _40) -> [return: bb99, unwind: bb85]; ++ _39 = move _2; ++ _38 = std::future::get_context::<'_, '_>(move _39) -> [return: bb99, unwind: bb85]; + } + + bb101: { -+ _41 = &mut _27; -+ _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb100, unwind: bb85]; ++ _40 = &mut _26; ++ _37 = Pin::<&mut impl Future>::new_unchecked(move _40) -> [return: bb100, unwind: bb85]; + } + + bb102: { -+ StorageLive(_27); -+ _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:86:27: 86:35}>(copy (_42.0: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35})) -> [return: bb101, unwind: bb85]; ++ StorageLive(_26); ++ _26 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:86:27: 86:35}>(copy (_41.0: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35})) -> [return: bb101, unwind: bb85]; + } + + bb103: { -+ _43 = &mut _26; -+ _42 = Pin::<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>::new_unchecked(move _43) -> [return: bb102, unwind: bb44]; ++ _42 = &mut _25; ++ _41 = Pin::<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>::new_unchecked(move _42) -> [return: bb102, unwind: bb44]; + } + + bb104: { -+ StorageDead(_44); ++ StorageDead(_43); + goto -> bb12; + } + + bb105: { -+ StorageDead(_44); ++ StorageDead(_43); + goto -> bb25; + } + + bb106 (cleanup): { -+ StorageDead(_44); ++ StorageDead(_43); + goto -> bb46; + } + @@ -866,99 +862,99 @@ + } + + bb108: { -+ _2 = move _45; -+ StorageDead(_45); ++ _2 = move _44; ++ StorageDead(_44); + goto -> bb107; + } + + bb109: { -+ _2 = move _45; -+ StorageDead(_45); ++ _2 = move _44; ++ StorageDead(_44); + goto -> bb114; + } + + bb110: { -+ StorageLive(_45); -+ _45 = yield(const ()) -> [resume: bb108, drop: bb109]; ++ StorageLive(_44); ++ _44 = yield(const ()) -> [resume: bb108, drop: bb109]; + } + + bb111: { -+ _47 = discriminant(_46); -+ switchInt(move _47) -> [0: bb105, 1: bb110, otherwise: bb90]; ++ _46 = discriminant(_45); ++ switchInt(move _46) -> [0: bb105, 1: bb110, otherwise: bb90]; + } + + bb112: { -+ _46 = as Future>::poll(move _48, move _49) -> [return: bb111, unwind: bb106]; ++ _45 = as Future>::poll(move _47, move _48) -> [return: bb111, unwind: bb106]; + } + + bb113: { -+ _50 = move _2; -+ _49 = std::future::get_context::<'_, '_>(move _50) -> [return: bb112, unwind: bb106]; ++ _49 = move _2; ++ _48 = std::future::get_context::<'_, '_>(move _49) -> [return: bb112, unwind: bb106]; + } + + bb114: { -+ _51 = &mut _44; -+ _48 = Pin::<&mut impl Future>::new_unchecked(move _51) -> [return: bb113, unwind: bb106]; ++ _50 = &mut _43; ++ _47 = Pin::<&mut impl Future>::new_unchecked(move _50) -> [return: bb113, unwind: bb106]; + } + + bb115: { -+ _2 = move _52; -+ StorageDead(_52); ++ _2 = move _51; ++ StorageDead(_51); + goto -> bb121; + } + + bb116: { -+ _2 = move _52; -+ StorageDead(_52); ++ _2 = move _51; ++ StorageDead(_51); + goto -> bb114; + } + + bb117: { -+ StorageLive(_52); -+ _52 = yield(const ()) -> [resume: bb115, drop: bb116]; ++ StorageLive(_51); ++ _51 = yield(const ()) -> [resume: bb115, drop: bb116]; + } + + bb118: { -+ _54 = discriminant(_53); -+ switchInt(move _54) -> [0: bb104, 1: bb117, otherwise: bb90]; ++ _53 = discriminant(_52); ++ switchInt(move _53) -> [0: bb104, 1: bb117, otherwise: bb90]; + } + + bb119: { -+ _53 = as Future>::poll(move _55, move _56) -> [return: bb118, unwind: bb106]; ++ _52 = as Future>::poll(move _54, move _55) -> [return: bb118, unwind: bb106]; + } + + bb120: { -+ _57 = move _2; -+ _56 = std::future::get_context::<'_, '_>(move _57) -> [return: bb119, unwind: bb106]; ++ _56 = move _2; ++ _55 = std::future::get_context::<'_, '_>(move _56) -> [return: bb119, unwind: bb106]; + } + + bb121: { -+ _58 = &mut _44; -+ _55 = Pin::<&mut impl Future>::new_unchecked(move _58) -> [return: bb120, unwind: bb106]; ++ _57 = &mut _43; ++ _54 = Pin::<&mut impl Future>::new_unchecked(move _57) -> [return: bb120, unwind: bb106]; + } + + bb122: { -+ StorageLive(_44); -+ _44 = async_drop_in_place::<{closure@$DIR/async_drop.rs:78:25: 78:27}>(copy (_59.0: &mut {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb121, unwind: bb106]; ++ StorageLive(_43); ++ _43 = async_drop_in_place::<{closure@$DIR/async_drop.rs:78:25: 78:27}>(copy (_58.0: &mut {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb121, unwind: bb106]; + } + + bb123: { -+ _60 = &mut _24; -+ _59 = Pin::<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>::new_unchecked(move _60) -> [return: bb122, unwind: bb46]; ++ _59 = &mut _23; ++ _58 = Pin::<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>::new_unchecked(move _59) -> [return: bb122, unwind: bb46]; + } + + bb124: { -+ StorageDead(_61); ++ StorageDead(_60); + goto -> bb14; + } + + bb125: { -+ StorageDead(_61); ++ StorageDead(_60); + goto -> bb27; + } + + bb126 (cleanup): { -+ StorageDead(_61); ++ StorageDead(_60); + goto -> bb48; + } + @@ -967,99 +963,99 @@ + } + + bb128: { -+ _2 = move _62; -+ StorageDead(_62); ++ _2 = move _61; ++ StorageDead(_61); + goto -> bb127; + } + + bb129: { -+ _2 = move _62; -+ StorageDead(_62); ++ _2 = move _61; ++ StorageDead(_61); + goto -> bb134; + } + + bb130: { -+ StorageLive(_62); -+ _62 = yield(const ()) -> [resume: bb128, drop: bb129]; ++ StorageLive(_61); ++ _61 = yield(const ()) -> [resume: bb128, drop: bb129]; + } + + bb131: { -+ _64 = discriminant(_63); -+ switchInt(move _64) -> [0: bb125, 1: bb130, otherwise: bb90]; ++ _63 = discriminant(_62); ++ switchInt(move _63) -> [0: bb125, 1: bb130, otherwise: bb90]; + } + + bb132: { -+ _63 = as Future>::poll(move _65, move _66) -> [return: bb131, unwind: bb126]; ++ _62 = as Future>::poll(move _64, move _65) -> [return: bb131, unwind: bb126]; + } + + bb133: { -+ _67 = move _2; -+ _66 = std::future::get_context::<'_, '_>(move _67) -> [return: bb132, unwind: bb126]; ++ _66 = move _2; ++ _65 = std::future::get_context::<'_, '_>(move _66) -> [return: bb132, unwind: bb126]; + } + + bb134: { -+ _68 = &mut _61; -+ _65 = Pin::<&mut impl Future>::new_unchecked(move _68) -> [return: bb133, unwind: bb126]; ++ _67 = &mut _60; ++ _64 = Pin::<&mut impl Future>::new_unchecked(move _67) -> [return: bb133, unwind: bb126]; + } + + bb135: { -+ _2 = move _69; -+ StorageDead(_69); ++ _2 = move _68; ++ StorageDead(_68); + goto -> bb141; + } + + bb136: { -+ _2 = move _69; -+ StorageDead(_69); ++ _2 = move _68; ++ StorageDead(_68); + goto -> bb134; + } + + bb137: { -+ StorageLive(_69); -+ _69 = yield(const ()) -> [resume: bb135, drop: bb136]; ++ StorageLive(_68); ++ _68 = yield(const ()) -> [resume: bb135, drop: bb136]; + } + + bb138: { -+ _71 = discriminant(_70); -+ switchInt(move _71) -> [0: bb124, 1: bb137, otherwise: bb90]; ++ _70 = discriminant(_69); ++ switchInt(move _70) -> [0: bb124, 1: bb137, otherwise: bb90]; + } + + bb139: { -+ _70 = as Future>::poll(move _72, move _73) -> [return: bb138, unwind: bb126]; ++ _69 = as Future>::poll(move _71, move _72) -> [return: bb138, unwind: bb126]; + } + + bb140: { -+ _74 = move _2; -+ _73 = std::future::get_context::<'_, '_>(move _74) -> [return: bb139, unwind: bb126]; ++ _73 = move _2; ++ _72 = std::future::get_context::<'_, '_>(move _73) -> [return: bb139, unwind: bb126]; + } + + bb141: { -+ _75 = &mut _61; -+ _72 = Pin::<&mut impl Future>::new_unchecked(move _75) -> [return: bb140, unwind: bb126]; ++ _74 = &mut _60; ++ _71 = Pin::<&mut impl Future>::new_unchecked(move _74) -> [return: bb140, unwind: bb126]; + } + + bb142: { -+ StorageLive(_61); -+ _61 = async_drop_in_place::>(copy (_76.0: &mut AsyncReference<'_>)) -> [return: bb141, unwind: bb126]; ++ StorageLive(_60); ++ _60 = async_drop_in_place::>(copy (_75.0: &mut AsyncReference<'_>)) -> [return: bb141, unwind: bb126]; + } + + bb143: { -+ _77 = &mut _20; -+ _76 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _77) -> [return: bb142, unwind: bb48]; ++ _76 = &mut _20; ++ _75 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _76) -> [return: bb142, unwind: bb48]; + } + + bb144: { -+ StorageDead(_78); ++ StorageDead(_77); + goto -> bb15; + } + + bb145: { -+ StorageDead(_78); ++ StorageDead(_77); + goto -> bb28; + } + + bb146 (cleanup): { -+ StorageDead(_78); ++ StorageDead(_77); + goto -> bb49; + } + @@ -1068,99 +1064,99 @@ + } + + bb148: { -+ _2 = move _79; -+ StorageDead(_79); ++ _2 = move _78; ++ StorageDead(_78); + goto -> bb147; + } + + bb149: { -+ _2 = move _79; -+ StorageDead(_79); ++ _2 = move _78; ++ StorageDead(_78); + goto -> bb154; + } + + bb150: { -+ StorageLive(_79); -+ _79 = yield(const ()) -> [resume: bb148, drop: bb149]; ++ StorageLive(_78); ++ _78 = yield(const ()) -> [resume: bb148, drop: bb149]; + } + + bb151: { -+ _81 = discriminant(_80); -+ switchInt(move _81) -> [0: bb145, 1: bb150, otherwise: bb90]; ++ _80 = discriminant(_79); ++ switchInt(move _80) -> [0: bb145, 1: bb150, otherwise: bb90]; + } + + bb152: { -+ _80 = as Future>::poll(move _82, move _83) -> [return: bb151, unwind: bb146]; ++ _79 = as Future>::poll(move _81, move _82) -> [return: bb151, unwind: bb146]; + } + + bb153: { -+ _84 = move _2; -+ _83 = std::future::get_context::<'_, '_>(move _84) -> [return: bb152, unwind: bb146]; ++ _83 = move _2; ++ _82 = std::future::get_context::<'_, '_>(move _83) -> [return: bb152, unwind: bb146]; + } + + bb154: { -+ _85 = &mut _78; -+ _82 = Pin::<&mut impl Future>::new_unchecked(move _85) -> [return: bb153, unwind: bb146]; ++ _84 = &mut _77; ++ _81 = Pin::<&mut impl Future>::new_unchecked(move _84) -> [return: bb153, unwind: bb146]; + } + + bb155: { -+ _2 = move _86; -+ StorageDead(_86); ++ _2 = move _85; ++ StorageDead(_85); + goto -> bb161; + } + + bb156: { -+ _2 = move _86; -+ StorageDead(_86); ++ _2 = move _85; ++ StorageDead(_85); + goto -> bb154; + } + + bb157: { -+ StorageLive(_86); -+ _86 = yield(const ()) -> [resume: bb155, drop: bb156]; ++ StorageLive(_85); ++ _85 = yield(const ()) -> [resume: bb155, drop: bb156]; + } + + bb158: { -+ _88 = discriminant(_87); -+ switchInt(move _88) -> [0: bb144, 1: bb157, otherwise: bb90]; ++ _87 = discriminant(_86); ++ switchInt(move _87) -> [0: bb144, 1: bb157, otherwise: bb90]; + } + + bb159: { -+ _87 = as Future>::poll(move _89, move _90) -> [return: bb158, unwind: bb146]; ++ _86 = as Future>::poll(move _88, move _89) -> [return: bb158, unwind: bb146]; + } + + bb160: { -+ _91 = move _2; -+ _90 = std::future::get_context::<'_, '_>(move _91) -> [return: bb159, unwind: bb146]; ++ _90 = move _2; ++ _89 = std::future::get_context::<'_, '_>(move _90) -> [return: bb159, unwind: bb146]; + } + + bb161: { -+ _92 = &mut _78; -+ _89 = Pin::<&mut impl Future>::new_unchecked(move _92) -> [return: bb160, unwind: bb146]; ++ _91 = &mut _77; ++ _88 = Pin::<&mut impl Future>::new_unchecked(move _91) -> [return: bb160, unwind: bb146]; + } + + bb162: { -+ StorageLive(_78); -+ _78 = async_drop_in_place::(copy (_93.0: &mut AsyncInt)) -> [return: bb161, unwind: bb146]; ++ StorageLive(_77); ++ _77 = async_drop_in_place::(copy (_92.0: &mut AsyncInt)) -> [return: bb161, unwind: bb146]; + } + + bb163: { -+ _94 = &mut _19; -+ _93 = Pin::<&mut AsyncInt>::new_unchecked(move _94) -> [return: bb162, unwind: bb49]; ++ _93 = &mut _19; ++ _92 = Pin::<&mut AsyncInt>::new_unchecked(move _93) -> [return: bb162, unwind: bb49]; + } + + bb164: { -+ StorageDead(_95); ++ StorageDead(_94); + goto -> bb16; + } + + bb165: { -+ StorageDead(_95); ++ StorageDead(_94); + goto -> bb30; + } + + bb166 (cleanup): { -+ StorageDead(_95); ++ StorageDead(_94); + goto -> bb54; + } + @@ -1169,99 +1165,99 @@ + } + + bb168: { -+ _2 = move _96; -+ StorageDead(_96); ++ _2 = move _95; ++ StorageDead(_95); + goto -> bb167; + } + + bb169: { -+ _2 = move _96; -+ StorageDead(_96); ++ _2 = move _95; ++ StorageDead(_95); + goto -> bb174; + } + + bb170: { -+ StorageLive(_96); -+ _96 = yield(const ()) -> [resume: bb168, drop: bb169]; ++ StorageLive(_95); ++ _95 = yield(const ()) -> [resume: bb168, drop: bb169]; + } + + bb171: { -+ _98 = discriminant(_97); -+ switchInt(move _98) -> [0: bb165, 1: bb170, otherwise: bb90]; ++ _97 = discriminant(_96); ++ switchInt(move _97) -> [0: bb165, 1: bb170, otherwise: bb90]; + } + + bb172: { -+ _97 = as Future>::poll(move _99, move _100) -> [return: bb171, unwind: bb166]; ++ _96 = as Future>::poll(move _98, move _99) -> [return: bb171, unwind: bb166]; + } + + bb173: { -+ _101 = move _2; -+ _100 = std::future::get_context::<'_, '_>(move _101) -> [return: bb172, unwind: bb166]; ++ _100 = move _2; ++ _99 = std::future::get_context::<'_, '_>(move _100) -> [return: bb172, unwind: bb166]; + } + + bb174: { -+ _102 = &mut _95; -+ _99 = Pin::<&mut impl Future>::new_unchecked(move _102) -> [return: bb173, unwind: bb166]; ++ _101 = &mut _94; ++ _98 = Pin::<&mut impl Future>::new_unchecked(move _101) -> [return: bb173, unwind: bb166]; + } + + bb175: { -+ _2 = move _103; -+ StorageDead(_103); ++ _2 = move _102; ++ StorageDead(_102); + goto -> bb181; + } + + bb176: { -+ _2 = move _103; -+ StorageDead(_103); ++ _2 = move _102; ++ StorageDead(_102); + goto -> bb174; + } + + bb177: { -+ StorageLive(_103); -+ _103 = yield(const ()) -> [resume: bb175, drop: bb176]; ++ StorageLive(_102); ++ _102 = yield(const ()) -> [resume: bb175, drop: bb176]; + } + + bb178: { -+ _105 = discriminant(_104); -+ switchInt(move _105) -> [0: bb164, 1: bb177, otherwise: bb90]; ++ _104 = discriminant(_103); ++ switchInt(move _104) -> [0: bb164, 1: bb177, otherwise: bb90]; + } + + bb179: { -+ _104 = as Future>::poll(move _106, move _107) -> [return: bb178, unwind: bb166]; ++ _103 = as Future>::poll(move _105, move _106) -> [return: bb178, unwind: bb166]; + } + + bb180: { -+ _108 = move _2; -+ _107 = std::future::get_context::<'_, '_>(move _108) -> [return: bb179, unwind: bb166]; ++ _107 = move _2; ++ _106 = std::future::get_context::<'_, '_>(move _107) -> [return: bb179, unwind: bb166]; + } + + bb181: { -+ _109 = &mut _95; -+ _106 = Pin::<&mut impl Future>::new_unchecked(move _109) -> [return: bb180, unwind: bb166]; ++ _108 = &mut _94; ++ _105 = Pin::<&mut impl Future>::new_unchecked(move _108) -> [return: bb180, unwind: bb166]; + } + + bb182: { -+ StorageLive(_95); -+ _95 = async_drop_in_place::(copy (_110.0: &mut AsyncEnum)) -> [return: bb181, unwind: bb166]; ++ StorageLive(_94); ++ _94 = async_drop_in_place::(copy (_109.0: &mut AsyncEnum)) -> [return: bb181, unwind: bb166]; + } + + bb183: { -+ _111 = &mut _15; -+ _110 = Pin::<&mut AsyncEnum>::new_unchecked(move _111) -> [return: bb182, unwind: bb54]; ++ _110 = &mut _15; ++ _109 = Pin::<&mut AsyncEnum>::new_unchecked(move _110) -> [return: bb182, unwind: bb54]; + } + + bb184: { -+ StorageDead(_112); ++ StorageDead(_111); + goto -> bb17; + } + + bb185: { -+ StorageDead(_112); ++ StorageDead(_111); + goto -> bb34; + } + + bb186 (cleanup): { -+ StorageDead(_112); ++ StorageDead(_111); + goto -> bb58; + } + @@ -1270,99 +1266,99 @@ + } + + bb188: { -+ _2 = move _113; -+ StorageDead(_113); ++ _2 = move _112; ++ StorageDead(_112); + goto -> bb187; + } + + bb189: { -+ _2 = move _113; -+ StorageDead(_113); ++ _2 = move _112; ++ StorageDead(_112); + goto -> bb194; + } + + bb190: { -+ StorageLive(_113); -+ _113 = yield(const ()) -> [resume: bb188, drop: bb189]; ++ StorageLive(_112); ++ _112 = yield(const ()) -> [resume: bb188, drop: bb189]; + } + + bb191: { -+ _115 = discriminant(_114); -+ switchInt(move _115) -> [0: bb185, 1: bb190, otherwise: bb90]; ++ _114 = discriminant(_113); ++ switchInt(move _114) -> [0: bb185, 1: bb190, otherwise: bb90]; + } + + bb192: { -+ _114 = as Future>::poll(move _116, move _117) -> [return: bb191, unwind: bb186]; ++ _113 = as Future>::poll(move _115, move _116) -> [return: bb191, unwind: bb186]; + } + + bb193: { -+ _118 = move _2; -+ _117 = std::future::get_context::<'_, '_>(move _118) -> [return: bb192, unwind: bb186]; ++ _117 = move _2; ++ _116 = std::future::get_context::<'_, '_>(move _117) -> [return: bb192, unwind: bb186]; + } + + bb194: { -+ _119 = &mut _112; -+ _116 = Pin::<&mut impl Future>::new_unchecked(move _119) -> [return: bb193, unwind: bb186]; ++ _118 = &mut _111; ++ _115 = Pin::<&mut impl Future>::new_unchecked(move _118) -> [return: bb193, unwind: bb186]; + } + + bb195: { -+ _2 = move _120; -+ StorageDead(_120); ++ _2 = move _119; ++ StorageDead(_119); + goto -> bb201; + } + + bb196: { -+ _2 = move _120; -+ StorageDead(_120); ++ _2 = move _119; ++ StorageDead(_119); + goto -> bb194; + } + + bb197: { -+ StorageLive(_120); -+ _120 = yield(const ()) -> [resume: bb195, drop: bb196]; ++ StorageLive(_119); ++ _119 = yield(const ()) -> [resume: bb195, drop: bb196]; + } + + bb198: { -+ _122 = discriminant(_121); -+ switchInt(move _122) -> [0: bb184, 1: bb197, otherwise: bb90]; ++ _121 = discriminant(_120); ++ switchInt(move _121) -> [0: bb184, 1: bb197, otherwise: bb90]; + } + + bb199: { -+ _121 = as Future>::poll(move _123, move _124) -> [return: bb198, unwind: bb186]; ++ _120 = as Future>::poll(move _122, move _123) -> [return: bb198, unwind: bb186]; + } + + bb200: { -+ _125 = move _2; -+ _124 = std::future::get_context::<'_, '_>(move _125) -> [return: bb199, unwind: bb186]; ++ _124 = move _2; ++ _123 = std::future::get_context::<'_, '_>(move _124) -> [return: bb199, unwind: bb186]; + } + + bb201: { -+ _126 = &mut _112; -+ _123 = Pin::<&mut impl Future>::new_unchecked(move _126) -> [return: bb200, unwind: bb186]; ++ _125 = &mut _111; ++ _122 = Pin::<&mut impl Future>::new_unchecked(move _125) -> [return: bb200, unwind: bb186]; + } + + bb202: { -+ StorageLive(_112); -+ _112 = async_drop_in_place::(copy (_127.0: &mut SyncThenAsync)) -> [return: bb201, unwind: bb186]; ++ StorageLive(_111); ++ _111 = async_drop_in_place::(copy (_126.0: &mut SyncThenAsync)) -> [return: bb201, unwind: bb186]; + } + + bb203: { -+ _128 = &mut _11; -+ _127 = Pin::<&mut SyncThenAsync>::new_unchecked(move _128) -> [return: bb202, unwind: bb58]; ++ _127 = &mut _11; ++ _126 = Pin::<&mut SyncThenAsync>::new_unchecked(move _127) -> [return: bb202, unwind: bb58]; + } + + bb204: { -+ StorageDead(_129); ++ StorageDead(_128); + goto -> bb18; + } + + bb205: { -+ StorageDead(_129); ++ StorageDead(_128); + goto -> bb37; + } + + bb206 (cleanup): { -+ StorageDead(_129); ++ StorageDead(_128); + goto -> bb61; + } + @@ -1371,99 +1367,99 @@ + } + + bb208: { -+ _2 = move _130; -+ StorageDead(_130); ++ _2 = move _129; ++ StorageDead(_129); + goto -> bb207; + } + + bb209: { -+ _2 = move _130; -+ StorageDead(_130); ++ _2 = move _129; ++ StorageDead(_129); + goto -> bb214; + } + + bb210: { -+ StorageLive(_130); -+ _130 = yield(const ()) -> [resume: bb208, drop: bb209]; ++ StorageLive(_129); ++ _129 = yield(const ()) -> [resume: bb208, drop: bb209]; + } + + bb211: { -+ _132 = discriminant(_131); -+ switchInt(move _132) -> [0: bb205, 1: bb210, otherwise: bb90]; ++ _131 = discriminant(_130); ++ switchInt(move _131) -> [0: bb205, 1: bb210, otherwise: bb90]; + } + + bb212: { -+ _131 = as Future>::poll(move _133, move _134) -> [return: bb211, unwind: bb206]; ++ _130 = as Future>::poll(move _132, move _133) -> [return: bb211, unwind: bb206]; + } + + bb213: { -+ _135 = move _2; -+ _134 = std::future::get_context::<'_, '_>(move _135) -> [return: bb212, unwind: bb206]; ++ _134 = move _2; ++ _133 = std::future::get_context::<'_, '_>(move _134) -> [return: bb212, unwind: bb206]; + } + + bb214: { -+ _136 = &mut _129; -+ _133 = Pin::<&mut impl Future>::new_unchecked(move _136) -> [return: bb213, unwind: bb206]; ++ _135 = &mut _128; ++ _132 = Pin::<&mut impl Future>::new_unchecked(move _135) -> [return: bb213, unwind: bb206]; + } + + bb215: { -+ _2 = move _137; -+ StorageDead(_137); ++ _2 = move _136; ++ StorageDead(_136); + goto -> bb221; + } + + bb216: { -+ _2 = move _137; -+ StorageDead(_137); ++ _2 = move _136; ++ StorageDead(_136); + goto -> bb214; + } + + bb217: { -+ StorageLive(_137); -+ _137 = yield(const ()) -> [resume: bb215, drop: bb216]; ++ StorageLive(_136); ++ _136 = yield(const ()) -> [resume: bb215, drop: bb216]; + } + + bb218: { -+ _139 = discriminant(_138); -+ switchInt(move _139) -> [0: bb204, 1: bb217, otherwise: bb90]; ++ _138 = discriminant(_137); ++ switchInt(move _138) -> [0: bb204, 1: bb217, otherwise: bb90]; + } + + bb219: { -+ _138 = as Future>::poll(move _140, move _141) -> [return: bb218, unwind: bb206]; ++ _137 = as Future>::poll(move _139, move _140) -> [return: bb218, unwind: bb206]; + } + + bb220: { -+ _142 = move _2; -+ _141 = std::future::get_context::<'_, '_>(move _142) -> [return: bb219, unwind: bb206]; ++ _141 = move _2; ++ _140 = std::future::get_context::<'_, '_>(move _141) -> [return: bb219, unwind: bb206]; + } + + bb221: { -+ _143 = &mut _129; -+ _140 = Pin::<&mut impl Future>::new_unchecked(move _143) -> [return: bb220, unwind: bb206]; ++ _142 = &mut _128; ++ _139 = Pin::<&mut impl Future>::new_unchecked(move _142) -> [return: bb220, unwind: bb206]; + } + + bb222: { -+ StorageLive(_129); -+ _129 = async_drop_in_place::(copy (_144.0: &mut AsyncStruct)) -> [return: bb221, unwind: bb206]; ++ StorageLive(_128); ++ _128 = async_drop_in_place::(copy (_143.0: &mut AsyncStruct)) -> [return: bb221, unwind: bb206]; + } + + bb223: { -+ _145 = &mut _8; -+ _144 = Pin::<&mut AsyncStruct>::new_unchecked(move _145) -> [return: bb222, unwind: bb61]; ++ _144 = &mut _8; ++ _143 = Pin::<&mut AsyncStruct>::new_unchecked(move _144) -> [return: bb222, unwind: bb61]; + } + + bb224: { -+ StorageDead(_146); ++ StorageDead(_145); + goto -> bb19; + } + + bb225: { -+ StorageDead(_146); ++ StorageDead(_145); + goto -> bb40; + } + + bb226 (cleanup): { -+ StorageDead(_146); ++ StorageDead(_145); + goto -> bb64; + } + @@ -1472,99 +1468,99 @@ + } + + bb228: { -+ _2 = move _147; -+ StorageDead(_147); ++ _2 = move _146; ++ StorageDead(_146); + goto -> bb227; + } + + bb229: { -+ _2 = move _147; -+ StorageDead(_147); ++ _2 = move _146; ++ StorageDead(_146); + goto -> bb234; + } + + bb230: { -+ StorageLive(_147); -+ _147 = yield(const ()) -> [resume: bb228, drop: bb229]; ++ StorageLive(_146); ++ _146 = yield(const ()) -> [resume: bb228, drop: bb229]; + } + + bb231: { -+ _149 = discriminant(_148); -+ switchInt(move _149) -> [0: bb225, 1: bb230, otherwise: bb90]; ++ _148 = discriminant(_147); ++ switchInt(move _148) -> [0: bb225, 1: bb230, otherwise: bb90]; + } + + bb232: { -+ _148 = as Future>::poll(move _150, move _151) -> [return: bb231, unwind: bb226]; ++ _147 = as Future>::poll(move _149, move _150) -> [return: bb231, unwind: bb226]; + } + + bb233: { -+ _152 = move _2; -+ _151 = std::future::get_context::<'_, '_>(move _152) -> [return: bb232, unwind: bb226]; ++ _151 = move _2; ++ _150 = std::future::get_context::<'_, '_>(move _151) -> [return: bb232, unwind: bb226]; + } + + bb234: { -+ _153 = &mut _146; -+ _150 = Pin::<&mut impl Future>::new_unchecked(move _153) -> [return: bb233, unwind: bb226]; ++ _152 = &mut _145; ++ _149 = Pin::<&mut impl Future>::new_unchecked(move _152) -> [return: bb233, unwind: bb226]; + } + + bb235: { -+ _2 = move _154; -+ StorageDead(_154); ++ _2 = move _153; ++ StorageDead(_153); + goto -> bb241; + } + + bb236: { -+ _2 = move _154; -+ StorageDead(_154); ++ _2 = move _153; ++ StorageDead(_153); + goto -> bb234; + } + + bb237: { -+ StorageLive(_154); -+ _154 = yield(const ()) -> [resume: bb235, drop: bb236]; ++ StorageLive(_153); ++ _153 = yield(const ()) -> [resume: bb235, drop: bb236]; + } + + bb238: { -+ _156 = discriminant(_155); -+ switchInt(move _156) -> [0: bb224, 1: bb237, otherwise: bb90]; ++ _155 = discriminant(_154); ++ switchInt(move _155) -> [0: bb224, 1: bb237, otherwise: bb90]; + } + + bb239: { -+ _155 = as Future>::poll(move _157, move _158) -> [return: bb238, unwind: bb226]; ++ _154 = as Future>::poll(move _156, move _157) -> [return: bb238, unwind: bb226]; + } + + bb240: { -+ _159 = move _2; -+ _158 = std::future::get_context::<'_, '_>(move _159) -> [return: bb239, unwind: bb226]; ++ _158 = move _2; ++ _157 = std::future::get_context::<'_, '_>(move _158) -> [return: bb239, unwind: bb226]; + } + + bb241: { -+ _160 = &mut _146; -+ _157 = Pin::<&mut impl Future>::new_unchecked(move _160) -> [return: bb240, unwind: bb226]; ++ _159 = &mut _145; ++ _156 = Pin::<&mut impl Future>::new_unchecked(move _159) -> [return: bb240, unwind: bb226]; + } + + bb242: { -+ StorageLive(_146); -+ _146 = async_drop_in_place::<[AsyncInt; 2]>(copy (_161.0: &mut [AsyncInt; 2])) -> [return: bb241, unwind: bb226]; ++ StorageLive(_145); ++ _145 = async_drop_in_place::<[AsyncInt; 2]>(copy (_160.0: &mut [AsyncInt; 2])) -> [return: bb241, unwind: bb226]; + } + + bb243: { -+ _162 = &mut _5; -+ _161 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _162) -> [return: bb242, unwind: bb64]; ++ _161 = &mut _5; ++ _160 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _161) -> [return: bb242, unwind: bb64]; + } + + bb244: { -+ StorageDead(_163); ++ StorageDead(_162); + goto -> bb20; + } + + bb245: { -+ StorageDead(_163); ++ StorageDead(_162); + goto -> bb41; + } + + bb246 (cleanup): { -+ StorageDead(_163); ++ StorageDead(_162); + goto -> bb65; + } + @@ -1573,85 +1569,85 @@ + } + + bb248: { -+ _2 = move _164; -+ StorageDead(_164); ++ _2 = move _163; ++ StorageDead(_163); + goto -> bb247; + } + + bb249: { -+ _2 = move _164; -+ StorageDead(_164); ++ _2 = move _163; ++ StorageDead(_163); + goto -> bb254; + } + + bb250: { -+ StorageLive(_164); -+ _164 = yield(const ()) -> [resume: bb248, drop: bb249]; ++ StorageLive(_163); ++ _163 = yield(const ()) -> [resume: bb248, drop: bb249]; + } + + bb251: { -+ _166 = discriminant(_165); -+ switchInt(move _166) -> [0: bb245, 1: bb250, otherwise: bb90]; ++ _165 = discriminant(_164); ++ switchInt(move _165) -> [0: bb245, 1: bb250, otherwise: bb90]; + } + + bb252: { -+ _165 = as Future>::poll(move _167, move _168) -> [return: bb251, unwind: bb246]; ++ _164 = as Future>::poll(move _166, move _167) -> [return: bb251, unwind: bb246]; + } + + bb253: { -+ _169 = move _2; -+ _168 = std::future::get_context::<'_, '_>(move _169) -> [return: bb252, unwind: bb246]; ++ _168 = move _2; ++ _167 = std::future::get_context::<'_, '_>(move _168) -> [return: bb252, unwind: bb246]; + } + + bb254: { -+ _170 = &mut _163; -+ _167 = Pin::<&mut impl Future>::new_unchecked(move _170) -> [return: bb253, unwind: bb246]; ++ _169 = &mut _162; ++ _166 = Pin::<&mut impl Future>::new_unchecked(move _169) -> [return: bb253, unwind: bb246]; + } + + bb255: { -+ _2 = move _171; -+ StorageDead(_171); ++ _2 = move _170; ++ StorageDead(_170); + goto -> bb261; + } + + bb256: { -+ _2 = move _171; -+ StorageDead(_171); ++ _2 = move _170; ++ StorageDead(_170); + goto -> bb254; + } + + bb257: { -+ StorageLive(_171); -+ _171 = yield(const ()) -> [resume: bb255, drop: bb256]; ++ StorageLive(_170); ++ _170 = yield(const ()) -> [resume: bb255, drop: bb256]; + } + + bb258: { -+ _173 = discriminant(_172); -+ switchInt(move _173) -> [0: bb244, 1: bb257, otherwise: bb90]; ++ _172 = discriminant(_171); ++ switchInt(move _172) -> [0: bb244, 1: bb257, otherwise: bb90]; + } + + bb259: { -+ _172 = as Future>::poll(move _174, move _175) -> [return: bb258, unwind: bb246]; ++ _171 = as Future>::poll(move _173, move _174) -> [return: bb258, unwind: bb246]; + } + + bb260: { -+ _176 = move _2; -+ _175 = std::future::get_context::<'_, '_>(move _176) -> [return: bb259, unwind: bb246]; ++ _175 = move _2; ++ _174 = std::future::get_context::<'_, '_>(move _175) -> [return: bb259, unwind: bb246]; + } + + bb261: { -+ _177 = &mut _163; -+ _174 = Pin::<&mut impl Future>::new_unchecked(move _177) -> [return: bb260, unwind: bb246]; ++ _176 = &mut _162; ++ _173 = Pin::<&mut impl Future>::new_unchecked(move _176) -> [return: bb260, unwind: bb246]; + } + + bb262: { -+ StorageLive(_163); -+ _163 = async_drop_in_place::(copy (_178.0: &mut AsyncInt)) -> [return: bb261, unwind: bb246]; ++ StorageLive(_162); ++ _162 = async_drop_in_place::(copy (_177.0: &mut AsyncInt)) -> [return: bb261, unwind: bb246]; + } + + bb263: { -+ _179 = &mut _4; -+ _178 = Pin::<&mut AsyncInt>::new_unchecked(move _179) -> [return: bb262, unwind: bb65]; ++ _178 = &mut _4; ++ _177 = Pin::<&mut AsyncInt>::new_unchecked(move _178) -> [return: bb262, unwind: bb65]; } } diff --git a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff index 08e9ff5c2796f..5045c95c3ed80 100644 --- a/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/async_drop.elaborate_drops-{closure#0}.StateTransform.diff @@ -53,7 +53,7 @@ + } + storage_conflicts = BitMatrix(20x20) {(_s0, _s0), (_s0, _s1), (_s0, _s2), (_s0, _s3), (_s0, _s4), (_s0, _s5), (_s0, _s6), (_s0, _s7), (_s0, _s8), (_s0, _s9), (_s0, _s10), (_s0, _s11), (_s0, _s12), (_s0, _s13), (_s0, _s14), (_s0, _s15), (_s0, _s16), (_s0, _s17), (_s0, _s18), (_s0, _s19), (_s1, _s0), (_s1, _s1), (_s1, _s2), (_s1, _s3), (_s1, _s4), (_s1, _s5), (_s1, _s6), (_s1, _s7), (_s1, _s8), (_s1, _s9), (_s1, _s10), (_s1, _s11), (_s1, _s12), (_s1, _s13), (_s1, _s14), (_s1, _s15), (_s1, _s16), (_s1, _s17), (_s1, _s18), (_s1, _s19), (_s2, _s0), (_s2, _s1), (_s2, _s2), (_s2, _s3), (_s2, _s4), (_s2, _s5), (_s2, _s6), (_s2, _s7), (_s2, _s8), (_s2, _s9), (_s2, _s10), (_s2, _s11), (_s2, _s12), (_s2, _s13), (_s2, _s14), (_s2, _s15), (_s2, _s16), (_s2, _s17), (_s2, _s18), (_s2, _s19), (_s3, _s0), (_s3, _s1), (_s3, _s2), (_s3, _s3), (_s3, _s4), (_s3, _s5), (_s3, _s6), (_s3, _s7), (_s3, _s8), (_s3, _s9), (_s3, _s10), (_s3, _s11), (_s3, _s12), (_s3, _s13), (_s3, _s14), (_s3, _s15), (_s3, _s16), (_s3, _s17), (_s3, _s18), (_s4, _s0), (_s4, _s1), (_s4, _s2), (_s4, _s3), (_s4, _s4), (_s4, _s5), (_s4, _s6), (_s4, _s7), (_s4, _s8), (_s4, _s9), (_s4, _s10), (_s4, _s11), (_s4, _s12), (_s4, _s13), (_s4, _s14), (_s4, _s15), (_s4, _s16), (_s4, _s17), (_s5, _s0), (_s5, _s1), (_s5, _s2), (_s5, _s3), (_s5, _s4), (_s5, _s5), (_s5, _s6), (_s5, _s7), (_s5, _s8), (_s5, _s9), (_s5, _s10), (_s5, _s11), (_s5, _s12), (_s5, _s13), (_s5, _s14), (_s5, _s15), (_s5, _s16), (_s6, _s0), (_s6, _s1), (_s6, _s2), (_s6, _s3), (_s6, _s4), (_s6, _s5), (_s6, _s6), (_s6, _s7), (_s6, _s8), (_s6, _s9), (_s6, _s10), (_s6, _s11), (_s6, _s12), (_s6, _s13), (_s6, _s14), (_s6, _s15), (_s7, _s0), (_s7, _s1), (_s7, _s2), (_s7, _s3), (_s7, _s4), (_s7, _s5), (_s7, _s6), (_s7, _s7), (_s7, _s8), (_s7, _s9), (_s7, _s10), (_s7, _s11), (_s7, _s12), (_s7, _s13), (_s7, _s14), (_s8, _s0), (_s8, _s1), (_s8, _s2), (_s8, _s3), (_s8, _s4), (_s8, _s5), (_s8, _s6), (_s8, _s7), (_s8, _s8), (_s8, _s9), (_s8, _s10), (_s8, _s11), (_s8, _s12), (_s8, _s13), (_s9, _s0), (_s9, _s1), (_s9, _s2), (_s9, _s3), (_s9, _s4), (_s9, _s5), (_s9, _s6), (_s9, _s7), (_s9, _s8), (_s9, _s9), (_s9, _s10), (_s9, _s11), (_s9, _s12), (_s10, _s0), (_s10, _s1), (_s10, _s2), (_s10, _s3), (_s10, _s4), (_s10, _s5), (_s10, _s6), (_s10, _s7), (_s10, _s8), (_s10, _s9), (_s10, _s10), (_s10, _s11), (_s11, _s0), (_s11, _s1), (_s11, _s2), (_s11, _s3), (_s11, _s4), (_s11, _s5), (_s11, _s6), (_s11, _s7), (_s11, _s8), (_s11, _s9), (_s11, _s10), (_s11, _s11), (_s12, _s0), (_s12, _s1), (_s12, _s2), (_s12, _s3), (_s12, _s4), (_s12, _s5), (_s12, _s6), (_s12, _s7), (_s12, _s8), (_s12, _s9), (_s12, _s12), (_s13, _s0), (_s13, _s1), (_s13, _s2), (_s13, _s3), (_s13, _s4), (_s13, _s5), (_s13, _s6), (_s13, _s7), (_s13, _s8), (_s13, _s13), (_s14, _s0), (_s14, _s1), (_s14, _s2), (_s14, _s3), (_s14, _s4), (_s14, _s5), (_s14, _s6), (_s14, _s7), (_s14, _s14), (_s15, _s0), (_s15, _s1), (_s15, _s2), (_s15, _s3), (_s15, _s4), (_s15, _s5), (_s15, _s6), (_s15, _s15), (_s16, _s0), (_s16, _s1), (_s16, _s2), (_s16, _s3), (_s16, _s4), (_s16, _s5), (_s16, _s16), (_s17, _s0), (_s17, _s1), (_s17, _s2), (_s17, _s3), (_s17, _s4), (_s17, _s17), (_s18, _s0), (_s18, _s1), (_s18, _s2), (_s18, _s3), (_s18, _s18), (_s19, _s0), (_s19, _s1), (_s19, _s2), (_s19, _s19)} + } -+ debug _task_context => _183; ++ debug _task_context => _182; + coroutine debug sync_int => _s1; + let mut _0: std::task::Poll<()>; let _3: SyncInt; @@ -67,193 +67,192 @@ let mut _16: AsyncInt; let mut _18: AsyncInt; let mut _21: &AsyncInt; - let _22: &AsyncInt; - let mut _27: impl std::future::Future; - let mut _28: std::future::ResumeTy; - let mut _29: std::task::Poll<()>; - let mut _30: isize; - let mut _31: std::pin::Pin<&mut impl std::future::Future>; - let mut _32: &mut std::task::Context<'_>; - let mut _33: std::future::ResumeTy; - let mut _34: &mut impl std::future::Future; - let mut _35: std::future::ResumeTy; - let mut _36: std::task::Poll<()>; - let mut _37: isize; - let mut _38: std::pin::Pin<&mut impl std::future::Future>; - let mut _39: &mut std::task::Context<'_>; - let mut _40: std::future::ResumeTy; - let mut _41: &mut impl std::future::Future; - let mut _42: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>; - let mut _43: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35}; - let mut _44: impl std::future::Future; - let mut _45: std::future::ResumeTy; - let mut _46: std::task::Poll<()>; - let mut _47: isize; - let mut _48: std::pin::Pin<&mut impl std::future::Future>; - let mut _49: &mut std::task::Context<'_>; - let mut _50: std::future::ResumeTy; - let mut _51: &mut impl std::future::Future; - let mut _52: std::future::ResumeTy; - let mut _53: std::task::Poll<()>; - let mut _54: isize; - let mut _55: std::pin::Pin<&mut impl std::future::Future>; - let mut _56: &mut std::task::Context<'_>; - let mut _57: std::future::ResumeTy; - let mut _58: &mut impl std::future::Future; - let mut _59: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>; - let mut _60: &mut {closure@$DIR/async_drop.rs:78:25: 78:27}; - let mut _61: impl std::future::Future; - let mut _62: std::future::ResumeTy; - let mut _63: std::task::Poll<()>; - let mut _64: isize; - let mut _65: std::pin::Pin<&mut impl std::future::Future>; - let mut _66: &mut std::task::Context<'_>; - let mut _67: std::future::ResumeTy; - let mut _68: &mut impl std::future::Future; - let mut _69: std::future::ResumeTy; - let mut _70: std::task::Poll<()>; - let mut _71: isize; - let mut _72: std::pin::Pin<&mut impl std::future::Future>; - let mut _73: &mut std::task::Context<'_>; - let mut _74: std::future::ResumeTy; - let mut _75: &mut impl std::future::Future; - let mut _76: std::pin::Pin<&mut AsyncReference<'_>>; - let mut _77: &mut AsyncReference<'_>; - let mut _78: impl std::future::Future; - let mut _79: std::future::ResumeTy; - let mut _80: std::task::Poll<()>; - let mut _81: isize; - let mut _82: std::pin::Pin<&mut impl std::future::Future>; - let mut _83: &mut std::task::Context<'_>; - let mut _84: std::future::ResumeTy; - let mut _85: &mut impl std::future::Future; - let mut _86: std::future::ResumeTy; - let mut _87: std::task::Poll<()>; - let mut _88: isize; - let mut _89: std::pin::Pin<&mut impl std::future::Future>; - let mut _90: &mut std::task::Context<'_>; - let mut _91: std::future::ResumeTy; - let mut _92: &mut impl std::future::Future; - let mut _93: std::pin::Pin<&mut AsyncInt>; - let mut _94: &mut AsyncInt; - let mut _95: impl std::future::Future; - let mut _96: std::future::ResumeTy; - let mut _97: std::task::Poll<()>; - let mut _98: isize; - let mut _99: std::pin::Pin<&mut impl std::future::Future>; - let mut _100: &mut std::task::Context<'_>; - let mut _101: std::future::ResumeTy; - let mut _102: &mut impl std::future::Future; - let mut _103: std::future::ResumeTy; - let mut _104: std::task::Poll<()>; - let mut _105: isize; - let mut _106: std::pin::Pin<&mut impl std::future::Future>; - let mut _107: &mut std::task::Context<'_>; - let mut _108: std::future::ResumeTy; - let mut _109: &mut impl std::future::Future; - let mut _110: std::pin::Pin<&mut AsyncEnum>; - let mut _111: &mut AsyncEnum; - let mut _112: impl std::future::Future; - let mut _113: std::future::ResumeTy; - let mut _114: std::task::Poll<()>; - let mut _115: isize; - let mut _116: std::pin::Pin<&mut impl std::future::Future>; - let mut _117: &mut std::task::Context<'_>; - let mut _118: std::future::ResumeTy; - let mut _119: &mut impl std::future::Future; - let mut _120: std::future::ResumeTy; - let mut _121: std::task::Poll<()>; - let mut _122: isize; - let mut _123: std::pin::Pin<&mut impl std::future::Future>; - let mut _124: &mut std::task::Context<'_>; - let mut _125: std::future::ResumeTy; - let mut _126: &mut impl std::future::Future; - let mut _127: std::pin::Pin<&mut SyncThenAsync>; - let mut _128: &mut SyncThenAsync; - let mut _129: impl std::future::Future; - let mut _130: std::future::ResumeTy; - let mut _131: std::task::Poll<()>; - let mut _132: isize; - let mut _133: std::pin::Pin<&mut impl std::future::Future>; - let mut _134: &mut std::task::Context<'_>; - let mut _135: std::future::ResumeTy; - let mut _136: &mut impl std::future::Future; - let mut _137: std::future::ResumeTy; - let mut _138: std::task::Poll<()>; - let mut _139: isize; - let mut _140: std::pin::Pin<&mut impl std::future::Future>; - let mut _141: &mut std::task::Context<'_>; - let mut _142: std::future::ResumeTy; - let mut _143: &mut impl std::future::Future; - let mut _144: std::pin::Pin<&mut AsyncStruct>; - let mut _145: &mut AsyncStruct; - let mut _146: impl std::future::Future; - let mut _147: std::future::ResumeTy; - let mut _148: std::task::Poll<()>; - let mut _149: isize; - let mut _150: std::pin::Pin<&mut impl std::future::Future>; - let mut _151: &mut std::task::Context<'_>; - let mut _152: std::future::ResumeTy; - let mut _153: &mut impl std::future::Future; - let mut _154: std::future::ResumeTy; - let mut _155: std::task::Poll<()>; - let mut _156: isize; - let mut _157: std::pin::Pin<&mut impl std::future::Future>; - let mut _158: &mut std::task::Context<'_>; - let mut _159: std::future::ResumeTy; - let mut _160: &mut impl std::future::Future; - let mut _161: std::pin::Pin<&mut [AsyncInt; 2]>; - let mut _162: &mut [AsyncInt; 2]; - let mut _163: impl std::future::Future; - let mut _164: std::future::ResumeTy; - let mut _165: std::task::Poll<()>; - let mut _166: isize; - let mut _167: std::pin::Pin<&mut impl std::future::Future>; - let mut _168: &mut std::task::Context<'_>; - let mut _169: std::future::ResumeTy; - let mut _170: &mut impl std::future::Future; - let mut _171: std::future::ResumeTy; - let mut _172: std::task::Poll<()>; - let mut _173: isize; - let mut _174: std::pin::Pin<&mut impl std::future::Future>; - let mut _175: &mut std::task::Context<'_>; - let mut _176: std::future::ResumeTy; - let mut _177: &mut impl std::future::Future; - let mut _178: std::pin::Pin<&mut AsyncInt>; - let mut _179: &mut AsyncInt; -+ let mut _180: (); -+ let mut _181: u32; -+ let mut _182: &mut {async fn body of elaborate_drops()}; -+ let mut _183: std::future::ResumeTy; -+ let mut _184: std::ptr::NonNull>; + let mut _26: impl std::future::Future; + let mut _27: std::future::ResumeTy; + let mut _28: std::task::Poll<()>; + let mut _29: isize; + let mut _30: std::pin::Pin<&mut impl std::future::Future>; + let mut _31: &mut std::task::Context<'_>; + let mut _32: std::future::ResumeTy; + let mut _33: &mut impl std::future::Future; + let mut _34: std::future::ResumeTy; + let mut _35: std::task::Poll<()>; + let mut _36: isize; + let mut _37: std::pin::Pin<&mut impl std::future::Future>; + let mut _38: &mut std::task::Context<'_>; + let mut _39: std::future::ResumeTy; + let mut _40: &mut impl std::future::Future; + let mut _41: std::pin::Pin<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>; + let mut _42: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35}; + let mut _43: impl std::future::Future; + let mut _44: std::future::ResumeTy; + let mut _45: std::task::Poll<()>; + let mut _46: isize; + let mut _47: std::pin::Pin<&mut impl std::future::Future>; + let mut _48: &mut std::task::Context<'_>; + let mut _49: std::future::ResumeTy; + let mut _50: &mut impl std::future::Future; + let mut _51: std::future::ResumeTy; + let mut _52: std::task::Poll<()>; + let mut _53: isize; + let mut _54: std::pin::Pin<&mut impl std::future::Future>; + let mut _55: &mut std::task::Context<'_>; + let mut _56: std::future::ResumeTy; + let mut _57: &mut impl std::future::Future; + let mut _58: std::pin::Pin<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>; + let mut _59: &mut {closure@$DIR/async_drop.rs:78:25: 78:27}; + let mut _60: impl std::future::Future; + let mut _61: std::future::ResumeTy; + let mut _62: std::task::Poll<()>; + let mut _63: isize; + let mut _64: std::pin::Pin<&mut impl std::future::Future>; + let mut _65: &mut std::task::Context<'_>; + let mut _66: std::future::ResumeTy; + let mut _67: &mut impl std::future::Future; + let mut _68: std::future::ResumeTy; + let mut _69: std::task::Poll<()>; + let mut _70: isize; + let mut _71: std::pin::Pin<&mut impl std::future::Future>; + let mut _72: &mut std::task::Context<'_>; + let mut _73: std::future::ResumeTy; + let mut _74: &mut impl std::future::Future; + let mut _75: std::pin::Pin<&mut AsyncReference<'_>>; + let mut _76: &mut AsyncReference<'_>; + let mut _77: impl std::future::Future; + let mut _78: std::future::ResumeTy; + let mut _79: std::task::Poll<()>; + let mut _80: isize; + let mut _81: std::pin::Pin<&mut impl std::future::Future>; + let mut _82: &mut std::task::Context<'_>; + let mut _83: std::future::ResumeTy; + let mut _84: &mut impl std::future::Future; + let mut _85: std::future::ResumeTy; + let mut _86: std::task::Poll<()>; + let mut _87: isize; + let mut _88: std::pin::Pin<&mut impl std::future::Future>; + let mut _89: &mut std::task::Context<'_>; + let mut _90: std::future::ResumeTy; + let mut _91: &mut impl std::future::Future; + let mut _92: std::pin::Pin<&mut AsyncInt>; + let mut _93: &mut AsyncInt; + let mut _94: impl std::future::Future; + let mut _95: std::future::ResumeTy; + let mut _96: std::task::Poll<()>; + let mut _97: isize; + let mut _98: std::pin::Pin<&mut impl std::future::Future>; + let mut _99: &mut std::task::Context<'_>; + let mut _100: std::future::ResumeTy; + let mut _101: &mut impl std::future::Future; + let mut _102: std::future::ResumeTy; + let mut _103: std::task::Poll<()>; + let mut _104: isize; + let mut _105: std::pin::Pin<&mut impl std::future::Future>; + let mut _106: &mut std::task::Context<'_>; + let mut _107: std::future::ResumeTy; + let mut _108: &mut impl std::future::Future; + let mut _109: std::pin::Pin<&mut AsyncEnum>; + let mut _110: &mut AsyncEnum; + let mut _111: impl std::future::Future; + let mut _112: std::future::ResumeTy; + let mut _113: std::task::Poll<()>; + let mut _114: isize; + let mut _115: std::pin::Pin<&mut impl std::future::Future>; + let mut _116: &mut std::task::Context<'_>; + let mut _117: std::future::ResumeTy; + let mut _118: &mut impl std::future::Future; + let mut _119: std::future::ResumeTy; + let mut _120: std::task::Poll<()>; + let mut _121: isize; + let mut _122: std::pin::Pin<&mut impl std::future::Future>; + let mut _123: &mut std::task::Context<'_>; + let mut _124: std::future::ResumeTy; + let mut _125: &mut impl std::future::Future; + let mut _126: std::pin::Pin<&mut SyncThenAsync>; + let mut _127: &mut SyncThenAsync; + let mut _128: impl std::future::Future; + let mut _129: std::future::ResumeTy; + let mut _130: std::task::Poll<()>; + let mut _131: isize; + let mut _132: std::pin::Pin<&mut impl std::future::Future>; + let mut _133: &mut std::task::Context<'_>; + let mut _134: std::future::ResumeTy; + let mut _135: &mut impl std::future::Future; + let mut _136: std::future::ResumeTy; + let mut _137: std::task::Poll<()>; + let mut _138: isize; + let mut _139: std::pin::Pin<&mut impl std::future::Future>; + let mut _140: &mut std::task::Context<'_>; + let mut _141: std::future::ResumeTy; + let mut _142: &mut impl std::future::Future; + let mut _143: std::pin::Pin<&mut AsyncStruct>; + let mut _144: &mut AsyncStruct; + let mut _145: impl std::future::Future; + let mut _146: std::future::ResumeTy; + let mut _147: std::task::Poll<()>; + let mut _148: isize; + let mut _149: std::pin::Pin<&mut impl std::future::Future>; + let mut _150: &mut std::task::Context<'_>; + let mut _151: std::future::ResumeTy; + let mut _152: &mut impl std::future::Future; + let mut _153: std::future::ResumeTy; + let mut _154: std::task::Poll<()>; + let mut _155: isize; + let mut _156: std::pin::Pin<&mut impl std::future::Future>; + let mut _157: &mut std::task::Context<'_>; + let mut _158: std::future::ResumeTy; + let mut _159: &mut impl std::future::Future; + let mut _160: std::pin::Pin<&mut [AsyncInt; 2]>; + let mut _161: &mut [AsyncInt; 2]; + let mut _162: impl std::future::Future; + let mut _163: std::future::ResumeTy; + let mut _164: std::task::Poll<()>; + let mut _165: isize; + let mut _166: std::pin::Pin<&mut impl std::future::Future>; + let mut _167: &mut std::task::Context<'_>; + let mut _168: std::future::ResumeTy; + let mut _169: &mut impl std::future::Future; + let mut _170: std::future::ResumeTy; + let mut _171: std::task::Poll<()>; + let mut _172: isize; + let mut _173: std::pin::Pin<&mut impl std::future::Future>; + let mut _174: &mut std::task::Context<'_>; + let mut _175: std::future::ResumeTy; + let mut _176: &mut impl std::future::Future; + let mut _177: std::pin::Pin<&mut AsyncInt>; + let mut _178: &mut AsyncInt; ++ let mut _179: (); ++ let mut _180: u32; ++ let mut _181: &mut {async fn body of elaborate_drops()}; ++ let mut _182: std::future::ResumeTy; ++ let mut _183: std::ptr::NonNull>; scope 1 { - debug sync_int => _3; -+ debug sync_int => (((*_182) as variant#20).1: SyncInt); ++ debug sync_int => (((*_181) as variant#20).1: SyncInt); + coroutine debug async_int => _s2; let _4: AsyncInt; scope 2 { - debug async_int => _4; -+ debug async_int => (((*_182) as variant#20).2: AsyncInt); ++ debug async_int => (((*_181) as variant#20).2: AsyncInt); + coroutine debug tuple => _s3; let _5: [AsyncInt; 2]; scope 3 { - debug tuple => _5; -+ debug tuple => (((*_182) as variant#18).3: [AsyncInt; 2]); ++ debug tuple => (((*_181) as variant#18).3: [AsyncInt; 2]); + coroutine debug async_struct => _s4; let _8: AsyncStruct; scope 4 { - debug async_struct => _8; -+ debug async_struct => (((*_182) as variant#16).4: AsyncStruct); ++ debug async_struct => (((*_181) as variant#16).4: AsyncStruct); + coroutine debug async_struct_mix => _s5; let _11: SyncThenAsync; scope 5 { - debug async_struct_mix => _11; -+ debug async_struct_mix => (((*_182) as variant#14).5: SyncThenAsync); ++ debug async_struct_mix => (((*_181) as variant#14).5: SyncThenAsync); + coroutine debug async_enum => _s6; let _15: AsyncEnum; scope 6 { - debug async_enum => _15; -+ debug async_enum => (((*_182) as variant#12).6: AsyncEnum); ++ debug async_enum => (((*_181) as variant#12).6: AsyncEnum); let _17: std::mem::ManuallyDrop; scope 7 { debug manually_drop_async_int => _17; @@ -261,28 +260,28 @@ let _19: AsyncInt; scope 8 { - debug foo => _19; -+ debug foo => (((*_182) as variant#10).7: AsyncInt); ++ debug foo => (((*_181) as variant#10).7: AsyncInt); + coroutine debug async_ref => _s8; let _20: AsyncReference<'_>; scope 9 { - debug async_ref => _20; -+ debug async_ref => (((*_182) as variant#8).8: AsyncReference<'_>); - let _23: AsyncInt; ++ debug async_ref => (((*_181) as variant#8).8: AsyncReference<'_>); + let _22: AsyncInt; scope 10 { - debug foo => _23; + debug foo => _22; + coroutine debug async_closure => _s9; - let _24: {closure@$DIR/async_drop.rs:78:25: 78:27}; + let _23: {closure@$DIR/async_drop.rs:78:25: 78:27}; scope 11 { -- debug async_closure => _24; -+ debug async_closure => (((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27}); - let _25: AsyncInt; +- debug async_closure => _23; ++ debug async_closure => (((*_181) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27}); + let _24: AsyncInt; scope 12 { - debug foo => _25; + debug foo => _24; + coroutine debug async_coroutine => _s10; - let _26: {async closure@$DIR/async_drop.rs:86:27: 86:35}; + let _25: {async closure@$DIR/async_drop.rs:86:27: 86:35}; scope 13 { -- debug async_coroutine => _26; -+ debug async_coroutine => (((*_182) as variant#4).10: {async closure@$DIR/async_drop.rs:86:27: 86:35}); +- debug async_coroutine => _25; ++ debug async_coroutine => (((*_181) as variant#4).10: {async closure@$DIR/async_drop.rs:86:27: 86:35}); } } } @@ -309,11 +308,11 @@ - _7 = AsyncInt(const 2_i32); - _5 = [move _6, move _7]; - goto -> bb1; -+ _184 = move _2 as std::ptr::NonNull> (Transmute); -+ _183 = std::future::ResumeTy(move _184); -+ _182 = copy (_1.0: &mut {async fn body of elaborate_drops()}); -+ _181 = discriminant((*_182)); -+ switchInt(move _181) -> [0: bb169, 1: bb168, 2: bb167, 3: bb149, 4: bb150, 5: bb151, 6: bb152, 7: bb153, 8: bb154, 9: bb155, 10: bb156, 11: bb157, 12: bb158, 13: bb159, 14: bb160, 15: bb161, 16: bb162, 17: bb163, 18: bb164, 19: bb165, 20: bb166, otherwise: bb43]; ++ _183 = move _2 as std::ptr::NonNull> (Transmute); ++ _182 = std::future::ResumeTy(move _183); ++ _181 = copy (_1.0: &mut {async fn body of elaborate_drops()}); ++ _180 = discriminant((*_181)); ++ switchInt(move _180) -> [0: bb169, 1: bb168, 2: bb167, 3: bb149, 4: bb150, 5: bb151, 6: bb152, 7: bb153, 8: bb154, 9: bb155, 10: bb156, 11: bb157, 12: bb158, 13: bb159, 14: bb160, 15: bb161, 16: bb162, 17: bb163, 18: bb164, 19: bb165, 20: bb166, otherwise: bb43]; } bb1: { @@ -330,7 +329,7 @@ StorageLive(_10); _10 = AsyncInt(const 4_i32); - _8 = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; -+ (((*_182) as variant#16).4: AsyncStruct) = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; ++ (((*_181) as variant#16).4: AsyncStruct) = AsyncStruct { i: const 3_i32, a: move _10, b: move _9 }; goto -> bb3; } @@ -350,7 +349,7 @@ StorageLive(_14); _14 = AsyncInt(const 9_i32); - _11 = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; -+ (((*_182) as variant#14).5: SyncThenAsync) = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; ++ (((*_181) as variant#14).5: SyncThenAsync) = SyncThenAsync { i: const 6_i32, a: move _12, b: move _13, c: move _14 }; goto -> bb5; } @@ -371,7 +370,7 @@ StorageLive(_16); _16 = AsyncInt(const 10_i32); - _15 = AsyncEnum::A(move _16); -+ (((*_182) as variant#12).6: AsyncEnum) = AsyncEnum::A(move _16); ++ (((*_181) as variant#12).6: AsyncEnum) = AsyncEnum::A(move _16); goto -> bb8; } @@ -390,55 +389,52 @@ - _19 = AsyncInt(const 12_i32); - StorageLive(_20); + nop; -+ (((*_182) as variant#10).7: AsyncInt) = AsyncInt(const 12_i32); ++ (((*_181) as variant#10).7: AsyncInt) = AsyncInt(const 12_i32); + nop; StorageLive(_21); - StorageLive(_22); -- _22 = &_19; -+ _22 = &(((*_182) as variant#10).7: AsyncInt); - _21 = &(*_22); +- _21 = &_19; - _20 = AsyncReference::<'_> { foo: move _21 }; -+ (((*_182) as variant#8).8: AsyncReference<'_>) = AsyncReference::<'_> { foo: move _21 }; ++ _21 = &(((*_181) as variant#10).7: AsyncInt); ++ (((*_181) as variant#8).8: AsyncReference<'_>) = AsyncReference::<'_> { foo: move _21 }; StorageDead(_21); - StorageDead(_22); - StorageLive(_23); - _23 = AsyncInt(const 14_i32); -- StorageLive(_24); -- _24 = {closure@$DIR/async_drop.rs:78:25: 78:27} { foo: move _23 }; + StorageLive(_22); + _22 = AsyncInt(const 14_i32); +- StorageLive(_23); +- _23 = {closure@$DIR/async_drop.rs:78:25: 78:27} { foo: move _22 }; + nop; -+ (((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27}) = {closure@$DIR/async_drop.rs:78:25: 78:27} { foo: move _23 }; - StorageLive(_25); - _25 = AsyncInt(const 15_i32); -- StorageLive(_26); -- _26 = {closure@$DIR/async_drop.rs:86:27: 86:35} { foo: move _25 }; ++ (((*_181) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27}) = {closure@$DIR/async_drop.rs:78:25: 78:27} { foo: move _22 }; + StorageLive(_24); + _24 = AsyncInt(const 15_i32); +- StorageLive(_25); +- _25 = {closure@$DIR/async_drop.rs:86:27: 86:35} { foo: move _24 }; - _0 = const (); - goto -> bb72; + nop; -+ (((*_182) as variant#4).10: {async closure@$DIR/async_drop.rs:86:27: 86:35}) = {closure@$DIR/async_drop.rs:86:27: 86:35} { foo: move _25 }; -+ (((*_182) as variant#20).0: ()) = const (); ++ (((*_181) as variant#4).10: {async closure@$DIR/async_drop.rs:86:27: 86:35}) = {closure@$DIR/async_drop.rs:86:27: 86:35} { foo: move _24 }; ++ (((*_181) as variant#20).0: ()) = const (); + goto -> bb51; } bb10: { -- StorageDead(_26); +- StorageDead(_25); + nop; goto -> bb11; } bb11: { - StorageDead(_25); + StorageDead(_24); - goto -> bb92; + goto -> bb63; } bb12: { -- StorageDead(_24); +- StorageDead(_23); + nop; goto -> bb13; } bb13: { - StorageDead(_23); + StorageDead(_22); - goto -> bb112; + goto -> bb75; } @@ -490,7 +486,7 @@ - StorageDead(_4); - drop(_3) -> [return: bb21, unwind: bb50]; + nop; -+ drop((((*_182) as variant#20).1: SyncInt)) -> [return: bb21, unwind: bb37]; ++ drop((((*_181) as variant#20).1: SyncInt)) -> [return: bb21, unwind: bb37]; } bb21: { @@ -501,13 +497,13 @@ } bb22: { -+ _0 = Poll::<()>::Ready(move (((*_182) as variant#20).0: ())); -+ discriminant((*_182)) = 1; ++ _0 = Poll::<()>::Ready(move (((*_181) as variant#20).0: ())); ++ discriminant((*_181)) = 1; return; } - bb23: { -- StorageDead(_26); +- StorageDead(_25); + bb23 (cleanup): { + nop; goto -> bb24; @@ -515,13 +511,13 @@ - bb24: { + bb24 (cleanup): { - StorageDead(_25); + StorageDead(_24); - goto -> bb25; -+ drop((((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb25, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb25, unwind terminate(cleanup)]; } - bb25: { -- StorageDead(_24); +- StorageDead(_23); + bb25 (cleanup): { + nop; goto -> bb26; @@ -529,9 +525,9 @@ - bb26: { + bb26 (cleanup): { - StorageDead(_23); + StorageDead(_22); - goto -> bb27; -+ drop((((*_182) as variant#8).8: AsyncReference<'_>)) -> [return: bb27, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#8).8: AsyncReference<'_>)) -> [return: bb27, unwind terminate(cleanup)]; } - bb27: { @@ -539,7 +535,7 @@ - goto -> bb28; + bb27 (cleanup): { + nop; -+ drop((((*_182) as variant#10).7: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#10).7: AsyncInt)) -> [return: bb28, unwind terminate(cleanup)]; } - bb28: { @@ -569,7 +565,7 @@ - goto -> bb32; + bb31 (cleanup): { + StorageDead(_17); -+ drop((((*_182) as variant#12).6: AsyncEnum)) -> [return: bb32, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#12).6: AsyncEnum)) -> [return: bb32, unwind terminate(cleanup)]; } - bb32: { @@ -577,7 +573,7 @@ - goto -> bb33; + bb32 (cleanup): { + nop; -+ drop((((*_182) as variant#14).5: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#14).5: SyncThenAsync)) -> [return: bb33, unwind terminate(cleanup)]; } - bb33: { @@ -585,7 +581,7 @@ - goto -> bb34; + bb33 (cleanup): { + nop; -+ drop((((*_182) as variant#16).4: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#16).4: AsyncStruct)) -> [return: bb34, unwind terminate(cleanup)]; } - bb34: { @@ -593,38 +589,38 @@ - goto -> bb35; + bb34 (cleanup): { + nop; -+ drop((((*_182) as variant#18).3: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#18).3: [AsyncInt; 2])) -> [return: bb35, unwind terminate(cleanup)]; } - bb35: { - coroutine_drop; + bb35 (cleanup): { + nop; -+ drop((((*_182) as variant#20).2: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#20).2: AsyncInt)) -> [return: bb36, unwind terminate(cleanup)]; } bb36 (cleanup): { -- StorageDead(_26); +- StorageDead(_25); - goto -> bb37; + nop; -+ drop((((*_182) as variant#20).1: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; ++ drop((((*_181) as variant#20).1: SyncInt)) -> [return: bb37, unwind terminate(cleanup)]; } bb37 (cleanup): { -- StorageDead(_25); -- drop(_24) -> [return: bb38, unwind terminate(cleanup)]; +- StorageDead(_24); +- drop(_23) -> [return: bb38, unwind terminate(cleanup)]; + nop; + goto -> bb38; } bb38 (cleanup): { -- StorageDead(_24); +- StorageDead(_23); - goto -> bb39; + goto -> bb148; } - bb39 (cleanup): { -- StorageDead(_23); +- StorageDead(_22); - drop(_20) -> [return: bb40, unwind terminate(cleanup)]; + bb39: { + nop; @@ -648,8 +644,8 @@ - bb42 (cleanup): { - goto -> bb43; + bb42: { -+ _183 = move _28; -+ StorageDead(_28); ++ _182 = move _27; ++ StorageDead(_27); + goto -> bb41; } @@ -664,8 +660,8 @@ - StorageDead(_17); - drop(_15) -> [return: bb45, unwind terminate(cleanup)]; + bb44: { -+ _183 = move _35; -+ StorageDead(_35); ++ _182 = move _34; ++ StorageDead(_34); + goto -> bb49; } @@ -673,13 +669,13 @@ - StorageDead(_15); - drop(_11) -> [return: bb46, unwind terminate(cleanup)]; + bb45: { -+ StorageLive(_35); ++ StorageLive(_34); + _0 = Poll::<()>::Pending; + StorageDead(_17); -+ StorageDead(_23); -+ StorageDead(_25); -+ StorageDead(_35); -+ discriminant((*_182)) = 4; ++ StorageDead(_22); ++ StorageDead(_24); ++ StorageDead(_34); ++ discriminant((*_181)) = 4; + return; } @@ -687,23 +683,23 @@ - StorageDead(_11); - drop(_8) -> [return: bb47, unwind terminate(cleanup)]; + bb46: { -+ _37 = discriminant(_36); -+ switchInt(move _37) -> [0: bb39, 1: bb45, otherwise: bb43]; ++ _36 = discriminant(_35); ++ switchInt(move _36) -> [0: bb39, 1: bb45, otherwise: bb43]; } - bb47 (cleanup): { - StorageDead(_8); - drop(_5) -> [return: bb48, unwind terminate(cleanup)]; + bb47: { -+ _36 = as Future>::poll(move _38, move _39) -> [return: bb46, unwind: bb40]; ++ _35 = as Future>::poll(move _37, move _38) -> [return: bb46, unwind: bb40]; } - bb48 (cleanup): { - StorageDead(_5); - drop(_4) -> [return: bb49, unwind terminate(cleanup)]; + bb48: { -+ _40 = move _183; -+ _39 = copy (_40.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); ++ _39 = move _182; ++ _38 = copy (_39.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb47; } @@ -711,8 +707,8 @@ - StorageDead(_4); - drop(_3) -> [return: bb50, unwind terminate(cleanup)]; + bb49: { -+ _41 = &mut (((*_182) as variant#4).11: impl std::future::Future); -+ _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb48, unwind: bb40]; ++ _40 = &mut (((*_181) as variant#4).11: impl std::future::Future); ++ _37 = Pin::<&mut impl Future>::new_unchecked(move _40) -> [return: bb48, unwind: bb40]; } - bb50 (cleanup): { @@ -720,25 +716,25 @@ - drop(_1) -> [return: bb51, unwind terminate(cleanup)]; + bb50: { + nop; -+ (((*_182) as variant#4).11: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:86:27: 86:35}>(copy (_42.0: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35})) -> [return: bb49, unwind: bb40]; ++ (((*_181) as variant#4).11: impl std::future::Future) = async_drop_in_place::<{async closure@$DIR/async_drop.rs:86:27: 86:35}>(copy (_41.0: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35})) -> [return: bb49, unwind: bb40]; } - bb51 (cleanup): { - resume; + bb51: { -+ _43 = &mut (((*_182) as variant#4).10: {async closure@$DIR/async_drop.rs:86:27: 86:35}); -+ _42 = Pin::<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>::new_unchecked(move _43) -> [return: bb50, unwind: bb23]; ++ _42 = &mut (((*_181) as variant#4).10: {async closure@$DIR/async_drop.rs:86:27: 86:35}); ++ _41 = Pin::<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>::new_unchecked(move _42) -> [return: bb50, unwind: bb23]; } bb52: { -- StorageDead(_27); +- StorageDead(_26); - goto -> bb10; + nop; + goto -> bb12; } - bb53: { -- StorageDead(_27); +- StorageDead(_26); - goto -> bb23; + bb53 (cleanup): { + nop; @@ -746,7 +742,7 @@ } - bb54 (cleanup): { -- StorageDead(_27); +- StorageDead(_26); - goto -> bb36; + bb54: { + assert(const false, "`async fn` resumed after async drop") -> [success: bb54, unwind: bb53]; @@ -754,84 +750,84 @@ bb55: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb55, unwind: bb54]; -+ _183 = move _45; -+ StorageDead(_45); ++ _182 = move _44; ++ StorageDead(_44); + goto -> bb54; } bb56: { -- _2 = move _28; -- StorageDead(_28); +- _2 = move _27; +- StorageDead(_27); - goto -> bb55; -+ _183 = move _52; -+ StorageDead(_52); ++ _182 = move _51; ++ StorageDead(_51); + goto -> bb61; } bb57: { -- _2 = move _28; -- StorageDead(_28); +- _2 = move _27; +- StorageDead(_27); - goto -> bb63; -+ StorageLive(_52); ++ StorageLive(_51); + _0 = Poll::<()>::Pending; + StorageDead(_17); -+ StorageDead(_23); -+ StorageDead(_52); -+ discriminant((*_182)) = 6; ++ StorageDead(_22); ++ StorageDead(_51); ++ discriminant((*_181)) = 6; + return; } bb58: { -- StorageLive(_28); -- _28 = yield(const ()) -> [resume: bb56, drop: bb57]; -+ _54 = discriminant(_53); -+ switchInt(move _54) -> [0: bb52, 1: bb57, otherwise: bb43]; +- StorageLive(_27); +- _27 = yield(const ()) -> [resume: bb56, drop: bb57]; ++ _53 = discriminant(_52); ++ switchInt(move _53) -> [0: bb52, 1: bb57, otherwise: bb43]; } bb59: { - unreachable; -+ _53 = as Future>::poll(move _55, move _56) -> [return: bb58, unwind: bb53]; ++ _52 = as Future>::poll(move _54, move _55) -> [return: bb58, unwind: bb53]; } bb60: { -- _30 = discriminant(_29); -- switchInt(move _30) -> [0: bb53, 1: bb58, otherwise: bb59]; -+ _57 = move _183; -+ _56 = copy (_57.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _29 = discriminant(_28); +- switchInt(move _29) -> [0: bb53, 1: bb58, otherwise: bb59]; ++ _56 = move _182; ++ _55 = copy (_56.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb59; } bb61: { -- _29 = as Future>::poll(move _31, move _32) -> [return: bb60, unwind: bb54]; -+ _58 = &mut (((*_182) as variant#6).10: impl std::future::Future); -+ _55 = Pin::<&mut impl Future>::new_unchecked(move _58) -> [return: bb60, unwind: bb53]; +- _28 = as Future>::poll(move _30, move _31) -> [return: bb60, unwind: bb54]; ++ _57 = &mut (((*_181) as variant#6).10: impl std::future::Future); ++ _54 = Pin::<&mut impl Future>::new_unchecked(move _57) -> [return: bb60, unwind: bb53]; } bb62: { -- _33 = move _2; -- _32 = std::future::get_context::<'_, '_>(move _33) -> [return: bb61, unwind: bb54]; +- _32 = move _2; +- _31 = std::future::get_context::<'_, '_>(move _32) -> [return: bb61, unwind: bb54]; + nop; -+ (((*_182) as variant#6).10: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:78:25: 78:27}>(copy (_59.0: &mut {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb61, unwind: bb53]; ++ (((*_181) as variant#6).10: impl std::future::Future) = async_drop_in_place::<{closure@$DIR/async_drop.rs:78:25: 78:27}>(copy (_58.0: &mut {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb61, unwind: bb53]; } bb63: { -- _34 = &mut _27; -- _31 = Pin::<&mut impl Future>::new_unchecked(move _34) -> [return: bb62, unwind: bb54]; -+ _60 = &mut (((*_182) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27}); -+ _59 = Pin::<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>::new_unchecked(move _60) -> [return: bb62, unwind: bb25]; +- _33 = &mut _26; +- _30 = Pin::<&mut impl Future>::new_unchecked(move _33) -> [return: bb62, unwind: bb54]; ++ _59 = &mut (((*_181) as variant#6).9: {closure@$DIR/async_drop.rs:78:25: 78:27}); ++ _58 = Pin::<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>::new_unchecked(move _59) -> [return: bb62, unwind: bb25]; } bb64: { -- _2 = move _35; -- StorageDead(_35); +- _2 = move _34; +- StorageDead(_34); - goto -> bb70; + nop; + goto -> bb14; } - bb65: { -- _2 = move _35; -- StorageDead(_35); +- _2 = move _34; +- StorageDead(_34); - goto -> bb63; + bb65 (cleanup): { + nop; @@ -839,78 +835,78 @@ } bb66: { -- StorageLive(_35); -- _35 = yield(const ()) -> [resume: bb64, drop: bb65]; +- StorageLive(_34); +- _34 = yield(const ()) -> [resume: bb64, drop: bb65]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb66, unwind: bb65]; } bb67: { -- _37 = discriminant(_36); -- switchInt(move _37) -> [0: bb52, 1: bb66, otherwise: bb59]; -+ _183 = move _62; -+ StorageDead(_62); +- _36 = discriminant(_35); +- switchInt(move _36) -> [0: bb52, 1: bb66, otherwise: bb59]; ++ _182 = move _61; ++ StorageDead(_61); + goto -> bb66; } bb68: { -- _36 = as Future>::poll(move _38, move _39) -> [return: bb67, unwind: bb54]; -+ _183 = move _69; -+ StorageDead(_69); +- _35 = as Future>::poll(move _37, move _38) -> [return: bb67, unwind: bb54]; ++ _182 = move _68; ++ StorageDead(_68); + goto -> bb73; } bb69: { -- _40 = move _2; -- _39 = std::future::get_context::<'_, '_>(move _40) -> [return: bb68, unwind: bb54]; -+ StorageLive(_69); +- _39 = move _2; +- _38 = std::future::get_context::<'_, '_>(move _39) -> [return: bb68, unwind: bb54]; ++ StorageLive(_68); + _0 = Poll::<()>::Pending; + StorageDead(_17); -+ StorageDead(_69); -+ discriminant((*_182)) = 8; ++ StorageDead(_68); ++ discriminant((*_181)) = 8; + return; } bb70: { -- _41 = &mut _27; -- _38 = Pin::<&mut impl Future>::new_unchecked(move _41) -> [return: bb69, unwind: bb54]; -+ _71 = discriminant(_70); -+ switchInt(move _71) -> [0: bb64, 1: bb69, otherwise: bb43]; +- _40 = &mut _26; +- _37 = Pin::<&mut impl Future>::new_unchecked(move _40) -> [return: bb69, unwind: bb54]; ++ _70 = discriminant(_69); ++ switchInt(move _70) -> [0: bb64, 1: bb69, otherwise: bb43]; } bb71: { -- StorageLive(_27); -- _27 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:86:27: 86:35}>(copy (_42.0: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35})) -> [return: bb70, unwind: bb54]; -+ _70 = as Future>::poll(move _72, move _73) -> [return: bb70, unwind: bb65]; +- StorageLive(_26); +- _26 = async_drop_in_place::<{async closure@$DIR/async_drop.rs:86:27: 86:35}>(copy (_41.0: &mut {async closure@$DIR/async_drop.rs:86:27: 86:35})) -> [return: bb70, unwind: bb54]; ++ _69 = as Future>::poll(move _71, move _72) -> [return: bb70, unwind: bb65]; } bb72: { -- _43 = &mut _26; -- _42 = Pin::<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>::new_unchecked(move _43) -> [return: bb71, unwind: bb36]; -+ _74 = move _183; -+ _73 = copy (_74.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _42 = &mut _25; +- _41 = Pin::<&mut {async closure@$DIR/async_drop.rs:86:27: 86:35}>::new_unchecked(move _42) -> [return: bb71, unwind: bb36]; ++ _73 = move _182; ++ _72 = copy (_73.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb71; } bb73: { -- StorageDead(_44); +- StorageDead(_43); - goto -> bb12; -+ _75 = &mut (((*_182) as variant#8).9: impl std::future::Future); -+ _72 = Pin::<&mut impl Future>::new_unchecked(move _75) -> [return: bb72, unwind: bb65]; ++ _74 = &mut (((*_181) as variant#8).9: impl std::future::Future); ++ _71 = Pin::<&mut impl Future>::new_unchecked(move _74) -> [return: bb72, unwind: bb65]; } bb74: { -- StorageDead(_44); +- StorageDead(_43); - goto -> bb25; + nop; -+ (((*_182) as variant#8).9: impl std::future::Future) = async_drop_in_place::>(copy (_76.0: &mut AsyncReference<'_>)) -> [return: bb73, unwind: bb65]; ++ (((*_181) as variant#8).9: impl std::future::Future) = async_drop_in_place::>(copy (_75.0: &mut AsyncReference<'_>)) -> [return: bb73, unwind: bb65]; } - bb75 (cleanup): { -- StorageDead(_44); +- StorageDead(_43); - goto -> bb38; + bb75: { -+ _77 = &mut (((*_182) as variant#8).8: AsyncReference<'_>); -+ _76 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _77) -> [return: bb74, unwind: bb27]; ++ _76 = &mut (((*_181) as variant#8).8: AsyncReference<'_>); ++ _75 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _76) -> [return: bb74, unwind: bb27]; } bb76: { @@ -920,8 +916,8 @@ } - bb77: { -- _2 = move _45; -- StorageDead(_45); +- _2 = move _44; +- StorageDead(_44); - goto -> bb76; + bb77 (cleanup): { + nop; @@ -929,270 +925,270 @@ } bb78: { -- _2 = move _45; -- StorageDead(_45); +- _2 = move _44; +- StorageDead(_44); - goto -> bb83; + assert(const false, "`async fn` resumed after async drop") -> [success: bb78, unwind: bb77]; } bb79: { -- StorageLive(_45); -- _45 = yield(const ()) -> [resume: bb77, drop: bb78]; -+ _183 = move _79; -+ StorageDead(_79); +- StorageLive(_44); +- _44 = yield(const ()) -> [resume: bb77, drop: bb78]; ++ _182 = move _78; ++ StorageDead(_78); + goto -> bb78; } bb80: { -- _47 = discriminant(_46); -- switchInt(move _47) -> [0: bb74, 1: bb79, otherwise: bb59]; -+ _183 = move _86; -+ StorageDead(_86); +- _46 = discriminant(_45); +- switchInt(move _46) -> [0: bb74, 1: bb79, otherwise: bb59]; ++ _182 = move _85; ++ StorageDead(_85); + goto -> bb85; } bb81: { -- _46 = as Future>::poll(move _48, move _49) -> [return: bb80, unwind: bb75]; -+ StorageLive(_86); +- _45 = as Future>::poll(move _47, move _48) -> [return: bb80, unwind: bb75]; ++ StorageLive(_85); + _0 = Poll::<()>::Pending; + StorageDead(_17); -+ StorageDead(_86); -+ discriminant((*_182)) = 10; ++ StorageDead(_85); ++ discriminant((*_181)) = 10; + return; } bb82: { -- _50 = move _2; -- _49 = std::future::get_context::<'_, '_>(move _50) -> [return: bb81, unwind: bb75]; -+ _88 = discriminant(_87); -+ switchInt(move _88) -> [0: bb76, 1: bb81, otherwise: bb43]; +- _49 = move _2; +- _48 = std::future::get_context::<'_, '_>(move _49) -> [return: bb81, unwind: bb75]; ++ _87 = discriminant(_86); ++ switchInt(move _87) -> [0: bb76, 1: bb81, otherwise: bb43]; } bb83: { -- _51 = &mut _44; -- _48 = Pin::<&mut impl Future>::new_unchecked(move _51) -> [return: bb82, unwind: bb75]; -+ _87 = as Future>::poll(move _89, move _90) -> [return: bb82, unwind: bb77]; +- _50 = &mut _43; +- _47 = Pin::<&mut impl Future>::new_unchecked(move _50) -> [return: bb82, unwind: bb75]; ++ _86 = as Future>::poll(move _88, move _89) -> [return: bb82, unwind: bb77]; } bb84: { -- _2 = move _52; -- StorageDead(_52); +- _2 = move _51; +- StorageDead(_51); - goto -> bb90; -+ _91 = move _183; -+ _90 = copy (_91.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); ++ _90 = move _182; ++ _89 = copy (_90.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb83; } bb85: { -- _2 = move _52; -- StorageDead(_52); +- _2 = move _51; +- StorageDead(_51); - goto -> bb83; -+ _92 = &mut (((*_182) as variant#10).8: impl std::future::Future); -+ _89 = Pin::<&mut impl Future>::new_unchecked(move _92) -> [return: bb84, unwind: bb77]; ++ _91 = &mut (((*_181) as variant#10).8: impl std::future::Future); ++ _88 = Pin::<&mut impl Future>::new_unchecked(move _91) -> [return: bb84, unwind: bb77]; } bb86: { -- StorageLive(_52); -- _52 = yield(const ()) -> [resume: bb84, drop: bb85]; +- StorageLive(_51); +- _51 = yield(const ()) -> [resume: bb84, drop: bb85]; + nop; -+ (((*_182) as variant#10).8: impl std::future::Future) = async_drop_in_place::(copy (_93.0: &mut AsyncInt)) -> [return: bb85, unwind: bb77]; ++ (((*_181) as variant#10).8: impl std::future::Future) = async_drop_in_place::(copy (_92.0: &mut AsyncInt)) -> [return: bb85, unwind: bb77]; } bb87: { -- _54 = discriminant(_53); -- switchInt(move _54) -> [0: bb73, 1: bb86, otherwise: bb59]; -+ _94 = &mut (((*_182) as variant#10).7: AsyncInt); -+ _93 = Pin::<&mut AsyncInt>::new_unchecked(move _94) -> [return: bb86, unwind: bb28]; +- _53 = discriminant(_52); +- switchInt(move _53) -> [0: bb73, 1: bb86, otherwise: bb59]; ++ _93 = &mut (((*_181) as variant#10).7: AsyncInt); ++ _92 = Pin::<&mut AsyncInt>::new_unchecked(move _93) -> [return: bb86, unwind: bb28]; } bb88: { -- _53 = as Future>::poll(move _55, move _56) -> [return: bb87, unwind: bb75]; +- _52 = as Future>::poll(move _54, move _55) -> [return: bb87, unwind: bb75]; + nop; + goto -> bb16; } - bb89: { -- _57 = move _2; -- _56 = std::future::get_context::<'_, '_>(move _57) -> [return: bb88, unwind: bb75]; +- _56 = move _2; +- _55 = std::future::get_context::<'_, '_>(move _56) -> [return: bb88, unwind: bb75]; + bb89 (cleanup): { + nop; + goto -> bb32; } bb90: { -- _58 = &mut _44; -- _55 = Pin::<&mut impl Future>::new_unchecked(move _58) -> [return: bb89, unwind: bb75]; +- _57 = &mut _43; +- _54 = Pin::<&mut impl Future>::new_unchecked(move _57) -> [return: bb89, unwind: bb75]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb90, unwind: bb89]; } bb91: { -- StorageLive(_44); -- _44 = async_drop_in_place::<{closure@$DIR/async_drop.rs:78:25: 78:27}>(copy (_59.0: &mut {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb90, unwind: bb75]; -+ _183 = move _96; -+ StorageDead(_96); +- StorageLive(_43); +- _43 = async_drop_in_place::<{closure@$DIR/async_drop.rs:78:25: 78:27}>(copy (_58.0: &mut {closure@$DIR/async_drop.rs:78:25: 78:27})) -> [return: bb90, unwind: bb75]; ++ _182 = move _95; ++ StorageDead(_95); + goto -> bb90; } bb92: { -- _60 = &mut _24; -- _59 = Pin::<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>::new_unchecked(move _60) -> [return: bb91, unwind: bb38]; -+ _183 = move _103; -+ StorageDead(_103); +- _59 = &mut _23; +- _58 = Pin::<&mut {closure@$DIR/async_drop.rs:78:25: 78:27}>::new_unchecked(move _59) -> [return: bb91, unwind: bb38]; ++ _182 = move _102; ++ StorageDead(_102); + goto -> bb97; } bb93: { -- StorageDead(_61); +- StorageDead(_60); - goto -> bb14; -+ StorageLive(_103); ++ StorageLive(_102); + _0 = Poll::<()>::Pending; -+ StorageDead(_103); -+ discriminant((*_182)) = 12; ++ StorageDead(_102); ++ discriminant((*_181)) = 12; + return; } bb94: { -- StorageDead(_61); +- StorageDead(_60); - goto -> bb27; -+ _105 = discriminant(_104); -+ switchInt(move _105) -> [0: bb88, 1: bb93, otherwise: bb43]; ++ _104 = discriminant(_103); ++ switchInt(move _104) -> [0: bb88, 1: bb93, otherwise: bb43]; } - bb95 (cleanup): { -- StorageDead(_61); +- StorageDead(_60); - goto -> bb40; + bb95: { -+ _104 = as Future>::poll(move _106, move _107) -> [return: bb94, unwind: bb89]; ++ _103 = as Future>::poll(move _105, move _106) -> [return: bb94, unwind: bb89]; } bb96: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb96, unwind: bb95]; -+ _108 = move _183; -+ _107 = copy (_108.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); ++ _107 = move _182; ++ _106 = copy (_107.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb95; } bb97: { -- _2 = move _62; -- StorageDead(_62); +- _2 = move _61; +- StorageDead(_61); - goto -> bb96; -+ _109 = &mut (((*_182) as variant#12).7: impl std::future::Future); -+ _106 = Pin::<&mut impl Future>::new_unchecked(move _109) -> [return: bb96, unwind: bb89]; ++ _108 = &mut (((*_181) as variant#12).7: impl std::future::Future); ++ _105 = Pin::<&mut impl Future>::new_unchecked(move _108) -> [return: bb96, unwind: bb89]; } bb98: { -- _2 = move _62; -- StorageDead(_62); +- _2 = move _61; +- StorageDead(_61); - goto -> bb103; + nop; -+ (((*_182) as variant#12).7: impl std::future::Future) = async_drop_in_place::(copy (_110.0: &mut AsyncEnum)) -> [return: bb97, unwind: bb89]; ++ (((*_181) as variant#12).7: impl std::future::Future) = async_drop_in_place::(copy (_109.0: &mut AsyncEnum)) -> [return: bb97, unwind: bb89]; } bb99: { -- StorageLive(_62); -- _62 = yield(const ()) -> [resume: bb97, drop: bb98]; -+ _111 = &mut (((*_182) as variant#12).6: AsyncEnum); -+ _110 = Pin::<&mut AsyncEnum>::new_unchecked(move _111) -> [return: bb98, unwind: bb32]; +- StorageLive(_61); +- _61 = yield(const ()) -> [resume: bb97, drop: bb98]; ++ _110 = &mut (((*_181) as variant#12).6: AsyncEnum); ++ _109 = Pin::<&mut AsyncEnum>::new_unchecked(move _110) -> [return: bb98, unwind: bb32]; } bb100: { -- _64 = discriminant(_63); -- switchInt(move _64) -> [0: bb94, 1: bb99, otherwise: bb59]; +- _63 = discriminant(_62); +- switchInt(move _63) -> [0: bb94, 1: bb99, otherwise: bb59]; + nop; + goto -> bb17; } - bb101: { -- _63 = as Future>::poll(move _65, move _66) -> [return: bb100, unwind: bb95]; +- _62 = as Future>::poll(move _64, move _65) -> [return: bb100, unwind: bb95]; + bb101 (cleanup): { + nop; + goto -> bb33; } bb102: { -- _67 = move _2; -- _66 = std::future::get_context::<'_, '_>(move _67) -> [return: bb101, unwind: bb95]; +- _66 = move _2; +- _65 = std::future::get_context::<'_, '_>(move _66) -> [return: bb101, unwind: bb95]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb102, unwind: bb101]; } bb103: { -- _68 = &mut _61; -- _65 = Pin::<&mut impl Future>::new_unchecked(move _68) -> [return: bb102, unwind: bb95]; -+ _183 = move _113; -+ StorageDead(_113); +- _67 = &mut _60; +- _64 = Pin::<&mut impl Future>::new_unchecked(move _67) -> [return: bb102, unwind: bb95]; ++ _182 = move _112; ++ StorageDead(_112); + goto -> bb102; } bb104: { -- _2 = move _69; -- StorageDead(_69); +- _2 = move _68; +- StorageDead(_68); - goto -> bb110; -+ _183 = move _120; -+ StorageDead(_120); ++ _182 = move _119; ++ StorageDead(_119); + goto -> bb109; } bb105: { -- _2 = move _69; -- StorageDead(_69); +- _2 = move _68; +- StorageDead(_68); - goto -> bb103; -+ StorageLive(_120); ++ StorageLive(_119); + _0 = Poll::<()>::Pending; -+ StorageDead(_120); -+ discriminant((*_182)) = 14; ++ StorageDead(_119); ++ discriminant((*_181)) = 14; + return; } bb106: { -- StorageLive(_69); -- _69 = yield(const ()) -> [resume: bb104, drop: bb105]; -+ _122 = discriminant(_121); -+ switchInt(move _122) -> [0: bb100, 1: bb105, otherwise: bb43]; +- StorageLive(_68); +- _68 = yield(const ()) -> [resume: bb104, drop: bb105]; ++ _121 = discriminant(_120); ++ switchInt(move _121) -> [0: bb100, 1: bb105, otherwise: bb43]; } bb107: { -- _71 = discriminant(_70); -- switchInt(move _71) -> [0: bb93, 1: bb106, otherwise: bb59]; -+ _121 = as Future>::poll(move _123, move _124) -> [return: bb106, unwind: bb101]; +- _70 = discriminant(_69); +- switchInt(move _70) -> [0: bb93, 1: bb106, otherwise: bb59]; ++ _120 = as Future>::poll(move _122, move _123) -> [return: bb106, unwind: bb101]; } bb108: { -- _70 = as Future>::poll(move _72, move _73) -> [return: bb107, unwind: bb95]; -+ _125 = move _183; -+ _124 = copy (_125.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _69 = as Future>::poll(move _71, move _72) -> [return: bb107, unwind: bb95]; ++ _124 = move _182; ++ _123 = copy (_124.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb107; } bb109: { -- _74 = move _2; -- _73 = std::future::get_context::<'_, '_>(move _74) -> [return: bb108, unwind: bb95]; -+ _126 = &mut (((*_182) as variant#14).6: impl std::future::Future); -+ _123 = Pin::<&mut impl Future>::new_unchecked(move _126) -> [return: bb108, unwind: bb101]; +- _73 = move _2; +- _72 = std::future::get_context::<'_, '_>(move _73) -> [return: bb108, unwind: bb95]; ++ _125 = &mut (((*_181) as variant#14).6: impl std::future::Future); ++ _122 = Pin::<&mut impl Future>::new_unchecked(move _125) -> [return: bb108, unwind: bb101]; } bb110: { -- _75 = &mut _61; -- _72 = Pin::<&mut impl Future>::new_unchecked(move _75) -> [return: bb109, unwind: bb95]; +- _74 = &mut _60; +- _71 = Pin::<&mut impl Future>::new_unchecked(move _74) -> [return: bb109, unwind: bb95]; + nop; -+ (((*_182) as variant#14).6: impl std::future::Future) = async_drop_in_place::(copy (_127.0: &mut SyncThenAsync)) -> [return: bb109, unwind: bb101]; ++ (((*_181) as variant#14).6: impl std::future::Future) = async_drop_in_place::(copy (_126.0: &mut SyncThenAsync)) -> [return: bb109, unwind: bb101]; } bb111: { -- StorageLive(_61); -- _61 = async_drop_in_place::>(copy (_76.0: &mut AsyncReference<'_>)) -> [return: bb110, unwind: bb95]; -+ _128 = &mut (((*_182) as variant#14).5: SyncThenAsync); -+ _127 = Pin::<&mut SyncThenAsync>::new_unchecked(move _128) -> [return: bb110, unwind: bb33]; +- StorageLive(_60); +- _60 = async_drop_in_place::>(copy (_75.0: &mut AsyncReference<'_>)) -> [return: bb110, unwind: bb95]; ++ _127 = &mut (((*_181) as variant#14).5: SyncThenAsync); ++ _126 = Pin::<&mut SyncThenAsync>::new_unchecked(move _127) -> [return: bb110, unwind: bb33]; } bb112: { -- _77 = &mut _20; -- _76 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _77) -> [return: bb111, unwind: bb40]; +- _76 = &mut _20; +- _75 = Pin::<&mut AsyncReference<'_>>::new_unchecked(move _76) -> [return: bb111, unwind: bb40]; + nop; + goto -> bb18; } - bb113: { -- StorageDead(_78); +- StorageDead(_77); - goto -> bb15; + bb113 (cleanup): { + nop; @@ -1200,91 +1196,91 @@ } bb114: { -- StorageDead(_78); +- StorageDead(_77); - goto -> bb28; + assert(const false, "`async fn` resumed after async drop") -> [success: bb114, unwind: bb113]; } - bb115 (cleanup): { -- StorageDead(_78); +- StorageDead(_77); - goto -> bb41; + bb115: { -+ _183 = move _130; -+ StorageDead(_130); ++ _182 = move _129; ++ StorageDead(_129); + goto -> bb114; } bb116: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb116, unwind: bb115]; -+ _183 = move _137; -+ StorageDead(_137); ++ _182 = move _136; ++ StorageDead(_136); + goto -> bb121; } bb117: { -- _2 = move _79; -- StorageDead(_79); +- _2 = move _78; +- StorageDead(_78); - goto -> bb116; -+ StorageLive(_137); ++ StorageLive(_136); + _0 = Poll::<()>::Pending; -+ StorageDead(_137); -+ discriminant((*_182)) = 16; ++ StorageDead(_136); ++ discriminant((*_181)) = 16; + return; } bb118: { -- _2 = move _79; -- StorageDead(_79); +- _2 = move _78; +- StorageDead(_78); - goto -> bb123; -+ _139 = discriminant(_138); -+ switchInt(move _139) -> [0: bb112, 1: bb117, otherwise: bb43]; ++ _138 = discriminant(_137); ++ switchInt(move _138) -> [0: bb112, 1: bb117, otherwise: bb43]; } bb119: { -- StorageLive(_79); -- _79 = yield(const ()) -> [resume: bb117, drop: bb118]; -+ _138 = as Future>::poll(move _140, move _141) -> [return: bb118, unwind: bb113]; +- StorageLive(_78); +- _78 = yield(const ()) -> [resume: bb117, drop: bb118]; ++ _137 = as Future>::poll(move _139, move _140) -> [return: bb118, unwind: bb113]; } bb120: { -- _81 = discriminant(_80); -- switchInt(move _81) -> [0: bb114, 1: bb119, otherwise: bb59]; -+ _142 = move _183; -+ _141 = copy (_142.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _80 = discriminant(_79); +- switchInt(move _80) -> [0: bb114, 1: bb119, otherwise: bb59]; ++ _141 = move _182; ++ _140 = copy (_141.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb119; } bb121: { -- _80 = as Future>::poll(move _82, move _83) -> [return: bb120, unwind: bb115]; -+ _143 = &mut (((*_182) as variant#16).5: impl std::future::Future); -+ _140 = Pin::<&mut impl Future>::new_unchecked(move _143) -> [return: bb120, unwind: bb113]; +- _79 = as Future>::poll(move _81, move _82) -> [return: bb120, unwind: bb115]; ++ _142 = &mut (((*_181) as variant#16).5: impl std::future::Future); ++ _139 = Pin::<&mut impl Future>::new_unchecked(move _142) -> [return: bb120, unwind: bb113]; } bb122: { -- _84 = move _2; -- _83 = std::future::get_context::<'_, '_>(move _84) -> [return: bb121, unwind: bb115]; +- _83 = move _2; +- _82 = std::future::get_context::<'_, '_>(move _83) -> [return: bb121, unwind: bb115]; + nop; -+ (((*_182) as variant#16).5: impl std::future::Future) = async_drop_in_place::(copy (_144.0: &mut AsyncStruct)) -> [return: bb121, unwind: bb113]; ++ (((*_181) as variant#16).5: impl std::future::Future) = async_drop_in_place::(copy (_143.0: &mut AsyncStruct)) -> [return: bb121, unwind: bb113]; } bb123: { -- _85 = &mut _78; -- _82 = Pin::<&mut impl Future>::new_unchecked(move _85) -> [return: bb122, unwind: bb115]; -+ _145 = &mut (((*_182) as variant#16).4: AsyncStruct); -+ _144 = Pin::<&mut AsyncStruct>::new_unchecked(move _145) -> [return: bb122, unwind: bb34]; +- _84 = &mut _77; +- _81 = Pin::<&mut impl Future>::new_unchecked(move _84) -> [return: bb122, unwind: bb115]; ++ _144 = &mut (((*_181) as variant#16).4: AsyncStruct); ++ _143 = Pin::<&mut AsyncStruct>::new_unchecked(move _144) -> [return: bb122, unwind: bb34]; } bb124: { -- _2 = move _86; -- StorageDead(_86); +- _2 = move _85; +- StorageDead(_85); - goto -> bb130; + nop; + goto -> bb19; } - bb125: { -- _2 = move _86; -- StorageDead(_86); +- _2 = move _85; +- StorageDead(_85); - goto -> bb123; + bb125 (cleanup): { + nop; @@ -1292,77 +1288,77 @@ } bb126: { -- StorageLive(_86); -- _86 = yield(const ()) -> [resume: bb124, drop: bb125]; +- StorageLive(_85); +- _85 = yield(const ()) -> [resume: bb124, drop: bb125]; + assert(const false, "`async fn` resumed after async drop") -> [success: bb126, unwind: bb125]; } bb127: { -- _88 = discriminant(_87); -- switchInt(move _88) -> [0: bb113, 1: bb126, otherwise: bb59]; -+ _183 = move _147; -+ StorageDead(_147); +- _87 = discriminant(_86); +- switchInt(move _87) -> [0: bb113, 1: bb126, otherwise: bb59]; ++ _182 = move _146; ++ StorageDead(_146); + goto -> bb126; } bb128: { -- _87 = as Future>::poll(move _89, move _90) -> [return: bb127, unwind: bb115]; -+ _183 = move _154; -+ StorageDead(_154); +- _86 = as Future>::poll(move _88, move _89) -> [return: bb127, unwind: bb115]; ++ _182 = move _153; ++ StorageDead(_153); + goto -> bb133; } bb129: { -- _91 = move _2; -- _90 = std::future::get_context::<'_, '_>(move _91) -> [return: bb128, unwind: bb115]; -+ StorageLive(_154); +- _90 = move _2; +- _89 = std::future::get_context::<'_, '_>(move _90) -> [return: bb128, unwind: bb115]; ++ StorageLive(_153); + _0 = Poll::<()>::Pending; -+ StorageDead(_154); -+ discriminant((*_182)) = 18; ++ StorageDead(_153); ++ discriminant((*_181)) = 18; + return; } bb130: { -- _92 = &mut _78; -- _89 = Pin::<&mut impl Future>::new_unchecked(move _92) -> [return: bb129, unwind: bb115]; -+ _156 = discriminant(_155); -+ switchInt(move _156) -> [0: bb124, 1: bb129, otherwise: bb43]; +- _91 = &mut _77; +- _88 = Pin::<&mut impl Future>::new_unchecked(move _91) -> [return: bb129, unwind: bb115]; ++ _155 = discriminant(_154); ++ switchInt(move _155) -> [0: bb124, 1: bb129, otherwise: bb43]; } bb131: { -- StorageLive(_78); -- _78 = async_drop_in_place::(copy (_93.0: &mut AsyncInt)) -> [return: bb130, unwind: bb115]; -+ _155 = as Future>::poll(move _157, move _158) -> [return: bb130, unwind: bb125]; +- StorageLive(_77); +- _77 = async_drop_in_place::(copy (_92.0: &mut AsyncInt)) -> [return: bb130, unwind: bb115]; ++ _154 = as Future>::poll(move _156, move _157) -> [return: bb130, unwind: bb125]; } bb132: { -- _94 = &mut _19; -- _93 = Pin::<&mut AsyncInt>::new_unchecked(move _94) -> [return: bb131, unwind: bb41]; -+ _159 = move _183; -+ _158 = copy (_159.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); +- _93 = &mut _19; +- _92 = Pin::<&mut AsyncInt>::new_unchecked(move _93) -> [return: bb131, unwind: bb41]; ++ _158 = move _182; ++ _157 = copy (_158.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb131; } bb133: { -- StorageDead(_95); +- StorageDead(_94); - goto -> bb16; -+ _160 = &mut (((*_182) as variant#18).4: impl std::future::Future); -+ _157 = Pin::<&mut impl Future>::new_unchecked(move _160) -> [return: bb132, unwind: bb125]; ++ _159 = &mut (((*_181) as variant#18).4: impl std::future::Future); ++ _156 = Pin::<&mut impl Future>::new_unchecked(move _159) -> [return: bb132, unwind: bb125]; } bb134: { -- StorageDead(_95); +- StorageDead(_94); - goto -> bb29; + nop; -+ (((*_182) as variant#18).4: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(copy (_161.0: &mut [AsyncInt; 2])) -> [return: bb133, unwind: bb125]; ++ (((*_181) as variant#18).4: impl std::future::Future) = async_drop_in_place::<[AsyncInt; 2]>(copy (_160.0: &mut [AsyncInt; 2])) -> [return: bb133, unwind: bb125]; } - bb135 (cleanup): { -- StorageDead(_95); +- StorageDead(_94); - goto -> bb45; + bb135: { -+ _162 = &mut (((*_182) as variant#18).3: [AsyncInt; 2]); -+ _161 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _162) -> [return: bb134, unwind: bb35]; ++ _161 = &mut (((*_181) as variant#18).3: [AsyncInt; 2]); ++ _160 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _161) -> [return: bb134, unwind: bb35]; } bb136: { @@ -1372,8 +1368,8 @@ } - bb137: { -- _2 = move _96; -- StorageDead(_96); +- _2 = move _95; +- StorageDead(_95); - goto -> bb136; + bb137 (cleanup): { + nop; @@ -1381,291 +1377,291 @@ } bb138: { -- _2 = move _96; -- StorageDead(_96); +- _2 = move _95; +- StorageDead(_95); - goto -> bb143; + assert(const false, "`async fn` resumed after async drop") -> [success: bb138, unwind: bb137]; } bb139: { -- StorageLive(_96); -- _96 = yield(const ()) -> [resume: bb137, drop: bb138]; -+ _183 = move _164; -+ StorageDead(_164); +- StorageLive(_95); +- _95 = yield(const ()) -> [resume: bb137, drop: bb138]; ++ _182 = move _163; ++ StorageDead(_163); + goto -> bb138; } bb140: { -- _98 = discriminant(_97); -- switchInt(move _98) -> [0: bb134, 1: bb139, otherwise: bb59]; -+ _183 = move _171; -+ StorageDead(_171); +- _97 = discriminant(_96); +- switchInt(move _97) -> [0: bb134, 1: bb139, otherwise: bb59]; ++ _182 = move _170; ++ StorageDead(_170); + goto -> bb145; } bb141: { -- _97 = as Future>::poll(move _99, move _100) -> [return: bb140, unwind: bb135]; -+ StorageLive(_171); +- _96 = as Future>::poll(move _98, move _99) -> [return: bb140, unwind: bb135]; ++ StorageLive(_170); + _0 = Poll::<()>::Pending; -+ StorageDead(_171); -+ discriminant((*_182)) = 20; ++ StorageDead(_170); ++ discriminant((*_181)) = 20; + return; } bb142: { -- _101 = move _2; -- _100 = std::future::get_context::<'_, '_>(move _101) -> [return: bb141, unwind: bb135]; -+ _173 = discriminant(_172); -+ switchInt(move _173) -> [0: bb136, 1: bb141, otherwise: bb43]; +- _100 = move _2; +- _99 = std::future::get_context::<'_, '_>(move _100) -> [return: bb141, unwind: bb135]; ++ _172 = discriminant(_171); ++ switchInt(move _172) -> [0: bb136, 1: bb141, otherwise: bb43]; } bb143: { -- _102 = &mut _95; -- _99 = Pin::<&mut impl Future>::new_unchecked(move _102) -> [return: bb142, unwind: bb135]; -+ _172 = as Future>::poll(move _174, move _175) -> [return: bb142, unwind: bb137]; +- _101 = &mut _94; +- _98 = Pin::<&mut impl Future>::new_unchecked(move _101) -> [return: bb142, unwind: bb135]; ++ _171 = as Future>::poll(move _173, move _174) -> [return: bb142, unwind: bb137]; } bb144: { -- _2 = move _103; -- StorageDead(_103); +- _2 = move _102; +- StorageDead(_102); - goto -> bb150; -+ _176 = move _183; -+ _175 = copy (_176.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); ++ _175 = move _182; ++ _174 = copy (_175.0: std::ptr::NonNull>) as &mut std::task::Context<'_> (Transmute); + goto -> bb143; } bb145: { -- _2 = move _103; -- StorageDead(_103); +- _2 = move _102; +- StorageDead(_102); - goto -> bb143; -+ _177 = &mut (((*_182) as variant#20).3: impl std::future::Future); -+ _174 = Pin::<&mut impl Future>::new_unchecked(move _177) -> [return: bb144, unwind: bb137]; ++ _176 = &mut (((*_181) as variant#20).3: impl std::future::Future); ++ _173 = Pin::<&mut impl Future>::new_unchecked(move _176) -> [return: bb144, unwind: bb137]; } bb146: { -- StorageLive(_103); -- _103 = yield(const ()) -> [resume: bb144, drop: bb145]; +- StorageLive(_102); +- _102 = yield(const ()) -> [resume: bb144, drop: bb145]; + nop; -+ (((*_182) as variant#20).3: impl std::future::Future) = async_drop_in_place::(copy (_178.0: &mut AsyncInt)) -> [return: bb145, unwind: bb137]; ++ (((*_181) as variant#20).3: impl std::future::Future) = async_drop_in_place::(copy (_177.0: &mut AsyncInt)) -> [return: bb145, unwind: bb137]; } bb147: { -- _105 = discriminant(_104); -- switchInt(move _105) -> [0: bb133, 1: bb146, otherwise: bb59]; -+ _179 = &mut (((*_182) as variant#20).2: AsyncInt); -+ _178 = Pin::<&mut AsyncInt>::new_unchecked(move _179) -> [return: bb146, unwind: bb36]; +- _104 = discriminant(_103); +- switchInt(move _104) -> [0: bb133, 1: bb146, otherwise: bb59]; ++ _178 = &mut (((*_181) as variant#20).2: AsyncInt); ++ _177 = Pin::<&mut AsyncInt>::new_unchecked(move _178) -> [return: bb146, unwind: bb36]; } - bb148: { -- _104 = as Future>::poll(move _106, move _107) -> [return: bb147, unwind: bb135]; +- _103 = as Future>::poll(move _105, move _106) -> [return: bb147, unwind: bb135]; + bb148 (cleanup): { -+ discriminant((*_182)) = 2; ++ discriminant((*_181)) = 2; + resume; } bb149: { -- _108 = move _2; -- _107 = std::future::get_context::<'_, '_>(move _108) -> [return: bb148, unwind: bb135]; +- _107 = move _2; +- _106 = std::future::get_context::<'_, '_>(move _107) -> [return: bb148, unwind: bb135]; + StorageLive(_17); -+ StorageLive(_23); -+ StorageLive(_25); -+ StorageLive(_28); -+ _28 = move _183; ++ StorageLive(_22); ++ StorageLive(_24); ++ StorageLive(_27); ++ _27 = move _182; + goto -> bb42; } bb150: { -- _109 = &mut _95; -- _106 = Pin::<&mut impl Future>::new_unchecked(move _109) -> [return: bb149, unwind: bb135]; +- _108 = &mut _94; +- _105 = Pin::<&mut impl Future>::new_unchecked(move _108) -> [return: bb149, unwind: bb135]; + StorageLive(_17); -+ StorageLive(_23); -+ StorageLive(_25); -+ StorageLive(_35); -+ _35 = move _183; ++ StorageLive(_22); ++ StorageLive(_24); ++ StorageLive(_34); ++ _34 = move _182; + goto -> bb44; } bb151: { -- StorageLive(_95); -- _95 = async_drop_in_place::(copy (_110.0: &mut AsyncEnum)) -> [return: bb150, unwind: bb135]; +- StorageLive(_94); +- _94 = async_drop_in_place::(copy (_109.0: &mut AsyncEnum)) -> [return: bb150, unwind: bb135]; + StorageLive(_17); -+ StorageLive(_23); -+ StorageLive(_45); -+ _45 = move _183; ++ StorageLive(_22); ++ StorageLive(_44); ++ _44 = move _182; + goto -> bb55; } bb152: { -- _111 = &mut _15; -- _110 = Pin::<&mut AsyncEnum>::new_unchecked(move _111) -> [return: bb151, unwind: bb45]; +- _110 = &mut _15; +- _109 = Pin::<&mut AsyncEnum>::new_unchecked(move _110) -> [return: bb151, unwind: bb45]; + StorageLive(_17); -+ StorageLive(_23); -+ StorageLive(_52); -+ _52 = move _183; ++ StorageLive(_22); ++ StorageLive(_51); ++ _51 = move _182; + goto -> bb56; } bb153: { -- StorageDead(_112); +- StorageDead(_111); - goto -> bb17; + StorageLive(_17); -+ StorageLive(_62); -+ _62 = move _183; ++ StorageLive(_61); ++ _61 = move _182; + goto -> bb67; } bb154: { -- StorageDead(_112); +- StorageDead(_111); - goto -> bb30; + StorageLive(_17); -+ StorageLive(_69); -+ _69 = move _183; ++ StorageLive(_68); ++ _68 = move _182; + goto -> bb68; } - bb155 (cleanup): { -- StorageDead(_112); +- StorageDead(_111); - goto -> bb46; + bb155: { + StorageLive(_17); -+ StorageLive(_79); -+ _79 = move _183; ++ StorageLive(_78); ++ _78 = move _182; + goto -> bb79; } bb156: { - assert(const false, "`async fn` resumed after async drop") -> [success: bb156, unwind: bb155]; + StorageLive(_17); -+ StorageLive(_86); -+ _86 = move _183; ++ StorageLive(_85); ++ _85 = move _182; + goto -> bb80; } bb157: { -- _2 = move _113; -- StorageDead(_113); +- _2 = move _112; +- StorageDead(_112); - goto -> bb156; -+ StorageLive(_96); -+ _96 = move _183; ++ StorageLive(_95); ++ _95 = move _182; + goto -> bb91; } bb158: { -- _2 = move _113; -- StorageDead(_113); +- _2 = move _112; +- StorageDead(_112); - goto -> bb163; -+ StorageLive(_103); -+ _103 = move _183; ++ StorageLive(_102); ++ _102 = move _182; + goto -> bb92; } bb159: { - StorageLive(_113); -- _113 = yield(const ()) -> [resume: bb157, drop: bb158]; -+ _113 = move _183; + StorageLive(_112); +- _112 = yield(const ()) -> [resume: bb157, drop: bb158]; ++ _112 = move _182; + goto -> bb103; } bb160: { -- _115 = discriminant(_114); -- switchInt(move _115) -> [0: bb154, 1: bb159, otherwise: bb59]; -+ StorageLive(_120); -+ _120 = move _183; +- _114 = discriminant(_113); +- switchInt(move _114) -> [0: bb154, 1: bb159, otherwise: bb59]; ++ StorageLive(_119); ++ _119 = move _182; + goto -> bb104; } bb161: { -- _114 = as Future>::poll(move _116, move _117) -> [return: bb160, unwind: bb155]; -+ StorageLive(_130); -+ _130 = move _183; +- _113 = as Future>::poll(move _115, move _116) -> [return: bb160, unwind: bb155]; ++ StorageLive(_129); ++ _129 = move _182; + goto -> bb115; } bb162: { -- _118 = move _2; -- _117 = std::future::get_context::<'_, '_>(move _118) -> [return: bb161, unwind: bb155]; -+ StorageLive(_137); -+ _137 = move _183; +- _117 = move _2; +- _116 = std::future::get_context::<'_, '_>(move _117) -> [return: bb161, unwind: bb155]; ++ StorageLive(_136); ++ _136 = move _182; + goto -> bb116; } bb163: { -- _119 = &mut _112; -- _116 = Pin::<&mut impl Future>::new_unchecked(move _119) -> [return: bb162, unwind: bb155]; -+ StorageLive(_147); -+ _147 = move _183; +- _118 = &mut _111; +- _115 = Pin::<&mut impl Future>::new_unchecked(move _118) -> [return: bb162, unwind: bb155]; ++ StorageLive(_146); ++ _146 = move _182; + goto -> bb127; } bb164: { -- _2 = move _120; -- StorageDead(_120); +- _2 = move _119; +- StorageDead(_119); - goto -> bb170; -+ StorageLive(_154); -+ _154 = move _183; ++ StorageLive(_153); ++ _153 = move _182; + goto -> bb128; } bb165: { -- _2 = move _120; -- StorageDead(_120); +- _2 = move _119; +- StorageDead(_119); - goto -> bb163; -+ StorageLive(_164); -+ _164 = move _183; ++ StorageLive(_163); ++ _163 = move _182; + goto -> bb139; } bb166: { -- StorageLive(_120); -- _120 = yield(const ()) -> [resume: bb164, drop: bb165]; -+ StorageLive(_171); -+ _171 = move _183; +- StorageLive(_119); +- _119 = yield(const ()) -> [resume: bb164, drop: bb165]; ++ StorageLive(_170); ++ _170 = move _182; + goto -> bb140; } bb167: { -- _122 = discriminant(_121); -- switchInt(move _122) -> [0: bb153, 1: bb166, otherwise: bb59]; +- _121 = discriminant(_120); +- switchInt(move _121) -> [0: bb153, 1: bb166, otherwise: bb59]; + assert(const false, "`async fn` resumed after panicking") -> [success: bb167, unwind continue]; } bb168: { -- _121 = as Future>::poll(move _123, move _124) -> [return: bb167, unwind: bb155]; +- _120 = as Future>::poll(move _122, move _123) -> [return: bb167, unwind: bb155]; + assert(const false, "`async fn` resumed after completion") -> [success: bb168, unwind continue]; } bb169: { -- _125 = move _2; -- _124 = std::future::get_context::<'_, '_>(move _125) -> [return: bb168, unwind: bb155]; +- _124 = move _2; +- _123 = std::future::get_context::<'_, '_>(move _124) -> [return: bb168, unwind: bb155]; - } - - bb170: { -- _126 = &mut _112; -- _123 = Pin::<&mut impl Future>::new_unchecked(move _126) -> [return: bb169, unwind: bb155]; +- _125 = &mut _111; +- _122 = Pin::<&mut impl Future>::new_unchecked(move _125) -> [return: bb169, unwind: bb155]; - } - - bb171: { -- StorageLive(_112); -- _112 = async_drop_in_place::(copy (_127.0: &mut SyncThenAsync)) -> [return: bb170, unwind: bb155]; +- StorageLive(_111); +- _111 = async_drop_in_place::(copy (_126.0: &mut SyncThenAsync)) -> [return: bb170, unwind: bb155]; - } - - bb172: { -- _128 = &mut _11; -- _127 = Pin::<&mut SyncThenAsync>::new_unchecked(move _128) -> [return: bb171, unwind: bb46]; +- _127 = &mut _11; +- _126 = Pin::<&mut SyncThenAsync>::new_unchecked(move _127) -> [return: bb171, unwind: bb46]; - } - - bb173: { -- StorageDead(_129); +- StorageDead(_128); - goto -> bb18; - } - - bb174: { -- StorageDead(_129); +- StorageDead(_128); - goto -> bb31; - } - - bb175 (cleanup): { -- StorageDead(_129); +- StorageDead(_128); - goto -> bb47; - } - @@ -1674,99 +1670,99 @@ - } - - bb177: { -- _2 = move _130; -- StorageDead(_130); +- _2 = move _129; +- StorageDead(_129); - goto -> bb176; - } - - bb178: { -- _2 = move _130; -- StorageDead(_130); +- _2 = move _129; +- StorageDead(_129); - goto -> bb183; - } - - bb179: { -- StorageLive(_130); -- _130 = yield(const ()) -> [resume: bb177, drop: bb178]; +- StorageLive(_129); +- _129 = yield(const ()) -> [resume: bb177, drop: bb178]; - } - - bb180: { -- _132 = discriminant(_131); -- switchInt(move _132) -> [0: bb174, 1: bb179, otherwise: bb59]; +- _131 = discriminant(_130); +- switchInt(move _131) -> [0: bb174, 1: bb179, otherwise: bb59]; - } - - bb181: { -- _131 = as Future>::poll(move _133, move _134) -> [return: bb180, unwind: bb175]; +- _130 = as Future>::poll(move _132, move _133) -> [return: bb180, unwind: bb175]; - } - - bb182: { -- _135 = move _2; -- _134 = std::future::get_context::<'_, '_>(move _135) -> [return: bb181, unwind: bb175]; +- _134 = move _2; +- _133 = std::future::get_context::<'_, '_>(move _134) -> [return: bb181, unwind: bb175]; - } - - bb183: { -- _136 = &mut _129; -- _133 = Pin::<&mut impl Future>::new_unchecked(move _136) -> [return: bb182, unwind: bb175]; +- _135 = &mut _128; +- _132 = Pin::<&mut impl Future>::new_unchecked(move _135) -> [return: bb182, unwind: bb175]; - } - - bb184: { -- _2 = move _137; -- StorageDead(_137); +- _2 = move _136; +- StorageDead(_136); - goto -> bb190; - } - - bb185: { -- _2 = move _137; -- StorageDead(_137); +- _2 = move _136; +- StorageDead(_136); - goto -> bb183; - } - - bb186: { -- StorageLive(_137); -- _137 = yield(const ()) -> [resume: bb184, drop: bb185]; +- StorageLive(_136); +- _136 = yield(const ()) -> [resume: bb184, drop: bb185]; - } - - bb187: { -- _139 = discriminant(_138); -- switchInt(move _139) -> [0: bb173, 1: bb186, otherwise: bb59]; +- _138 = discriminant(_137); +- switchInt(move _138) -> [0: bb173, 1: bb186, otherwise: bb59]; - } - - bb188: { -- _138 = as Future>::poll(move _140, move _141) -> [return: bb187, unwind: bb175]; +- _137 = as Future>::poll(move _139, move _140) -> [return: bb187, unwind: bb175]; - } - - bb189: { -- _142 = move _2; -- _141 = std::future::get_context::<'_, '_>(move _142) -> [return: bb188, unwind: bb175]; +- _141 = move _2; +- _140 = std::future::get_context::<'_, '_>(move _141) -> [return: bb188, unwind: bb175]; - } - - bb190: { -- _143 = &mut _129; -- _140 = Pin::<&mut impl Future>::new_unchecked(move _143) -> [return: bb189, unwind: bb175]; +- _142 = &mut _128; +- _139 = Pin::<&mut impl Future>::new_unchecked(move _142) -> [return: bb189, unwind: bb175]; - } - - bb191: { -- StorageLive(_129); -- _129 = async_drop_in_place::(copy (_144.0: &mut AsyncStruct)) -> [return: bb190, unwind: bb175]; +- StorageLive(_128); +- _128 = async_drop_in_place::(copy (_143.0: &mut AsyncStruct)) -> [return: bb190, unwind: bb175]; - } - - bb192: { -- _145 = &mut _8; -- _144 = Pin::<&mut AsyncStruct>::new_unchecked(move _145) -> [return: bb191, unwind: bb47]; +- _144 = &mut _8; +- _143 = Pin::<&mut AsyncStruct>::new_unchecked(move _144) -> [return: bb191, unwind: bb47]; - } - - bb193: { -- StorageDead(_146); +- StorageDead(_145); - goto -> bb19; - } - - bb194: { -- StorageDead(_146); +- StorageDead(_145); - goto -> bb32; - } - - bb195 (cleanup): { -- StorageDead(_146); +- StorageDead(_145); - goto -> bb48; - } - @@ -1775,99 +1771,99 @@ - } - - bb197: { -- _2 = move _147; -- StorageDead(_147); +- _2 = move _146; +- StorageDead(_146); - goto -> bb196; - } - - bb198: { -- _2 = move _147; -- StorageDead(_147); +- _2 = move _146; +- StorageDead(_146); - goto -> bb203; - } - - bb199: { -- StorageLive(_147); -- _147 = yield(const ()) -> [resume: bb197, drop: bb198]; +- StorageLive(_146); +- _146 = yield(const ()) -> [resume: bb197, drop: bb198]; - } - - bb200: { -- _149 = discriminant(_148); -- switchInt(move _149) -> [0: bb194, 1: bb199, otherwise: bb59]; +- _148 = discriminant(_147); +- switchInt(move _148) -> [0: bb194, 1: bb199, otherwise: bb59]; - } - - bb201: { -- _148 = as Future>::poll(move _150, move _151) -> [return: bb200, unwind: bb195]; +- _147 = as Future>::poll(move _149, move _150) -> [return: bb200, unwind: bb195]; - } - - bb202: { -- _152 = move _2; -- _151 = std::future::get_context::<'_, '_>(move _152) -> [return: bb201, unwind: bb195]; +- _151 = move _2; +- _150 = std::future::get_context::<'_, '_>(move _151) -> [return: bb201, unwind: bb195]; - } - - bb203: { -- _153 = &mut _146; -- _150 = Pin::<&mut impl Future>::new_unchecked(move _153) -> [return: bb202, unwind: bb195]; +- _152 = &mut _145; +- _149 = Pin::<&mut impl Future>::new_unchecked(move _152) -> [return: bb202, unwind: bb195]; - } - - bb204: { -- _2 = move _154; -- StorageDead(_154); +- _2 = move _153; +- StorageDead(_153); - goto -> bb210; - } - - bb205: { -- _2 = move _154; -- StorageDead(_154); +- _2 = move _153; +- StorageDead(_153); - goto -> bb203; - } - - bb206: { -- StorageLive(_154); -- _154 = yield(const ()) -> [resume: bb204, drop: bb205]; +- StorageLive(_153); +- _153 = yield(const ()) -> [resume: bb204, drop: bb205]; - } - - bb207: { -- _156 = discriminant(_155); -- switchInt(move _156) -> [0: bb193, 1: bb206, otherwise: bb59]; +- _155 = discriminant(_154); +- switchInt(move _155) -> [0: bb193, 1: bb206, otherwise: bb59]; - } - - bb208: { -- _155 = as Future>::poll(move _157, move _158) -> [return: bb207, unwind: bb195]; +- _154 = as Future>::poll(move _156, move _157) -> [return: bb207, unwind: bb195]; - } - - bb209: { -- _159 = move _2; -- _158 = std::future::get_context::<'_, '_>(move _159) -> [return: bb208, unwind: bb195]; +- _158 = move _2; +- _157 = std::future::get_context::<'_, '_>(move _158) -> [return: bb208, unwind: bb195]; - } - - bb210: { -- _160 = &mut _146; -- _157 = Pin::<&mut impl Future>::new_unchecked(move _160) -> [return: bb209, unwind: bb195]; +- _159 = &mut _145; +- _156 = Pin::<&mut impl Future>::new_unchecked(move _159) -> [return: bb209, unwind: bb195]; - } - - bb211: { -- StorageLive(_146); -- _146 = async_drop_in_place::<[AsyncInt; 2]>(copy (_161.0: &mut [AsyncInt; 2])) -> [return: bb210, unwind: bb195]; +- StorageLive(_145); +- _145 = async_drop_in_place::<[AsyncInt; 2]>(copy (_160.0: &mut [AsyncInt; 2])) -> [return: bb210, unwind: bb195]; - } - - bb212: { -- _162 = &mut _5; -- _161 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _162) -> [return: bb211, unwind: bb48]; +- _161 = &mut _5; +- _160 = Pin::<&mut [AsyncInt; 2]>::new_unchecked(move _161) -> [return: bb211, unwind: bb48]; - } - - bb213: { -- StorageDead(_163); +- StorageDead(_162); - goto -> bb20; - } - - bb214: { -- StorageDead(_163); +- StorageDead(_162); - goto -> bb33; - } - - bb215 (cleanup): { -- StorageDead(_163); +- StorageDead(_162); - goto -> bb49; - } - @@ -1876,95 +1872,95 @@ - } - - bb217: { -- _2 = move _164; -- StorageDead(_164); +- _2 = move _163; +- StorageDead(_163); - goto -> bb216; - } - - bb218: { -- _2 = move _164; -- StorageDead(_164); +- _2 = move _163; +- StorageDead(_163); - goto -> bb223; - } - - bb219: { -- StorageLive(_164); -- _164 = yield(const ()) -> [resume: bb217, drop: bb218]; +- StorageLive(_163); +- _163 = yield(const ()) -> [resume: bb217, drop: bb218]; - } - - bb220: { -- _166 = discriminant(_165); -- switchInt(move _166) -> [0: bb214, 1: bb219, otherwise: bb59]; +- _165 = discriminant(_164); +- switchInt(move _165) -> [0: bb214, 1: bb219, otherwise: bb59]; - } - - bb221: { -- _165 = as Future>::poll(move _167, move _168) -> [return: bb220, unwind: bb215]; +- _164 = as Future>::poll(move _166, move _167) -> [return: bb220, unwind: bb215]; - } - - bb222: { -- _169 = move _2; -- _168 = std::future::get_context::<'_, '_>(move _169) -> [return: bb221, unwind: bb215]; +- _168 = move _2; +- _167 = std::future::get_context::<'_, '_>(move _168) -> [return: bb221, unwind: bb215]; - } - - bb223: { -- _170 = &mut _163; -- _167 = Pin::<&mut impl Future>::new_unchecked(move _170) -> [return: bb222, unwind: bb215]; +- _169 = &mut _162; +- _166 = Pin::<&mut impl Future>::new_unchecked(move _169) -> [return: bb222, unwind: bb215]; - } - - bb224: { -- _2 = move _171; -- StorageDead(_171); +- _2 = move _170; +- StorageDead(_170); - goto -> bb230; - } - - bb225: { -- _2 = move _171; -- StorageDead(_171); +- _2 = move _170; +- StorageDead(_170); - goto -> bb223; - } - - bb226: { -- StorageLive(_171); -- _171 = yield(const ()) -> [resume: bb224, drop: bb225]; +- StorageLive(_170); +- _170 = yield(const ()) -> [resume: bb224, drop: bb225]; - } - - bb227: { -- _173 = discriminant(_172); -- switchInt(move _173) -> [0: bb213, 1: bb226, otherwise: bb59]; +- _172 = discriminant(_171); +- switchInt(move _172) -> [0: bb213, 1: bb226, otherwise: bb59]; - } - - bb228: { -- _172 = as Future>::poll(move _174, move _175) -> [return: bb227, unwind: bb215]; +- _171 = as Future>::poll(move _173, move _174) -> [return: bb227, unwind: bb215]; - } - - bb229: { -- _176 = move _2; -- _175 = std::future::get_context::<'_, '_>(move _176) -> [return: bb228, unwind: bb215]; +- _175 = move _2; +- _174 = std::future::get_context::<'_, '_>(move _175) -> [return: bb228, unwind: bb215]; - } - - bb230: { -- _177 = &mut _163; -- _174 = Pin::<&mut impl Future>::new_unchecked(move _177) -> [return: bb229, unwind: bb215]; +- _176 = &mut _162; +- _173 = Pin::<&mut impl Future>::new_unchecked(move _176) -> [return: bb229, unwind: bb215]; - } - - bb231: { -- StorageLive(_163); -- _163 = async_drop_in_place::(copy (_178.0: &mut AsyncInt)) -> [return: bb230, unwind: bb215]; +- StorageLive(_162); +- _162 = async_drop_in_place::(copy (_177.0: &mut AsyncInt)) -> [return: bb230, unwind: bb215]; - } - - bb232: { -- _179 = &mut _4; -- _178 = Pin::<&mut AsyncInt>::new_unchecked(move _179) -> [return: bb231, unwind: bb49]; +- _178 = &mut _4; +- _177 = Pin::<&mut AsyncInt>::new_unchecked(move _178) -> [return: bb231, unwind: bb49]; + nop; -+ (((*_182) as variant#20).1: SyncInt) = SyncInt(const 0_i32); ++ (((*_181) as variant#20).1: SyncInt) = SyncInt(const 0_i32); + nop; -+ (((*_182) as variant#20).2: AsyncInt) = AsyncInt(const 0_i32); ++ (((*_181) as variant#20).2: AsyncInt) = AsyncInt(const 0_i32); + nop; + StorageLive(_6); + _6 = AsyncInt(const 1_i32); + StorageLive(_7); + _7 = AsyncInt(const 2_i32); -+ (((*_182) as variant#18).3: [AsyncInt; 2]) = [move _6, move _7]; ++ (((*_181) as variant#18).3: [AsyncInt; 2]) = [move _6, move _7]; + goto -> bb1; } } diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff index d9d65147e1e83..5d3fda130d4d1 100644 --- a/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#0}.StateTransform.diff @@ -18,7 +18,7 @@ + } + storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} + } -+ debug arg => (((*_18) as variant#4).0: std::string::String); ++ debug arg => (((*_15) as variant#4).0: std::string::String); + coroutine debug arg => _s0; + let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; let _3: std::string::String; @@ -28,15 +28,12 @@ let mut _7: &std::panic::Location<'_>; let _8: std::string::String; let mut _9: (&str, std::string::String, &std::panic::Location<'_>); - let mut _10: &str; - let _11: &str; - let mut _12: std::string::String; - let mut _13: &std::string::String; - let mut _14: &std::panic::Location<'_>; - let _15: &std::panic::Location<'_>; -+ let mut _16: (); -+ let mut _17: u32; -+ let mut _18: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}; + let mut _10: std::string::String; + let mut _11: &std::string::String; + let mut _12: &std::panic::Location<'_>; ++ let mut _13: (); ++ let mut _14: u32; ++ let mut _15: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}; bb0: { - StorageLive(_3); @@ -44,17 +41,17 @@ - StorageLive(_5); - StorageLive(_6); - _6 = &_2; -- _5 = ::clone(move _6) -> [return: bb1, unwind: bb31]; -+ _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}); -+ _17 = discriminant((*_18)); -+ switchInt(move _17) -> [0: bb35, 1: bb33, 2: bb32, 3: bb30, 4: bb31, otherwise: bb34]; +- _5 = ::clone(move _6) -> [return: bb1, unwind: bb30]; ++ _15 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:19:5: 19:18}); ++ _14 = discriminant((*_15)); ++ switchInt(move _14) -> [0: bb34, 1: bb32, 2: bb31, 3: bb29, 4: bb30, otherwise: bb33]; } bb1: { StorageDead(_6); StorageLive(_7); -- _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb30]; -+ _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb21]; +- _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb29]; ++ _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb20]; } bb2: { @@ -69,7 +66,7 @@ + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); + StorageDead(_3); + StorageDead(_4); -+ discriminant((*_18)) = 3; ++ discriminant((*_15)) = 3; + return; } @@ -79,8 +76,8 @@ bb5: { StorageDead(_4); -- drop(_3) -> [return: bb6, unwind: bb34]; -+ drop(_3) -> [return: bb6, unwind: bb25]; +- drop(_3) -> [return: bb6, unwind: bb33]; ++ drop(_3) -> [return: bb6, unwind: bb24]; } bb6: { @@ -89,41 +86,32 @@ StorageLive(_9); StorageLive(_10); StorageLive(_11); - _11 = const "second"; - _10 = &(*_11); - StorageLive(_12); - StorageLive(_13); -- _13 = &_2; -- _12 = ::clone(move _13) -> [return: bb7, unwind: bb28]; -+ _13 = &(((*_18) as variant#4).0: std::string::String); -+ _12 = ::clone(move _13) -> [return: bb7, unwind: bb19]; +- _11 = &_2; +- _10 = ::clone(move _11) -> [return: bb7, unwind: bb25]; ++ _11 = &(((*_15) as variant#4).0: std::string::String); ++ _10 = ::clone(move _11) -> [return: bb7, unwind: bb16]; } bb7: { - StorageDead(_13); - StorageLive(_14); - StorageLive(_15); -- _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb24]; -+ _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb15]; + StorageDead(_11); + StorageLive(_12); +- _12 = Location::<'_>::caller() -> [return: bb8, unwind: bb24]; ++ _12 = Location::<'_>::caller() -> [return: bb8, unwind: bb15]; } bb8: { - _14 = &(*_15); - _9 = (move _10, move _12, move _14); - StorageDead(_14); + _9 = (const "second", move _10, move _12); + StorageDead(_12); goto -> bb9; } bb9: { - StorageDead(_12); StorageDead(_10); - _8 = yield(move _9) -> [resume: bb10, drop: bb15]; + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); + StorageDead(_8); + StorageDead(_9); -+ StorageDead(_11); -+ StorageDead(_15); -+ discriminant((*_18)) = 4; ++ discriminant((*_15)) = 4; + return; } @@ -133,210 +121,187 @@ bb11: { StorageDead(_9); -- drop(_8) -> [return: bb12, unwind: bb27]; -+ drop(_8) -> [return: bb12, unwind: bb18]; +- drop(_8) -> [return: bb12, unwind: bb28]; ++ drop(_8) -> [return: bb12, unwind: bb19]; } bb12: { - StorageDead(_15); - StorageDead(_11); StorageDead(_8); - _0 = const (); -- drop(_2) -> [return: bb13, unwind: bb36]; -+ _16 = const (); -+ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb13, unwind: bb27]; +- drop(_2) -> [return: bb13, unwind: bb35]; ++ _13 = const (); ++ drop((((*_15) as variant#4).0: std::string::String)) -> [return: bb13, unwind: bb26]; } bb13: { -- drop(_1) -> [return: bb14, unwind: bb37]; +- drop(_1) -> [return: bb14, unwind: bb36]; + goto -> bb14; } bb14: { -+ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); -+ discriminant((*_18)) = 1; ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _13); ++ discriminant((*_15)) = 1; return; } - bb15: { - goto -> bb16; + bb15 (cleanup): { -+ StorageDead(_14); -+ drop(_12) -> [return: bb16, unwind terminate(cleanup)]; ++ StorageDead(_12); ++ drop(_10) -> [return: bb17, unwind terminate(cleanup)]; } - bb16: { - StorageDead(_9); + bb16 (cleanup): { -+ StorageDead(_12); -+ StorageDead(_10); ++ StorageDead(_11); goto -> bb17; } - bb17: { -- StorageDead(_15); -- StorageDead(_11); - StorageDead(_8); - goto -> bb21; + bb17 (cleanup): { -+ StorageDead(_9); ++ StorageDead(_10); + goto -> bb18; } - bb18: { -- goto -> bb19; + bb18 (cleanup): { -+ StorageDead(_15); -+ goto -> bb20; ++ StorageDead(_9); + goto -> bb19; } - bb19: { - StorageDead(_4); +- goto -> bb20; + bb19 (cleanup): { -+ StorageDead(_13); -+ StorageDead(_12); -+ StorageDead(_10); -+ StorageDead(_9); - goto -> bb20; ++ StorageDead(_8); ++ goto -> bb25; } - bb20: { - StorageDead(_3); - goto -> bb21; + bb20 (cleanup): { -+ StorageDead(_11); -+ StorageDead(_8); -+ goto -> bb26; ++ StorageDead(_7); ++ drop(_5) -> [return: bb22, unwind terminate(cleanup)]; } - bb21: { -- drop(_2) -> [return: bb22, unwind: bb38]; +- drop(_2) -> [return: bb22, unwind: bb37]; + bb21 (cleanup): { -+ StorageDead(_7); -+ drop(_5) -> [return: bb23, unwind terminate(cleanup)]; ++ StorageDead(_6); ++ goto -> bb22; } - bb22: { -- drop(_1) -> [return: bb23, unwind: bb37]; +- drop(_1) -> [return: bb23, unwind: bb36]; + bb22 (cleanup): { -+ StorageDead(_6); ++ StorageDead(_5); + goto -> bb23; } - bb23: { - coroutine_drop; + bb23 (cleanup): { -+ StorageDead(_5); ++ StorageDead(_4); + goto -> bb24; } bb24 (cleanup): { -- StorageDead(_14); -- drop(_12) -> [return: bb25, unwind terminate(cleanup)]; -+ StorageDead(_4); +- StorageDead(_12); +- drop(_10) -> [return: bb26, unwind terminate(cleanup)]; ++ StorageDead(_3); + goto -> bb25; } bb25 (cleanup): { -- StorageDead(_12); -- StorageDead(_10); -+ StorageDead(_3); - goto -> bb26; +- StorageDead(_11); +- goto -> bb26; ++ drop((((*_15) as variant#4).0: std::string::String)) -> [return: bb26, unwind terminate(cleanup)]; } bb26 (cleanup): { -- StorageDead(_9); -- goto -> bb27; -+ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb27, unwind terminate(cleanup)]; +- StorageDead(_10); + goto -> bb27; } bb27 (cleanup): { -- StorageDead(_15); -- goto -> bb29; -+ goto -> bb28; - } - - bb28 (cleanup): { -- StorageDead(_13); -- StorageDead(_12); -- StorageDead(_10); - StorageDead(_9); - goto -> bb29; + goto -> bb28; } - bb29 (cleanup): { -- StorageDead(_11); + bb28 (cleanup): { - StorageDead(_8); -- goto -> bb35; -+ discriminant((*_18)) = 2; +- goto -> bb34; ++ discriminant((*_15)) = 2; + resume; } -- bb30 (cleanup): { +- bb29 (cleanup): { - StorageDead(_7); -- drop(_5) -> [return: bb32, unwind terminate(cleanup)]; -+ bb30: { +- drop(_5) -> [return: bb31, unwind terminate(cleanup)]; ++ bb29: { + StorageLive(_3); + StorageLive(_4); + _3 = move _2; + goto -> bb4; } -- bb31 (cleanup): { +- bb30 (cleanup): { - StorageDead(_6); -- goto -> bb32; -+ bb31: { +- goto -> bb31; ++ bb30: { + StorageLive(_8); + StorageLive(_9); -+ StorageLive(_11); -+ StorageLive(_15); + _8 = move _2; + goto -> bb10; } -- bb32 (cleanup): { +- bb31 (cleanup): { - StorageDead(_5); +- goto -> bb32; ++ bb31: { ++ assert(const false, "coroutine resumed after panicking") -> [success: bb31, unwind continue]; + } + +- bb32 (cleanup): { +- StorageDead(_4); - goto -> bb33; + bb32: { -+ assert(const false, "coroutine resumed after panicking") -> [success: bb32, unwind continue]; ++ assert(const false, "coroutine resumed after completion") -> [success: bb32, unwind continue]; } - bb33 (cleanup): { -- StorageDead(_4); +- StorageDead(_3); - goto -> bb34; + bb33: { -+ assert(const false, "coroutine resumed after completion") -> [success: bb33, unwind continue]; - } - -- bb34 (cleanup): { -- StorageDead(_3); -- goto -> bb35; -+ bb34: { + unreachable; } -- bb35 (cleanup): { -- drop(_2) -> [return: bb36, unwind terminate(cleanup)]; +- bb34 (cleanup): { +- drop(_2) -> [return: bb35, unwind terminate(cleanup)]; - } - -- bb36 (cleanup): { -- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; +- bb35 (cleanup): { +- drop(_1) -> [return: bb36, unwind terminate(cleanup)]; - } - -- bb37 (cleanup): { +- bb36 (cleanup): { - resume; - } - -- bb38 (cleanup): { -- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; -+ bb35: { -+ (((*_18) as variant#4).0: std::string::String) = move _2; +- bb37 (cleanup): { +- drop(_1) -> [return: bb36, unwind terminate(cleanup)]; ++ bb34: { ++ (((*_15) as variant#4).0: std::string::String) = move _2; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); + StorageLive(_6); -+ _6 = &(((*_18) as variant#4).0: std::string::String); -+ _5 = ::clone(move _6) -> [return: bb1, unwind: bb22]; ++ _6 = &(((*_15) as variant#4).0: std::string::String); ++ _5 = ::clone(move _6) -> [return: bb1, unwind: bb21]; } } diff --git a/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff index d25c2f61b722a..1f524c214d747 100644 --- a/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff +++ b/tests/mir-opt/coroutine/coroutine.main-{closure#1}.StateTransform.diff @@ -18,7 +18,7 @@ + } + storage_conflicts = BitMatrix(1x1) {(_s0, _s0)} + } -+ debug arg => (((*_18) as variant#4).0: std::string::String); ++ debug arg => (((*_15) as variant#4).0: std::string::String); + coroutine debug arg => _s0; + let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; let _3: std::string::String; @@ -28,15 +28,12 @@ let mut _7: &std::panic::Location<'_>; let _8: std::string::String; let mut _9: (&str, std::string::String, &std::panic::Location<'_>); - let mut _10: &str; - let _11: &str; - let mut _12: std::string::String; - let mut _13: &std::string::String; - let mut _14: &std::panic::Location<'_>; - let _15: &std::panic::Location<'_>; -+ let mut _16: (); -+ let mut _17: u32; -+ let mut _18: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}; + let mut _10: std::string::String; + let mut _11: &std::string::String; + let mut _12: &std::panic::Location<'_>; ++ let mut _13: (); ++ let mut _14: u32; ++ let mut _15: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}; bb0: { - StorageLive(_3); @@ -44,17 +41,17 @@ - StorageLive(_5); - StorageLive(_6); - _6 = &_2; -- _5 = ::clone(move _6) -> [return: bb1, unwind: bb31]; -+ _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}); -+ _17 = discriminant((*_18)); -+ switchInt(move _17) -> [0: bb35, 1: bb33, 2: bb32, 3: bb30, 4: bb31, otherwise: bb34]; +- _5 = ::clone(move _6) -> [return: bb1, unwind: bb30]; ++ _15 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:26:5: 26:18}); ++ _14 = discriminant((*_15)); ++ switchInt(move _14) -> [0: bb34, 1: bb32, 2: bb31, 3: bb29, 4: bb30, otherwise: bb33]; } bb1: { StorageDead(_6); StorageLive(_7); -- _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb30]; -+ _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb21]; +- _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb29]; ++ _7 = Location::<'_>::caller() -> [return: bb2, unwind: bb20]; } bb2: { @@ -69,7 +66,7 @@ + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); + StorageDead(_3); + StorageDead(_4); -+ discriminant((*_18)) = 3; ++ discriminant((*_15)) = 3; + return; } @@ -79,8 +76,8 @@ bb5: { StorageDead(_4); -- drop(_3) -> [return: bb6, unwind: bb34]; -+ drop(_3) -> [return: bb6, unwind: bb25]; +- drop(_3) -> [return: bb6, unwind: bb33]; ++ drop(_3) -> [return: bb6, unwind: bb24]; } bb6: { @@ -89,41 +86,32 @@ StorageLive(_9); StorageLive(_10); StorageLive(_11); - _11 = const "second"; - _10 = &(*_11); - StorageLive(_12); - StorageLive(_13); -- _13 = &_2; -- _12 = ::clone(move _13) -> [return: bb7, unwind: bb28]; -+ _13 = &(((*_18) as variant#4).0: std::string::String); -+ _12 = ::clone(move _13) -> [return: bb7, unwind: bb19]; +- _11 = &_2; +- _10 = ::clone(move _11) -> [return: bb7, unwind: bb25]; ++ _11 = &(((*_15) as variant#4).0: std::string::String); ++ _10 = ::clone(move _11) -> [return: bb7, unwind: bb16]; } bb7: { - StorageDead(_13); - StorageLive(_14); - StorageLive(_15); -- _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb24]; -+ _15 = Location::<'_>::caller() -> [return: bb8, unwind: bb15]; + StorageDead(_11); + StorageLive(_12); +- _12 = Location::<'_>::caller() -> [return: bb8, unwind: bb24]; ++ _12 = Location::<'_>::caller() -> [return: bb8, unwind: bb15]; } bb8: { - _14 = &(*_15); - _9 = (move _10, move _12, move _14); - StorageDead(_14); + _9 = (const "second", move _10, move _12); + StorageDead(_12); goto -> bb9; } bb9: { - StorageDead(_12); StorageDead(_10); - _8 = yield(move _9) -> [resume: bb10, drop: bb15]; + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); + StorageDead(_8); + StorageDead(_9); -+ StorageDead(_11); -+ StorageDead(_15); -+ discriminant((*_18)) = 4; ++ discriminant((*_15)) = 4; + return; } @@ -133,210 +121,187 @@ bb11: { StorageDead(_9); -- drop(_8) -> [return: bb12, unwind: bb27]; -+ drop(_8) -> [return: bb12, unwind: bb18]; +- drop(_8) -> [return: bb12, unwind: bb28]; ++ drop(_8) -> [return: bb12, unwind: bb19]; } bb12: { - StorageDead(_15); - StorageDead(_11); StorageDead(_8); - _0 = const (); -- drop(_2) -> [return: bb13, unwind: bb36]; -+ _16 = const (); -+ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb13, unwind: bb27]; +- drop(_2) -> [return: bb13, unwind: bb35]; ++ _13 = const (); ++ drop((((*_15) as variant#4).0: std::string::String)) -> [return: bb13, unwind: bb26]; } bb13: { -- drop(_1) -> [return: bb14, unwind: bb37]; +- drop(_1) -> [return: bb14, unwind: bb36]; + goto -> bb14; } bb14: { -+ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); -+ discriminant((*_18)) = 1; ++ _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _13); ++ discriminant((*_15)) = 1; return; } - bb15: { - goto -> bb16; + bb15 (cleanup): { -+ StorageDead(_14); -+ drop(_12) -> [return: bb16, unwind terminate(cleanup)]; ++ StorageDead(_12); ++ drop(_10) -> [return: bb17, unwind terminate(cleanup)]; } - bb16: { - StorageDead(_9); + bb16 (cleanup): { -+ StorageDead(_12); -+ StorageDead(_10); ++ StorageDead(_11); goto -> bb17; } - bb17: { -- StorageDead(_15); -- StorageDead(_11); - StorageDead(_8); - goto -> bb21; + bb17 (cleanup): { -+ StorageDead(_9); ++ StorageDead(_10); + goto -> bb18; } - bb18: { -- goto -> bb19; + bb18 (cleanup): { -+ StorageDead(_15); -+ goto -> bb20; ++ StorageDead(_9); + goto -> bb19; } - bb19: { - StorageDead(_4); +- goto -> bb20; + bb19 (cleanup): { -+ StorageDead(_13); -+ StorageDead(_12); -+ StorageDead(_10); -+ StorageDead(_9); - goto -> bb20; ++ StorageDead(_8); ++ goto -> bb25; } - bb20: { - StorageDead(_3); - goto -> bb21; + bb20 (cleanup): { -+ StorageDead(_11); -+ StorageDead(_8); -+ goto -> bb26; ++ StorageDead(_7); ++ drop(_5) -> [return: bb22, unwind terminate(cleanup)]; } - bb21: { -- drop(_2) -> [return: bb22, unwind: bb38]; +- drop(_2) -> [return: bb22, unwind: bb37]; + bb21 (cleanup): { -+ StorageDead(_7); -+ drop(_5) -> [return: bb23, unwind terminate(cleanup)]; ++ StorageDead(_6); ++ goto -> bb22; } - bb22: { -- drop(_1) -> [return: bb23, unwind: bb37]; +- drop(_1) -> [return: bb23, unwind: bb36]; + bb22 (cleanup): { -+ StorageDead(_6); ++ StorageDead(_5); + goto -> bb23; } - bb23: { - coroutine_drop; + bb23 (cleanup): { -+ StorageDead(_5); ++ StorageDead(_4); + goto -> bb24; } bb24 (cleanup): { -- StorageDead(_14); -- drop(_12) -> [return: bb25, unwind terminate(cleanup)]; -+ StorageDead(_4); +- StorageDead(_12); +- drop(_10) -> [return: bb26, unwind terminate(cleanup)]; ++ StorageDead(_3); + goto -> bb25; } bb25 (cleanup): { -- StorageDead(_12); -- StorageDead(_10); -+ StorageDead(_3); - goto -> bb26; +- StorageDead(_11); +- goto -> bb26; ++ drop((((*_15) as variant#4).0: std::string::String)) -> [return: bb26, unwind terminate(cleanup)]; } bb26 (cleanup): { -- StorageDead(_9); -- goto -> bb27; -+ drop((((*_18) as variant#4).0: std::string::String)) -> [return: bb27, unwind terminate(cleanup)]; +- StorageDead(_10); + goto -> bb27; } bb27 (cleanup): { -- StorageDead(_15); -- goto -> bb29; -+ goto -> bb28; - } - - bb28 (cleanup): { -- StorageDead(_13); -- StorageDead(_12); -- StorageDead(_10); - StorageDead(_9); - goto -> bb29; + goto -> bb28; } - bb29 (cleanup): { -- StorageDead(_11); + bb28 (cleanup): { - StorageDead(_8); -- goto -> bb35; -+ discriminant((*_18)) = 2; +- goto -> bb34; ++ discriminant((*_15)) = 2; + resume; } -- bb30 (cleanup): { +- bb29 (cleanup): { - StorageDead(_7); -- drop(_5) -> [return: bb32, unwind terminate(cleanup)]; -+ bb30: { +- drop(_5) -> [return: bb31, unwind terminate(cleanup)]; ++ bb29: { + StorageLive(_3); + StorageLive(_4); + _3 = move _2; + goto -> bb4; } -- bb31 (cleanup): { +- bb30 (cleanup): { - StorageDead(_6); -- goto -> bb32; -+ bb31: { +- goto -> bb31; ++ bb30: { + StorageLive(_8); + StorageLive(_9); -+ StorageLive(_11); -+ StorageLive(_15); + _8 = move _2; + goto -> bb10; } -- bb32 (cleanup): { +- bb31 (cleanup): { - StorageDead(_5); +- goto -> bb32; ++ bb31: { ++ assert(const false, "coroutine resumed after panicking") -> [success: bb31, unwind continue]; + } + +- bb32 (cleanup): { +- StorageDead(_4); - goto -> bb33; + bb32: { -+ assert(const false, "coroutine resumed after panicking") -> [success: bb32, unwind continue]; ++ assert(const false, "coroutine resumed after completion") -> [success: bb32, unwind continue]; } - bb33 (cleanup): { -- StorageDead(_4); +- StorageDead(_3); - goto -> bb34; + bb33: { -+ assert(const false, "coroutine resumed after completion") -> [success: bb33, unwind continue]; - } - -- bb34 (cleanup): { -- StorageDead(_3); -- goto -> bb35; -+ bb34: { + unreachable; } -- bb35 (cleanup): { -- drop(_2) -> [return: bb36, unwind terminate(cleanup)]; +- bb34 (cleanup): { +- drop(_2) -> [return: bb35, unwind terminate(cleanup)]; - } - -- bb36 (cleanup): { -- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; +- bb35 (cleanup): { +- drop(_1) -> [return: bb36, unwind terminate(cleanup)]; - } - -- bb37 (cleanup): { +- bb36 (cleanup): { - resume; - } - -- bb38 (cleanup): { -- drop(_1) -> [return: bb37, unwind terminate(cleanup)]; -+ bb35: { -+ (((*_18) as variant#4).0: std::string::String) = move _2; +- bb37 (cleanup): { +- drop(_1) -> [return: bb36, unwind terminate(cleanup)]; ++ bb34: { ++ (((*_15) as variant#4).0: std::string::String) = move _2; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); + StorageLive(_6); -+ _6 = &(((*_18) as variant#4).0: std::string::String); -+ _5 = ::clone(move _6) -> [return: bb1, unwind: bb22]; ++ _6 = &(((*_15) as variant#4).0: std::string::String); ++ _5 = ::clone(move _6) -> [return: bb1, unwind: bb21]; } } diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff index 9823a48785a5b..0c09227c460d9 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff @@ -90,7 +90,7 @@ bb5: { StorageLive(_12); _12 = &(((*_7) as V2).0: i32); - _9 = &(*_12); + _9 = copy _12; StorageDead(_12); goto -> bb7; } diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff index e4e68483f2557..f84661447f129 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff @@ -90,7 +90,7 @@ bb5: { StorageLive(_12); _12 = &(((*_7) as V2).0: i32); - _9 = &(*_12); + _9 = copy _12; StorageDead(_12); goto -> bb7; } diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-abort.diff index a0e83265d31c5..829a1df596b99 100644 --- a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-abort.diff @@ -6,13 +6,12 @@ let mut _1: i32; let _2: (); let mut _3: &i32; - let _4: &i32; - let _5: (); + let _4: (); scope 1 { debug a => _1; - let _6: i32; + let _5: i32; scope 2 { - debug b => _6; + debug b => _5; } } @@ -21,27 +20,24 @@ _1 = const 0_i32; StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); + _3 = &_1; _2 = escape::(move _3) -> [return: bb1, unwind unreachable]; } bb1: { StorageDead(_3); - StorageDead(_4); StorageDead(_2); _1 = const 1_i32; - StorageLive(_5); - _5 = some_function() -> [return: bb2, unwind unreachable]; + StorageLive(_4); + _4 = some_function() -> [return: bb2, unwind unreachable]; } bb2: { - StorageDead(_5); - StorageLive(_6); - _6 = copy _1; + StorageDead(_4); + StorageLive(_5); + _5 = copy _1; _0 = const (); - StorageDead(_6); + StorageDead(_5); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff index 6dead031a9f6a..37ede922c9a35 100644 --- a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.panic-unwind.diff @@ -6,13 +6,12 @@ let mut _1: i32; let _2: (); let mut _3: &i32; - let _4: &i32; - let _5: (); + let _4: (); scope 1 { debug a => _1; - let _6: i32; + let _5: i32; scope 2 { - debug b => _6; + debug b => _5; } } @@ -21,27 +20,24 @@ _1 = const 0_i32; StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); + _3 = &_1; _2 = escape::(move _3) -> [return: bb1, unwind continue]; } bb1: { StorageDead(_3); - StorageDead(_4); StorageDead(_2); _1 = const 1_i32; - StorageLive(_5); - _5 = some_function() -> [return: bb2, unwind continue]; + StorageLive(_4); + _4 = some_function() -> [return: bb2, unwind continue]; } bb2: { - StorageDead(_5); - StorageLive(_6); - _6 = copy _1; + StorageDead(_4); + StorageLive(_5); + _5 = copy _1; _0 = const (); - StorageDead(_6); + StorageDead(_5); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff index fd9ef54fe775f..6a748d0580161 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff @@ -6,21 +6,20 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _10: &[u32]; - let _11: usize; - let mut _12: usize; - let mut _13: bool; - let mut _14: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _9: &[u32]; + let _10: usize; + let mut _11: usize; + let mut _12: bool; + let mut _13: &[u32; 3]; scope 1 { debug local => _1; - let _9: u32; + let _8: u32; scope 2 { - debug constant => _9; + debug constant => _8; } } @@ -28,48 +27,45 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _14 = const main::promoted[0]; - _4 = copy _14; - _3 = copy _4; + _13 = const main::promoted[0]; + _3 = copy _13; _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind unreachable]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = copy (*_2)[1 of 2]; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); + StorageLive(_8); StorageLive(_9); + _9 = const main::SLICE; StorageLive(_10); - _10 = const main::SLICE; - StorageLive(_11); - _11 = const 1_usize; -- _12 = PtrMetadata(copy _10); -- _13 = Lt(copy _11, copy _12); -- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable]; -+ _12 = const 3_usize; -+ _13 = const true; + _10 = const 1_usize; +- _11 = PtrMetadata(copy _9); +- _12 = Lt(copy _10, copy _11); +- assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb2, unwind unreachable]; ++ _11 = const 3_usize; ++ _12 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; } bb2: { -- _9 = copy (*_10)[_11]; -+ _9 = copy (*_10)[1 of 2]; - StorageDead(_11); +- _8 = copy (*_9)[_10]; ++ _8 = copy (*_9)[1 of 2]; StorageDead(_10); - _0 = const (); StorageDead(_9); + _0 = const (); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff index 1fec08c256201..9f2f5c610c735 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff @@ -6,21 +6,20 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _10: &[u32]; - let _11: usize; - let mut _12: usize; - let mut _13: bool; - let mut _14: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _9: &[u32]; + let _10: usize; + let mut _11: usize; + let mut _12: bool; + let mut _13: &[u32; 3]; scope 1 { debug local => _1; - let _9: u32; + let _8: u32; scope 2 { - debug constant => _9; + debug constant => _8; } } @@ -28,48 +27,45 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _14 = const main::promoted[0]; - _4 = copy _14; - _3 = copy _4; + _13 = const main::promoted[0]; + _3 = copy _13; _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind continue]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = copy (*_2)[1 of 2]; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); + StorageLive(_8); StorageLive(_9); + _9 = const main::SLICE; StorageLive(_10); - _10 = const main::SLICE; - StorageLive(_11); - _11 = const 1_usize; -- _12 = PtrMetadata(copy _10); -- _13 = Lt(copy _11, copy _12); -- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue]; -+ _12 = const 3_usize; -+ _13 = const true; + _10 = const 1_usize; +- _11 = PtrMetadata(copy _9); +- _12 = Lt(copy _10, copy _11); +- assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb2, unwind continue]; ++ _11 = const 3_usize; ++ _12 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; } bb2: { -- _9 = copy (*_10)[_11]; -+ _9 = copy (*_10)[1 of 2]; - StorageDead(_11); +- _8 = copy (*_9)[_10]; ++ _8 = copy (*_9)[1 of 2]; StorageDead(_10); - _0 = const (); StorageDead(_9); + _0 = const (); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff index fd9ef54fe775f..6a748d0580161 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff @@ -6,21 +6,20 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _10: &[u32]; - let _11: usize; - let mut _12: usize; - let mut _13: bool; - let mut _14: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _9: &[u32]; + let _10: usize; + let mut _11: usize; + let mut _12: bool; + let mut _13: &[u32; 3]; scope 1 { debug local => _1; - let _9: u32; + let _8: u32; scope 2 { - debug constant => _9; + debug constant => _8; } } @@ -28,48 +27,45 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _14 = const main::promoted[0]; - _4 = copy _14; - _3 = copy _4; + _13 = const main::promoted[0]; + _3 = copy _13; _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind unreachable]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = copy (*_2)[1 of 2]; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); + StorageLive(_8); StorageLive(_9); + _9 = const main::SLICE; StorageLive(_10); - _10 = const main::SLICE; - StorageLive(_11); - _11 = const 1_usize; -- _12 = PtrMetadata(copy _10); -- _13 = Lt(copy _11, copy _12); -- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable]; -+ _12 = const 3_usize; -+ _13 = const true; + _10 = const 1_usize; +- _11 = PtrMetadata(copy _9); +- _12 = Lt(copy _10, copy _11); +- assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb2, unwind unreachable]; ++ _11 = const 3_usize; ++ _12 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; } bb2: { -- _9 = copy (*_10)[_11]; -+ _9 = copy (*_10)[1 of 2]; - StorageDead(_11); +- _8 = copy (*_9)[_10]; ++ _8 = copy (*_9)[1 of 2]; StorageDead(_10); - _0 = const (); StorageDead(_9); + _0 = const (); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff index 1fec08c256201..9f2f5c610c735 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff @@ -6,21 +6,20 @@ let _1: u32; let mut _2: &[u32]; let mut _3: &[u32; 3]; - let _4: &[u32; 3]; - let _5: [u32; 3]; - let _6: usize; - let mut _7: usize; - let mut _8: bool; - let mut _10: &[u32]; - let _11: usize; - let mut _12: usize; - let mut _13: bool; - let mut _14: &[u32; 3]; + let _4: [u32; 3]; + let _5: usize; + let mut _6: usize; + let mut _7: bool; + let mut _9: &[u32]; + let _10: usize; + let mut _11: usize; + let mut _12: bool; + let mut _13: &[u32; 3]; scope 1 { debug local => _1; - let _9: u32; + let _8: u32; scope 2 { - debug constant => _9; + debug constant => _8; } } @@ -28,48 +27,45 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _14 = const main::promoted[0]; - _4 = copy _14; - _3 = copy _4; + _13 = const main::promoted[0]; + _3 = copy _13; _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); - StorageLive(_6); - _6 = const 1_usize; -- _7 = PtrMetadata(copy _2); -- _8 = Lt(copy _6, copy _7); -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; -+ _7 = const 3_usize; -+ _8 = const true; + StorageLive(_5); + _5 = const 1_usize; +- _6 = PtrMetadata(copy _2); +- _7 = Lt(copy _5, copy _6); +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb1, unwind continue]; ++ _6 = const 3_usize; ++ _7 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { -- _1 = copy (*_2)[_6]; +- _1 = copy (*_2)[_5]; + _1 = copy (*_2)[1 of 2]; - StorageDead(_6); - StorageDead(_4); + StorageDead(_5); StorageDead(_2); + StorageLive(_8); StorageLive(_9); + _9 = const main::SLICE; StorageLive(_10); - _10 = const main::SLICE; - StorageLive(_11); - _11 = const 1_usize; -- _12 = PtrMetadata(copy _10); -- _13 = Lt(copy _11, copy _12); -- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue]; -+ _12 = const 3_usize; -+ _13 = const true; + _10 = const 1_usize; +- _11 = PtrMetadata(copy _9); +- _12 = Lt(copy _10, copy _11); +- assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb2, unwind continue]; ++ _11 = const 3_usize; ++ _12 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; } bb2: { -- _9 = copy (*_10)[_11]; -+ _9 = copy (*_10)[1 of 2]; - StorageDead(_11); +- _8 = copy (*_9)[_10]; ++ _8 = copy (*_9)[1 of 2]; StorageDead(_10); - _0 = const (); StorageDead(_9); + _0 = const (); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dead-store-elimination/ref.dead_first.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/ref.dead_first.DeadStoreElimination-initial.diff index 2a793e24990ae..043f1863732b9 100644 --- a/tests/mir-opt/dead-store-elimination/ref.dead_first.DeadStoreElimination-initial.diff +++ b/tests/mir-opt/dead-store-elimination/ref.dead_first.DeadStoreElimination-initial.diff @@ -6,7 +6,6 @@ let mut _0: &i32; let mut _2: &i32; let mut _3: &i32; - let _4: &i32; scope 1 { debug a => _2; } @@ -16,13 +15,10 @@ - _2 = &((*_1).2: i32); + // DBG: _2 = &((*_1).2: i32); StorageLive(_3); - StorageLive(_4); - _4 = &((*_1).0: i32); - _3 = &(*_4); + _3 = &((*_1).0: i32); _2 = move _3; StorageDead(_3); - StorageDead(_4); - _0 = &(*_2); + _0 = copy _2; StorageDead(_2); return; } diff --git a/tests/mir-opt/dead-store-elimination/ref.rs b/tests/mir-opt/dead-store-elimination/ref.rs index 2d3200edab9f6..40672bf51999d 100644 --- a/tests/mir-opt/dead-store-elimination/ref.rs +++ b/tests/mir-opt/dead-store-elimination/ref.rs @@ -23,8 +23,8 @@ pub fn dead_first(v: &Foo) -> &i32 { // CHECK: bb0: // CHECK: DBG: [[var_a]] = &((*_1).2: i32) // CHECK: [[tmp_4:_[0-9]+]] = &((*_1).0: i32) - // CHECK: [[tmp_3:_[0-9]+]] = &(*[[tmp_4]]) - // CHECK: [[var_a]] = move [[tmp_3]] + // CHECK: [[tmp_3:_[0-9]+]] = move [[tmp_4]] + // CHECK: _0 = copy [[tmp_3]] let mut a = &v.c; a = &v.a; a diff --git a/tests/mir-opt/debuginfo/single_use_consts.invalid_debuginfo.SingleUseConsts.diff b/tests/mir-opt/debuginfo/single_use_consts.invalid_debuginfo.SingleUseConsts.diff index 09e9f26546a85..9afc511ef1c8f 100644 --- a/tests/mir-opt/debuginfo/single_use_consts.invalid_debuginfo.SingleUseConsts.diff +++ b/tests/mir-opt/debuginfo/single_use_consts.invalid_debuginfo.SingleUseConsts.diff @@ -7,21 +7,19 @@ scope 1 (inlined foo) { let _2: (); let mut _3: &isize; - let _4: &isize; - let _5: isize; - let mut _6: &isize; + let _4: isize; + let mut _5: &isize; scope 2 (inlined bar) { -- debug x => _4; +- debug x => _3; + debug x => const foo::promoted[0]; - let _7: isize; - let mut _9: &isize; - let _10: &isize; + let _6: isize; + let mut _8: &isize; scope 3 { -- debug a => _7; +- debug a => _6; + debug a => const 1_isize; - let mut _8: &isize; + let mut _7: &isize; scope 4 { -- debug z => _4; +- debug z => _3; + debug z => const foo::promoted[0]; } } @@ -30,17 +28,17 @@ bb0: { StorageLive(_1); - StorageLive(_4); -- _4 = const foo::promoted[0]; + StorageLive(_3); +- _3 = const foo::promoted[0]; + nop; - StorageLive(_7); -- _7 = const 1_isize; -- // DBG: _4 = &_7; + StorageLive(_6); +- _6 = const 1_isize; +- // DBG: _3 = &_6; + nop; - StorageDead(_7); + StorageDead(_6); + StorageDead(_3); - _1 = const (); + nop; - StorageDead(_4); StorageDead(_1); _0 = const (); return; diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index ebf10f94313d5..a7763f13ee721 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -4,28 +4,27 @@ fn test() -> () { let mut _0: (); let _1: &std::boxed::Box<()>; - let _2: &std::boxed::Box<()>; - let _3: std::boxed::Box<()>; - let mut _4: (); - let mut _7: *const (); - let mut _9: *const [()]; - let mut _10: std::boxed::Box<()>; - let mut _11: *const (); - let mut _14: usize; + let _2: std::boxed::Box<()>; + let mut _3: (); + let mut _6: *const (); + let mut _8: *const [()]; + let mut _9: std::boxed::Box<()>; + let mut _10: *const (); + let mut _13: usize; scope 1 { debug vp_ctx => _1; - let _5: *const (); + let _4: *const (); scope 2 { - debug slf => _5; - let _6: *const [()]; + debug slf => _4; + let _5: *const [()]; scope 3 { - debug bytes => _6; - let _8: *mut (); + debug bytes => _5; + let _7: *mut (); scope 4 { - debug _x => _8; + debug _x => _7; } scope 9 (inlined foo) { - let mut _15: *const [()]; + let mut _14: *const [()]; } } scope 7 (inlined slice_from_raw_parts::<()>) { @@ -35,8 +34,8 @@ } } scope 5 (inlined Box::<()>::new) { - let mut _12: *mut (); - let mut _13: *mut u8; + let mut _11: *mut (); + let mut _12: *mut u8; scope 6 { } } @@ -45,60 +44,57 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); -- _4 = (); -+ _4 = const (); +- _3 = (); ++ _3 = const (); + StorageLive(_11); StorageLive(_12); - StorageLive(_13); -- _13 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; -+ _13 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; +- _12 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; ++ _12 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; } bb1: { - StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } bb2: { - _12 = copy _13 as *mut () (PtrToPtr); -- (*_12) = move _4; -+ (*_12) = const (); - _3 = copy _13 as std::boxed::Box<()> (Transmute); - StorageDead(_13); + _11 = copy _12 as *mut () (PtrToPtr); +- (*_11) = move _3; ++ (*_11) = const (); + _2 = copy _12 as std::boxed::Box<()> (Transmute); StorageDead(_12); - StorageDead(_4); - _2 = &_3; - _1 = &(*_2); - StorageDead(_2); + StorageDead(_11); + StorageDead(_3); + _1 = &_2; + StorageLive(_4); + _9 = no_retag copy (*_1); + _10 = copy (_9.0: std::ptr::Unique<()>) as *const () (BoxDerefTransmute); + _4 = &raw const (*_10); StorageLive(_5); - _10 = no_retag copy (*_1); - _11 = copy (_10.0: std::boxed::BoxRaw<()>) as *const () (BoxDerefTransmute); - _5 = &raw const (*_11); StorageLive(_6); + _6 = copy _4; + StorageLive(_13); + _13 = const 1_usize; +- _5 = *const [()] from (copy _6, copy _13); ++ _5 = *const [()] from (copy _4, const 1_usize); + StorageDead(_13); + StorageDead(_6); StorageLive(_7); - _7 = copy _5; + StorageLive(_8); + _8 = copy _5; StorageLive(_14); - _14 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _14); -+ _6 = *const [()] from (copy _5, const 1_usize); +- _14 = copy _8; +- _7 = copy _8 as *mut () (PtrToPtr); ++ _14 = copy _5; ++ _7 = copy _4 as *mut () (PtrToPtr); StorageDead(_14); - StorageDead(_7); - StorageLive(_8); - StorageLive(_9); - _9 = copy _6; - StorageLive(_15); -- _15 = copy _9; -- _8 = copy _9 as *mut () (PtrToPtr); -+ _15 = copy _6; -+ _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_15); - StorageDead(_9); - _0 = const (); StorageDead(_8); - StorageDead(_6); + _0 = const (); + StorageDead(_7); StorageDead(_5); - drop(_3) -> [return: bb1, unwind unreachable]; + StorageDead(_4); + drop(_2) -> [return: bb1, unwind unreachable]; } + } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff index 503d931849567..3c25ebe031c6d 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff @@ -4,28 +4,27 @@ fn test() -> () { let mut _0: (); let _1: &std::boxed::Box<()>; - let _2: &std::boxed::Box<()>; - let _3: std::boxed::Box<()>; - let mut _4: (); - let mut _7: *const (); - let mut _9: *const [()]; - let mut _10: std::boxed::Box<()>; - let mut _11: *const (); - let mut _12: usize; + let _2: std::boxed::Box<()>; + let mut _3: (); + let mut _6: *const (); + let mut _8: *const [()]; + let mut _9: std::boxed::Box<()>; + let mut _10: *const (); + let mut _11: usize; scope 1 { debug vp_ctx => _1; - let _5: *const (); + let _4: *const (); scope 2 { - debug slf => _5; - let _6: *const [()]; + debug slf => _4; + let _5: *const [()]; scope 3 { - debug bytes => _6; - let _8: *mut (); + debug bytes => _5; + let _7: *mut (); scope 4 { - debug _x => _8; + debug _x => _7; } scope 7 (inlined foo) { - let mut _13: *const [()]; + let mut _12: *const [()]; } } scope 5 (inlined slice_from_raw_parts::<()>) { @@ -39,50 +38,47 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); -- _4 = (); -- _3 = Box::<()>::new(move _4) -> [return: bb1, unwind continue]; -+ _4 = const (); -+ _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; +- _3 = (); +- _2 = Box::<()>::new(move _3) -> [return: bb1, unwind continue]; ++ _3 = const (); ++ _2 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } bb1: { - StorageDead(_4); - _2 = &_3; - _1 = &(*_2); - StorageDead(_2); + StorageDead(_3); + _1 = &_2; + StorageLive(_4); + _9 = no_retag copy (*_1); + _10 = copy (_9.0: std::ptr::Unique<()>) as *const () (BoxDerefTransmute); + _4 = &raw const (*_10); StorageLive(_5); - _10 = no_retag copy (*_1); - _11 = copy (_10.0: std::boxed::BoxRaw<()>) as *const () (BoxDerefTransmute); - _5 = &raw const (*_11); StorageLive(_6); + _6 = copy _4; + StorageLive(_11); + _11 = const 1_usize; +- _5 = *const [()] from (copy _6, copy _11); ++ _5 = *const [()] from (copy _4, const 1_usize); + StorageDead(_11); + StorageDead(_6); StorageLive(_7); - _7 = copy _5; + StorageLive(_8); + _8 = copy _5; StorageLive(_12); - _12 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _12); -+ _6 = *const [()] from (copy _5, const 1_usize); +- _12 = copy _8; +- _7 = copy _8 as *mut () (PtrToPtr); ++ _12 = copy _5; ++ _7 = copy _4 as *mut () (PtrToPtr); StorageDead(_12); - StorageDead(_7); - StorageLive(_8); - StorageLive(_9); - _9 = copy _6; - StorageLive(_13); -- _13 = copy _9; -- _8 = copy _9 as *mut () (PtrToPtr); -+ _13 = copy _6; -+ _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_13); - StorageDead(_9); - _0 = const (); StorageDead(_8); - StorageDead(_6); + _0 = const (); + StorageDead(_7); StorageDead(_5); - drop(_3) -> [return: bb2, unwind: bb3]; + StorageDead(_4); + drop(_2) -> [return: bb2, unwind: bb3]; } bb2: { - StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 888454e6eb5a9..2a51fe05cc528 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -4,28 +4,27 @@ fn test() -> () { let mut _0: (); let _1: &std::boxed::Box<()>; - let _2: &std::boxed::Box<()>; - let _3: std::boxed::Box<()>; - let mut _4: (); - let mut _7: *const (); - let mut _9: *const [()]; - let mut _10: std::boxed::Box<()>; - let mut _11: *const (); - let mut _14: usize; + let _2: std::boxed::Box<()>; + let mut _3: (); + let mut _6: *const (); + let mut _8: *const [()]; + let mut _9: std::boxed::Box<()>; + let mut _10: *const (); + let mut _13: usize; scope 1 { debug vp_ctx => _1; - let _5: *const (); + let _4: *const (); scope 2 { - debug slf => _5; - let _6: *const [()]; + debug slf => _4; + let _5: *const [()]; scope 3 { - debug bytes => _6; - let _8: *mut (); + debug bytes => _5; + let _7: *mut (); scope 4 { - debug _x => _8; + debug _x => _7; } scope 9 (inlined foo) { - let mut _15: *const [()]; + let mut _14: *const [()]; } } scope 7 (inlined slice_from_raw_parts::<()>) { @@ -35,8 +34,8 @@ } } scope 5 (inlined Box::<()>::new) { - let mut _12: *mut (); - let mut _13: *mut u8; + let mut _11: *mut (); + let mut _12: *mut u8; scope 6 { } } @@ -45,60 +44,57 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); -- _4 = (); -+ _4 = const (); +- _3 = (); ++ _3 = const (); + StorageLive(_11); StorageLive(_12); - StorageLive(_13); -- _13 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; -+ _13 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; +- _12 = boxed::box_new_uninit(const <() as std::mem::SizedTypeProperties>::LAYOUT) -> [return: bb2, unwind unreachable]; ++ _12 = boxed::box_new_uninit(const Layout {{ size: 0_usize, align: std::mem::Alignment {{ _inner_repr_trick: mem::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> [return: bb2, unwind unreachable]; } bb1: { - StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } bb2: { - _12 = copy _13 as *mut () (PtrToPtr); -- (*_12) = move _4; -+ (*_12) = const (); - _3 = copy _13 as std::boxed::Box<()> (Transmute); - StorageDead(_13); + _11 = copy _12 as *mut () (PtrToPtr); +- (*_11) = move _3; ++ (*_11) = const (); + _2 = copy _12 as std::boxed::Box<()> (Transmute); StorageDead(_12); - StorageDead(_4); - _2 = &_3; - _1 = &(*_2); - StorageDead(_2); + StorageDead(_11); + StorageDead(_3); + _1 = &_2; + StorageLive(_4); + _9 = no_retag copy (*_1); + _10 = copy (_9.0: std::ptr::Unique<()>) as *const () (BoxDerefTransmute); + _4 = &raw const (*_10); StorageLive(_5); - _10 = no_retag copy (*_1); - _11 = copy (_10.0: std::boxed::BoxRaw<()>) as *const () (BoxDerefTransmute); - _5 = &raw const (*_11); StorageLive(_6); + _6 = copy _4; + StorageLive(_13); + _13 = const 1_usize; +- _5 = *const [()] from (copy _6, copy _13); ++ _5 = *const [()] from (copy _4, const 1_usize); + StorageDead(_13); + StorageDead(_6); StorageLive(_7); - _7 = copy _5; + StorageLive(_8); + _8 = copy _5; StorageLive(_14); - _14 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _14); -+ _6 = *const [()] from (copy _5, const 1_usize); +- _14 = copy _8; +- _7 = copy _8 as *mut () (PtrToPtr); ++ _14 = copy _5; ++ _7 = copy _4 as *mut () (PtrToPtr); StorageDead(_14); - StorageDead(_7); - StorageLive(_8); - StorageLive(_9); - _9 = copy _6; - StorageLive(_15); -- _15 = copy _9; -- _8 = copy _9 as *mut () (PtrToPtr); -+ _15 = copy _6; -+ _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_15); - StorageDead(_9); - _0 = const (); StorageDead(_8); - StorageDead(_6); + _0 = const (); + StorageDead(_7); StorageDead(_5); - drop(_3) -> [return: bb1, unwind unreachable]; + StorageDead(_4); + drop(_2) -> [return: bb1, unwind unreachable]; } + } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff index 503d931849567..3c25ebe031c6d 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff @@ -4,28 +4,27 @@ fn test() -> () { let mut _0: (); let _1: &std::boxed::Box<()>; - let _2: &std::boxed::Box<()>; - let _3: std::boxed::Box<()>; - let mut _4: (); - let mut _7: *const (); - let mut _9: *const [()]; - let mut _10: std::boxed::Box<()>; - let mut _11: *const (); - let mut _12: usize; + let _2: std::boxed::Box<()>; + let mut _3: (); + let mut _6: *const (); + let mut _8: *const [()]; + let mut _9: std::boxed::Box<()>; + let mut _10: *const (); + let mut _11: usize; scope 1 { debug vp_ctx => _1; - let _5: *const (); + let _4: *const (); scope 2 { - debug slf => _5; - let _6: *const [()]; + debug slf => _4; + let _5: *const [()]; scope 3 { - debug bytes => _6; - let _8: *mut (); + debug bytes => _5; + let _7: *mut (); scope 4 { - debug _x => _8; + debug _x => _7; } scope 7 (inlined foo) { - let mut _13: *const [()]; + let mut _12: *const [()]; } } scope 5 (inlined slice_from_raw_parts::<()>) { @@ -39,50 +38,47 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - StorageLive(_4); -- _4 = (); -- _3 = Box::<()>::new(move _4) -> [return: bb1, unwind continue]; -+ _4 = const (); -+ _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; +- _3 = (); +- _2 = Box::<()>::new(move _3) -> [return: bb1, unwind continue]; ++ _3 = const (); ++ _2 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } bb1: { - StorageDead(_4); - _2 = &_3; - _1 = &(*_2); - StorageDead(_2); + StorageDead(_3); + _1 = &_2; + StorageLive(_4); + _9 = no_retag copy (*_1); + _10 = copy (_9.0: std::ptr::Unique<()>) as *const () (BoxDerefTransmute); + _4 = &raw const (*_10); StorageLive(_5); - _10 = no_retag copy (*_1); - _11 = copy (_10.0: std::boxed::BoxRaw<()>) as *const () (BoxDerefTransmute); - _5 = &raw const (*_11); StorageLive(_6); + _6 = copy _4; + StorageLive(_11); + _11 = const 1_usize; +- _5 = *const [()] from (copy _6, copy _11); ++ _5 = *const [()] from (copy _4, const 1_usize); + StorageDead(_11); + StorageDead(_6); StorageLive(_7); - _7 = copy _5; + StorageLive(_8); + _8 = copy _5; StorageLive(_12); - _12 = const 1_usize; -- _6 = *const [()] from (copy _7, copy _12); -+ _6 = *const [()] from (copy _5, const 1_usize); +- _12 = copy _8; +- _7 = copy _8 as *mut () (PtrToPtr); ++ _12 = copy _5; ++ _7 = copy _4 as *mut () (PtrToPtr); StorageDead(_12); - StorageDead(_7); - StorageLive(_8); - StorageLive(_9); - _9 = copy _6; - StorageLive(_13); -- _13 = copy _9; -- _8 = copy _9 as *mut () (PtrToPtr); -+ _13 = copy _6; -+ _8 = copy _5 as *mut () (PtrToPtr); - StorageDead(_13); - StorageDead(_9); - _0 = const (); StorageDead(_8); - StorageDead(_6); + _0 = const (); + StorageDead(_7); StorageDead(_5); - drop(_3) -> [return: bb2, unwind: bb3]; + StorageDead(_4); + drop(_2) -> [return: bb2, unwind: bb3]; } bb2: { - StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff index 69c74d11d17e3..ace7950ebfa33 100644 --- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff @@ -23,32 +23,28 @@ let _22: !; let mut _23: core::panicking::AssertKind; let mut _24: &*const u8; - let _25: &*const u8; - let mut _26: &*const u8; - let _27: &*const u8; - let mut _28: std::option::Option>; - let mut _30: &str; + let mut _25: &*const u8; + let mut _26: std::option::Option>; + let mut _28: &str; + let _29: (); + let mut _30: &[u8]; let _31: (); - let mut _32: &[u8]; - let _33: (); - let mut _34: (&*const u8, &*const u8); - let mut _35: &*const u8; - let _36: *const u8; - let mut _37: &str; - let mut _38: &*const u8; - let _39: *const u8; - let mut _40: &[u8]; - let mut _43: bool; - let mut _44: *const u8; - let mut _45: *const u8; - let mut _46: !; - let _48: !; - let mut _49: core::panicking::AssertKind; - let mut _50: &*const u8; - let _51: &*const u8; - let mut _52: &*const u8; - let _53: &*const u8; - let mut _54: std::option::Option>; + let mut _32: (&*const u8, &*const u8); + let mut _33: &*const u8; + let _34: *const u8; + let mut _35: &str; + let mut _36: &*const u8; + let _37: *const u8; + let mut _38: &[u8]; + let mut _41: bool; + let mut _42: *const u8; + let mut _43: *const u8; + let mut _44: !; + let _46: !; + let mut _47: core::panicking::AssertKind; + let mut _48: &*const u8; + let mut _49: &*const u8; + let mut _50: std::option::Option>; scope 1 { debug s => _1; let _4: &str; @@ -56,7 +52,7 @@ debug t => _4; let _15: &*const u8; let _16: &*const u8; - let _29: &[u8]; + let _27: &[u8]; scope 3 { debug left_val => _15; debug right_val => _16; @@ -66,15 +62,15 @@ } } scope 5 { - debug u => _29; - let _41: &*const u8; - let _42: &*const u8; + debug u => _27; + let _39: &*const u8; + let _40: &*const u8; scope 6 { - debug left_val => _41; - debug right_val => _42; - let _47: core::panicking::AssertKind; + debug left_val => _39; + debug right_val => _40; + let _45: core::panicking::AssertKind; scope 7 { - debug kind => _47; + debug kind => _45; } } } @@ -169,16 +165,18 @@ StorageDead(_10); StorageDead(_8); StorageDead(_7); + StorageLive(_27); + StorageLive(_28); +- _28 = copy _1; +- _27 = move _28 as &[u8] (Transmute); ++ _28 = const "my favourite slice"; ++ _27 = const "my favourite slice" as &[u8] (Transmute); + StorageDead(_28); StorageLive(_29); StorageLive(_30); - _30 = &(*_1); - _29 = move _30 as &[u8] (Transmute); - StorageDead(_30); - StorageLive(_31); - StorageLive(_32); - _32 = copy _29; -- _31 = opaque::<&[u8]>(move _32) -> [return: bb7, unwind unreachable]; -+ _31 = opaque::<&[u8]>(copy _29) -> [return: bb7, unwind unreachable]; + _30 = copy _27; +- _29 = opaque::<&[u8]>(move _30) -> [return: bb7, unwind unreachable]; ++ _29 = opaque::<&[u8]>(copy _27) -> [return: bb7, unwind unreachable]; } bb6: { @@ -192,116 +190,108 @@ - _23 = move _21; + _23 = const core::panicking::AssertKind::Eq; StorageLive(_24); +- _24 = &(*_15); ++ _24 = &(*_9); StorageLive(_25); -- _25 = &(*_15); -+ _25 = &(*_9); - _24 = &(*_25); +- _25 = &(*_16); ++ _25 = &(*_12); StorageLive(_26); - StorageLive(_27); -- _27 = &(*_16); -+ _27 = &(*_12); - _26 = &(*_27); - StorageLive(_28); -- _28 = Option::>::None; -- _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind unreachable; -+ _28 = const Option::>::None; -+ _22 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _26, const Option::>::None) -> unwind unreachable; +- _26 = Option::>::None; +- _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _25, move _26) -> unwind unreachable; ++ _26 = const Option::>::None; ++ _22 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _25, const Option::>::None) -> unwind unreachable; } bb7: { - StorageDead(_32); - StorageDead(_31); - StorageLive(_33); - StorageLive(_34); -- StorageLive(_35); + StorageDead(_30); + StorageDead(_29); + StorageLive(_31); + StorageLive(_32); +- StorageLive(_33); + nop; - StorageLive(_36); - StorageLive(_37); - _37 = &(*_1); - _36 = core::str::::as_ptr(move _37) -> [return: bb8, unwind unreachable]; + StorageLive(_34); + StorageLive(_35); + _35 = &(*_1); + _34 = core::str::::as_ptr(move _35) -> [return: bb8, unwind unreachable]; } bb8: { - StorageDead(_37); - _35 = &_36; -- StorageLive(_38); + StorageDead(_35); + _33 = &_34; +- StorageLive(_36); + nop; - StorageLive(_39); - StorageLive(_40); - _40 = &(*_29); - _39 = core::slice::::as_ptr(move _40) -> [return: bb9, unwind unreachable]; + StorageLive(_37); + StorageLive(_38); + _38 = &(*_27); + _37 = core::slice::::as_ptr(move _38) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_40); - _38 = &_39; -- _34 = (move _35, move _38); -- StorageDead(_38); -- StorageDead(_35); -+ _34 = (copy _35, copy _38); + StorageDead(_38); + _36 = &_37; +- _32 = (move _33, move _36); +- StorageDead(_36); +- StorageDead(_33); ++ _32 = (copy _33, copy _36); + nop; + nop; + StorageLive(_39); +- _39 = copy (_32.0: &*const u8); ++ _39 = copy _33; + StorageLive(_40); +- _40 = copy (_32.1: &*const u8); ++ _40 = copy _36; StorageLive(_41); -- _41 = copy (_34.0: &*const u8); -+ _41 = copy _35; StorageLive(_42); -- _42 = copy (_34.1: &*const u8); -+ _42 = copy _38; +- _42 = copy (*_39); ++ _42 = copy _34; StorageLive(_43); - StorageLive(_44); -- _44 = copy (*_41); -+ _44 = copy _36; - StorageLive(_45); -- _45 = copy (*_42); -- _43 = Eq(move _44, move _45); -+ _45 = copy _39; -+ _43 = Eq(copy _36, copy _39); - switchInt(move _43) -> [0: bb11, otherwise: bb10]; +- _43 = copy (*_40); +- _41 = Eq(move _42, move _43); ++ _43 = copy _37; ++ _41 = Eq(copy _34, copy _37); + switchInt(move _41) -> [0: bb11, otherwise: bb10]; } bb10: { - StorageDead(_45); - StorageDead(_44); - _33 = const (); StorageDead(_43); StorageDead(_42); + _31 = const (); StorageDead(_41); + StorageDead(_40); StorageDead(_39); - StorageDead(_36); + StorageDead(_37); StorageDead(_34); - StorageDead(_33); + StorageDead(_32); + StorageDead(_31); _0 = const (); - StorageDead(_29); + StorageDead(_27); StorageDead(_4); StorageDead(_1); return; } bb11: { - StorageDead(_45); - StorageDead(_44); + StorageDead(_43); + StorageDead(_42); + StorageLive(_45); +- _45 = core::panicking::AssertKind::Eq; ++ _45 = const core::panicking::AssertKind::Eq; + StorageLive(_46); StorageLive(_47); -- _47 = core::panicking::AssertKind::Eq; +- _47 = move _45; + _47 = const core::panicking::AssertKind::Eq; StorageLive(_48); +- _48 = &(*_39); ++ _48 = &(*_33); StorageLive(_49); -- _49 = move _47; -+ _49 = const core::panicking::AssertKind::Eq; +- _49 = &(*_40); ++ _49 = &(*_36); StorageLive(_50); - StorageLive(_51); -- _51 = &(*_41); -+ _51 = &(*_35); - _50 = &(*_51); - StorageLive(_52); - StorageLive(_53); -- _53 = &(*_42); -+ _53 = &(*_38); - _52 = &(*_53); - StorageLive(_54); -- _54 = Option::>::None; -- _48 = core::panicking::assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind unreachable; -+ _54 = const Option::>::None; -+ _48 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _50, move _52, const Option::>::None) -> unwind unreachable; +- _50 = Option::>::None; +- _46 = core::panicking::assert_failed::<*const u8, *const u8>(move _47, move _48, move _49, move _50) -> unwind unreachable; ++ _50 = const Option::>::None; ++ _46 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _48, move _49, const Option::>::None) -> unwind unreachable; } } diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff index 4a27c577303d7..208c02c5582e8 100644 --- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff @@ -23,32 +23,28 @@ let _22: !; let mut _23: core::panicking::AssertKind; let mut _24: &*const u8; - let _25: &*const u8; - let mut _26: &*const u8; - let _27: &*const u8; - let mut _28: std::option::Option>; - let mut _30: &str; + let mut _25: &*const u8; + let mut _26: std::option::Option>; + let mut _28: &str; + let _29: (); + let mut _30: &[u8]; let _31: (); - let mut _32: &[u8]; - let _33: (); - let mut _34: (&*const u8, &*const u8); - let mut _35: &*const u8; - let _36: *const u8; - let mut _37: &str; - let mut _38: &*const u8; - let _39: *const u8; - let mut _40: &[u8]; - let mut _43: bool; - let mut _44: *const u8; - let mut _45: *const u8; - let mut _46: !; - let _48: !; - let mut _49: core::panicking::AssertKind; - let mut _50: &*const u8; - let _51: &*const u8; - let mut _52: &*const u8; - let _53: &*const u8; - let mut _54: std::option::Option>; + let mut _32: (&*const u8, &*const u8); + let mut _33: &*const u8; + let _34: *const u8; + let mut _35: &str; + let mut _36: &*const u8; + let _37: *const u8; + let mut _38: &[u8]; + let mut _41: bool; + let mut _42: *const u8; + let mut _43: *const u8; + let mut _44: !; + let _46: !; + let mut _47: core::panicking::AssertKind; + let mut _48: &*const u8; + let mut _49: &*const u8; + let mut _50: std::option::Option>; scope 1 { debug s => _1; let _4: &str; @@ -56,7 +52,7 @@ debug t => _4; let _15: &*const u8; let _16: &*const u8; - let _29: &[u8]; + let _27: &[u8]; scope 3 { debug left_val => _15; debug right_val => _16; @@ -66,15 +62,15 @@ } } scope 5 { - debug u => _29; - let _41: &*const u8; - let _42: &*const u8; + debug u => _27; + let _39: &*const u8; + let _40: &*const u8; scope 6 { - debug left_val => _41; - debug right_val => _42; - let _47: core::panicking::AssertKind; + debug left_val => _39; + debug right_val => _40; + let _45: core::panicking::AssertKind; scope 7 { - debug kind => _47; + debug kind => _45; } } } @@ -169,16 +165,18 @@ StorageDead(_10); StorageDead(_8); StorageDead(_7); + StorageLive(_27); + StorageLive(_28); +- _28 = copy _1; +- _27 = move _28 as &[u8] (Transmute); ++ _28 = const "my favourite slice"; ++ _27 = const "my favourite slice" as &[u8] (Transmute); + StorageDead(_28); StorageLive(_29); StorageLive(_30); - _30 = &(*_1); - _29 = move _30 as &[u8] (Transmute); - StorageDead(_30); - StorageLive(_31); - StorageLive(_32); - _32 = copy _29; -- _31 = opaque::<&[u8]>(move _32) -> [return: bb7, unwind continue]; -+ _31 = opaque::<&[u8]>(copy _29) -> [return: bb7, unwind continue]; + _30 = copy _27; +- _29 = opaque::<&[u8]>(move _30) -> [return: bb7, unwind continue]; ++ _29 = opaque::<&[u8]>(copy _27) -> [return: bb7, unwind continue]; } bb6: { @@ -192,116 +190,108 @@ - _23 = move _21; + _23 = const core::panicking::AssertKind::Eq; StorageLive(_24); +- _24 = &(*_15); ++ _24 = &(*_9); StorageLive(_25); -- _25 = &(*_15); -+ _25 = &(*_9); - _24 = &(*_25); +- _25 = &(*_16); ++ _25 = &(*_12); StorageLive(_26); - StorageLive(_27); -- _27 = &(*_16); -+ _27 = &(*_12); - _26 = &(*_27); - StorageLive(_28); -- _28 = Option::>::None; -- _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind continue; -+ _28 = const Option::>::None; -+ _22 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _26, const Option::>::None) -> unwind continue; +- _26 = Option::>::None; +- _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _25, move _26) -> unwind continue; ++ _26 = const Option::>::None; ++ _22 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _25, const Option::>::None) -> unwind continue; } bb7: { - StorageDead(_32); - StorageDead(_31); - StorageLive(_33); - StorageLive(_34); -- StorageLive(_35); + StorageDead(_30); + StorageDead(_29); + StorageLive(_31); + StorageLive(_32); +- StorageLive(_33); + nop; - StorageLive(_36); - StorageLive(_37); - _37 = &(*_1); - _36 = core::str::::as_ptr(move _37) -> [return: bb8, unwind continue]; + StorageLive(_34); + StorageLive(_35); + _35 = &(*_1); + _34 = core::str::::as_ptr(move _35) -> [return: bb8, unwind continue]; } bb8: { - StorageDead(_37); - _35 = &_36; -- StorageLive(_38); + StorageDead(_35); + _33 = &_34; +- StorageLive(_36); + nop; - StorageLive(_39); - StorageLive(_40); - _40 = &(*_29); - _39 = core::slice::::as_ptr(move _40) -> [return: bb9, unwind continue]; + StorageLive(_37); + StorageLive(_38); + _38 = &(*_27); + _37 = core::slice::::as_ptr(move _38) -> [return: bb9, unwind continue]; } bb9: { - StorageDead(_40); - _38 = &_39; -- _34 = (move _35, move _38); -- StorageDead(_38); -- StorageDead(_35); -+ _34 = (copy _35, copy _38); + StorageDead(_38); + _36 = &_37; +- _32 = (move _33, move _36); +- StorageDead(_36); +- StorageDead(_33); ++ _32 = (copy _33, copy _36); + nop; + nop; + StorageLive(_39); +- _39 = copy (_32.0: &*const u8); ++ _39 = copy _33; + StorageLive(_40); +- _40 = copy (_32.1: &*const u8); ++ _40 = copy _36; StorageLive(_41); -- _41 = copy (_34.0: &*const u8); -+ _41 = copy _35; StorageLive(_42); -- _42 = copy (_34.1: &*const u8); -+ _42 = copy _38; +- _42 = copy (*_39); ++ _42 = copy _34; StorageLive(_43); - StorageLive(_44); -- _44 = copy (*_41); -+ _44 = copy _36; - StorageLive(_45); -- _45 = copy (*_42); -- _43 = Eq(move _44, move _45); -+ _45 = copy _39; -+ _43 = Eq(copy _36, copy _39); - switchInt(move _43) -> [0: bb11, otherwise: bb10]; +- _43 = copy (*_40); +- _41 = Eq(move _42, move _43); ++ _43 = copy _37; ++ _41 = Eq(copy _34, copy _37); + switchInt(move _41) -> [0: bb11, otherwise: bb10]; } bb10: { - StorageDead(_45); - StorageDead(_44); - _33 = const (); StorageDead(_43); StorageDead(_42); + _31 = const (); StorageDead(_41); + StorageDead(_40); StorageDead(_39); - StorageDead(_36); + StorageDead(_37); StorageDead(_34); - StorageDead(_33); + StorageDead(_32); + StorageDead(_31); _0 = const (); - StorageDead(_29); + StorageDead(_27); StorageDead(_4); StorageDead(_1); return; } bb11: { - StorageDead(_45); - StorageDead(_44); + StorageDead(_43); + StorageDead(_42); + StorageLive(_45); +- _45 = core::panicking::AssertKind::Eq; ++ _45 = const core::panicking::AssertKind::Eq; + StorageLive(_46); StorageLive(_47); -- _47 = core::panicking::AssertKind::Eq; +- _47 = move _45; + _47 = const core::panicking::AssertKind::Eq; StorageLive(_48); +- _48 = &(*_39); ++ _48 = &(*_33); StorageLive(_49); -- _49 = move _47; -+ _49 = const core::panicking::AssertKind::Eq; +- _49 = &(*_40); ++ _49 = &(*_36); StorageLive(_50); - StorageLive(_51); -- _51 = &(*_41); -+ _51 = &(*_35); - _50 = &(*_51); - StorageLive(_52); - StorageLive(_53); -- _53 = &(*_42); -+ _53 = &(*_38); - _52 = &(*_53); - StorageLive(_54); -- _54 = Option::>::None; -- _48 = core::panicking::assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind continue; -+ _54 = const Option::>::None; -+ _48 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _50, move _52, const Option::>::None) -> unwind continue; +- _50 = Option::>::None; +- _46 = core::panicking::assert_failed::<*const u8, *const u8>(move _47, move _48, move _49, move _50) -> unwind continue; ++ _50 = const Option::>::None; ++ _46 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _48, move _49, const Option::>::None) -> unwind continue; } } diff --git a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff index 43cd8ba7809a2..cf362720fa96a 100644 --- a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff @@ -7,50 +7,48 @@ let mut _2: *const dyn std::marker::Send; let _3: &dyn std::marker::Send; let mut _4: &i32; - let _5: &i32; - let _6: i32; - let mut _8: *const dyn std::marker::Send; - let _9: &dyn std::marker::Send; - let mut _10: &i32; - let _11: &i32; - let _12: i32; - let _13: (); - let mut _14: bool; + let _5: i32; + let mut _7: *const dyn std::marker::Send; + let _8: &dyn std::marker::Send; + let mut _9: &i32; + let _10: i32; + let _11: (); + let mut _12: bool; + let mut _13: *const dyn std::marker::Send; + let mut _14: *const dyn std::marker::Send; let mut _15: *const dyn std::marker::Send; - let mut _16: *const dyn std::marker::Send; - let mut _17: *const dyn std::marker::Send; - let _18: (); - let mut _19: bool; + let _16: (); + let mut _17: bool; + let mut _18: *const dyn std::marker::Send; + let mut _19: *const dyn std::marker::Send; let mut _20: *const dyn std::marker::Send; - let mut _21: *const dyn std::marker::Send; - let mut _22: *const dyn std::marker::Send; - let _23: (); - let mut _24: bool; + let _21: (); + let mut _22: bool; + let mut _23: *const dyn std::marker::Send; + let mut _24: *const dyn std::marker::Send; let mut _25: *const dyn std::marker::Send; - let mut _26: *const dyn std::marker::Send; - let mut _27: *const dyn std::marker::Send; - let _28: (); - let mut _29: bool; + let _26: (); + let mut _27: bool; + let mut _28: *const dyn std::marker::Send; + let mut _29: *const dyn std::marker::Send; let mut _30: *const dyn std::marker::Send; - let mut _31: *const dyn std::marker::Send; - let mut _32: *const dyn std::marker::Send; - let _33: (); - let mut _34: bool; + let _31: (); + let mut _32: bool; + let mut _33: *const dyn std::marker::Send; + let mut _34: *const dyn std::marker::Send; let mut _35: *const dyn std::marker::Send; - let mut _36: *const dyn std::marker::Send; - let mut _37: *const dyn std::marker::Send; - let _38: (); - let mut _39: bool; + let _36: (); + let mut _37: bool; + let mut _38: *const dyn std::marker::Send; + let mut _39: *const dyn std::marker::Send; let mut _40: *const dyn std::marker::Send; - let mut _41: *const dyn std::marker::Send; - let mut _42: *const dyn std::marker::Send; - let mut _44: &i32; + let mut _42: &i32; scope 1 { debug a => _1; - let _7: *const dyn std::marker::Send; - let mut _43: &i32; + let _6: *const dyn std::marker::Send; + let mut _41: &i32; scope 2 { - debug b => _7; + debug b => _6; } } @@ -60,10 +58,8 @@ + nop; StorageLive(_3); StorageLive(_4); - StorageLive(_5); - _44 = const wide_ptr_provenance::promoted[1]; - _5 = &(*_44); - _4 = &(*_5); + _42 = const wide_ptr_provenance::promoted[1]; + _4 = &(*_42); _3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_4); _2 = &raw const (*_3); @@ -71,160 +67,156 @@ - StorageDead(_2); + _1 = copy _2; + nop; - StorageDead(_5); StorageDead(_3); - StorageLive(_7); -- StorageLive(_8); + StorageLive(_6); +- StorageLive(_7); + nop; + StorageLive(_8); StorageLive(_9); - StorageLive(_10); - StorageLive(_11); - _43 = const wide_ptr_provenance::promoted[0]; - _11 = &(*_43); - _10 = &(*_11); - _9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); - StorageDead(_10); - _8 = &raw const (*_9); -- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -- StorageDead(_8); -+ _7 = copy _8; -+ nop; - StorageDead(_11); + _41 = const wide_ptr_provenance::promoted[0]; + _9 = &(*_41); + _8 = move _9 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_9); + _7 = &raw const (*_8); +- _6 = move _7 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); +- StorageDead(_7); ++ _6 = copy _7; ++ nop; + StorageDead(_8); + StorageLive(_11); + StorageLive(_12); StorageLive(_13); +- _13 = copy _1; ++ _13 = copy _2; StorageLive(_14); StorageLive(_15); -- _15 = copy _1; -+ _15 = copy _2; - StorageLive(_16); - StorageLive(_17); -- _17 = copy _7; -- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _17 = copy _8; -+ _16 = copy _8; - StorageDead(_17); -- _14 = Eq(move _15, move _16); -+ _14 = Eq(copy _2, copy _8); - StorageDead(_16); +- _15 = copy _6; +- _14 = move _15 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _15 = copy _7; ++ _14 = copy _7; StorageDead(_15); - _13 = opaque::(move _14) -> [return: bb1, unwind unreachable]; +- _12 = Eq(move _13, move _14); ++ _12 = Eq(copy _2, copy _7); + StorageDead(_14); + StorageDead(_13); + _11 = opaque::(move _12) -> [return: bb1, unwind unreachable]; } bb1: { - StorageDead(_14); - StorageDead(_13); + StorageDead(_12); + StorageDead(_11); + StorageLive(_16); + StorageLive(_17); StorageLive(_18); +- _18 = copy _1; ++ _18 = copy _2; StorageLive(_19); StorageLive(_20); -- _20 = copy _1; -+ _20 = copy _2; - StorageLive(_21); - StorageLive(_22); -- _22 = copy _7; -- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _22 = copy _8; -+ _21 = copy _8; - StorageDead(_22); -- _19 = Ne(move _20, move _21); -+ _19 = Ne(copy _2, copy _8); - StorageDead(_21); +- _20 = copy _6; +- _19 = move _20 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _20 = copy _7; ++ _19 = copy _7; StorageDead(_20); - _18 = opaque::(move _19) -> [return: bb2, unwind unreachable]; +- _17 = Ne(move _18, move _19); ++ _17 = Ne(copy _2, copy _7); + StorageDead(_19); + StorageDead(_18); + _16 = opaque::(move _17) -> [return: bb2, unwind unreachable]; } bb2: { - StorageDead(_19); - StorageDead(_18); + StorageDead(_17); + StorageDead(_16); + StorageLive(_21); + StorageLive(_22); StorageLive(_23); +- _23 = copy _1; ++ _23 = copy _2; StorageLive(_24); StorageLive(_25); -- _25 = copy _1; -+ _25 = copy _2; - StorageLive(_26); - StorageLive(_27); -- _27 = copy _7; -- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _27 = copy _8; -+ _26 = copy _8; - StorageDead(_27); -- _24 = Lt(move _25, move _26); -+ _24 = Lt(copy _2, copy _8); - StorageDead(_26); +- _25 = copy _6; +- _24 = move _25 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _25 = copy _7; ++ _24 = copy _7; StorageDead(_25); - _23 = opaque::(move _24) -> [return: bb3, unwind unreachable]; +- _22 = Lt(move _23, move _24); ++ _22 = Lt(copy _2, copy _7); + StorageDead(_24); + StorageDead(_23); + _21 = opaque::(move _22) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_24); - StorageDead(_23); + StorageDead(_22); + StorageDead(_21); + StorageLive(_26); + StorageLive(_27); StorageLive(_28); +- _28 = copy _1; ++ _28 = copy _2; StorageLive(_29); StorageLive(_30); -- _30 = copy _1; -+ _30 = copy _2; - StorageLive(_31); - StorageLive(_32); -- _32 = copy _7; -- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _32 = copy _8; -+ _31 = copy _8; - StorageDead(_32); -- _29 = Le(move _30, move _31); -+ _29 = Le(copy _2, copy _8); - StorageDead(_31); +- _30 = copy _6; +- _29 = move _30 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _30 = copy _7; ++ _29 = copy _7; StorageDead(_30); - _28 = opaque::(move _29) -> [return: bb4, unwind unreachable]; +- _27 = Le(move _28, move _29); ++ _27 = Le(copy _2, copy _7); + StorageDead(_29); + StorageDead(_28); + _26 = opaque::(move _27) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_29); - StorageDead(_28); + StorageDead(_27); + StorageDead(_26); + StorageLive(_31); + StorageLive(_32); StorageLive(_33); +- _33 = copy _1; ++ _33 = copy _2; StorageLive(_34); StorageLive(_35); -- _35 = copy _1; -+ _35 = copy _2; - StorageLive(_36); - StorageLive(_37); -- _37 = copy _7; -- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _37 = copy _8; -+ _36 = copy _8; - StorageDead(_37); -- _34 = Gt(move _35, move _36); -+ _34 = Gt(copy _2, copy _8); - StorageDead(_36); +- _35 = copy _6; +- _34 = move _35 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _35 = copy _7; ++ _34 = copy _7; StorageDead(_35); - _33 = opaque::(move _34) -> [return: bb5, unwind unreachable]; +- _32 = Gt(move _33, move _34); ++ _32 = Gt(copy _2, copy _7); + StorageDead(_34); + StorageDead(_33); + _31 = opaque::(move _32) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_34); - StorageDead(_33); + StorageDead(_32); + StorageDead(_31); + StorageLive(_36); + StorageLive(_37); StorageLive(_38); +- _38 = copy _1; ++ _38 = copy _2; StorageLive(_39); StorageLive(_40); -- _40 = copy _1; -+ _40 = copy _2; - StorageLive(_41); - StorageLive(_42); -- _42 = copy _7; -- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _42 = copy _8; -+ _41 = copy _8; - StorageDead(_42); -- _39 = Ge(move _40, move _41); -+ _39 = Ge(copy _2, copy _8); - StorageDead(_41); +- _40 = copy _6; +- _39 = move _40 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _40 = copy _7; ++ _39 = copy _7; StorageDead(_40); - _38 = opaque::(move _39) -> [return: bb6, unwind unreachable]; +- _37 = Ge(move _38, move _39); ++ _37 = Ge(copy _2, copy _7); + StorageDead(_39); + StorageDead(_38); + _36 = opaque::(move _37) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_39); - StorageDead(_38); + StorageDead(_37); + StorageDead(_36); _0 = const (); - StorageDead(_7); + StorageDead(_6); StorageDead(_1); return; } diff --git a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff index 49cca20153bd4..65a69b0400cd9 100644 --- a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff @@ -7,50 +7,48 @@ let mut _2: *const dyn std::marker::Send; let _3: &dyn std::marker::Send; let mut _4: &i32; - let _5: &i32; - let _6: i32; - let mut _8: *const dyn std::marker::Send; - let _9: &dyn std::marker::Send; - let mut _10: &i32; - let _11: &i32; - let _12: i32; - let _13: (); - let mut _14: bool; + let _5: i32; + let mut _7: *const dyn std::marker::Send; + let _8: &dyn std::marker::Send; + let mut _9: &i32; + let _10: i32; + let _11: (); + let mut _12: bool; + let mut _13: *const dyn std::marker::Send; + let mut _14: *const dyn std::marker::Send; let mut _15: *const dyn std::marker::Send; - let mut _16: *const dyn std::marker::Send; - let mut _17: *const dyn std::marker::Send; - let _18: (); - let mut _19: bool; + let _16: (); + let mut _17: bool; + let mut _18: *const dyn std::marker::Send; + let mut _19: *const dyn std::marker::Send; let mut _20: *const dyn std::marker::Send; - let mut _21: *const dyn std::marker::Send; - let mut _22: *const dyn std::marker::Send; - let _23: (); - let mut _24: bool; + let _21: (); + let mut _22: bool; + let mut _23: *const dyn std::marker::Send; + let mut _24: *const dyn std::marker::Send; let mut _25: *const dyn std::marker::Send; - let mut _26: *const dyn std::marker::Send; - let mut _27: *const dyn std::marker::Send; - let _28: (); - let mut _29: bool; + let _26: (); + let mut _27: bool; + let mut _28: *const dyn std::marker::Send; + let mut _29: *const dyn std::marker::Send; let mut _30: *const dyn std::marker::Send; - let mut _31: *const dyn std::marker::Send; - let mut _32: *const dyn std::marker::Send; - let _33: (); - let mut _34: bool; + let _31: (); + let mut _32: bool; + let mut _33: *const dyn std::marker::Send; + let mut _34: *const dyn std::marker::Send; let mut _35: *const dyn std::marker::Send; - let mut _36: *const dyn std::marker::Send; - let mut _37: *const dyn std::marker::Send; - let _38: (); - let mut _39: bool; + let _36: (); + let mut _37: bool; + let mut _38: *const dyn std::marker::Send; + let mut _39: *const dyn std::marker::Send; let mut _40: *const dyn std::marker::Send; - let mut _41: *const dyn std::marker::Send; - let mut _42: *const dyn std::marker::Send; - let mut _44: &i32; + let mut _42: &i32; scope 1 { debug a => _1; - let _7: *const dyn std::marker::Send; - let mut _43: &i32; + let _6: *const dyn std::marker::Send; + let mut _41: &i32; scope 2 { - debug b => _7; + debug b => _6; } } @@ -60,10 +58,8 @@ + nop; StorageLive(_3); StorageLive(_4); - StorageLive(_5); - _44 = const wide_ptr_provenance::promoted[1]; - _5 = &(*_44); - _4 = &(*_5); + _42 = const wide_ptr_provenance::promoted[1]; + _4 = &(*_42); _3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_4); _2 = &raw const (*_3); @@ -71,160 +67,156 @@ - StorageDead(_2); + _1 = copy _2; + nop; - StorageDead(_5); StorageDead(_3); - StorageLive(_7); -- StorageLive(_8); + StorageLive(_6); +- StorageLive(_7); + nop; + StorageLive(_8); StorageLive(_9); - StorageLive(_10); - StorageLive(_11); - _43 = const wide_ptr_provenance::promoted[0]; - _11 = &(*_43); - _10 = &(*_11); - _9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); - StorageDead(_10); - _8 = &raw const (*_9); -- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -- StorageDead(_8); -+ _7 = copy _8; -+ nop; - StorageDead(_11); + _41 = const wide_ptr_provenance::promoted[0]; + _9 = &(*_41); + _8 = move _9 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_9); + _7 = &raw const (*_8); +- _6 = move _7 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); +- StorageDead(_7); ++ _6 = copy _7; ++ nop; + StorageDead(_8); + StorageLive(_11); + StorageLive(_12); StorageLive(_13); +- _13 = copy _1; ++ _13 = copy _2; StorageLive(_14); StorageLive(_15); -- _15 = copy _1; -+ _15 = copy _2; - StorageLive(_16); - StorageLive(_17); -- _17 = copy _7; -- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _17 = copy _8; -+ _16 = copy _8; - StorageDead(_17); -- _14 = Eq(move _15, move _16); -+ _14 = Eq(copy _2, copy _8); - StorageDead(_16); +- _15 = copy _6; +- _14 = move _15 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _15 = copy _7; ++ _14 = copy _7; StorageDead(_15); - _13 = opaque::(move _14) -> [return: bb1, unwind continue]; +- _12 = Eq(move _13, move _14); ++ _12 = Eq(copy _2, copy _7); + StorageDead(_14); + StorageDead(_13); + _11 = opaque::(move _12) -> [return: bb1, unwind continue]; } bb1: { - StorageDead(_14); - StorageDead(_13); + StorageDead(_12); + StorageDead(_11); + StorageLive(_16); + StorageLive(_17); StorageLive(_18); +- _18 = copy _1; ++ _18 = copy _2; StorageLive(_19); StorageLive(_20); -- _20 = copy _1; -+ _20 = copy _2; - StorageLive(_21); - StorageLive(_22); -- _22 = copy _7; -- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _22 = copy _8; -+ _21 = copy _8; - StorageDead(_22); -- _19 = Ne(move _20, move _21); -+ _19 = Ne(copy _2, copy _8); - StorageDead(_21); +- _20 = copy _6; +- _19 = move _20 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _20 = copy _7; ++ _19 = copy _7; StorageDead(_20); - _18 = opaque::(move _19) -> [return: bb2, unwind continue]; +- _17 = Ne(move _18, move _19); ++ _17 = Ne(copy _2, copy _7); + StorageDead(_19); + StorageDead(_18); + _16 = opaque::(move _17) -> [return: bb2, unwind continue]; } bb2: { - StorageDead(_19); - StorageDead(_18); + StorageDead(_17); + StorageDead(_16); + StorageLive(_21); + StorageLive(_22); StorageLive(_23); +- _23 = copy _1; ++ _23 = copy _2; StorageLive(_24); StorageLive(_25); -- _25 = copy _1; -+ _25 = copy _2; - StorageLive(_26); - StorageLive(_27); -- _27 = copy _7; -- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _27 = copy _8; -+ _26 = copy _8; - StorageDead(_27); -- _24 = Lt(move _25, move _26); -+ _24 = Lt(copy _2, copy _8); - StorageDead(_26); +- _25 = copy _6; +- _24 = move _25 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _25 = copy _7; ++ _24 = copy _7; StorageDead(_25); - _23 = opaque::(move _24) -> [return: bb3, unwind continue]; +- _22 = Lt(move _23, move _24); ++ _22 = Lt(copy _2, copy _7); + StorageDead(_24); + StorageDead(_23); + _21 = opaque::(move _22) -> [return: bb3, unwind continue]; } bb3: { - StorageDead(_24); - StorageDead(_23); + StorageDead(_22); + StorageDead(_21); + StorageLive(_26); + StorageLive(_27); StorageLive(_28); +- _28 = copy _1; ++ _28 = copy _2; StorageLive(_29); StorageLive(_30); -- _30 = copy _1; -+ _30 = copy _2; - StorageLive(_31); - StorageLive(_32); -- _32 = copy _7; -- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _32 = copy _8; -+ _31 = copy _8; - StorageDead(_32); -- _29 = Le(move _30, move _31); -+ _29 = Le(copy _2, copy _8); - StorageDead(_31); +- _30 = copy _6; +- _29 = move _30 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _30 = copy _7; ++ _29 = copy _7; StorageDead(_30); - _28 = opaque::(move _29) -> [return: bb4, unwind continue]; +- _27 = Le(move _28, move _29); ++ _27 = Le(copy _2, copy _7); + StorageDead(_29); + StorageDead(_28); + _26 = opaque::(move _27) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_29); - StorageDead(_28); + StorageDead(_27); + StorageDead(_26); + StorageLive(_31); + StorageLive(_32); StorageLive(_33); +- _33 = copy _1; ++ _33 = copy _2; StorageLive(_34); StorageLive(_35); -- _35 = copy _1; -+ _35 = copy _2; - StorageLive(_36); - StorageLive(_37); -- _37 = copy _7; -- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _37 = copy _8; -+ _36 = copy _8; - StorageDead(_37); -- _34 = Gt(move _35, move _36); -+ _34 = Gt(copy _2, copy _8); - StorageDead(_36); +- _35 = copy _6; +- _34 = move _35 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _35 = copy _7; ++ _34 = copy _7; StorageDead(_35); - _33 = opaque::(move _34) -> [return: bb5, unwind continue]; +- _32 = Gt(move _33, move _34); ++ _32 = Gt(copy _2, copy _7); + StorageDead(_34); + StorageDead(_33); + _31 = opaque::(move _32) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_34); - StorageDead(_33); + StorageDead(_32); + StorageDead(_31); + StorageLive(_36); + StorageLive(_37); StorageLive(_38); +- _38 = copy _1; ++ _38 = copy _2; StorageLive(_39); StorageLive(_40); -- _40 = copy _1; -+ _40 = copy _2; - StorageLive(_41); - StorageLive(_42); -- _42 = copy _7; -- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _42 = copy _8; -+ _41 = copy _8; - StorageDead(_42); -- _39 = Ge(move _40, move _41); -+ _39 = Ge(copy _2, copy _8); - StorageDead(_41); +- _40 = copy _6; +- _39 = move _40 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _40 = copy _7; ++ _39 = copy _7; StorageDead(_40); - _38 = opaque::(move _39) -> [return: bb6, unwind continue]; +- _37 = Ge(move _38, move _39); ++ _37 = Ge(copy _2, copy _7); + StorageDead(_39); + StorageDead(_38); + _36 = opaque::(move _37) -> [return: bb6, unwind continue]; } bb6: { - StorageDead(_39); - StorageDead(_38); + StorageDead(_37); + StorageDead(_36); _0 = const (); - StorageDead(_7); + StorageDead(_6); StorageDead(_1); return; } diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff index 0165136fda4ca..646d42cf0f9ee 100644 --- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff @@ -8,80 +8,76 @@ let mut _4: *const dyn std::marker::Send; let _5: &dyn std::marker::Send; let mut _6: &i32; - let _7: &i32; - let _8: usize; - let mut _9: bool; - let mut _11: *const dyn std::marker::Send; - let _12: &dyn std::marker::Send; - let mut _13: &i32; - let _14: &i32; - let _15: usize; + let _7: usize; + let mut _8: bool; + let mut _10: *const dyn std::marker::Send; + let _11: &dyn std::marker::Send; + let mut _12: &i32; + let _13: usize; + let mut _14: bool; + let _15: (); let mut _16: bool; - let _17: (); - let mut _18: bool; + let mut _17: *const dyn std::marker::Send; + let mut _18: *const dyn std::marker::Send; let mut _19: *const dyn std::marker::Send; - let mut _20: *const dyn std::marker::Send; - let mut _21: *const dyn std::marker::Send; - let _22: (); - let mut _23: bool; + let _20: (); + let mut _21: bool; + let mut _22: *const dyn std::marker::Send; + let mut _23: *const dyn std::marker::Send; let mut _24: *const dyn std::marker::Send; - let mut _25: *const dyn std::marker::Send; - let mut _26: *const dyn std::marker::Send; - let _27: (); - let mut _28: bool; + let _25: (); + let mut _26: bool; + let mut _27: *const dyn std::marker::Send; + let mut _28: *const dyn std::marker::Send; let mut _29: *const dyn std::marker::Send; - let mut _30: *const dyn std::marker::Send; - let mut _31: *const dyn std::marker::Send; - let _32: (); - let mut _33: bool; + let _30: (); + let mut _31: bool; + let mut _32: *const dyn std::marker::Send; + let mut _33: *const dyn std::marker::Send; let mut _34: *const dyn std::marker::Send; - let mut _35: *const dyn std::marker::Send; - let mut _36: *const dyn std::marker::Send; - let _37: (); - let mut _38: bool; + let _35: (); + let mut _36: bool; + let mut _37: *const dyn std::marker::Send; + let mut _38: *const dyn std::marker::Send; let mut _39: *const dyn std::marker::Send; - let mut _40: *const dyn std::marker::Send; - let mut _41: *const dyn std::marker::Send; - let _42: (); - let mut _43: bool; + let _40: (); + let mut _41: bool; + let mut _42: *const dyn std::marker::Send; + let mut _43: *const dyn std::marker::Send; let mut _44: *const dyn std::marker::Send; - let mut _45: *const dyn std::marker::Send; - let mut _46: *const dyn std::marker::Send; - let mut _47: &[i32; 2]; + let mut _45: &[i32; 2]; scope 1 { debug slice => _1; let _3: *const dyn std::marker::Send; scope 2 { debug a => _3; - let _10: *const dyn std::marker::Send; + let _9: *const dyn std::marker::Send; scope 3 { - debug b => _10; + debug b => _9; } } } bb0: { StorageLive(_1); - _47 = const wide_ptr_same_provenance::promoted[0]; - _1 = &(*_47); + _45 = const wide_ptr_same_provenance::promoted[0]; + _1 = &(*_45); StorageLive(_3); - StorageLive(_4); + nop; StorageLive(_5); StorageLive(_6); StorageLive(_7); - StorageLive(_8); - _8 = const 0_usize; -- _9 = Lt(copy _8, const 2_usize); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind unreachable]; -+ _9 = const true; + _7 = const 0_usize; +- _8 = Lt(copy _7, const 2_usize); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _7) -> [success: bb1, unwind unreachable]; ++ _8 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind unreachable]; } bb1: { -- _7 = &(*_1)[_8]; -+ _7 = &(*_1)[0 of 1]; - _6 = &(*_7); +- _6 = &(*_1)[_7]; ++ _6 = &(*_1)[0 of 1]; _5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_6); _4 = &raw const (*_5); @@ -89,171 +85,167 @@ - StorageDead(_4); + _3 = copy _4; + nop; - StorageDead(_8); StorageDead(_7); StorageDead(_5); - StorageLive(_10); -- StorageLive(_11); + StorageLive(_9); +- StorageLive(_10); + nop; + StorageLive(_11); StorageLive(_12); StorageLive(_13); - StorageLive(_14); - StorageLive(_15); - _15 = const 1_usize; -- _16 = Lt(copy _15, const 2_usize); -- assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind unreachable]; -+ _16 = const true; + _13 = const 1_usize; +- _14 = Lt(copy _13, const 2_usize); +- assert(move _14, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _13) -> [success: bb2, unwind unreachable]; ++ _14 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind unreachable]; } bb2: { -- _14 = &(*_1)[_15]; -+ _14 = &(*_1)[1 of 2]; - _13 = &(*_14); - _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); - StorageDead(_13); - _11 = &raw const (*_12); -- _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -- StorageDead(_11); -+ _10 = copy _11; -+ nop; - StorageDead(_15); - StorageDead(_14); +- _12 = &(*_1)[_13]; ++ _12 = &(*_1)[1 of 2]; + _11 = move _12 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_12); + _10 = &raw const (*_11); +- _9 = move _10 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); +- StorageDead(_10); ++ _9 = copy _10; ++ nop; + StorageDead(_13); + StorageDead(_11); + StorageLive(_15); + StorageLive(_16); StorageLive(_17); +- _17 = copy _3; ++ _17 = copy _4; StorageLive(_18); StorageLive(_19); -- _19 = copy _3; -+ _19 = copy _4; - StorageLive(_20); - StorageLive(_21); -- _21 = copy _10; -- _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _21 = copy _11; -+ _20 = copy _11; - StorageDead(_21); -- _18 = Eq(move _19, move _20); -+ _18 = Eq(copy _4, copy _11); - StorageDead(_20); +- _19 = copy _9; +- _18 = move _19 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _19 = copy _10; ++ _18 = copy _10; StorageDead(_19); - _17 = opaque::(move _18) -> [return: bb3, unwind unreachable]; +- _16 = Eq(move _17, move _18); ++ _16 = Eq(copy _4, copy _10); + StorageDead(_18); + StorageDead(_17); + _15 = opaque::(move _16) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_18); - StorageDead(_17); + StorageDead(_16); + StorageDead(_15); + StorageLive(_20); + StorageLive(_21); StorageLive(_22); +- _22 = copy _3; ++ _22 = copy _4; StorageLive(_23); StorageLive(_24); -- _24 = copy _3; -+ _24 = copy _4; - StorageLive(_25); - StorageLive(_26); -- _26 = copy _10; -- _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _26 = copy _11; -+ _25 = copy _11; - StorageDead(_26); -- _23 = Ne(move _24, move _25); -+ _23 = Ne(copy _4, copy _11); - StorageDead(_25); +- _24 = copy _9; +- _23 = move _24 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _24 = copy _10; ++ _23 = copy _10; StorageDead(_24); - _22 = opaque::(move _23) -> [return: bb4, unwind unreachable]; +- _21 = Ne(move _22, move _23); ++ _21 = Ne(copy _4, copy _10); + StorageDead(_23); + StorageDead(_22); + _20 = opaque::(move _21) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_23); - StorageDead(_22); + StorageDead(_21); + StorageDead(_20); + StorageLive(_25); + StorageLive(_26); StorageLive(_27); +- _27 = copy _3; ++ _27 = copy _4; StorageLive(_28); StorageLive(_29); -- _29 = copy _3; -+ _29 = copy _4; - StorageLive(_30); - StorageLive(_31); -- _31 = copy _10; -- _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _31 = copy _11; -+ _30 = copy _11; - StorageDead(_31); -- _28 = Lt(move _29, move _30); -+ _28 = Lt(copy _4, copy _11); - StorageDead(_30); +- _29 = copy _9; +- _28 = move _29 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _29 = copy _10; ++ _28 = copy _10; StorageDead(_29); - _27 = opaque::(move _28) -> [return: bb5, unwind unreachable]; +- _26 = Lt(move _27, move _28); ++ _26 = Lt(copy _4, copy _10); + StorageDead(_28); + StorageDead(_27); + _25 = opaque::(move _26) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_28); - StorageDead(_27); + StorageDead(_26); + StorageDead(_25); + StorageLive(_30); + StorageLive(_31); StorageLive(_32); +- _32 = copy _3; ++ _32 = copy _4; StorageLive(_33); StorageLive(_34); -- _34 = copy _3; -+ _34 = copy _4; - StorageLive(_35); - StorageLive(_36); -- _36 = copy _10; -- _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _36 = copy _11; -+ _35 = copy _11; - StorageDead(_36); -- _33 = Le(move _34, move _35); -+ _33 = Le(copy _4, copy _11); - StorageDead(_35); +- _34 = copy _9; +- _33 = move _34 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _34 = copy _10; ++ _33 = copy _10; StorageDead(_34); - _32 = opaque::(move _33) -> [return: bb6, unwind unreachable]; +- _31 = Le(move _32, move _33); ++ _31 = Le(copy _4, copy _10); + StorageDead(_33); + StorageDead(_32); + _30 = opaque::(move _31) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_33); - StorageDead(_32); + StorageDead(_31); + StorageDead(_30); + StorageLive(_35); + StorageLive(_36); StorageLive(_37); +- _37 = copy _3; ++ _37 = copy _4; StorageLive(_38); StorageLive(_39); -- _39 = copy _3; -+ _39 = copy _4; - StorageLive(_40); - StorageLive(_41); -- _41 = copy _10; -- _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _41 = copy _11; -+ _40 = copy _11; - StorageDead(_41); -- _38 = Gt(move _39, move _40); -+ _38 = Gt(copy _4, copy _11); - StorageDead(_40); +- _39 = copy _9; +- _38 = move _39 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _39 = copy _10; ++ _38 = copy _10; StorageDead(_39); - _37 = opaque::(move _38) -> [return: bb7, unwind unreachable]; +- _36 = Gt(move _37, move _38); ++ _36 = Gt(copy _4, copy _10); + StorageDead(_38); + StorageDead(_37); + _35 = opaque::(move _36) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_38); - StorageDead(_37); + StorageDead(_36); + StorageDead(_35); + StorageLive(_40); + StorageLive(_41); StorageLive(_42); +- _42 = copy _3; ++ _42 = copy _4; StorageLive(_43); StorageLive(_44); -- _44 = copy _3; -+ _44 = copy _4; - StorageLive(_45); - StorageLive(_46); -- _46 = copy _10; -- _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _46 = copy _11; -+ _45 = copy _11; - StorageDead(_46); -- _43 = Ge(move _44, move _45); -+ _43 = Ge(copy _4, copy _11); - StorageDead(_45); +- _44 = copy _9; +- _43 = move _44 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _44 = copy _10; ++ _43 = copy _10; StorageDead(_44); - _42 = opaque::(move _43) -> [return: bb8, unwind unreachable]; +- _41 = Ge(move _42, move _43); ++ _41 = Ge(copy _4, copy _10); + StorageDead(_43); + StorageDead(_42); + _40 = opaque::(move _41) -> [return: bb8, unwind unreachable]; } bb8: { - StorageDead(_43); - StorageDead(_42); + StorageDead(_41); + StorageDead(_40); _0 = const (); - StorageDead(_10); + StorageDead(_9); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff index bbaab46b47560..9fa88a39f280a 100644 --- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff @@ -8,80 +8,76 @@ let mut _4: *const dyn std::marker::Send; let _5: &dyn std::marker::Send; let mut _6: &i32; - let _7: &i32; - let _8: usize; - let mut _9: bool; - let mut _11: *const dyn std::marker::Send; - let _12: &dyn std::marker::Send; - let mut _13: &i32; - let _14: &i32; - let _15: usize; + let _7: usize; + let mut _8: bool; + let mut _10: *const dyn std::marker::Send; + let _11: &dyn std::marker::Send; + let mut _12: &i32; + let _13: usize; + let mut _14: bool; + let _15: (); let mut _16: bool; - let _17: (); - let mut _18: bool; + let mut _17: *const dyn std::marker::Send; + let mut _18: *const dyn std::marker::Send; let mut _19: *const dyn std::marker::Send; - let mut _20: *const dyn std::marker::Send; - let mut _21: *const dyn std::marker::Send; - let _22: (); - let mut _23: bool; + let _20: (); + let mut _21: bool; + let mut _22: *const dyn std::marker::Send; + let mut _23: *const dyn std::marker::Send; let mut _24: *const dyn std::marker::Send; - let mut _25: *const dyn std::marker::Send; - let mut _26: *const dyn std::marker::Send; - let _27: (); - let mut _28: bool; + let _25: (); + let mut _26: bool; + let mut _27: *const dyn std::marker::Send; + let mut _28: *const dyn std::marker::Send; let mut _29: *const dyn std::marker::Send; - let mut _30: *const dyn std::marker::Send; - let mut _31: *const dyn std::marker::Send; - let _32: (); - let mut _33: bool; + let _30: (); + let mut _31: bool; + let mut _32: *const dyn std::marker::Send; + let mut _33: *const dyn std::marker::Send; let mut _34: *const dyn std::marker::Send; - let mut _35: *const dyn std::marker::Send; - let mut _36: *const dyn std::marker::Send; - let _37: (); - let mut _38: bool; + let _35: (); + let mut _36: bool; + let mut _37: *const dyn std::marker::Send; + let mut _38: *const dyn std::marker::Send; let mut _39: *const dyn std::marker::Send; - let mut _40: *const dyn std::marker::Send; - let mut _41: *const dyn std::marker::Send; - let _42: (); - let mut _43: bool; + let _40: (); + let mut _41: bool; + let mut _42: *const dyn std::marker::Send; + let mut _43: *const dyn std::marker::Send; let mut _44: *const dyn std::marker::Send; - let mut _45: *const dyn std::marker::Send; - let mut _46: *const dyn std::marker::Send; - let mut _47: &[i32; 2]; + let mut _45: &[i32; 2]; scope 1 { debug slice => _1; let _3: *const dyn std::marker::Send; scope 2 { debug a => _3; - let _10: *const dyn std::marker::Send; + let _9: *const dyn std::marker::Send; scope 3 { - debug b => _10; + debug b => _9; } } } bb0: { StorageLive(_1); - _47 = const wide_ptr_same_provenance::promoted[0]; - _1 = &(*_47); + _45 = const wide_ptr_same_provenance::promoted[0]; + _1 = &(*_45); StorageLive(_3); - StorageLive(_4); + nop; StorageLive(_5); StorageLive(_6); StorageLive(_7); - StorageLive(_8); - _8 = const 0_usize; -- _9 = Lt(copy _8, const 2_usize); -- assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind continue]; -+ _9 = const true; + _7 = const 0_usize; +- _8 = Lt(copy _7, const 2_usize); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _7) -> [success: bb1, unwind continue]; ++ _8 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind continue]; } bb1: { -- _7 = &(*_1)[_8]; -+ _7 = &(*_1)[0 of 1]; - _6 = &(*_7); +- _6 = &(*_1)[_7]; ++ _6 = &(*_1)[0 of 1]; _5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_6); _4 = &raw const (*_5); @@ -89,171 +85,167 @@ - StorageDead(_4); + _3 = copy _4; + nop; - StorageDead(_8); StorageDead(_7); StorageDead(_5); - StorageLive(_10); -- StorageLive(_11); + StorageLive(_9); +- StorageLive(_10); + nop; + StorageLive(_11); StorageLive(_12); StorageLive(_13); - StorageLive(_14); - StorageLive(_15); - _15 = const 1_usize; -- _16 = Lt(copy _15, const 2_usize); -- assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind continue]; -+ _16 = const true; + _13 = const 1_usize; +- _14 = Lt(copy _13, const 2_usize); +- assert(move _14, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _13) -> [success: bb2, unwind continue]; ++ _14 = const true; + assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind continue]; } bb2: { -- _14 = &(*_1)[_15]; -+ _14 = &(*_1)[1 of 2]; - _13 = &(*_14); - _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); - StorageDead(_13); - _11 = &raw const (*_12); -- _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -- StorageDead(_11); -+ _10 = copy _11; -+ nop; - StorageDead(_15); - StorageDead(_14); +- _12 = &(*_1)[_13]; ++ _12 = &(*_1)[1 of 2]; + _11 = move _12 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_12); + _10 = &raw const (*_11); +- _9 = move _10 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); +- StorageDead(_10); ++ _9 = copy _10; ++ nop; + StorageDead(_13); + StorageDead(_11); + StorageLive(_15); + StorageLive(_16); StorageLive(_17); +- _17 = copy _3; ++ _17 = copy _4; StorageLive(_18); StorageLive(_19); -- _19 = copy _3; -+ _19 = copy _4; - StorageLive(_20); - StorageLive(_21); -- _21 = copy _10; -- _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _21 = copy _11; -+ _20 = copy _11; - StorageDead(_21); -- _18 = Eq(move _19, move _20); -+ _18 = Eq(copy _4, copy _11); - StorageDead(_20); +- _19 = copy _9; +- _18 = move _19 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _19 = copy _10; ++ _18 = copy _10; StorageDead(_19); - _17 = opaque::(move _18) -> [return: bb3, unwind continue]; +- _16 = Eq(move _17, move _18); ++ _16 = Eq(copy _4, copy _10); + StorageDead(_18); + StorageDead(_17); + _15 = opaque::(move _16) -> [return: bb3, unwind continue]; } bb3: { - StorageDead(_18); - StorageDead(_17); + StorageDead(_16); + StorageDead(_15); + StorageLive(_20); + StorageLive(_21); StorageLive(_22); +- _22 = copy _3; ++ _22 = copy _4; StorageLive(_23); StorageLive(_24); -- _24 = copy _3; -+ _24 = copy _4; - StorageLive(_25); - StorageLive(_26); -- _26 = copy _10; -- _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _26 = copy _11; -+ _25 = copy _11; - StorageDead(_26); -- _23 = Ne(move _24, move _25); -+ _23 = Ne(copy _4, copy _11); - StorageDead(_25); +- _24 = copy _9; +- _23 = move _24 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _24 = copy _10; ++ _23 = copy _10; StorageDead(_24); - _22 = opaque::(move _23) -> [return: bb4, unwind continue]; +- _21 = Ne(move _22, move _23); ++ _21 = Ne(copy _4, copy _10); + StorageDead(_23); + StorageDead(_22); + _20 = opaque::(move _21) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_23); - StorageDead(_22); + StorageDead(_21); + StorageDead(_20); + StorageLive(_25); + StorageLive(_26); StorageLive(_27); +- _27 = copy _3; ++ _27 = copy _4; StorageLive(_28); StorageLive(_29); -- _29 = copy _3; -+ _29 = copy _4; - StorageLive(_30); - StorageLive(_31); -- _31 = copy _10; -- _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _31 = copy _11; -+ _30 = copy _11; - StorageDead(_31); -- _28 = Lt(move _29, move _30); -+ _28 = Lt(copy _4, copy _11); - StorageDead(_30); +- _29 = copy _9; +- _28 = move _29 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _29 = copy _10; ++ _28 = copy _10; StorageDead(_29); - _27 = opaque::(move _28) -> [return: bb5, unwind continue]; +- _26 = Lt(move _27, move _28); ++ _26 = Lt(copy _4, copy _10); + StorageDead(_28); + StorageDead(_27); + _25 = opaque::(move _26) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_28); - StorageDead(_27); + StorageDead(_26); + StorageDead(_25); + StorageLive(_30); + StorageLive(_31); StorageLive(_32); +- _32 = copy _3; ++ _32 = copy _4; StorageLive(_33); StorageLive(_34); -- _34 = copy _3; -+ _34 = copy _4; - StorageLive(_35); - StorageLive(_36); -- _36 = copy _10; -- _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _36 = copy _11; -+ _35 = copy _11; - StorageDead(_36); -- _33 = Le(move _34, move _35); -+ _33 = Le(copy _4, copy _11); - StorageDead(_35); +- _34 = copy _9; +- _33 = move _34 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _34 = copy _10; ++ _33 = copy _10; StorageDead(_34); - _32 = opaque::(move _33) -> [return: bb6, unwind continue]; +- _31 = Le(move _32, move _33); ++ _31 = Le(copy _4, copy _10); + StorageDead(_33); + StorageDead(_32); + _30 = opaque::(move _31) -> [return: bb6, unwind continue]; } bb6: { - StorageDead(_33); - StorageDead(_32); + StorageDead(_31); + StorageDead(_30); + StorageLive(_35); + StorageLive(_36); StorageLive(_37); +- _37 = copy _3; ++ _37 = copy _4; StorageLive(_38); StorageLive(_39); -- _39 = copy _3; -+ _39 = copy _4; - StorageLive(_40); - StorageLive(_41); -- _41 = copy _10; -- _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _41 = copy _11; -+ _40 = copy _11; - StorageDead(_41); -- _38 = Gt(move _39, move _40); -+ _38 = Gt(copy _4, copy _11); - StorageDead(_40); +- _39 = copy _9; +- _38 = move _39 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _39 = copy _10; ++ _38 = copy _10; StorageDead(_39); - _37 = opaque::(move _38) -> [return: bb7, unwind continue]; +- _36 = Gt(move _37, move _38); ++ _36 = Gt(copy _4, copy _10); + StorageDead(_38); + StorageDead(_37); + _35 = opaque::(move _36) -> [return: bb7, unwind continue]; } bb7: { - StorageDead(_38); - StorageDead(_37); + StorageDead(_36); + StorageDead(_35); + StorageLive(_40); + StorageLive(_41); StorageLive(_42); +- _42 = copy _3; ++ _42 = copy _4; StorageLive(_43); StorageLive(_44); -- _44 = copy _3; -+ _44 = copy _4; - StorageLive(_45); - StorageLive(_46); -- _46 = copy _10; -- _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); -+ _46 = copy _11; -+ _45 = copy _11; - StorageDead(_46); -- _43 = Ge(move _44, move _45); -+ _43 = Ge(copy _4, copy _11); - StorageDead(_45); +- _44 = copy _9; +- _43 = move _44 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); ++ _44 = copy _10; ++ _43 = copy _10; StorageDead(_44); - _42 = opaque::(move _43) -> [return: bb8, unwind continue]; +- _41 = Ge(move _42, move _43); ++ _41 = Ge(copy _4, copy _10); + StorageDead(_43); + StorageDead(_42); + _40 = opaque::(move _41) -> [return: bb8, unwind continue]; } bb8: { - StorageDead(_43); - StorageDead(_42); + StorageDead(_41); + StorageDead(_40); _0 = const (); - StorageDead(_10); + StorageDead(_9); StorageDead(_3); StorageDead(_1); return; diff --git a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff index 9381c7c0af537..fc0ebd354bd64 100644 --- a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff +++ b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff @@ -6,20 +6,15 @@ let mut _0: AllCopy; let mut _2: i32; let mut _3: &i32; - let _4: &i32; - let mut _5: u64; - let mut _6: &u64; - let _7: &u64; - let mut _8: [i8; 3]; - let mut _9: &[i8; 3]; - let _10: &[i8; 3]; + let mut _4: u64; + let mut _5: &u64; + let mut _6: [i8; 3]; + let mut _7: &[i8; 3]; bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &((*_1).0: i32); - _3 = copy _4; + _3 = &((*_1).0: i32); - _2 = copy (*_3); + _2 = copy ((*_1).0: i32); goto -> bb1; @@ -27,36 +22,29 @@ bb1: { StorageDead(_3); + StorageLive(_4); StorageLive(_5); - StorageLive(_6); - StorageLive(_7); - _7 = &((*_1).1: u64); - _6 = copy _7; -- _5 = copy (*_6); -+ _5 = copy ((*_1).1: u64); + _5 = &((*_1).1: u64); +- _4 = copy (*_5); ++ _4 = copy ((*_1).1: u64); goto -> bb2; } bb2: { - StorageDead(_6); - StorageLive(_8); - StorageLive(_9); - StorageLive(_10); - _10 = &((*_1).2: [i8; 3]); - _9 = copy _10; -- _8 = copy (*_9); -+ _8 = copy ((*_1).2: [i8; 3]); + StorageDead(_5); + StorageLive(_6); + StorageLive(_7); + _7 = &((*_1).2: [i8; 3]); +- _6 = copy (*_7); ++ _6 = copy ((*_1).2: [i8; 3]); goto -> bb3; } bb3: { - StorageDead(_9); -- _0 = AllCopy { a: move _2, b: move _5, c: move _8 }; -+ _0 = copy (*_1); - StorageDead(_10); - StorageDead(_8); StorageDead(_7); - StorageDead(_5); +- _0 = AllCopy { a: move _2, b: move _4, c: move _6 }; ++ _0 = copy (*_1); + StorageDead(_6); StorageDead(_4); StorageDead(_2); return; diff --git a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff index c0e8622a5c43d..0b9d4ae601d58 100644 --- a/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.deref_nonssa_2.GVN.diff @@ -5,20 +5,19 @@ let mut _0: Single; let mut _1: Single; let mut _3: &Single; - let _4: &Single; - let mut _7: Single; - let mut _8: u8; + let mut _6: Single; + let mut _7: u8; scope 1 { debug a => _1; let _2: SingleRef<'_>; scope 2 { debug r => _2; - let _5: &Single; + let _4: &Single; scope 3 { - debug b => _5; - let _6: u8; + debug b => _4; + let _5: u8; scope 4 { - debug c => _6; + debug c => _5; } } } @@ -31,33 +30,30 @@ StorageLive(_2); - StorageLive(_3); + nop; - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); + _3 = &_1; - _2 = SingleRef::<'_>(move _3); - StorageDead(_3); + _2 = SingleRef::<'_>(copy _3); + nop; - StorageDead(_4); + StorageLive(_4); +- _4 = copy (_2.0: &Single); ++ _4 = copy _3; StorageLive(_5); -- _5 = copy (_2.0: &Single); -+ _5 = copy _3; +- _5 = copy ((*_4).0: u8); ++ _5 = copy ((*_3).0: u8); StorageLive(_6); -- _6 = copy ((*_5).0: u8); -+ _6 = copy ((*_3).0: u8); - StorageLive(_7); -- _7 = Single(const 1_u8); -- _1 = move _7; -+ _7 = const Single(1_u8); +- _6 = Single(const 1_u8); +- _1 = move _6; ++ _6 = const Single(1_u8); + _1 = const Single(1_u8); - StorageDead(_7); - StorageLive(_8); - _8 = copy _6; -- _0 = Single(move _8); -+ _0 = Single(copy _6); - StorageDead(_8); StorageDead(_6); + StorageLive(_7); + _7 = copy _5; +- _0 = Single(move _7); ++ _0 = Single(copy _5); + StorageDead(_7); StorageDead(_5); + StorageDead(_4); StorageDead(_2); StorageDead(_1); return; diff --git a/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-abort.diff b/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-abort.diff index c107eec9ee65b..df9a05b716d37 100644 --- a/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-abort.diff @@ -5,10 +5,10 @@ debug x => _1; debug y => _2; let mut _0: std::cmp::Ordering; - let _3: &i32; + let mut _3: &i32; let _4: usize; let mut _5: bool; - let _6: &i32; + let mut _6: &i32; let _7: usize; let mut _8: bool; scope 1 (inlined std::cmp::impls::::cmp) { @@ -17,6 +17,7 @@ } bb0: { + StorageLive(_3); StorageLive(_4); _4 = const 0_usize; - _5 = Lt(copy _4, const 1_usize); @@ -28,6 +29,7 @@ bb1: { - _3 = &_1[_4]; + _3 = &_1[0 of 1]; + StorageLive(_6); StorageLive(_7); _7 = const 0_usize; - _8 = Lt(copy _7, const 1_usize); @@ -48,6 +50,8 @@ _0 = Cmp(move _9, move _10); StorageDead(_10); StorageDead(_9); + StorageDead(_6); + StorageDead(_3); StorageDead(_7); StorageDead(_4); return; diff --git a/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-unwind.diff b/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-unwind.diff index 498df5adc1ef7..89031c71ce153 100644 --- a/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn_copy_constant_projection.compare_constant_index.GVN.panic-unwind.diff @@ -5,10 +5,10 @@ debug x => _1; debug y => _2; let mut _0: std::cmp::Ordering; - let _3: &i32; + let mut _3: &i32; let _4: usize; let mut _5: bool; - let _6: &i32; + let mut _6: &i32; let _7: usize; let mut _8: bool; scope 1 (inlined std::cmp::impls::::cmp) { @@ -17,6 +17,7 @@ } bb0: { + StorageLive(_3); StorageLive(_4); _4 = const 0_usize; - _5 = Lt(copy _4, const 1_usize); @@ -28,6 +29,7 @@ bb1: { - _3 = &_1[_4]; + _3 = &_1[0 of 1]; + StorageLive(_6); StorageLive(_7); _7 = const 0_usize; - _8 = Lt(copy _7, const 1_usize); @@ -48,6 +50,8 @@ _0 = Cmp(move _9, move _10); StorageDead(_10); StorageDead(_9); + StorageDead(_6); + StorageDead(_3); StorageDead(_7); StorageDead(_4); return; diff --git a/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff index 4e491782c8cd0..198618adf0750 100644 --- a/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff +++ b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff @@ -5,45 +5,45 @@ debug val => _1; let mut _0: Value; let _2: &Value; - let _3: &Value; - let mut _4: &Value; - let mut _6: !; - let mut _8: isize; - let mut _9: !; - let mut _10: (); - let mut _12: i32; - let _13: (); - let mut _14: bool; - let mut _15: !; - let mut _16: Value; + let mut _3: &Value; + let mut _5: !; + let mut _7: isize; + let mut _8: !; + let mut _9: (); + let mut _11: i32; + let _12: (); + let mut _13: bool; + let mut _14: !; + let mut _15: Value; scope 1 { - debug val_alias => _3; - let mut _5: bool; + debug val_alias => _2; + let mut _4: bool; scope 2 { - debug stop => _5; - let _7: i32; + debug stop => _4; + let _6: i32; scope 3 { - debug v => _7; - let _11: Value; + debug v => _6; + let _10: Value; scope 4 { - debug v => _11; + debug v => _10; } } } } bb0: { - StorageLive(_4); - _4 = &(*_1); - _3 = get::(copy _4) -> [return: bb1, unwind unreachable]; + StorageLive(_2); + StorageLive(_3); + _3 = &(*_1); + _2 = get::(copy _3) -> [return: bb1, unwind unreachable]; } bb1: { - StorageDead(_4); - StorageLive(_5); - _5 = const false; - _8 = discriminant((*_3)); - switchInt(move _8) -> [0: bb3, otherwise: bb2]; + StorageDead(_3); + StorageLive(_4); + _4 = const false; + _7 = discriminant((*_2)); + switchInt(move _7) -> [0: bb3, otherwise: bb2]; } bb2: { @@ -51,42 +51,50 @@ } bb3: { - StorageLive(_7); - _7 = copy (((*_3) as V0).0: i32); + StorageLive(_6); + _6 = copy (((*_2) as V0).0: i32); + StorageLive(_8); goto -> bb4; } bb4: { + StorageLive(_10); StorageLive(_11); + _11 = copy _6; +- _10 = Value::V0(move _11); ++ _10 = Value::V0(copy _6); + StorageDead(_11); StorageLive(_12); - _12 = copy _7; -- _11 = Value::V0(move _12); -+ _11 = Value::V0(copy _7); - StorageDead(_12); - StorageLive(_14); - _14 = copy _5; - switchInt(move _14) -> [0: bb6, otherwise: bb5]; + StorageLive(_13); + _13 = copy _4; + switchInt(move _13) -> [0: bb6, otherwise: bb5]; } bb5: { - _0 = move _11; - StorageDead(_14); - StorageDead(_11); - StorageDead(_7); - StorageDead(_5); + _0 = move _10; + StorageDead(_13); + StorageDead(_12); + StorageDead(_10); + StorageDead(_8); + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); return; } bb6: { - StorageDead(_14); - _5 = const true; - StorageLive(_16); -- _16 = Value::V1; -- (*_1) = move _16; -+ _16 = const Value::V1; + _12 = const (); + StorageDead(_13); + StorageDead(_12); + _4 = const true; + StorageLive(_15); +- _15 = Value::V1; +- (*_1) = move _15; ++ _15 = const Value::V1; + (*_1) = const Value::V1; - StorageDead(_16); - StorageDead(_11); + StorageDead(_15); + _9 = const (); + StorageDead(_10); goto -> bb4; } } diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir index 2d88f9e55249f..d0470c1cb92eb 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir @@ -3,19 +3,15 @@ fn c(_1: &[T]) -> &[T] { debug x => _1; let mut _0: &[T]; - let _2: &[T]; - let mut _3: &[T]; + let mut _2: &[T]; scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { - debug self => _3; + debug self => _2; } bb0: { StorageLive(_2); - StorageLive(_3); - _3 = copy _1; - _2 = copy _3; + _2 = copy _1; _0 = copy _2; - StorageDead(_3); StorageDead(_2); return; } diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index e2e2aaf8c45d9..15316e142c0af 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -3,26 +3,22 @@ fn d(_1: &Box) -> &T { debug x => _1; let mut _0: &T; - let _2: &T; - let mut _3: &std::boxed::Box; + let mut _2: &std::boxed::Box; scope 1 (inlined as AsRef>::as_ref) { - debug self => _3; - let mut _4: *const T; - let mut _5: std::boxed::BoxRaw; + debug self => _2; + let mut _3: *const T; + let mut _4: std::ptr::Unique; } bb0: { StorageLive(_2); + _2 = copy _1; StorageLive(_3); - _3 = copy _1; StorageLive(_4); - StorageLive(_5); - _5 = no_retag copy ((*_3).0: std::boxed::BoxRaw); - _4 = copy _5 as *const T (BoxDerefTransmute); - _2 = &(*_4); - StorageDead(_5); + _4 = no_retag copy ((*_2).0: std::ptr::Unique); + _3 = copy _4 as *const T (BoxDerefTransmute); + _0 = &(*_3); StorageDead(_4); - _0 = copy _2; StorageDead(_3); StorageDead(_2); return; diff --git a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff index 5f9a8fe9547dd..6e63394bd185b 100644 --- a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff +++ b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-abort.diff @@ -6,57 +6,42 @@ let mut _0: MyThing; let mut _2: T; let mut _3: &T; - let _4: &T; - let mut _5: u64; - let mut _6: &u64; - let _7: &u64; - let mut _8: [f32; 3]; - let mut _9: &[f32; 3]; - let _10: &[f32; 3]; + let mut _4: u64; + let mut _5: &u64; + let mut _6: [f32; 3]; + let mut _7: &[f32; 3]; bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &((*_1).0: T); -- _3 = &(*_4); -+ _3 = copy _4; + _3 = &((*_1).0: T); _2 = ::clone(move _3) -> [return: bb1, unwind unreachable]; } bb1: { StorageDead(_3); + StorageLive(_4); StorageLive(_5); - StorageLive(_6); - StorageLive(_7); - _7 = &((*_1).1: u64); -- _6 = &(*_7); -- _5 = ::clone(move _6) -> [return: bb2, unwind unreachable]; -+ _6 = copy _7; -+ _5 = copy (*_6); + _5 = &((*_1).1: u64); +- _4 = ::clone(move _5) -> [return: bb2, unwind unreachable]; ++ _4 = copy (*_5); + goto -> bb2; } bb2: { - StorageDead(_6); - StorageLive(_8); - StorageLive(_9); - StorageLive(_10); - _10 = &((*_1).2: [f32; 3]); -- _9 = &(*_10); -- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind unreachable]; -+ _9 = copy _10; -+ _8 = copy (*_9); + StorageDead(_5); + StorageLive(_6); + StorageLive(_7); + _7 = &((*_1).2: [f32; 3]); +- _6 = <[f32; 3] as Clone>::clone(move _7) -> [return: bb3, unwind unreachable]; ++ _6 = copy (*_7); + goto -> bb3; } bb3: { - StorageDead(_9); - _0 = MyThing:: { v: move _2, i: move _5, a: move _8 }; - StorageDead(_10); - StorageDead(_8); StorageDead(_7); - StorageDead(_5); + _0 = MyThing:: { v: move _2, i: move _4, a: move _6 }; + StorageDead(_6); StorageDead(_4); StorageDead(_2); return; diff --git a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff index 0a02c2d4c0f1b..a01ccc6cff3a8 100644 --- a/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff +++ b/tests/mir-opt/instsimplify/combine_clone_of_primitives.{impl#0}-clone.InstSimplify-after-simplifycfg.panic-unwind.diff @@ -6,57 +6,42 @@ let mut _0: MyThing; let mut _2: T; let mut _3: &T; - let _4: &T; - let mut _5: u64; - let mut _6: &u64; - let _7: &u64; - let mut _8: [f32; 3]; - let mut _9: &[f32; 3]; - let _10: &[f32; 3]; + let mut _4: u64; + let mut _5: &u64; + let mut _6: [f32; 3]; + let mut _7: &[f32; 3]; bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &((*_1).0: T); -- _3 = &(*_4); -+ _3 = copy _4; + _3 = &((*_1).0: T); _2 = ::clone(move _3) -> [return: bb1, unwind continue]; } bb1: { StorageDead(_3); + StorageLive(_4); StorageLive(_5); - StorageLive(_6); - StorageLive(_7); - _7 = &((*_1).1: u64); -- _6 = &(*_7); -- _5 = ::clone(move _6) -> [return: bb2, unwind: bb4]; -+ _6 = copy _7; -+ _5 = copy (*_6); + _5 = &((*_1).1: u64); +- _4 = ::clone(move _5) -> [return: bb2, unwind: bb4]; ++ _4 = copy (*_5); + goto -> bb2; } bb2: { - StorageDead(_6); - StorageLive(_8); - StorageLive(_9); - StorageLive(_10); - _10 = &((*_1).2: [f32; 3]); -- _9 = &(*_10); -- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; -+ _9 = copy _10; -+ _8 = copy (*_9); + StorageDead(_5); + StorageLive(_6); + StorageLive(_7); + _7 = &((*_1).2: [f32; 3]); +- _6 = <[f32; 3] as Clone>::clone(move _7) -> [return: bb3, unwind: bb4]; ++ _6 = copy (*_7); + goto -> bb3; } bb3: { - StorageDead(_9); - _0 = MyThing:: { v: move _2, i: move _5, a: move _8 }; - StorageDead(_10); - StorageDead(_8); StorageDead(_7); - StorageDead(_5); + _0 = MyThing:: { v: move _2, i: move _4, a: move _6 }; + StorageDead(_6); StorageDead(_4); StorageDead(_2); return; diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index 95f9b5997d4f6..72489e68fe55a 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -5,7 +5,7 @@ debug x => _1; let mut _0: (); let _2: &[T]; - let _3: &[T; 3]; + let mut _3: &[T; 3]; let _4: [T; 3]; let mut _8: !; scope 1 { diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index 87449b043fd5e..cb6a318b22ed4 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -5,7 +5,7 @@ debug x => _1; let mut _0: (); let _2: &[T]; - let _3: &[T; 3]; + let mut _3: &[T; 3]; let _4: [T; 3]; let mut _8: !; scope 1 { diff --git a/tests/mir-opt/issue_78192.f.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/issue_78192.f.InstSimplify-after-simplifycfg.diff index aae0570973df3..20e51515808c5 100644 --- a/tests/mir-opt/issue_78192.f.InstSimplify-after-simplifycfg.diff +++ b/tests/mir-opt/issue_78192.f.InstSimplify-after-simplifycfg.diff @@ -5,8 +5,7 @@ debug a => _1; let mut _0: *const T; let _2: &*const T; - let _3: &*const T; - let _4: *const T; + let _3: *const T; scope 1 { debug b => _2; } @@ -14,13 +13,10 @@ bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &raw const (*_1); - _3 = &_4; - _2 = copy _3; - StorageDead(_3); + _3 = &raw const (*_1); + _2 = &_3; _0 = copy (*_2); - StorageDead(_4); + StorageDead(_3); StorageDead(_2); return; } diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir index 7468e591b37b2..8fa1fef40f57a 100644 --- a/tests/mir-opt/issue_91633.fun.built.after.mir +++ b/tests/mir-opt/issue_91633.fun.built.after.mir @@ -24,7 +24,7 @@ fn fun(_1: &[T]) -> &T { _2 = &(*_1)[_3]; FakeRead(ForLet(None), _2); StorageDead(_3); - _0 = &(*_2); + _0 = copy _2; StorageDead(_2); return; } diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir index ea20caa3ca2c7..c16e4765ae7d7 100644 --- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir @@ -22,29 +22,25 @@ fn main() -> () { let _15: !; let mut _16: core::panicking::AssertKind; let mut _17: &&[u8]; - let _18: &&[u8]; - let mut _19: &&[u8; 4]; - let _20: &&[u8; 4]; - let mut _21: std::option::Option>; - let _22: (); - let mut _23: (&&[u8], &&[u8; 4]); - let mut _24: &&[u8]; - let _25: &[u8]; - let mut _26: &&[u8; 4]; - let _27: &[u8; 4]; - let _28: &&[u8]; - let _29: &&[u8; 4]; - let mut _30: bool; - let mut _31: &&[u8]; - let mut _32: &&[u8; 4]; - let mut _33: !; - let _35: !; - let mut _36: core::panicking::AssertKind; - let mut _37: &&[u8]; - let _38: &&[u8]; - let mut _39: &&[u8; 4]; - let _40: &&[u8; 4]; - let mut _41: std::option::Option>; + let mut _18: &&[u8; 4]; + let mut _19: std::option::Option>; + let _20: (); + let mut _21: (&&[u8], &&[u8; 4]); + let mut _22: &&[u8]; + let _23: &[u8]; + let mut _24: &&[u8; 4]; + let _25: &[u8; 4]; + let _26: &&[u8]; + let _27: &&[u8; 4]; + let mut _28: bool; + let mut _29: &&[u8]; + let mut _30: &&[u8; 4]; + let mut _31: !; + let _33: !; + let mut _34: core::panicking::AssertKind; + let mut _35: &&[u8]; + let mut _36: &&[u8; 4]; + let mut _37: std::option::Option>; scope 1 { debug left_val => _8; debug right_val => _9; @@ -54,11 +50,11 @@ fn main() -> () { } } scope 3 { - debug left_val => _28; - debug right_val => _29; - let _34: core::panicking::AssertKind; + debug left_val => _26; + debug right_val => _27; + let _32: core::panicking::AssertKind; scope 4 { - debug kind => _34; + debug kind => _32; } } @@ -123,25 +119,19 @@ fn main() -> () { StorageLive(_16); _16 = move _14; StorageLive(_17); + _17 = &(*_8); StorageLive(_18); - _18 = &(*_8); - _17 = &(*_18); + _18 = &(*_9); StorageLive(_19); - StorageLive(_20); - _20 = &(*_9); - _19 = &(*_20); - StorageLive(_21); - _21 = Option::>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> [return: bb7, unwind: bb23]; + _19 = Option::>::None; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _18, move _19) -> [return: bb7, unwind: bb23]; } bb7: { - StorageDead(_21); StorageDead(_19); + StorageDead(_18); StorageDead(_17); StorageDead(_16); - StorageDead(_20); - StorageDead(_18); StorageDead(_15); StorageDead(_14); unreachable; @@ -169,47 +159,47 @@ fn main() -> () { StorageDead(_4); StorageDead(_2); StorageDead(_1); + StorageLive(_20); + StorageLive(_21); StorageLive(_22); StorageLive(_23); - StorageLive(_24); - StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; + _23 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; } bb12: { + _22 = &_23; + StorageLive(_24); + StorageLive(_25); + _25 = const b"AAAA"; _24 = &_25; + _21 = (move _22, move _24); + StorageDead(_24); + StorageDead(_22); + PlaceMention(_21); StorageLive(_26); + _26 = copy (_21.0: &&[u8]); StorageLive(_27); - _27 = const b"AAAA"; - _26 = &_27; - _23 = (move _24, move _26); - StorageDead(_26); - StorageDead(_24); - PlaceMention(_23); + _27 = copy (_21.1: &&[u8; 4]); StorageLive(_28); - _28 = copy (_23.0: &&[u8]); StorageLive(_29); - _29 = copy (_23.1: &&[u8; 4]); + _29 = &(*_26); StorageLive(_30); - StorageLive(_31); - _31 = &(*_28); - StorageLive(_32); - _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; + _30 = &(*_27); + _28 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _29, move _30) -> [return: bb14, unwind: bb23]; } bb13: { - FakeRead(ForMatchedPlace(None), _23); + FakeRead(ForMatchedPlace(None), _21); unreachable; } bb14: { - switchInt(move _30) -> [0: bb16, otherwise: bb15]; + switchInt(move _28) -> [0: bb16, otherwise: bb15]; } bb15: { - StorageDead(_32); - StorageDead(_31); + StorageDead(_30); + StorageDead(_29); goto -> bb20; } @@ -218,36 +208,30 @@ fn main() -> () { } bb17: { - StorageDead(_32); - StorageDead(_31); + StorageDead(_30); + StorageDead(_29); + StorageLive(_32); + _32 = core::panicking::AssertKind::Eq; + FakeRead(ForLet(None), _32); + StorageLive(_33); StorageLive(_34); - _34 = core::panicking::AssertKind::Eq; - FakeRead(ForLet(None), _34); + _34 = move _32; StorageLive(_35); + _35 = &(*_26); StorageLive(_36); - _36 = move _34; + _36 = &(*_27); StorageLive(_37); - StorageLive(_38); - _38 = &(*_28); - _37 = &(*_38); - StorageLive(_39); - StorageLive(_40); - _40 = &(*_29); - _39 = &(*_40); - StorageLive(_41); - _41 = Option::>::None; - _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> [return: bb18, unwind: bb23]; + _37 = Option::>::None; + _33 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _34, move _35, move _36, move _37) -> [return: bb18, unwind: bb23]; } bb18: { - StorageDead(_41); - StorageDead(_39); StorageDead(_37); StorageDead(_36); - StorageDead(_40); - StorageDead(_38); StorageDead(_35); StorageDead(_34); + StorageDead(_33); + StorageDead(_32); unreachable; } @@ -256,22 +240,22 @@ fn main() -> () { } bb20: { - _22 = const (); + _20 = const (); goto -> bb21; } bb21: { - StorageDead(_30); - StorageDead(_29); StorageDead(_28); + StorageDead(_27); + StorageDead(_26); goto -> bb22; } bb22: { - StorageDead(_27); StorageDead(_25); StorageDead(_23); - StorageDead(_22); + StorageDead(_21); + StorageDead(_20); _0 = const (); return; } diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir index ea20caa3ca2c7..c16e4765ae7d7 100644 --- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir @@ -22,29 +22,25 @@ fn main() -> () { let _15: !; let mut _16: core::panicking::AssertKind; let mut _17: &&[u8]; - let _18: &&[u8]; - let mut _19: &&[u8; 4]; - let _20: &&[u8; 4]; - let mut _21: std::option::Option>; - let _22: (); - let mut _23: (&&[u8], &&[u8; 4]); - let mut _24: &&[u8]; - let _25: &[u8]; - let mut _26: &&[u8; 4]; - let _27: &[u8; 4]; - let _28: &&[u8]; - let _29: &&[u8; 4]; - let mut _30: bool; - let mut _31: &&[u8]; - let mut _32: &&[u8; 4]; - let mut _33: !; - let _35: !; - let mut _36: core::panicking::AssertKind; - let mut _37: &&[u8]; - let _38: &&[u8]; - let mut _39: &&[u8; 4]; - let _40: &&[u8; 4]; - let mut _41: std::option::Option>; + let mut _18: &&[u8; 4]; + let mut _19: std::option::Option>; + let _20: (); + let mut _21: (&&[u8], &&[u8; 4]); + let mut _22: &&[u8]; + let _23: &[u8]; + let mut _24: &&[u8; 4]; + let _25: &[u8; 4]; + let _26: &&[u8]; + let _27: &&[u8; 4]; + let mut _28: bool; + let mut _29: &&[u8]; + let mut _30: &&[u8; 4]; + let mut _31: !; + let _33: !; + let mut _34: core::panicking::AssertKind; + let mut _35: &&[u8]; + let mut _36: &&[u8; 4]; + let mut _37: std::option::Option>; scope 1 { debug left_val => _8; debug right_val => _9; @@ -54,11 +50,11 @@ fn main() -> () { } } scope 3 { - debug left_val => _28; - debug right_val => _29; - let _34: core::panicking::AssertKind; + debug left_val => _26; + debug right_val => _27; + let _32: core::panicking::AssertKind; scope 4 { - debug kind => _34; + debug kind => _32; } } @@ -123,25 +119,19 @@ fn main() -> () { StorageLive(_16); _16 = move _14; StorageLive(_17); + _17 = &(*_8); StorageLive(_18); - _18 = &(*_8); - _17 = &(*_18); + _18 = &(*_9); StorageLive(_19); - StorageLive(_20); - _20 = &(*_9); - _19 = &(*_20); - StorageLive(_21); - _21 = Option::>::None; - _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _19, move _21) -> [return: bb7, unwind: bb23]; + _19 = Option::>::None; + _15 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _16, move _17, move _18, move _19) -> [return: bb7, unwind: bb23]; } bb7: { - StorageDead(_21); StorageDead(_19); + StorageDead(_18); StorageDead(_17); StorageDead(_16); - StorageDead(_20); - StorageDead(_18); StorageDead(_15); StorageDead(_14); unreachable; @@ -169,47 +159,47 @@ fn main() -> () { StorageDead(_4); StorageDead(_2); StorageDead(_1); + StorageLive(_20); + StorageLive(_21); StorageLive(_22); StorageLive(_23); - StorageLive(_24); - StorageLive(_25); - _25 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; + _23 = function_with_bytes::<&*b"AAAA">() -> [return: bb12, unwind: bb23]; } bb12: { + _22 = &_23; + StorageLive(_24); + StorageLive(_25); + _25 = const b"AAAA"; _24 = &_25; + _21 = (move _22, move _24); + StorageDead(_24); + StorageDead(_22); + PlaceMention(_21); StorageLive(_26); + _26 = copy (_21.0: &&[u8]); StorageLive(_27); - _27 = const b"AAAA"; - _26 = &_27; - _23 = (move _24, move _26); - StorageDead(_26); - StorageDead(_24); - PlaceMention(_23); + _27 = copy (_21.1: &&[u8; 4]); StorageLive(_28); - _28 = copy (_23.0: &&[u8]); StorageLive(_29); - _29 = copy (_23.1: &&[u8; 4]); + _29 = &(*_26); StorageLive(_30); - StorageLive(_31); - _31 = &(*_28); - StorageLive(_32); - _32 = &(*_29); - _30 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _31, move _32) -> [return: bb14, unwind: bb23]; + _30 = &(*_27); + _28 = <&[u8] as PartialEq<&[u8; 4]>>::eq(move _29, move _30) -> [return: bb14, unwind: bb23]; } bb13: { - FakeRead(ForMatchedPlace(None), _23); + FakeRead(ForMatchedPlace(None), _21); unreachable; } bb14: { - switchInt(move _30) -> [0: bb16, otherwise: bb15]; + switchInt(move _28) -> [0: bb16, otherwise: bb15]; } bb15: { - StorageDead(_32); - StorageDead(_31); + StorageDead(_30); + StorageDead(_29); goto -> bb20; } @@ -218,36 +208,30 @@ fn main() -> () { } bb17: { - StorageDead(_32); - StorageDead(_31); + StorageDead(_30); + StorageDead(_29); + StorageLive(_32); + _32 = core::panicking::AssertKind::Eq; + FakeRead(ForLet(None), _32); + StorageLive(_33); StorageLive(_34); - _34 = core::panicking::AssertKind::Eq; - FakeRead(ForLet(None), _34); + _34 = move _32; StorageLive(_35); + _35 = &(*_26); StorageLive(_36); - _36 = move _34; + _36 = &(*_27); StorageLive(_37); - StorageLive(_38); - _38 = &(*_28); - _37 = &(*_38); - StorageLive(_39); - StorageLive(_40); - _40 = &(*_29); - _39 = &(*_40); - StorageLive(_41); - _41 = Option::>::None; - _35 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _36, move _37, move _39, move _41) -> [return: bb18, unwind: bb23]; + _37 = Option::>::None; + _33 = core::panicking::assert_failed::<&[u8], &[u8; 4]>(move _34, move _35, move _36, move _37) -> [return: bb18, unwind: bb23]; } bb18: { - StorageDead(_41); - StorageDead(_39); StorageDead(_37); StorageDead(_36); - StorageDead(_40); - StorageDead(_38); StorageDead(_35); StorageDead(_34); + StorageDead(_33); + StorageDead(_32); unreachable; } @@ -256,22 +240,22 @@ fn main() -> () { } bb20: { - _22 = const (); + _20 = const (); goto -> bb21; } bb21: { - StorageDead(_30); - StorageDead(_29); StorageDead(_28); + StorageDead(_27); + StorageDead(_26); goto -> bb22; } bb22: { - StorageDead(_27); StorageDead(_25); StorageDead(_23); - StorageDead(_22); + StorageDead(_21); + StorageDead(_20); _0 = const (); return; } diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff index fb406b8dfefc9..24bdf12f2adc4 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff @@ -45,9 +45,9 @@ let mut _28: &str; scope 5 (inlined >::eq) { scope 6 (inlined #[track_caller] >::index) { - let _29: &str; + let mut _29: &str; scope 7 (inlined String::as_str) { - let _30: &[u8]; + let mut _30: &[u8]; scope 8 (inlined Vec::::as_slice) { let _31: *const [u8]; let mut _32: *const u8; @@ -117,9 +117,9 @@ let mut _48: &str; scope 31 (inlined >::eq) { scope 32 (inlined #[track_caller] >::index) { - let _49: &str; + let mut _49: &str; scope 33 (inlined String::as_str) { - let _50: &[u8]; + let mut _50: &[u8]; scope 34 (inlined Vec::::as_slice) { let _51: *const [u8]; let mut _52: *const u8; @@ -222,9 +222,9 @@ _21 = const chained_conditions::promoted[1]; _10 = &(*_21); StorageLive(_27); + _27 = copy (*_8); StorageLive(_28); - _27 = no_retag copy (*_8); - _28 = no_retag copy (*_10); + _28 = copy (*_10); StorageLive(_29); StorageLive(_30); StorageLive(_31); @@ -284,9 +284,9 @@ _20 = const chained_conditions::promoted[0]; _17 = &(*_20); StorageLive(_47); + _47 = copy (*_15); StorageLive(_48); - _47 = no_retag copy (*_15); - _48 = no_retag copy (*_17); + _48 = copy (*_17); StorageLive(_49); StorageLive(_50); StorageLive(_51); diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff index d291e3d1eb51e..c1a069d022fb8 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff @@ -45,9 +45,9 @@ let mut _28: &str; scope 5 (inlined >::eq) { scope 6 (inlined #[track_caller] >::index) { - let _29: &str; + let mut _29: &str; scope 7 (inlined String::as_str) { - let _30: &[u8]; + let mut _30: &[u8]; scope 8 (inlined Vec::::as_slice) { let _31: *const [u8]; let mut _32: *const u8; @@ -117,9 +117,9 @@ let mut _48: &str; scope 31 (inlined >::eq) { scope 32 (inlined #[track_caller] >::index) { - let _49: &str; + let mut _49: &str; scope 33 (inlined String::as_str) { - let _50: &[u8]; + let mut _50: &[u8]; scope 34 (inlined Vec::::as_slice) { let _51: *const [u8]; let mut _52: *const u8; @@ -222,9 +222,9 @@ _21 = const chained_conditions::promoted[1]; _10 = &(*_21); StorageLive(_27); + _27 = copy (*_8); StorageLive(_28); - _27 = no_retag copy (*_8); - _28 = no_retag copy (*_10); + _28 = copy (*_10); StorageLive(_29); StorageLive(_30); StorageLive(_31); @@ -284,9 +284,9 @@ _20 = const chained_conditions::promoted[0]; _17 = &(*_20); StorageLive(_47); + _47 = copy (*_15); StorageLive(_48); - _47 = no_retag copy (*_15); - _48 = no_retag copy (*_17); + _48 = copy (*_17); StorageLive(_49); StorageLive(_50); StorageLive(_51); diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff index 714a12804e692..1b56438bfa342 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff @@ -6,42 +6,38 @@ let mut _0: usize; let _2: &[u8]; let mut _3: &[u8; N]; - let _4: &[u8; N]; - let mut _6: &[u8]; - let _7: &[u8]; + let mut _5: &[u8]; + let _6: &[u8]; scope 1 { debug arr => _2; - let _5: *const [u8]; + let _4: *const [u8]; scope 2 { - debug arr => _5; + debug arr => _4; } } bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); + _3 = &_1; _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - StorageDead(_4); + StorageLive(_4); + _4 = &raw const (*_2); StorageLive(_5); - _5 = &raw const (*_2); StorageLive(_6); - StorageLive(_7); - _7 = &(*_5); - _6 = &(*_7); -- _0 = PtrMetadata(move _6); + _6 = &(*_4); + _5 = &(*_6); +- _0 = PtrMetadata(move _5); + _0 = const N; goto -> bb1; } bb1: { - StorageDead(_6); StorageDead(_5); + StorageDead(_4); StorageDead(_2); - StorageDead(_7); + StorageDead(_6); return; } } diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff index 714a12804e692..1b56438bfa342 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff @@ -6,42 +6,38 @@ let mut _0: usize; let _2: &[u8]; let mut _3: &[u8; N]; - let _4: &[u8; N]; - let mut _6: &[u8]; - let _7: &[u8]; + let mut _5: &[u8]; + let _6: &[u8]; scope 1 { debug arr => _2; - let _5: *const [u8]; + let _4: *const [u8]; scope 2 { - debug arr => _5; + debug arr => _4; } } bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); + _3 = &_1; _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - StorageDead(_4); + StorageLive(_4); + _4 = &raw const (*_2); StorageLive(_5); - _5 = &raw const (*_2); StorageLive(_6); - StorageLive(_7); - _7 = &(*_5); - _6 = &(*_7); -- _0 = PtrMetadata(move _6); + _6 = &(*_4); + _5 = &(*_6); +- _0 = PtrMetadata(move _5); + _0 = const N; goto -> bb1; } bb1: { - StorageDead(_6); StorageDead(_5); + StorageDead(_4); StorageDead(_2); - StorageDead(_7); + StorageDead(_6); return; } } diff --git a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-abort.diff index 564f07ff26d4f..a3fb6aba6204b 100644 --- a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-abort.diff @@ -6,29 +6,23 @@ let mut _0: (); let _2: ::Discriminant; let mut _3: &T; - let _4: &T; - let _5: u8; - let mut _6: &i32; - let _7: &i32; - let _8: i32; - let _9: u8; - let mut _10: &(); - let _11: &(); - let _12: (); - let _13: isize; - let mut _14: &E; - let _15: &E; - let _16: E; - let mut _17: &E; - let mut _18: &(); - let mut _19: &i32; + let _4: u8; + let mut _5: &i32; + let _6: i32; + let _7: u8; + let mut _8: &(); + let _9: (); + let _10: isize; + let mut _11: &E; + let _12: E; + let mut _13: &E; + let mut _14: &(); + let mut _15: &i32; bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); + _3 = &_1; - _2 = discriminant_value::(move _3) -> [return: bb1, unwind unreachable]; + _2 = discriminant((*_3)); + goto -> bb1; @@ -36,53 +30,43 @@ bb1: { StorageDead(_3); - StorageDead(_4); StorageDead(_2); + StorageLive(_4); StorageLive(_5); - StorageLive(_6); - StorageLive(_7); - _19 = const discriminant::::promoted[2]; - _7 = &(*_19); - _6 = &(*_7); -- _5 = discriminant_value::(move _6) -> [return: bb2, unwind unreachable]; -+ _5 = discriminant((*_6)); + _15 = const discriminant::::promoted[2]; + _5 = &(*_15); +- _4 = discriminant_value::(move _5) -> [return: bb2, unwind unreachable]; ++ _4 = discriminant((*_5)); + goto -> bb2; } bb2: { - StorageDead(_6); - StorageDead(_7); StorageDead(_5); - StorageLive(_9); - StorageLive(_10); - StorageLive(_11); - _18 = const discriminant::::promoted[1]; - _11 = &(*_18); - _10 = &(*_11); -- _9 = discriminant_value::<()>(move _10) -> [return: bb3, unwind unreachable]; -+ _9 = discriminant((*_10)); + StorageDead(_4); + StorageLive(_7); + StorageLive(_8); + _14 = const discriminant::::promoted[1]; + _8 = &(*_14); +- _7 = discriminant_value::<()>(move _8) -> [return: bb3, unwind unreachable]; ++ _7 = discriminant((*_8)); + goto -> bb3; } bb3: { - StorageDead(_10); - StorageDead(_11); - StorageDead(_9); - StorageLive(_13); - StorageLive(_14); - StorageLive(_15); - _17 = const discriminant::::promoted[0]; - _15 = &(*_17); - _14 = &(*_15); -- _13 = discriminant_value::(move _14) -> [return: bb4, unwind unreachable]; -+ _13 = discriminant((*_14)); + StorageDead(_8); + StorageDead(_7); + StorageLive(_10); + StorageLive(_11); + _13 = const discriminant::::promoted[0]; + _11 = &(*_13); +- _10 = discriminant_value::(move _11) -> [return: bb4, unwind unreachable]; ++ _10 = discriminant((*_11)); + goto -> bb4; } bb4: { - StorageDead(_14); - StorageDead(_15); - StorageDead(_13); + StorageDead(_11); + StorageDead(_10); _0 = const (); drop(_1) -> [return: bb5, unwind unreachable]; } diff --git a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-unwind.diff index 7410af284dcd0..d4a60fa817ea8 100644 --- a/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.panic-unwind.diff @@ -6,29 +6,23 @@ let mut _0: (); let _2: ::Discriminant; let mut _3: &T; - let _4: &T; - let _5: u8; - let mut _6: &i32; - let _7: &i32; - let _8: i32; - let _9: u8; - let mut _10: &(); - let _11: &(); - let _12: (); - let _13: isize; - let mut _14: &E; - let _15: &E; - let _16: E; - let mut _17: &E; - let mut _18: &(); - let mut _19: &i32; + let _4: u8; + let mut _5: &i32; + let _6: i32; + let _7: u8; + let mut _8: &(); + let _9: (); + let _10: isize; + let mut _11: &E; + let _12: E; + let mut _13: &E; + let mut _14: &(); + let mut _15: &i32; bb0: { StorageLive(_2); StorageLive(_3); - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); + _3 = &_1; - _2 = discriminant_value::(move _3) -> [return: bb1, unwind unreachable]; + _2 = discriminant((*_3)); + goto -> bb1; @@ -36,53 +30,43 @@ bb1: { StorageDead(_3); - StorageDead(_4); StorageDead(_2); + StorageLive(_4); StorageLive(_5); - StorageLive(_6); - StorageLive(_7); - _19 = const discriminant::::promoted[2]; - _7 = &(*_19); - _6 = &(*_7); -- _5 = discriminant_value::(move _6) -> [return: bb2, unwind unreachable]; -+ _5 = discriminant((*_6)); + _15 = const discriminant::::promoted[2]; + _5 = &(*_15); +- _4 = discriminant_value::(move _5) -> [return: bb2, unwind unreachable]; ++ _4 = discriminant((*_5)); + goto -> bb2; } bb2: { - StorageDead(_6); - StorageDead(_7); StorageDead(_5); - StorageLive(_9); - StorageLive(_10); - StorageLive(_11); - _18 = const discriminant::::promoted[1]; - _11 = &(*_18); - _10 = &(*_11); -- _9 = discriminant_value::<()>(move _10) -> [return: bb3, unwind unreachable]; -+ _9 = discriminant((*_10)); + StorageDead(_4); + StorageLive(_7); + StorageLive(_8); + _14 = const discriminant::::promoted[1]; + _8 = &(*_14); +- _7 = discriminant_value::<()>(move _8) -> [return: bb3, unwind unreachable]; ++ _7 = discriminant((*_8)); + goto -> bb3; } bb3: { - StorageDead(_10); - StorageDead(_11); - StorageDead(_9); - StorageLive(_13); - StorageLive(_14); - StorageLive(_15); - _17 = const discriminant::::promoted[0]; - _15 = &(*_17); - _14 = &(*_15); -- _13 = discriminant_value::(move _14) -> [return: bb4, unwind unreachable]; -+ _13 = discriminant((*_14)); + StorageDead(_8); + StorageDead(_7); + StorageLive(_10); + StorageLive(_11); + _13 = const discriminant::::promoted[0]; + _11 = &(*_13); +- _10 = discriminant_value::(move _11) -> [return: bb4, unwind unreachable]; ++ _10 = discriminant((*_11)); + goto -> bb4; } bb4: { - StorageDead(_14); - StorageDead(_15); - StorageDead(_13); + StorageDead(_11); + StorageDead(_10); _0 = const (); drop(_1) -> [return: bb5, unwind: bb6]; } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.runtime-optimized.after.mir b/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.runtime-optimized.after.mir index 18069a37ed90d..7f1cacb5632fb 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.runtime-optimized.after.mir +++ b/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.runtime-optimized.after.mir @@ -5,7 +5,7 @@ fn clone_as_copy(_1: &NestCopy) -> NestCopy { let mut _0: NestCopy; scope 1 (inlined ::clone) { debug self => _1; - let _2: &AllCopy; + let mut _2: &AllCopy; scope 2 (inlined ::clone) { debug self => _2; } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.runtime-optimized.after.mir b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.runtime-optimized.after.mir index ef907c83c10e0..a478e89dd97cc 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.runtime-optimized.after.mir +++ b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.runtime-optimized.after.mir @@ -17,7 +17,7 @@ fn enum_clone_as_copy(_1: &Enum1) -> Enum1 { debug __self_0 => _3; scope 4 (inlined ::clone) { debug self => _3; - let _4: &AllCopy; + let mut _4: &AllCopy; scope 5 (inlined ::clone) { debug self => _4; } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.rs b/tests/mir-opt/pre-codegen/clone_as_copy.rs index 3c8d07c89c8a0..f3095d9d95880 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.rs +++ b/tests/mir-opt/pre-codegen/clone_as_copy.rs @@ -25,7 +25,7 @@ enum Enum1 { // EMIT_MIR clone_as_copy.clone_as_copy.runtime-optimized.after.mir fn clone_as_copy(v: &NestCopy) -> NestCopy { // CHECK-LABEL: fn clone_as_copy( - // CHECK: let [[DEAD_VAR:_.*]]: &AllCopy; + // CHECK: let mut [[DEAD_VAR:_.*]]: &AllCopy; // CHECK: bb0: { // CHECK-NEXT: DBG: [[DEAD_VAR]] = &((*_1).1: AllCopy) // CHECK-NEXT: _0 = copy (*_1); diff --git a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-abort.mir index 004de976667d3..b6005915003f6 100644 --- a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-abort.mir @@ -4,12 +4,12 @@ fn ::cmp(_1: &MultiField, _2: &Mul debug self => _1; debug other => _2; let mut _0: std::cmp::Ordering; - let _3: &char; - let _4: &char; + let mut _3: &char; + let mut _4: &char; let mut _5: std::cmp::Ordering; let mut _6: i8; - let _7: &i16; - let _8: &i16; + let mut _7: &i16; + let mut _8: &i16; scope 1 { debug cmp => _5; } @@ -17,7 +17,7 @@ fn ::cmp(_1: &MultiField, _2: &Mul bb0: { _3 = &((*_1).0: char); _4 = &((*_2).0: char); - _5 = ::cmp(copy _3, copy _4) -> [return: bb1, unwind unreachable]; + _5 = ::cmp(move _3, move _4) -> [return: bb1, unwind unreachable]; } bb1: { @@ -28,7 +28,7 @@ fn ::cmp(_1: &MultiField, _2: &Mul bb2: { _7 = &((*_1).1: i16); _8 = &((*_2).1: i16); - _0 = ::cmp(copy _7, copy _8) -> [return: bb4, unwind unreachable]; + _0 = ::cmp(move _7, move _8) -> [return: bb4, unwind unreachable]; } bb3: { diff --git a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-unwind.mir index 5df51f2b3f253..05b5a50697f81 100644 --- a/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.panic-unwind.mir @@ -4,12 +4,12 @@ fn ::cmp(_1: &MultiField, _2: &Mul debug self => _1; debug other => _2; let mut _0: std::cmp::Ordering; - let _3: &char; - let _4: &char; + let mut _3: &char; + let mut _4: &char; let mut _5: std::cmp::Ordering; let mut _6: i8; - let _7: &i16; - let _8: &i16; + let mut _7: &i16; + let mut _8: &i16; scope 1 { debug cmp => _5; } @@ -17,7 +17,7 @@ fn ::cmp(_1: &MultiField, _2: &Mul bb0: { _3 = &((*_1).0: char); _4 = &((*_2).0: char); - _5 = ::cmp(copy _3, copy _4) -> [return: bb1, unwind continue]; + _5 = ::cmp(move _3, move _4) -> [return: bb1, unwind continue]; } bb1: { @@ -28,7 +28,7 @@ fn ::cmp(_1: &MultiField, _2: &Mul bb2: { _7 = &((*_1).1: i16); _8 = &((*_2).1: i16); - _0 = ::cmp(copy _7, copy _8) -> [return: bb4, unwind continue]; + _0 = ::cmp(move _7, move _8) -> [return: bb4, unwind continue]; } bb3: { diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index a0526d279a863..db036bec6dbe9 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -24,7 +24,7 @@ let _11: std::alloc::AllocError; let mut _12: !; let mut _13: &dyn std::fmt::Debug; - let _14: &std::alloc::AllocError; + let mut _14: &std::alloc::AllocError; scope 8 { } scope 9 { @@ -88,6 +88,7 @@ StorageLive(_14); _14 = &_11; _13 = copy _14 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); + StorageDead(_14); _12 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _13) -> unwind unreachable; } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index 3a6b52b0f2496..cec4f478b05d1 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -24,7 +24,7 @@ let _11: std::alloc::AllocError; let mut _12: !; let mut _13: &dyn std::fmt::Debug; - let _14: &std::alloc::AllocError; + let mut _14: &std::alloc::AllocError; scope 8 { } scope 9 { @@ -88,6 +88,7 @@ StorageLive(_14); _14 = &_11; _13 = copy _14 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); + StorageDead(_14); _12 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _13) -> unwind unreachable; } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.runtime-optimized.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.runtime-optimized.after.mir index d4ba112510aa3..675890db0060d 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.runtime-optimized.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.runtime-optimized.after.mir @@ -77,7 +77,7 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 // DBG: _19 = &((*_6).3: usize); StorageLive(_9); // DBG: _20 = &_16; - // DBG: _21 = &?; + // DBG: _21 = &_18; _7 = copy ((*_3).0: usize); _8 = copy ((*_5).2: usize); _9 = Le(copy _7, copy _8); @@ -87,7 +87,7 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 bb1: { StorageLive(_12); // DBG: _22 = &_19; - // DBG: _23 = &?; + // DBG: _23 = &_17; StorageLive(_10); _10 = copy ((*_6).3: usize); StorageLive(_11); @@ -101,7 +101,7 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 bb2: { StorageLive(_13); // DBG: _24 = &_18; - // DBG: _25 = &?; + // DBG: _25 = &_16; _13 = Le(copy _8, copy _7); switchInt(move _13) -> [0: bb3, otherwise: bb4]; } @@ -113,7 +113,7 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 bb4: { // DBG: _26 = &_17; - // DBG: _27 = &?; + // DBG: _27 = &_19; StorageLive(_14); _14 = copy ((*_4).1: usize); StorageLive(_15); diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir index b42087b5c822d..d652b8cd67db5 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir @@ -53,7 +53,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _15: std::ptr::NonNull; let mut _18: bool; let mut _24: usize; - let _26: &T; + let mut _26: &T; scope 29 { let _14: *const T; scope 30 { diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-abort.mir index 2e662fc36ac67..15e757eec8387 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-abort.mir @@ -22,7 +22,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _14: std::ptr::NonNull; let mut _17: bool; let mut _20: usize; - let _22: &T; + let mut _22: &T; scope 17 { let _13: *const T; scope 18 { diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-unwind.mir index dc5feaa1344b0..d9437647d1c32 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.runtime-optimized.after.panic-unwind.mir @@ -22,7 +22,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _14: std::ptr::NonNull; let mut _17: bool; let mut _20: usize; - let _22: &T; + let mut _22: &T; scope 17 { let _13: *const T; scope 18 { diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-abort.mir index c2c521729b75c..d1020e63f45ae 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-abort.mir @@ -22,7 +22,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _15: *const T; let mut _20: bool; let mut _21: *const T; - let _34: &T; + let mut _34: &T; scope 20 { let _16: std::ptr::NonNull; let _22: usize; diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-unwind.mir index c11eab18521dd..9bcabe0e1ab02 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.runtime-optimized.after.panic-unwind.mir @@ -22,7 +22,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _15: *const T; let mut _20: bool; let mut _21: *const T; - let _34: &T; + let mut _34: &T; scope 20 { let _16: std::ptr::NonNull; let _22: usize; diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-abort.mir index 889d7c1e69afb..a5caa9d06534f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-abort.mir @@ -9,7 +9,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { let mut _7: bool; let mut _9: std::ptr::NonNull; let mut _11: usize; - let _13: &T; + let mut _13: &T; scope 2 { let _3: *const T; scope 3 { diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-unwind.mir index 889d7c1e69afb..a5caa9d06534f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.runtime-optimized.after.panic-unwind.mir @@ -9,7 +9,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { let mut _7: bool; let mut _9: std::ptr::NonNull; let mut _11: usize; - let _13: &T; + let mut _13: &T; scope 2 { let _3: *const T; scope 3 { diff --git a/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-abort.mir index d8b15701bbd9b..effcf715dd710 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-abort.mir @@ -3,7 +3,7 @@ fn outer(_1: u8) -> u8 { debug v => _1; // in scope 0 at $DIR/spans.rs:10:14: 10:15 let mut _0: u8; // return place in scope 0 at $DIR/spans.rs:10:24: 10:26 - let _2: &u8; // in scope 0 at $DIR/spans.rs:11:11: 11:13 + let mut _2: &u8; // in scope 0 at $DIR/spans.rs:11:11: 11:13 scope 1 (inlined inner) { // at $DIR/spans.rs:11:5: 11:14 debug x => _2; // in scope 1 at $DIR/spans.rs:14:14: 14:15 } diff --git a/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-unwind.mir index d8b15701bbd9b..effcf715dd710 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.runtime-optimized.after.panic-unwind.mir @@ -3,7 +3,7 @@ fn outer(_1: u8) -> u8 { debug v => _1; // in scope 0 at $DIR/spans.rs:10:14: 10:15 let mut _0: u8; // return place in scope 0 at $DIR/spans.rs:10:24: 10:26 - let _2: &u8; // in scope 0 at $DIR/spans.rs:11:11: 11:13 + let mut _2: &u8; // in scope 0 at $DIR/spans.rs:11:11: 11:13 scope 1 (inlined inner) { // at $DIR/spans.rs:11:5: 11:14 debug x => _2; // in scope 1 at $DIR/spans.rs:14:14: 14:15 } diff --git a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff index 0f90cc40a3d8b..19af5f4dd8314 100644 --- a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff @@ -12,42 +12,40 @@ let _9: (); let _10: usize; let mut _13: &usize; - let _14: &usize; - let _16: (); - let mut _17: (); - let _18: (); - let _19: usize; - let _23: (); - let mut _24: &&usize; - let _25: (); - let _26: usize; - let _30: (); - let mut _31: *mut &usize; - let _32: (); - let _33: usize; - let _36: (); - let mut _37: &usize; - let _38: (); - let _39: usize; - let _45: (); - let mut _46: &usize; - let _47: (); - let _48: &T; - let _50: (); - let mut _51: (); - let _52: (); - let _53: &T; - let mut _54: &T; - let _55: &T; + let _15: (); + let mut _16: (); + let _17: (); + let _18: usize; + let _22: (); + let mut _23: &&usize; + let _24: (); + let _25: usize; + let _29: (); + let mut _30: *mut &usize; + let _31: (); + let _32: usize; + let _35: (); + let mut _36: &usize; + let _37: (); + let _38: usize; + let _44: (); + let mut _45: &usize; + let _46: (); + let _47: &T; + let _49: (); + let mut _50: (); + let _51: (); + let _52: &T; + let mut _53: &T; + let _55: (); + let mut _56: (); let _57: (); - let mut _58: (); - let _59: (); - let _60: usize; - let _64: (); - let mut _65: (); - let _66: usize; - let _70: (); - let mut _71: (); + let _58: usize; + let _62: (); + let mut _63: (); + let _64: usize; + let _68: (); + let mut _69: (); scope 1 { debug a => _4; let _5: &usize; @@ -67,71 +65,71 @@ let mut _12: &usize; scope 6 { debug b => _12; - let _15: usize; + let _14: usize; scope 7 { - debug c => _15; + debug c => _14; } } } } scope 8 { - debug a => _19; - let _20: &usize; + debug a => _18; + let _19: &usize; scope 9 { - debug b => _20; - let _21: &&usize; + debug b => _19; + let _20: &&usize; scope 10 { - debug d => _21; - let _22: usize; + debug d => _20; + let _21: usize; scope 11 { - debug c => _22; + debug c => _21; } } } } scope 12 { - debug a => _26; - let mut _27: &usize; + debug a => _25; + let mut _26: &usize; scope 13 { - debug b => _27; - let _28: *mut &usize; + debug b => _26; + let _27: *mut &usize; scope 14 { - debug d => _28; - let _29: usize; + debug d => _27; + let _28: usize; scope 15 { - debug c => _29; + debug c => _28; } } } } scope 16 { - debug a => _33; - let _34: &usize; + debug a => _32; + let _33: &usize; scope 17 { - debug b => _34; - let _35: usize; + debug b => _33; + let _34: usize; scope 18 { - debug c => _35; + debug c => _34; } } } scope 19 { - debug a => _39; - let _40: &usize; + debug a => _38; + let _39: &usize; scope 20 { - debug b1 => _40; - let _41: usize; + debug b1 => _39; + let _40: usize; scope 21 { - debug c => _41; - let _42: &usize; + debug c => _40; + let _41: &usize; scope 22 { - debug b2 => _42; - let _43: usize; + debug b2 => _41; + let _42: usize; scope 23 { - debug c2 => _43; - let _44: &usize; + debug c2 => _42; + let _43: &usize; scope 24 { - debug b3 => _44; + debug b3 => _43; } } } @@ -139,46 +137,46 @@ } } scope 25 { -- debug a => _48; +- debug a => _47; + debug a => _1; - let _49: T; + let _48: T; scope 26 { - debug b => _49; + debug b => _48; } } scope 27 { - debug a => _53; - let _56: T; + debug a => _52; + let _54: T; scope 28 { - debug b => _56; + debug b => _54; } } scope 29 { - debug a => _60; - let _61: &usize; + debug a => _58; + let _59: &usize; scope 30 { - debug b => _61; - let _62: &&usize; + debug b => _59; + let _60: &&usize; scope 31 { - debug d => _62; - let _63: usize; + debug d => _60; + let _61: usize; scope 32 { - debug c => _63; + debug c => _61; } } } } scope 33 { - debug a => _66; - let mut _67: &usize; + debug a => _64; + let mut _65: &usize; scope 34 { - debug b => _67; - let _68: &mut &usize; + debug b => _65; + let _66: &mut &usize; scope 35 { - debug d => _68; - let _69: usize; + debug d => _66; + let _67: usize; scope 36 { - debug c => _69; + debug c => _67; } } } @@ -215,231 +213,223 @@ StorageLive(_12); _12 = &_10; StorageLive(_13); -- StorageLive(_14); -- _14 = &_11; -- _13 = &(*_14); + _13 = &_11; - _12 = move _13; -+ _13 = &_11; + _12 = copy _13; StorageDead(_13); -- StorageDead(_14); + StorageLive(_14); + _14 = copy (*_12); StorageLive(_15); - _15 = copy (*_12); StorageLive(_16); - StorageLive(_17); - _17 = (); - _16 = opaque::<()>(move _17) -> [return: bb2, unwind continue]; + _16 = (); + _15 = opaque::<()>(move _16) -> [return: bb2, unwind continue]; } bb2: { - StorageDead(_17); StorageDead(_16); -- _9 = const (); StorageDead(_15); +- _9 = const (); + StorageDead(_14); StorageDead(_12); StorageDead(_11); StorageDead(_10); - StorageDead(_9); -- StorageLive(_18); +- StorageLive(_17); + StorageLive(_18); + _18 = const 5_usize; StorageLive(_19); - _19 = const 5_usize; + _19 = &_18; StorageLive(_20); _20 = &_19; StorageLive(_21); - _21 = &_20; +- _21 = copy (*_19); ++ _21 = copy _18; StorageLive(_22); -- _22 = copy (*_20); -+ _22 = copy _19; StorageLive(_23); - StorageLive(_24); - _24 = copy _21; -- _23 = opaque::<&&usize>(move _24) -> [return: bb3, unwind continue]; -+ _23 = opaque::<&&usize>(copy _24) -> [return: bb3, unwind continue]; + _23 = copy _20; +- _22 = opaque::<&&usize>(move _23) -> [return: bb3, unwind continue]; ++ _22 = opaque::<&&usize>(copy _23) -> [return: bb3, unwind continue]; } bb3: { - StorageDead(_24); StorageDead(_23); -- _18 = const (); StorageDead(_22); +- _17 = const (); StorageDead(_21); StorageDead(_20); StorageDead(_19); -- StorageDead(_18); -- StorageLive(_25); + StorageDead(_18); +- StorageDead(_17); +- StorageLive(_24); + StorageLive(_25); + _25 = const 5_usize; StorageLive(_26); - _26 = const 5_usize; + _26 = &_25; StorageLive(_27); - _27 = &_26; + _27 = &raw mut _26; StorageLive(_28); - _28 = &raw mut _27; + _28 = copy (*_26); StorageLive(_29); - _29 = copy (*_27); StorageLive(_30); - StorageLive(_31); - _31 = copy _28; -- _30 = opaque::<*mut &usize>(move _31) -> [return: bb4, unwind continue]; -+ _30 = opaque::<*mut &usize>(copy _31) -> [return: bb4, unwind continue]; + _30 = copy _27; +- _29 = opaque::<*mut &usize>(move _30) -> [return: bb4, unwind continue]; ++ _29 = opaque::<*mut &usize>(copy _30) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_31); StorageDead(_30); -- _25 = const (); StorageDead(_29); +- _24 = const (); StorageDead(_28); StorageDead(_27); StorageDead(_26); -- StorageDead(_25); -- StorageLive(_32); + StorageDead(_25); +- StorageDead(_24); +- StorageLive(_31); + StorageLive(_32); + _32 = const 7_usize; StorageLive(_33); - _33 = const 7_usize; + _33 = &_32; StorageLive(_34); - _34 = &_33; +- _34 = copy (*_33); ++ _34 = copy _32; StorageLive(_35); -- _35 = copy (*_34); -+ _35 = copy _33; StorageLive(_36); - StorageLive(_37); - _37 = copy _34; -- _36 = opaque::<&usize>(move _37) -> [return: bb5, unwind continue]; -+ _36 = opaque::<&usize>(copy _37) -> [return: bb5, unwind continue]; + _36 = copy _33; +- _35 = opaque::<&usize>(move _36) -> [return: bb5, unwind continue]; ++ _35 = opaque::<&usize>(copy _36) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_37); StorageDead(_36); -- _32 = const (); StorageDead(_35); +- _31 = const (); StorageDead(_34); StorageDead(_33); -- StorageDead(_32); -- StorageLive(_38); + StorageDead(_32); +- StorageDead(_31); +- StorageLive(_37); + StorageLive(_38); + _38 = const 7_usize; StorageLive(_39); - _39 = const 7_usize; + _39 = &_38; StorageLive(_40); - _40 = &_39; +- _40 = copy (*_39); ++ _40 = copy _38; StorageLive(_41); -- _41 = copy (*_40); -+ _41 = copy _39; + _41 = copy _39; StorageLive(_42); - _42 = copy _40; +- _42 = copy (*_41); ++ _42 = copy _38; StorageLive(_43); -- _43 = copy (*_42); -+ _43 = copy _39; + _43 = copy _41; StorageLive(_44); - _44 = copy _42; StorageLive(_45); - StorageLive(_46); - _46 = copy _44; -- _45 = opaque::<&usize>(move _46) -> [return: bb6, unwind continue]; -+ _45 = opaque::<&usize>(copy _46) -> [return: bb6, unwind continue]; + _45 = copy _43; +- _44 = opaque::<&usize>(move _45) -> [return: bb6, unwind continue]; ++ _44 = opaque::<&usize>(copy _45) -> [return: bb6, unwind continue]; } bb6: { - StorageDead(_46); StorageDead(_45); -- _38 = const (); StorageDead(_44); +- _37 = const (); StorageDead(_43); StorageDead(_42); StorageDead(_41); StorageDead(_40); StorageDead(_39); -- StorageDead(_38); + StorageDead(_38); +- StorageDead(_37); +- StorageLive(_46); - StorageLive(_47); -- StorageLive(_48); -- _48 = &(*_1); +- _47 = &(*_1); + StorageLive(_48); +- _48 = copy (*_47); ++ _48 = copy (*_1); StorageLive(_49); -- _49 = copy (*_48); -+ _49 = copy (*_1); StorageLive(_50); - StorageLive(_51); - _51 = (); - _50 = opaque::<()>(move _51) -> [return: bb7, unwind continue]; + _50 = (); + _49 = opaque::<()>(move _50) -> [return: bb7, unwind continue]; } bb7: { - StorageDead(_51); StorageDead(_50); -- _47 = const (); StorageDead(_49); -- StorageDead(_48); +- _46 = const (); + StorageDead(_48); - StorageDead(_47); -- StorageLive(_52); +- StorageDead(_46); +- StorageLive(_51); + StorageLive(_52); + _52 = &(*_2); StorageLive(_53); - _53 = &(*_2); + _53 = &(*_1); +- _2 = move _53; ++ _2 = copy _53; + StorageDead(_53); StorageLive(_54); -- StorageLive(_55); -- _55 = &(*_1); -- _54 = &(*_55); -- _2 = move _54; -+ _54 = &(*_1); -+ _2 = copy _54; - StorageDead(_54); -- StorageDead(_55); + _54 = copy (*_52); + StorageLive(_55); StorageLive(_56); - _56 = copy (*_53); - StorageLive(_57); - StorageLive(_58); - _58 = (); - _57 = opaque::<()>(move _58) -> [return: bb8, unwind continue]; + _56 = (); + _55 = opaque::<()>(move _56) -> [return: bb8, unwind continue]; } bb8: { - StorageDead(_58); - StorageDead(_57); -- _52 = const (); StorageDead(_56); - StorageDead(_53); -- StorageDead(_52); -- StorageLive(_59); + StorageDead(_55); +- _51 = const (); + StorageDead(_54); + StorageDead(_52); +- StorageDead(_51); +- StorageLive(_57); + StorageLive(_58); + _58 = const 5_usize; + StorageLive(_59); + _59 = &_58; StorageLive(_60); - _60 = const 5_usize; + _60 = &_59; StorageLive(_61); - _61 = &_60; +- _61 = copy (*_59); ++ _61 = copy _58; StorageLive(_62); - _62 = &_61; StorageLive(_63); -- _63 = copy (*_61); -+ _63 = copy _60; - StorageLive(_64); - StorageLive(_65); - _65 = (); - _64 = opaque::<()>(move _65) -> [return: bb9, unwind continue]; + _63 = (); + _62 = opaque::<()>(move _63) -> [return: bb9, unwind continue]; } bb9: { - StorageDead(_65); - StorageDead(_64); -- _59 = const (); StorageDead(_63); StorageDead(_62); +- _57 = const (); StorageDead(_61); StorageDead(_60); -- StorageDead(_59); + StorageDead(_59); + StorageDead(_58); +- StorageDead(_57); + StorageLive(_64); + _64 = const 5_usize; + StorageLive(_65); + _65 = &_64; StorageLive(_66); - _66 = const 5_usize; + _66 = &mut _65; StorageLive(_67); - _67 = &_66; + _67 = copy (*_65); StorageLive(_68); - _68 = &mut _67; StorageLive(_69); - _69 = copy (*_67); - StorageLive(_70); - StorageLive(_71); - _71 = (); - _70 = opaque::<()>(move _71) -> [return: bb10, unwind continue]; + _69 = (); + _68 = opaque::<()>(move _69) -> [return: bb10, unwind continue]; } bb10: { - StorageDead(_71); - StorageDead(_70); - _0 = const (); StorageDead(_69); StorageDead(_68); + _0 = const (); StorageDead(_67); StorageDead(_66); + StorageDead(_65); + StorageDead(_64); return; } } diff --git a/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff index 37a669d72b85e..7925f75135f5a 100644 --- a/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff +++ b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff @@ -6,7 +6,6 @@ let _1: [u8; 10]; - let mut _2: &[u8]; - let mut _3: &[u8; 10]; -- let _4: &[u8; 10]; scope 1 { debug bytes => _1; scope 2 { @@ -18,12 +17,9 @@ _1 = [const 0_u8; 10]; - StorageLive(_2); - StorageLive(_3); -- StorageLive(_4); -- _4 = &_1; -- _3 = &(*_4); +- _3 = &_1; - _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); - StorageDead(_3); -- StorageDead(_4); - StorageDead(_2); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index 87340ebf0b90f..d44b9b138be4e 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -17,22 +17,17 @@ let mut _17: &std::boxed::Box; let mut _18: core::fmt::rt::Argument<'_>; let mut _19: &u32; - let mut _20: &[u8; 7]; - let _21: &[u8; 7]; - let mut _22: &[core::fmt::rt::Argument<'_>; 2]; - let _23: &[core::fmt::rt::Argument<'_>; 2]; - let mut _24: &std::boxed::Box; - let mut _25: &u32; - let mut _26: bool; - let mut _27: isize; - let mut _28: isize; - let mut _29: isize; -+ let _30: std::result::Result, ::Err>; -+ let _31: u32; + let mut _20: &[core::fmt::rt::Argument<'_>; 2]; + let mut _21: bool; + let mut _22: isize; + let mut _23: isize; + let mut _24: isize; ++ let _25: std::result::Result, ::Err>; ++ let _26: u32; scope 1 { - debug foo => _1; -+ debug ((foo: Foo).0: std::result::Result, ::Err>) => _30; -+ debug ((foo: Foo).1: u32) => _31; ++ debug ((foo: Foo).0: std::result::Result, ::Err>) => _25; ++ debug ((foo: Foo).1: u32) => _26; let _5: std::result::Result, ::Err>; scope 2 { debug x => _5; @@ -43,12 +38,12 @@ debug x => _8; let _8: std::boxed::Box; let _12: (&std::boxed::Box, &u32); -+ let _32: &std::boxed::Box; -+ let _33: &u32; ++ let _27: &std::boxed::Box; ++ let _28: &u32; scope 5 { - debug args => _12; -+ debug ((args: (&Box, &u32)).0: &std::boxed::Box) => _32; -+ debug ((args: (&Box, &u32)).1: &u32) => _33; ++ debug ((args: (&Box, &u32)).0: &std::boxed::Box) => _27; ++ debug ((args: (&Box, &u32)).1: &u32) => _28; let _15: [core::fmt::rt::Argument<'_>; 2]; scope 6 { debug args => _15; @@ -60,10 +55,10 @@ } bb0: { - _26 = const false; + _21 = const false; - StorageLive(_1); -+ StorageLive(_30); -+ StorageLive(_31); ++ StorageLive(_25); ++ StorageLive(_26); + nop; StorageLive(_2); StorageLive(_3); @@ -77,17 +72,17 @@ _2 = Result::, ::Err>::Ok(move _3); StorageDead(_3); - _1 = Foo:: { x: move _2, y: const 7_u32 }; -+ _30 = move _2; -+ _31 = const 7_u32; ++ _25 = move _2; ++ _26 = const 7_u32; + nop; StorageDead(_2); StorageLive(_5); - _26 = const true; + _21 = const true; - _5 = move (_1.0: std::result::Result, ::Err>); -+ _5 = move _30; ++ _5 = move _25; StorageLive(_6); - _6 = copy (_1.1: u32); -+ _6 = copy _31; ++ _6 = copy _26; _7 = discriminant(_5); switchInt(move _7) -> [0: bb2, otherwise: bb7]; } @@ -99,25 +94,24 @@ StorageLive(_10); StorageLive(_11); - StorageLive(_12); -+ StorageLive(_32); -+ StorageLive(_33); ++ StorageLive(_27); ++ StorageLive(_28); + nop; StorageLive(_13); _13 = &_8; StorageLive(_14); _14 = &_6; - _12 = (move _13, move _14); -+ _32 = move _13; -+ _33 = move _14; ++ _27 = move _13; ++ _28 = move _14; + nop; StorageDead(_14); StorageDead(_13); StorageLive(_15); StorageLive(_16); StorageLive(_17); -- _24 = no_retag copy (_12.0: &std::boxed::Box); -+ _24 = no_retag copy _32; - _17 = &(*_24); +- _17 = copy (_12.0: &std::boxed::Box); ++ _17 = copy _27; _16 = core::fmt::rt::Argument::<'_>::new_display::>(move _17) -> [return: bb3, unwind unreachable]; } @@ -125,9 +119,8 @@ StorageDead(_17); StorageLive(_18); StorageLive(_19); -- _25 = no_retag copy (_12.1: &u32); -+ _25 = no_retag copy _33; - _19 = &(*_25); +- _19 = copy (_12.1: &u32); ++ _19 = copy _28; _18 = core::fmt::rt::Argument::<'_>::new_display::(move _19) -> [return: bb4, unwind unreachable]; } @@ -137,20 +130,11 @@ StorageDead(_18); StorageDead(_16); StorageLive(_20); - StorageLive(_21); - _21 = const b"\xc0\x01 \xc0\x01\n\x00"; - _20 = &(*_21); - StorageLive(_22); - StorageLive(_23); - _23 = &_15; - _22 = &(*_23); - _11 = Arguments::<'_>::new::<7, 2>(move _20, move _22) -> [return: bb5, unwind unreachable]; + _20 = &_15; + _11 = Arguments::<'_>::new::<7, 2>(const b"\xc0\x01 \xc0\x01\n\x00", move _20) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_23); - StorageDead(_22); - StorageDead(_21); StorageDead(_20); _10 = std::io::_eprint(move _11) -> [return: bb6, unwind unreachable]; } @@ -159,8 +143,8 @@ StorageDead(_11); StorageDead(_15); - StorageDead(_12); -+ StorageDead(_32); -+ StorageDead(_33); ++ StorageDead(_27); ++ StorageDead(_28); + nop; StorageDead(_10); _9 = const (); @@ -181,16 +165,16 @@ bb9: { StorageDead(_6); - _27 = discriminant(_5); - switchInt(move _27) -> [0: bb10, otherwise: bb11]; + _22 = discriminant(_5); + switchInt(move _22) -> [0: bb10, otherwise: bb11]; } bb10: { - _26 = const false; + _21 = const false; StorageDead(_5); - StorageDead(_1); -+ StorageDead(_30); -+ StorageDead(_31); ++ StorageDead(_25); ++ StorageDead(_26); + nop; return; } diff --git a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir index 4e1a59cea791c..c0ec752c2b613 100644 --- a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir +++ b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir @@ -5,44 +5,41 @@ fn method_1(_1: Guard) -> () { let mut _0: (); let mut _2: std::result::Result; let mut _3: &Guard; - let _4: &Guard; - let _5: Guard; - let mut _6: &Guard; - let mut _7: isize; - let _8: OtherDrop; - let _9: (); - let mut _10: bool; + let _4: Guard; + let mut _5: &Guard; + let mut _6: isize; + let _7: OtherDrop; + let _8: (); + let mut _9: bool; scope 1 { - debug other_drop => _8; + debug other_drop => _7; } scope 2 { - debug err => _9; + debug err => _8; } bb0: { - _10 = const false; + _9 = const false; StorageLive(_2); StorageLive(_3); StorageLive(_4); StorageLive(_5); - StorageLive(_6); - _6 = &_1; - _5 = ::clone(move _6) -> [return: bb1, unwind: bb13]; + _5 = &_1; + _4 = ::clone(move _5) -> [return: bb1, unwind: bb13]; } bb1: { - StorageDead(_6); - _4 = &_5; - _3 = &(*_4); + StorageDead(_5); + _3 = &_4; _2 = method_2(move _3) -> [return: bb2, unwind: bb12]; } bb2: { - _10 = const true; + _9 = const true; StorageDead(_3); PlaceMention(_2); - _7 = discriminant(_2); - switchInt(move _7) -> [0: bb5, 1: bb4, otherwise: bb3]; + _6 = discriminant(_2); + switchInt(move _6) -> [0: bb5, 1: bb4, otherwise: bb3]; } bb3: { @@ -50,22 +47,22 @@ fn method_1(_1: Guard) -> () { } bb4: { - StorageLive(_9); - _9 = copy ((_2 as Err).0: ()); + StorageLive(_8); + _8 = copy ((_2 as Err).0: ()); _0 = const (); - StorageDead(_9); + StorageDead(_8); goto -> bb7; } bb5: { - StorageLive(_8); - _8 = move ((_2 as Ok).0: OtherDrop); + StorageLive(_7); + _7 = move ((_2 as Ok).0: OtherDrop); _0 = const (); - drop(_8) -> [return: bb6, unwind: bb11]; + drop(_7) -> [return: bb6, unwind: bb11]; } bb6: { - StorageDead(_8); + StorageDead(_7); goto -> bb7; } @@ -74,13 +71,12 @@ fn method_1(_1: Guard) -> () { } bb8: { - drop(_5) -> [return: bb9, unwind: bb13]; + drop(_4) -> [return: bb9, unwind: bb13]; } bb9: { - StorageDead(_5); StorageDead(_4); - _10 = const false; + _9 = const false; StorageDead(_2); drop(_1) -> [return: bb10, unwind: bb14]; } @@ -94,7 +90,7 @@ fn method_1(_1: Guard) -> () { } bb12 (cleanup): { - drop(_5) -> [return: bb13, unwind terminate(cleanup)]; + drop(_4) -> [return: bb13, unwind terminate(cleanup)]; } bb13 (cleanup): { diff --git a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir index 4e1a59cea791c..c0ec752c2b613 100644 --- a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir +++ b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir @@ -5,44 +5,41 @@ fn method_1(_1: Guard) -> () { let mut _0: (); let mut _2: std::result::Result; let mut _3: &Guard; - let _4: &Guard; - let _5: Guard; - let mut _6: &Guard; - let mut _7: isize; - let _8: OtherDrop; - let _9: (); - let mut _10: bool; + let _4: Guard; + let mut _5: &Guard; + let mut _6: isize; + let _7: OtherDrop; + let _8: (); + let mut _9: bool; scope 1 { - debug other_drop => _8; + debug other_drop => _7; } scope 2 { - debug err => _9; + debug err => _8; } bb0: { - _10 = const false; + _9 = const false; StorageLive(_2); StorageLive(_3); StorageLive(_4); StorageLive(_5); - StorageLive(_6); - _6 = &_1; - _5 = ::clone(move _6) -> [return: bb1, unwind: bb13]; + _5 = &_1; + _4 = ::clone(move _5) -> [return: bb1, unwind: bb13]; } bb1: { - StorageDead(_6); - _4 = &_5; - _3 = &(*_4); + StorageDead(_5); + _3 = &_4; _2 = method_2(move _3) -> [return: bb2, unwind: bb12]; } bb2: { - _10 = const true; + _9 = const true; StorageDead(_3); PlaceMention(_2); - _7 = discriminant(_2); - switchInt(move _7) -> [0: bb5, 1: bb4, otherwise: bb3]; + _6 = discriminant(_2); + switchInt(move _6) -> [0: bb5, 1: bb4, otherwise: bb3]; } bb3: { @@ -50,22 +47,22 @@ fn method_1(_1: Guard) -> () { } bb4: { - StorageLive(_9); - _9 = copy ((_2 as Err).0: ()); + StorageLive(_8); + _8 = copy ((_2 as Err).0: ()); _0 = const (); - StorageDead(_9); + StorageDead(_8); goto -> bb7; } bb5: { - StorageLive(_8); - _8 = move ((_2 as Ok).0: OtherDrop); + StorageLive(_7); + _7 = move ((_2 as Ok).0: OtherDrop); _0 = const (); - drop(_8) -> [return: bb6, unwind: bb11]; + drop(_7) -> [return: bb6, unwind: bb11]; } bb6: { - StorageDead(_8); + StorageDead(_7); goto -> bb7; } @@ -74,13 +71,12 @@ fn method_1(_1: Guard) -> () { } bb8: { - drop(_5) -> [return: bb9, unwind: bb13]; + drop(_4) -> [return: bb9, unwind: bb13]; } bb9: { - StorageDead(_5); StorageDead(_4); - _10 = const false; + _9 = const false; StorageDead(_2); drop(_1) -> [return: bb10, unwind: bb14]; } @@ -94,7 +90,7 @@ fn method_1(_1: Guard) -> () { } bb12 (cleanup): { - drop(_5) -> [return: bb13, unwind terminate(cleanup)]; + drop(_4) -> [return: bb13, unwind terminate(cleanup)]; } bb13 (cleanup): { diff --git a/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-abort.diff index 610a1a4624f75..43dfd7d5c1a1f 100644 --- a/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-abort.diff @@ -9,13 +9,7 @@ let mut _4: &Test3; let mut _5: isize; let _6: &str; - let _7: &str; - let _8: &str; - let _9: &str; - let mut _10: isize; - let _11: &str; - let _12: &str; - let _13: &str; + let mut _7: isize; scope 1 { debug plop => _1; } @@ -39,26 +33,17 @@ } bb2: { - StorageLive(_8); - _8 = const "D"; - _3 = &(*_8); - StorageDead(_8); + _3 = const "D"; goto -> bb6; } bb3: { - StorageLive(_7); - _7 = const "C"; - _3 = &(*_7); - StorageDead(_7); + _3 = const "C"; goto -> bb6; } bb4: { - StorageLive(_6); - _6 = const "B(Empty)"; - _3 = &(*_6); - StorageDead(_6); + _3 = const "B(Empty)"; goto -> bb6; } @@ -70,43 +55,34 @@ bb6: { StorageDead(_4); StorageDead(_3); - StorageLive(_9); - _10 = discriminant((_1.1: Test3)); -- switchInt(move _10) -> [0: bb10, 1: bb9, 2: bb8, 3: bb7, otherwise: bb1]; -+ switchInt(move _10) -> [0: bb1, 1: bb1, 2: bb8, 3: bb7, otherwise: bb1]; + StorageLive(_6); + _7 = discriminant((_1.1: Test3)); +- switchInt(move _7) -> [0: bb10, 1: bb9, 2: bb8, 3: bb7, otherwise: bb1]; ++ switchInt(move _7) -> [0: bb1, 1: bb1, 2: bb8, 3: bb7, otherwise: bb1]; } bb7: { - StorageLive(_13); - _13 = const "D"; - _9 = &(*_13); - StorageDead(_13); + _6 = const "D"; goto -> bb11; } bb8: { - StorageLive(_12); - _12 = const "C"; - _9 = &(*_12); - StorageDead(_12); + _6 = const "C"; goto -> bb11; } bb9: { - StorageLive(_11); - _11 = const "B(Empty)"; - _9 = &(*_11); - StorageDead(_11); + _6 = const "B(Empty)"; goto -> bb11; } bb10: { - _9 = const "A(Empty)"; + _6 = const "A(Empty)"; goto -> bb11; } bb11: { - StorageDead(_9); + StorageDead(_6); _0 = const (); StorageDead(_1); return; diff --git a/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-unwind.diff index 610a1a4624f75..43dfd7d5c1a1f 100644 --- a/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-unwind.diff @@ -9,13 +9,7 @@ let mut _4: &Test3; let mut _5: isize; let _6: &str; - let _7: &str; - let _8: &str; - let _9: &str; - let mut _10: isize; - let _11: &str; - let _12: &str; - let _13: &str; + let mut _7: isize; scope 1 { debug plop => _1; } @@ -39,26 +33,17 @@ } bb2: { - StorageLive(_8); - _8 = const "D"; - _3 = &(*_8); - StorageDead(_8); + _3 = const "D"; goto -> bb6; } bb3: { - StorageLive(_7); - _7 = const "C"; - _3 = &(*_7); - StorageDead(_7); + _3 = const "C"; goto -> bb6; } bb4: { - StorageLive(_6); - _6 = const "B(Empty)"; - _3 = &(*_6); - StorageDead(_6); + _3 = const "B(Empty)"; goto -> bb6; } @@ -70,43 +55,34 @@ bb6: { StorageDead(_4); StorageDead(_3); - StorageLive(_9); - _10 = discriminant((_1.1: Test3)); -- switchInt(move _10) -> [0: bb10, 1: bb9, 2: bb8, 3: bb7, otherwise: bb1]; -+ switchInt(move _10) -> [0: bb1, 1: bb1, 2: bb8, 3: bb7, otherwise: bb1]; + StorageLive(_6); + _7 = discriminant((_1.1: Test3)); +- switchInt(move _7) -> [0: bb10, 1: bb9, 2: bb8, 3: bb7, otherwise: bb1]; ++ switchInt(move _7) -> [0: bb1, 1: bb1, 2: bb8, 3: bb7, otherwise: bb1]; } bb7: { - StorageLive(_13); - _13 = const "D"; - _9 = &(*_13); - StorageDead(_13); + _6 = const "D"; goto -> bb11; } bb8: { - StorageLive(_12); - _12 = const "C"; - _9 = &(*_12); - StorageDead(_12); + _6 = const "C"; goto -> bb11; } bb9: { - StorageLive(_11); - _11 = const "B(Empty)"; - _9 = &(*_11); - StorageDead(_11); + _6 = const "B(Empty)"; goto -> bb11; } bb10: { - _9 = const "A(Empty)"; + _6 = const "A(Empty)"; goto -> bb11; } bb11: { - StorageDead(_9); + StorageDead(_6); _0 = const (); StorageDead(_1); return; diff --git a/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-abort.diff index 97c71762f22e6..df7c48e89306b 100644 --- a/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-abort.diff @@ -6,7 +6,6 @@ let _1: &str; let mut _2: Test2; let mut _3: isize; - let _4: &str; bb0: { StorageLive(_1); @@ -21,10 +20,7 @@ } bb2: { - StorageLive(_4); - _4 = const "E"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "E"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-unwind.diff index 97c71762f22e6..df7c48e89306b 100644 --- a/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-unwind.diff @@ -6,7 +6,6 @@ let _1: &str; let mut _2: Test2; let mut _3: isize; - let _4: &str; bb0: { StorageLive(_1); @@ -21,10 +20,7 @@ } bb2: { - StorageLive(_4); - _4 = const "E"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "E"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-abort.diff index 7e798abcd4ed3..27954f057c873 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-abort.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test1; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -19,18 +17,12 @@ } bb1: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb4; } bb2: { - StorageLive(_4); - _4 = const "B(Empty)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(Empty)"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-unwind.diff index 7e798abcd4ed3..27954f057c873 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-unwind.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test1; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -19,18 +17,12 @@ } bb1: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb4; } bb2: { - StorageLive(_4); - _4 = const "B(Empty)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(Empty)"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-abort.diff index ac9b047624b1f..f6a9b793f3b24 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-abort.diff @@ -6,7 +6,6 @@ let _1: &str; let mut _2: Test2; let mut _3: isize; - let _4: &str; bb0: { StorageLive(_1); @@ -18,10 +17,7 @@ } bb1: { - StorageLive(_4); - _4 = const "E"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "E"; goto -> bb3; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-unwind.diff index ac9b047624b1f..f6a9b793f3b24 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-unwind.diff @@ -6,7 +6,6 @@ let _1: &str; let mut _2: Test2; let mut _3: isize; - let _4: &str; bb0: { StorageLive(_1); @@ -18,10 +17,7 @@ } bb1: { - StorageLive(_4); - _4 = const "E"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "E"; goto -> bb3; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-abort.diff index 9e85e56c583bf..84b84fcd1c881 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-abort.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test3; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -19,18 +17,12 @@ } bb1: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb4; } bb2: { - StorageLive(_4); - _4 = const "B(Empty)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(Empty)"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-unwind.diff index 9e85e56c583bf..84b84fcd1c881 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-unwind.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test3; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -19,18 +17,12 @@ } bb1: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb4; } bb2: { - StorageLive(_4); - _4 = const "B(Empty)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(Empty)"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-abort.diff index e83c6131fa587..ac27cbf653ca8 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-abort.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test4; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -18,18 +16,12 @@ } bb1: { - StorageLive(_5); - _5 = const "CD"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "CD"; goto -> bb4; } bb2: { - StorageLive(_4); - _4 = const "B(i32)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(i32)"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-unwind.diff index e83c6131fa587..ac27cbf653ca8 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-unwind.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test4; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -18,18 +16,12 @@ } bb1: { - StorageLive(_5); - _5 = const "CD"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "CD"; goto -> bb4; } bb2: { - StorageLive(_4); - _4 = const "B(i32)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(i32)"; goto -> bb4; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-abort.diff index 33e33ebddec6a..6157f7382684b 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-abort.diff @@ -6,9 +6,6 @@ let _1: &str; let mut _2: Test4; let mut _3: isize; - let _4: &str; - let _5: &str; - let _6: &str; bb0: { StorageLive(_1); @@ -20,26 +17,17 @@ } bb1: { - StorageLive(_6); - _6 = const "D"; - _1 = &(*_6); - StorageDead(_6); + _1 = const "D"; goto -> bb5; } bb2: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb5; } bb3: { - StorageLive(_4); - _4 = const "B(i32)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(i32)"; goto -> bb5; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-unwind.diff index 33e33ebddec6a..6157f7382684b 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-unwind.diff @@ -6,9 +6,6 @@ let _1: &str; let mut _2: Test4; let mut _3: isize; - let _4: &str; - let _5: &str; - let _6: &str; bb0: { StorageLive(_1); @@ -20,26 +17,17 @@ } bb1: { - StorageLive(_6); - _6 = const "D"; - _1 = &(*_6); - StorageDead(_6); + _1 = const "D"; goto -> bb5; } bb2: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb5; } bb3: { - StorageLive(_4); - _4 = const "B(i32)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(i32)"; goto -> bb5; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-abort.diff index d11c07c4ba301..bfbe54f5a80c2 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-abort.diff @@ -6,10 +6,6 @@ let _1: &str; let mut _2: Test4; let mut _3: isize; - let _4: &str; - let _5: &str; - let _6: &str; - let _7: &str; bb0: { StorageLive(_1); @@ -21,10 +17,7 @@ } bb1: { - StorageLive(_7); - _7 = const "A(other)D"; - _1 = &(*_7); - StorageDead(_7); + _1 = const "A(other)D"; goto -> bb7; } @@ -33,26 +26,17 @@ } bb3: { - StorageLive(_6); - _6 = const "C"; - _1 = &(*_6); - StorageDead(_6); + _1 = const "C"; goto -> bb7; } bb4: { - StorageLive(_5); - _5 = const "B(i32)"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "B(i32)"; goto -> bb7; } bb5: { - StorageLive(_4); - _4 = const "A(2)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "A(2)"; goto -> bb7; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-unwind.diff index d11c07c4ba301..bfbe54f5a80c2 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-unwind.diff @@ -6,10 +6,6 @@ let _1: &str; let mut _2: Test4; let mut _3: isize; - let _4: &str; - let _5: &str; - let _6: &str; - let _7: &str; bb0: { StorageLive(_1); @@ -21,10 +17,7 @@ } bb1: { - StorageLive(_7); - _7 = const "A(other)D"; - _1 = &(*_7); - StorageDead(_7); + _1 = const "A(other)D"; goto -> bb7; } @@ -33,26 +26,17 @@ } bb3: { - StorageLive(_6); - _6 = const "C"; - _1 = &(*_6); - StorageDead(_6); + _1 = const "C"; goto -> bb7; } bb4: { - StorageLive(_5); - _5 = const "B(i32)"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "B(i32)"; goto -> bb7; } bb5: { - StorageLive(_4); - _4 = const "A(2)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "A(2)"; goto -> bb7; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-abort.diff index ae1ca6efd4348..26fc801723412 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-abort.diff @@ -6,9 +6,6 @@ let _1: &str; let mut _2: Test5; let mut _3: i8; - let _4: &str; - let _5: &str; - let _6: &str; bb0: { StorageLive(_1); @@ -20,26 +17,17 @@ } bb1: { - StorageLive(_6); - _6 = const "D"; - _1 = &(*_6); - StorageDead(_6); + _1 = const "D"; goto -> bb5; } bb2: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb5; } bb3: { - StorageLive(_4); - _4 = const "B(T)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(T)"; goto -> bb5; } diff --git a/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-unwind.diff index 1e660036e46ae..95369d4f9ddcf 100644 --- a/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-unwind.diff @@ -6,9 +6,6 @@ let _1: &str; let mut _2: Test5; let mut _3: i8; - let _4: &str; - let _5: &str; - let _6: &str; bb0: { StorageLive(_1); @@ -20,26 +17,17 @@ } bb1: { - StorageLive(_6); - _6 = const "D"; - _1 = &(*_6); - StorageDead(_6); + _1 = const "D"; goto -> bb5; } bb2: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb5; } bb3: { - StorageLive(_4); - _4 = const "B(T)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(T)"; goto -> bb5; } diff --git a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff index befee026d6cb4..260a77eeb82f8 100644 --- a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test1; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -23,18 +21,12 @@ } bb2: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb5; } bb3: { - StorageLive(_4); - _4 = const "B(Empty)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(Empty)"; goto -> bb5; } diff --git a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff index befee026d6cb4..260a77eeb82f8 100644 --- a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff @@ -6,8 +6,6 @@ let _1: &str; let mut _2: Test1; let mut _3: isize; - let _4: &str; - let _5: &str; bb0: { StorageLive(_1); @@ -23,18 +21,12 @@ } bb2: { - StorageLive(_5); - _5 = const "C"; - _1 = &(*_5); - StorageDead(_5); + _1 = const "C"; goto -> bb5; } bb3: { - StorageLive(_4); - _4 = const "B(Empty)"; - _1 = &(*_4); - StorageDead(_4); + _1 = const "B(Empty)"; goto -> bb5; } diff --git a/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs index 49b55164235c9..0a9bd45785742 100644 --- a/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs +++ b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.rs @@ -53,8 +53,8 @@ fn main() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: let _local: &_ = m_s; - //~^ NOTE Capturing m_s[Deref] -> Immutable - //~| NOTE Min Capture m_s[Deref] -> Immutable + //~^ NOTE Capturing m_s[] -> ByCopy + //~| NOTE Min Capture m_s[] -> ByCopy }; } diff --git a/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr index b744865c4c2fc..487dd8f3952d4 100644 --- a/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr +++ b/tests/ui/closures/cromulent-copy-closure-captures-analysis-2021.stderr @@ -166,7 +166,7 @@ LL | | let _local: &_ = m_s; LL | | }; | |_________^ | -note: Capturing m_s[Deref] -> Immutable +note: Capturing m_s[] -> ByCopy --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:55:30 | LL | let _local: &_ = m_s; @@ -184,7 +184,7 @@ LL | | let _local: &_ = m_s; LL | | }; | |_________^ | -note: Min Capture m_s[Deref] -> Immutable +note: Min Capture m_s[] -> ByCopy --> $DIR/cromulent-copy-closure-captures-analysis-2021.rs:55:30 | LL | let _local: &_ = m_s; diff --git a/tests/ui/dropck/dropck_trait_cycle_checked.stderr b/tests/ui/dropck/dropck_trait_cycle_checked.stderr index f32736f1a674c..c7f724d0d0e08 100644 --- a/tests/ui/dropck/dropck_trait_cycle_checked.stderr +++ b/tests/ui/dropck/dropck_trait_cycle_checked.stderr @@ -2,7 +2,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:111:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` LL | o1.set0(&o2); | ^^^ borrowed value does not live long enough ... @@ -15,7 +15,7 @@ error[E0597]: `o3` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:112:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` + | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` LL | o1.set0(&o2); LL | o1.set1(&o3); | ^^^ borrowed value does not live long enough @@ -43,7 +43,7 @@ error[E0597]: `o3` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:114:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` + | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` ... LL | o2.set1(&o3); | ^^^ borrowed value does not live long enough @@ -57,7 +57,7 @@ error[E0597]: `o1` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:115:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o1` declared here -------- coercion requires that `o1` is borrowed for `'static` + | -- binding `o1` declared here -------- coercion requires that `o1` is borrowed for `'static` ... LL | o3.set0(&o1); | ^^^ borrowed value does not live long enough @@ -71,7 +71,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:116:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` ... LL | o3.set1(&o2); | ^^^ borrowed value does not live long enough diff --git a/tests/ui/dst/dst-object-from-unsized-type.next.stderr b/tests/ui/dst/dst-object-from-unsized-type.next.stderr index 032ba0cb14aeb..f94464984c6bb 100644 --- a/tests/ui/dst/dst-object-from-unsized-type.next.stderr +++ b/tests/ui/dst/dst-object-from-unsized-type.next.stderr @@ -32,14 +32,14 @@ LL - fn test2(t: &T) { LL + fn test2(t: &T) { | -error[E0277]: the trait bound `&str: CoerceUnsized<&dyn Foo>` is not satisfied in `str` +error[E0277]: the trait bound `&'static str: CoerceUnsized<&dyn Foo>` is not satisfied in `str` --> $DIR/dst-object-from-unsized-type.rs:23:28 | LL | let _: &[&dyn Foo] = &["hi"]; | ^^^^ within `str`, the trait `Sized` is not implemented for `str` | = note: `str` is considered to contain a `[u8]` slice for auto trait purposes - = note: required for `&str` to implement `CoerceUnsized<&dyn Foo>` + = note: required for `&'static str` to implement `CoerceUnsized<&dyn Foo>` = note: required for the cast from `&'static str` to `&dyn Foo` error[E0277]: the trait bound `&[u8]: CoerceUnsized<&dyn Foo>` is not satisfied in `[u8]` diff --git a/tests/ui/dst/dst-object-from-unsized-type.rs b/tests/ui/dst/dst-object-from-unsized-type.rs index 1e6113b3fc6fb..7807549c7625f 100644 --- a/tests/ui/dst/dst-object-from-unsized-type.rs +++ b/tests/ui/dst/dst-object-from-unsized-type.rs @@ -22,7 +22,7 @@ fn test2(t: &T) { fn test3() { let _: &[&dyn Foo] = &["hi"]; //[current]~^ ERROR the size for values of type - //[next]~^^ ERROR the trait bound `&str: CoerceUnsized<&dyn Foo>` is not satisfied in `str` + //[next]~^^ ERROR the trait bound `&'static str: CoerceUnsized<&dyn Foo>` is not satisfied in `str` } fn test4(x: &[u8]) { diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr index f5527eeb2cdba..623ac276b2d69 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -41,7 +41,7 @@ LL | | }); | |______^ argument requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` - = note: requirement occurs because of the type `Cell<&'?11 u32>`, which makes the generic argument `&'?11 u32` invariant + = note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 2fe03bff19884..6fe93e729c8e4 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -29,7 +29,7 @@ LL | foo(cell, |cell_a, cell_x| { LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure | ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here | - = note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant + = note: requirement occurs because of the type `Cell<&'?8 u32>`, which makes the generic argument `&'?8 u32` invariant = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 2f27fbe3f2efc..33b41a6f59f1d 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -36,7 +36,7 @@ LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` | - = note: requirement occurs because of the type `Cell<&'?37 u32>`, which makes the generic argument `&'?37 u32` invariant + = note: requirement occurs because of the type `Cell<&'?33 u32>`, which makes the generic argument `&'?33 u32` invariant = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 00be8fd7ab5c2..5bed3b40199fd 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -37,7 +37,7 @@ LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` | - = note: requirement occurs because of the type `Cell<&'?43 u32>`, which makes the generic argument `&'?43 u32` invariant + = note: requirement occurs because of the type `Cell<&'?39 u32>`, which makes the generic argument `&'?39 u32` invariant = note: the struct `Cell` is invariant over the parameter `T` = help: see for more information about variance diff --git a/tests/ui/regions/regions-free-region-ordering-incorrect.rs b/tests/ui/regions/regions-free-region-ordering-incorrect.rs index 1aee6e87644e9..de0040f3b8b9a 100644 --- a/tests/ui/regions/regions-free-region-ordering-incorrect.rs +++ b/tests/ui/regions/regions-free-region-ordering-incorrect.rs @@ -7,14 +7,14 @@ struct Node<'b, T: 'b> { val: T, - next: Option<&'b Node<'b, T>> + next: Option<&'b Node<'b, T>>, } impl<'b, T> Node<'b, T> { fn get<'a>(&'a self) -> &'b T { - match self.next { //~ ERROR lifetime may not live long enough + match self.next { Some(ref next) => next.get(), - None => &self.val + None => &self.val, //~ ERROR lifetime may not live long enough } } } diff --git a/tests/ui/regions/regions-free-region-ordering-incorrect.stderr b/tests/ui/regions/regions-free-region-ordering-incorrect.stderr index 9025f0c3cbd21..2b3968e9ff0e0 100644 --- a/tests/ui/regions/regions-free-region-ordering-incorrect.stderr +++ b/tests/ui/regions/regions-free-region-ordering-incorrect.stderr @@ -1,15 +1,13 @@ error: lifetime may not live long enough - --> $DIR/regions-free-region-ordering-incorrect.rs:15:9 + --> $DIR/regions-free-region-ordering-incorrect.rs:17:21 | -LL | impl<'b, T> Node<'b, T> { - | -- lifetime `'b` defined here -LL | fn get<'a>(&'a self) -> &'b T { - | -- lifetime `'a` defined here -LL | / match self.next { -LL | | Some(ref next) => next.get(), -LL | | None => &self.val -LL | | } - | |_________^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` +LL | impl<'b, T> Node<'b, T> { + | -- lifetime `'b` defined here +LL | fn get<'a>(&'a self) -> &'b T { + | -- lifetime `'a` defined here +... +LL | None => &self.val, + | ^^^^^^^^^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/tests/ui/rustc_public-ir-print/operands.stdout b/tests/ui/rustc_public-ir-print/operands.stdout index c8d31c6339cf2..56ca7509a9d14 100644 --- a/tests/ui/rustc_public-ir-print/operands.stdout +++ b/tests/ui/rustc_public-ir-print/operands.stdout @@ -25,77 +25,68 @@ fn operands(_1: u8) -> () { let _22: !; let mut _23: core::panicking::AssertKind; let mut _24: &u8; - let _25: &u8; - let mut _26: &u8; + let mut _25: &u8; + let mut _26: Option>; let _27: &u8; - let mut _28: Option>; - let _29: &u8; - let _30: u8; - let _31: (); - let mut _32: (&u8, &u8); - let mut _33: &u8; - let mut _34: &u8; - let _35: &u8; - let _36: &u8; - let mut _37: bool; - let mut _38: u8; - let mut _39: u8; - let mut _40: !; - let _41: core::panicking::AssertKind; - let _42: !; - let mut _43: core::panicking::AssertKind; - let mut _44: &u8; - let _45: &u8; - let mut _46: &u8; - let _47: &u8; - let mut _48: Option>; - let _49: (u8, u8); - let mut _50: u8; - let mut _51: u8; - let _52: u8; - let _53: u8; - let _54: (); - let mut _55: (&u8, &u8); - let mut _56: &u8; - let mut _57: &u8; - let _58: &u8; - let _59: &u8; - let mut _60: bool; - let mut _61: u8; - let mut _62: u8; - let mut _63: !; - let _64: core::panicking::AssertKind; - let _65: !; - let mut _66: core::panicking::AssertKind; - let mut _67: &u8; - let _68: &u8; - let mut _69: &u8; - let _70: &u8; - let mut _71: Option>; - let _72: usize; - let mut _73: &[u8]; - let mut _74: &[u8; 10]; - let _75: usize; - let mut _76: &usize; - let _77: &usize; - let _78: (); - let mut _79: (&usize, &usize); - let mut _80: &usize; - let mut _81: &usize; - let _82: &usize; - let _83: &usize; - let mut _84: bool; - let mut _85: usize; - let mut _86: usize; - let mut _87: !; - let _88: core::panicking::AssertKind; - let _89: !; - let mut _90: core::panicking::AssertKind; - let mut _91: &usize; - let _92: &usize; - let mut _93: &usize; - let _94: &usize; - let mut _95: Option>; + let _28: u8; + let _29: (); + let mut _30: (&u8, &u8); + let mut _31: &u8; + let mut _32: &u8; + let _33: &u8; + let _34: &u8; + let mut _35: bool; + let mut _36: u8; + let mut _37: u8; + let mut _38: !; + let _39: core::panicking::AssertKind; + let _40: !; + let mut _41: core::panicking::AssertKind; + let mut _42: &u8; + let mut _43: &u8; + let mut _44: Option>; + let _45: (u8, u8); + let mut _46: u8; + let mut _47: u8; + let _48: u8; + let _49: u8; + let _50: (); + let mut _51: (&u8, &u8); + let mut _52: &u8; + let mut _53: &u8; + let _54: &u8; + let _55: &u8; + let mut _56: bool; + let mut _57: u8; + let mut _58: u8; + let mut _59: !; + let _60: core::panicking::AssertKind; + let _61: !; + let mut _62: core::panicking::AssertKind; + let mut _63: &u8; + let mut _64: &u8; + let mut _65: Option>; + let _66: usize; + let mut _67: &[u8]; + let mut _68: &[u8; 10]; + let _69: usize; + let mut _70: &usize; + let _71: (); + let mut _72: (&usize, &usize); + let mut _73: &usize; + let mut _74: &usize; + let _75: &usize; + let _76: &usize; + let mut _77: bool; + let mut _78: usize; + let mut _79: usize; + let mut _80: !; + let _81: core::panicking::AssertKind; + let _82: !; + let mut _83: core::panicking::AssertKind; + let mut _84: &usize; + let mut _85: &usize; + let mut _86: Option>; debug val => _1; debug array => _2; debug first => _4; @@ -103,22 +94,22 @@ fn operands(_1: u8) -> () { debug left_val => _15; debug right_val => _16; debug kind => _21; - debug reference => _29; - debug dereferenced => _30; - debug left_val => _35; - debug right_val => _36; - debug kind => _41; - debug tuple => _49; - debug first_again => _52; - debug first_again_again => _53; - debug left_val => _58; - debug right_val => _59; - debug kind => _64; - debug length => _72; - debug size_of => _75; - debug left_val => _82; - debug right_val => _83; - debug kind => _88; + debug reference => _27; + debug dereferenced => _28; + debug left_val => _33; + debug right_val => _34; + debug kind => _39; + debug tuple => _45; + debug first_again => _48; + debug first_again_again => _49; + debug left_val => _54; + debug right_val => _55; + debug kind => _60; + debug length => _66; + debug size_of => _69; + debug left_val => _75; + debug right_val => _76; + debug kind => _81; bb0: { StorageLive(_2); StorageLive(_3); @@ -177,30 +168,30 @@ fn operands(_1: u8) -> () { StorageDead(_15); StorageDead(_12); StorageDead(_11); + StorageLive(_27); + _27 = &_4; + StorageLive(_28); + _28 = (*_27); StorageLive(_29); - _29 = &_4; StorageLive(_30); - _30 = (*_29); StorageLive(_31); + _31 = &_28; StorageLive(_32); + _32 = &_4; + _30 = (move _31, move _32); + StorageDead(_32); + StorageDead(_31); StorageLive(_33); - _33 = &_30; + _33 = (_30.0: &u8); StorageLive(_34); - _34 = &_4; - _32 = (move _33, move _34); - StorageDead(_34); - StorageDead(_33); + _34 = (_30.1: &u8); StorageLive(_35); - _35 = (_32.0: &u8); StorageLive(_36); - _36 = (_32.1: &u8); + _36 = (*_33); StorageLive(_37); - StorageLive(_38); - _38 = (*_35); - StorageLive(_39); - _39 = (*_36); - _37 = Eq(move _38, move _39); - switchInt(move _37) -> [0: bb7, otherwise: bb6]; + _37 = (*_34); + _35 = Eq(move _36, move _37); + switchInt(move _35) -> [0: bb7, otherwise: bb6]; } bb5: { StorageDead(_19); @@ -211,190 +202,171 @@ fn operands(_1: u8) -> () { StorageLive(_23); _23 = move _21; StorageLive(_24); + _24 = &(*_15); StorageLive(_25); - _25 = &(*_15); - _24 = &(*_25); + _25 = &(*_16); StorageLive(_26); - StorageLive(_27); - _27 = &(*_16); - _26 = &(*_27); - StorageLive(_28); - _28 = Option::None; - _22 = core::panicking::assert_failed::(move _23, move _24, move _26, move _28) -> unwind unreachable; + _26 = Option::None; + _22 = core::panicking::assert_failed::(move _23, move _24, move _25, move _26) -> unwind unreachable; } bb6: { - StorageDead(_39); - StorageDead(_38); - _31 = (); StorageDead(_37); StorageDead(_36); + _29 = (); StorageDead(_35); - StorageDead(_32); - StorageDead(_31); + StorageDead(_34); + StorageDead(_33); + StorageDead(_30); + StorageDead(_29); + StorageLive(_45); + StorageLive(_46); + _46 = _4; + StorageLive(_47); + _47 = _7; + _45 = (move _46, move _47); + StorageDead(_47); + StorageDead(_46); + StorageLive(_48); + _48 = (_45.0: u8); StorageLive(_49); + _49 = (_45.0: u8); StorageLive(_50); - _50 = _4; StorageLive(_51); - _51 = _7; - _49 = (move _50, move _51); - StorageDead(_51); - StorageDead(_50); StorageLive(_52); - _52 = (_49.0: u8); + _52 = &_48; StorageLive(_53); - _53 = (_49.0: u8); + _53 = &_49; + _51 = (move _52, move _53); + StorageDead(_53); + StorageDead(_52); StorageLive(_54); + _54 = (_51.0: &u8); StorageLive(_55); + _55 = (_51.1: &u8); StorageLive(_56); - _56 = &_52; StorageLive(_57); - _57 = &_53; - _55 = (move _56, move _57); - StorageDead(_57); - StorageDead(_56); + _57 = (*_54); StorageLive(_58); - _58 = (_55.0: &u8); - StorageLive(_59); - _59 = (_55.1: &u8); - StorageLive(_60); - StorageLive(_61); - _61 = (*_58); - StorageLive(_62); - _62 = (*_59); - _60 = Eq(move _61, move _62); - switchInt(move _60) -> [0: bb9, otherwise: bb8]; + _58 = (*_55); + _56 = Eq(move _57, move _58); + switchInt(move _56) -> [0: bb9, otherwise: bb8]; } bb7: { - StorageDead(_39); - StorageDead(_38); + StorageDead(_37); + StorageDead(_36); + StorageLive(_39); + _39 = AssertKind::Eq; + StorageLive(_40); StorageLive(_41); - _41 = AssertKind::Eq; + _41 = move _39; StorageLive(_42); + _42 = &(*_33); StorageLive(_43); - _43 = move _41; + _43 = &(*_34); StorageLive(_44); - StorageLive(_45); - _45 = &(*_35); - _44 = &(*_45); - StorageLive(_46); - StorageLive(_47); - _47 = &(*_36); - _46 = &(*_47); - StorageLive(_48); - _48 = Option::None; - _42 = core::panicking::assert_failed::(move _43, move _44, move _46, move _48) -> unwind unreachable; + _44 = Option::None; + _40 = core::panicking::assert_failed::(move _41, move _42, move _43, move _44) -> unwind unreachable; } bb8: { - StorageDead(_62); - StorageDead(_61); - _54 = (); - StorageDead(_60); - StorageDead(_59); StorageDead(_58); + StorageDead(_57); + _50 = (); + StorageDead(_56); StorageDead(_55); StorageDead(_54); - StorageLive(_72); - StorageLive(_73); - StorageLive(_74); - _74 = &_2; - _73 = move _74 as &[u8]; - StorageDead(_74); - _72 = core::slice::::len(move _73) -> [return: bb10, unwind unreachable]; + StorageDead(_51); + StorageDead(_50); + StorageLive(_66); + StorageLive(_67); + StorageLive(_68); + _68 = &_2; + _67 = move _68 as &[u8]; + StorageDead(_68); + _66 = core::slice::::len(move _67) -> [return: bb10, unwind unreachable]; } bb9: { - StorageDead(_62); - StorageDead(_61); + StorageDead(_58); + StorageDead(_57); + StorageLive(_60); + _60 = AssertKind::Eq; + StorageLive(_61); + StorageLive(_62); + _62 = move _60; + StorageLive(_63); + _63 = &(*_54); StorageLive(_64); - _64 = AssertKind::Eq; + _64 = &(*_55); StorageLive(_65); - StorageLive(_66); - _66 = move _64; - StorageLive(_67); - StorageLive(_68); - _68 = &(*_58); - _67 = &(*_68); + _65 = Option::None; + _61 = core::panicking::assert_failed::(move _62, move _63, move _64, move _65) -> unwind unreachable; + } + bb10: { + StorageDead(_67); StorageLive(_69); StorageLive(_70); - _70 = &(*_59); - _69 = &(*_70); - StorageLive(_71); - _71 = Option::None; - _65 = core::panicking::assert_failed::(move _66, move _67, move _69, move _71) -> unwind unreachable; + _70 = &_66; + _69 = std::mem::size_of_val::(move _70) -> [return: bb11, unwind unreachable]; } - bb10: { + bb11: { + StorageDead(_70); + StorageLive(_71); + StorageLive(_72); + StorageLive(_73); + _73 = &_66; + StorageLive(_74); + _74 = &_69; + _72 = (move _73, move _74); + StorageDead(_74); StorageDead(_73); StorageLive(_75); + _75 = (_72.0: &usize); StorageLive(_76); + _76 = (_72.1: &usize); StorageLive(_77); - _77 = &_72; - _76 = &(*_77); - _75 = std::mem::size_of_val::(move _76) -> [return: bb11, unwind unreachable]; - } - bb11: { - StorageDead(_76); - StorageDead(_77); StorageLive(_78); + _78 = (*_75); StorageLive(_79); - StorageLive(_80); - _80 = &_72; - StorageLive(_81); - _81 = &_75; - _79 = (move _80, move _81); - StorageDead(_81); - StorageDead(_80); - StorageLive(_82); - _82 = (_79.0: &usize); - StorageLive(_83); - _83 = (_79.1: &usize); - StorageLive(_84); - StorageLive(_85); - _85 = (*_82); - StorageLive(_86); - _86 = (*_83); - _84 = Eq(move _85, move _86); - switchInt(move _84) -> [0: bb13, otherwise: bb12]; + _79 = (*_76); + _77 = Eq(move _78, move _79); + switchInt(move _77) -> [0: bb13, otherwise: bb12]; } bb12: { - StorageDead(_86); - StorageDead(_85); - _78 = (); - StorageDead(_84); - StorageDead(_83); - StorageDead(_82); StorageDead(_79); StorageDead(_78); - _0 = (); + _71 = (); + StorageDead(_77); + StorageDead(_76); StorageDead(_75); StorageDead(_72); - StorageDead(_53); - StorageDead(_52); + StorageDead(_71); + _0 = (); + StorageDead(_69); + StorageDead(_66); StorageDead(_49); - StorageDead(_30); - StorageDead(_29); + StorageDead(_48); + StorageDead(_45); + StorageDead(_28); + StorageDead(_27); StorageDead(_7); StorageDead(_4); StorageDead(_2); return; } bb13: { - StorageDead(_86); - StorageDead(_85); - StorageLive(_88); - _88 = AssertKind::Eq; - StorageLive(_89); - StorageLive(_90); - _90 = move _88; - StorageLive(_91); - StorageLive(_92); - _92 = &(*_82); - _91 = &(*_92); - StorageLive(_93); - StorageLive(_94); - _94 = &(*_83); - _93 = &(*_94); - StorageLive(_95); - _95 = Option::None; - _89 = core::panicking::assert_failed::(move _90, move _91, move _93, move _95) -> unwind unreachable; + StorageDead(_79); + StorageDead(_78); + StorageLive(_81); + _81 = AssertKind::Eq; + StorageLive(_82); + StorageLive(_83); + _83 = move _81; + StorageLive(_84); + _84 = &(*_75); + StorageLive(_85); + _85 = &(*_76); + StorageLive(_86); + _86 = Option::None; + _82 = core::panicking::assert_failed::(move _83, move _84, move _85, move _86) -> unwind unreachable; } } fn more_operands() -> [Ctors; 3] { diff --git a/tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr b/tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr index 4c469fd2222e3..beb31a127530e 100644 --- a/tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr +++ b/tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr @@ -121,7 +121,7 @@ error[E0277]: `&u8` cannot be safely transmuted into `&u8` LL | unsafe { extend_hrtb(src) } | ^^^^^^^^^^^^---^ | | | - | | `&u8` doesn't satisfy the trait bound + | | `&'a u8` doesn't satisfy the trait bound | unsatisfied trait bound | = help: the nightly-only, unstable trait `for<'b> std::mem::TransmuteFrom<&u8, std::mem::Assume { alignment: false, lifetimes: true, safety: false, validity: false }>` is not implemented for `&'b u8` From bbfc5b351c5e76159b2cea0b7be54174ac0225e6 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 9 Oct 2026 20:27:39 +0000 Subject: [PATCH 20/22] Destabilize `vec::from_elem` --- library/alloc/src/vec/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 8bcad62226a0b..15edfdbf1fdca 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3798,7 +3798,7 @@ impl Vec { #[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "liballoc_internals", issue = "none")] #[rustc_diagnostic_item = "vec_from_elem"] pub fn from_elem(elem: T, n: usize) -> Vec { ::from_elem(elem, n, Global) From b3735af98e615ed709c48d3eaeb627159aee0cb6 Mon Sep 17 00:00:00 2001 From: tmiasko Date: Sat, 10 Oct 2026 11:12:34 +0000 Subject: [PATCH 21/22] Fix incorrect impl JoinSemiLattice for State The implementation had an incorrect short-circruting behavior, i.e., it failed to join `borrow` when `qualif` changed. This lead implementation to accept code that should have been rejected. Fix the issue and fallout in the standard library and tests. --- .../src/check_consts/resolver.rs | 5 ++++- library/alloctests/tests/lib.rs | 1 + library/core/src/mem/maybe_dangling.rs | 1 + library/coretests/tests/lib.rs | 1 + .../consts/qualif-indirect-mutation-fail.rs | 22 +++++++++++++++++++ .../qualif-indirect-mutation-fail.stderr | 20 ++++++++++++++++- 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index 4fc8c62ccf80a..6b1947558635b 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -319,7 +319,10 @@ impl DebugWithContext for State { impl JoinSemiLattice for State { fn join(&mut self, other: &Self) -> bool { - self.qualif.join(&other.qualif) || self.borrow.join(&other.borrow) + // `join` has a side-effect on `self` so make sure we always call it on both fields. + let a = self.qualif.join(&other.qualif); + let b = self.borrow.join(&other.borrow); + a || b } } diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 5c8ee92388dd0..5987bc66632c4 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -16,6 +16,7 @@ #![feature(const_btree_len)] #![feature(const_cmp)] #![feature(const_heap)] +#![feature(const_precise_live_drops)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] diff --git a/library/core/src/mem/maybe_dangling.rs b/library/core/src/mem/maybe_dangling.rs index 46e5228a2da3f..d0ed5440cccd1 100644 --- a/library/core/src/mem/maybe_dangling.rs +++ b/library/core/src/mem/maybe_dangling.rs @@ -99,6 +99,7 @@ impl MaybeDangling

{ /// Extracts the value from the `MaybeDangling` container. /// /// Note that this is UB if the inner value is currently dangling. + #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn into_inner(self) -> P where P: Sized, diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 1fdb0c820d662..4e9628a9b3294 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -36,6 +36,7 @@ #![feature(const_iter)] #![feature(const_ops)] #![feature(const_option_ops)] +#![feature(const_precise_live_drops)] #![feature(const_ref_cell)] #![feature(const_result_trait_fn)] #![feature(const_select_unpredictable)] diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.rs b/tests/ui/consts/qualif-indirect-mutation-fail.rs index 26d251788c3ab..a4a063a4520f3 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.rs +++ b/tests/ui/consts/qualif-indirect-mutation-fail.rs @@ -69,3 +69,25 @@ pub const fn address_of_const() { let y: Option = None; //~ ERROR destructor of std::ptr::addr_of!(y); } + +// Regression test for an incorrect implementation of state join. +pub const fn regression_test_for_incorrect_join() { + let mut a = Some(NotConstDestruct); //~ ERROR destructor of + let b = NotConstDestruct; + let p = &raw mut a; + let x = unsafe { std::ptr::read(p) }; + std::mem::forget(a); + std::mem::forget(x); + a = None; + unsafe { std::ptr::write(p, Some(b)) }; +} + +// Use after move cannot sneak past checks. +// NB: Semantics of MIR move elimination might make it possible to accept this. +pub const fn use_after_move() { + let mut a = None; //~ ERROR destructor of + let p = &raw mut a; + std::mem::forget(a); + a = None; + unsafe { std::ptr::write(p, Some(NotConstDestruct)) }; +} diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr index 2301490065d45..8d5e6010e582e 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr +++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr @@ -77,6 +77,24 @@ LL | let x: Option = None; LL | } | - value is dropped here -error: aborting due to 9 previous errors +error[E0493]: destructor of `Option` cannot be evaluated at compile-time + --> $DIR/qualif-indirect-mutation-fail.rs:75:9 + | +LL | let mut a = Some(NotConstDestruct); + | ^^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here + +error[E0493]: destructor of `Option` cannot be evaluated at compile-time + --> $DIR/qualif-indirect-mutation-fail.rs:88:9 + | +LL | let mut a = None; + | ^^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here + +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0493`. From d3817995ec3ea041ca649273052ece70ec4783a5 Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas Chirananthavat)" Date: Sun, 11 Oct 2026 17:09:07 +0700 Subject: [PATCH 22/22] Fix build error for crater. This just potentially makes the order of diagnostics nondeterministic, which is fine. --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 4f688ca449477..6148f6d229815 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -237,7 +237,6 @@ where if !region_errors.iter().all(&is_bound_failure) { region_errors.retain(|e| !is_bound_failure(e)); } - region_errors.sort_by_key(|e| e.origin().span()); for error in ®ion_errors { let span = error.origin().span();