From be76bdf9058172dd22a67332b45c0ab93268b3b3 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Wed, 15 Sep 2021 20:54:50 -0400 Subject: [PATCH 01/18] Remove ToPredicate impls that use Binder::dummy --- .../src/type_check/canonical.rs | 4 +-- compiler/rustc_borrowck/src/type_check/mod.rs | 10 +++++-- .../src/infer/canonical/query_response.rs | 6 ++-- compiler/rustc_infer/src/infer/combine.rs | 5 ++-- compiler/rustc_infer/src/infer/sub.rs | 4 +-- compiler/rustc_infer/src/traits/engine.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 17 ----------- .../rustc_trait_selection/src/autoderef.rs | 2 +- compiler/rustc_trait_selection/src/infer.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- .../src/traits/fulfill.rs | 3 +- .../rustc_trait_selection/src/traits/mod.rs | 3 +- .../src/traits/object_safety.rs | 12 ++++---- .../src/traits/select/confirmation.rs | 6 ++-- .../rustc_trait_selection/src/traits/util.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 28 +++++++++++-------- compiler/rustc_traits/src/type_op.rs | 5 ++-- compiler/rustc_typeck/src/check/_match.rs | 15 +++++----- compiler/rustc_typeck/src/check/coercion.rs | 4 +-- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- compiler/rustc_typeck/src/check/method/mod.rs | 2 +- .../rustc_typeck/src/check/method/probe.rs | 3 +- compiler/rustc_typeck/src/check/wfcheck.rs | 8 +++--- compiler/rustc_typeck/src/collect.rs | 23 +++++++++------ compiler/rustc_typeck/src/hir_wf_check.rs | 3 +- compiler/rustc_typeck/src/outlives/mod.rs | 10 ++++--- 27 files changed, 99 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 18070164e8219..e776198822281 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -89,10 +89,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { category: ConstraintCategory, ) { self.prove_predicates( - Some(ty::PredicateKind::Trait(ty::TraitPredicate { + Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: ty::BoundConstness::NotConst, - })), + }))), locations, category, ); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3e757827a5e6c..1184a7aa0ac9f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1078,7 +1078,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } self.prove_predicate( - ty::PredicateKind::WellFormed(inferred_ty.into()).to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())) + .to_predicate(self.tcx()), Locations::All(span), ConstraintCategory::TypeAnnotation, ); @@ -1314,7 +1315,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { obligations.obligations.push(traits::Obligation::new( ObligationCause::dummy(), param_env, - ty::PredicateKind::WellFormed(revealed_ty.into()).to_predicate(infcx.tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(revealed_ty.into())) + .to_predicate(infcx.tcx), )); obligations.add( infcx @@ -1584,7 +1586,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_call_dest(body, term, &sig, destination, term_location); self.prove_predicates( - sig.inputs_and_output.iter().map(|ty| ty::PredicateKind::WellFormed(ty.into())), + sig.inputs_and_output + .iter() + .map(|ty| ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))), term_location.to_locations(), ConstraintCategory::Boring, ); diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 6a97a6c43c11e..b5c0307255771 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -669,8 +669,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { self.obligations.push(Obligation { cause: self.cause.clone(), param_env: self.param_env, - predicate: ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(sup, sub)) - .to_predicate(self.infcx.tcx), + predicate: ty::Binder::dummy(ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate( + sup, sub, + ))) + .to_predicate(self.infcx.tcx), recursion_depth: 0, }); } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a0ee212bed0cd..7deded0282cd3 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -360,7 +360,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { self.obligations.push(Obligation::new( self.trace.cause.clone(), self.param_env, - ty::PredicateKind::WellFormed(b_ty.into()).to_predicate(self.infcx.tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into())) + .to_predicate(self.infcx.tcx), )); } @@ -463,7 +464,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { self.obligations.push(Obligation::new( self.trace.cause.clone(), self.param_env, - predicate.to_predicate(self.tcx()), + ty::Binder::dummy(predicate).to_predicate(self.tcx()), )); } } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 1692d8ee526d0..8ef0d132cf09f 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -97,11 +97,11 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { self.fields.obligations.push(Obligation::new( self.fields.trace.cause.clone(), self.fields.param_env, - ty::PredicateKind::Subtype(ty::SubtypePredicate { + ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: self.a_is_expected, a, b, - }) + })) .to_predicate(self.tcx()), )); diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 42333dc29bc7c..a4509c69b3c05 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -34,7 +34,7 @@ pub trait TraitEngine<'tcx>: 'tcx { cause, recursion_depth: 0, param_env, - predicate: trait_ref.without_const().to_predicate(infcx.tcx), + predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx), }, ); } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 3a25cb66896d5..30d5613d5820d 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -231,6 +231,7 @@ impl Elaborator<'tcx> { None } }) + .map(ty::Binder::dummy) .map(|predicate_kind| predicate_kind.to_predicate(tcx)) .filter(|&predicate| visited.insert(predicate)) .map(|predicate| { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 777c6035be831..ab27bd6caa7df 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -792,23 +792,6 @@ impl ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> { } } -impl ToPredicate<'tcx> for PredicateKind<'tcx> { - #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - tcx.mk_predicate(Binder::dummy(self)) - } -} - -impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateKind::Trait(ty::TraitPredicate { - trait_ref: self.value, - constness: self.constness, - }) - .to_predicate(tcx) - } -} - impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.value diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 969962e55b0df..a89796f172c5a 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let obligation = traits::Obligation::new( cause.clone(), self.param_env, - trait_ref.without_const().to_predicate(tcx), + ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), ); if !self.infcx.predicate_may_hold(&obligation) { debug!("overloaded_deref_ty: cannot match obligation"); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 42cbed600d5bf..8fb4eb641c26a 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -120,7 +120,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { cause: traits::ObligationCause::dummy(), param_env, recursion_depth: 0, - predicate: trait_ref.without_const().to_predicate(self.tcx), + predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx), }; self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 9371ff3405eb0..1f4bdb316ad3a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -724,7 +724,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let new_obligation = Obligation::new( ObligationCause::dummy(), param_env, - new_trait_ref.without_const().to_predicate(self.tcx), + ty::Binder::dummy(new_trait_ref).without_const().to_predicate(self.tcx), ); if self.predicate_must_hold_modulo_regions(&new_obligation) { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index b376f42929249..788c55276ad36 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -405,7 +405,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { | ty::PredicateKind::Coerce(_) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) => { - let pred = infcx.replace_bound_vars_with_placeholders(binder); + let pred = + ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder)); ProcessResult::Changed(mk_pending(vec![ obligation.with(pred.to_predicate(self.selcx.tcx())), ])) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index ef208c44471cb..baa26cb9ef877 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -139,7 +139,8 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( infcx.tcx.def_path_str(def_id) ); - let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }; + let trait_ref = + ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }); let obligation = Obligation { param_env, cause: ObligationCause::misc(span, hir::CRATE_HIR_ID), diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4922cf45a4a10..8bc67f0d17df6 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -671,10 +671,10 @@ fn receiver_is_dispatchable<'tcx>( let param_env = tcx.param_env(method.def_id); // Self: Unsize - let unsize_predicate = ty::TraitRef { + let unsize_predicate = ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]), - } + }) .without_const() .to_predicate(tcx); @@ -689,7 +689,9 @@ fn receiver_is_dispatchable<'tcx>( } }); - ty::TraitRef { def_id: unsize_did, substs }.without_const().to_predicate(tcx) + ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, substs }) + .without_const() + .to_predicate(tcx) }; let caller_bounds: Vec> = param_env @@ -703,10 +705,10 @@ fn receiver_is_dispatchable<'tcx>( // Receiver: DispatchFromDyn U]> let obligation = { - let predicate = ty::TraitRef { + let predicate = ty::Binder::dummy(ty::TraitRef { def_id: dispatch_from_dyn_did, substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), - } + }) .without_const() .to_predicate(tcx); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3b6555de912e9..4e86807ba183e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -646,7 +646,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations.push(Obligation::new( obligation.cause.clone(), obligation.param_env, - ty::PredicateKind::ClosureKind(closure_def_id, substs, kind) + ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)) .to_predicate(self.tcx()), )); } @@ -898,10 +898,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); // We can only make objects from sized types. - let tr = ty::TraitRef::new( + let tr = ty::Binder::dummy(ty::TraitRef::new( tcx.require_lang_item(LangItem::Sized, None), tcx.mk_substs_trait(source, &[]), - ); + )); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); // If the type is `Foo + 'a`, ensure that the type diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index b108d85bb20c9..ed49abbbedc92 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -248,7 +248,7 @@ pub fn predicate_for_trait_ref<'tcx>( cause, param_env, recursion_depth, - predicate: trait_ref.without_const().to_predicate(tcx), + predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 75307f135636b..68081646391b3 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -349,7 +349,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { new_cause, depth, param_env, - ty::PredicateKind::WellFormed(arg).to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx), ) }), ); @@ -399,7 +399,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause.clone(), depth, param_env, - ty::PredicateKind::WellFormed(arg).to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx), ) }), ); @@ -416,7 +416,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, self.param_env, - trait_ref.without_const().to_predicate(self.infcx.tcx), + ty::Binder::dummy(trait_ref).without_const().to_predicate(self.infcx.tcx), )); } } @@ -443,9 +443,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let obligations = self.nominal_obligations(uv.def.did, substs); self.out.extend(obligations); - let predicate = ty::PredicateKind::ConstEvaluatable( + let predicate = ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable( ty::Unevaluated::new(uv.def, substs), - ) + )) .to_predicate(self.tcx()); let cause = self.cause(traits::MiscObligation); self.out.push(traits::Obligation::with_depth( @@ -469,8 +469,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, self.param_env, - ty::PredicateKind::WellFormed(resolved_constant.into()) - .to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed( + resolved_constant.into(), + )) + .to_predicate(self.tcx()), )); } } @@ -556,8 +558,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, depth, param_env, - ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(rty, r)) - .to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::TypeOutlives( + ty::OutlivesPredicate(rty, r), + )) + .to_predicate(self.tcx()), )); } } @@ -646,7 +650,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause.clone(), depth, param_env, - ty::PredicateKind::ObjectSafe(did).to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did)) + .to_predicate(tcx), ) })); } @@ -673,7 +678,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, param_env, - ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())) + .to_predicate(self.tcx()), )); } else { // Yes, resolved, proceed with the result. diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index a76fb84261615..f954cab240ca2 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -156,7 +156,8 @@ impl AscribeUserTypeCx<'me, 'tcx> { self.relate(self_ty, Variance::Invariant, impl_self_ty)?; self.prove_predicate( - ty::PredicateKind::WellFormed(impl_self_ty.into()).to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into())) + .to_predicate(self.tcx()), span, ); } @@ -173,7 +174,7 @@ impl AscribeUserTypeCx<'me, 'tcx> { // type were ill-formed but did not appear in `ty`, // which...could happen with normalization... self.prove_predicate( - ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(self.tcx()), span, ); Ok(()) diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 01227cad334fc..6a231e719e664 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -524,13 +524,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for o in obligations { match o.predicate.kind().skip_binder() { ty::PredicateKind::Trait(t) => { - let pred = ty::PredicateKind::Trait(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: t.def_id(), - substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]), - }, - constness: t.constness, - }); + let pred = + ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { + trait_ref: ty::TraitRef { + def_id: t.def_id(), + substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]), + }, + constness: t.constness, + })); let obl = Obligation::new( o.cause.clone(), self.param_env, diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 6fe96e4cc27b2..d6ba40654db82 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -273,10 +273,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { obligations.push(Obligation::new( self.cause.clone(), self.param_env, - ty::PredicateKind::Coerce(ty::CoercePredicate { + ty::Binder::dummy(ty::PredicateKind::Coerce(ty::CoercePredicate { a: source_ty, b: target_ty, - }) + })) .to_predicate(self.tcx()), )); } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 9748c0835bf12..59c1e97d13ff1 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -568,7 +568,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.register_predicate(traits::Obligation::new( cause, self.param_env, - ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx), )); } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 2136d925423b9..8c547c74426e6 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -412,7 +412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { obligations.push(traits::Obligation::new( cause, self.param_env, - ty::PredicateKind::WellFormed(method_ty.into()).to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())).to_predicate(tcx), )); let callee = MethodCallee { def_id, substs: trait_ref.substs, sig: fn_sig }; diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index cbfdce96bc57b..bf83191ad57b1 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1470,7 +1470,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } } - let predicate = trait_ref.without_const().to_predicate(self.tcx); + let predicate = + ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx); let obligation = traits::Obligation::new(cause, self.param_env, predicate); if !self.predicate_may_hold(&obligation) { result = ProbeResult::NoMatch; diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index cb07fcf5fef58..fba3eb3f5e2a3 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -541,10 +541,10 @@ fn check_type_defn<'tcx, F>( fcx.register_predicate(traits::Obligation::new( cause, fcx.param_env, - ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new( + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new( ty::WithOptConstParam::unknown(discr_def_id.to_def_id()), discr_substs, - )) + ))) .to_predicate(tcx), )); } @@ -1290,10 +1290,10 @@ fn receiver_is_implemented( cause: ObligationCause<'tcx>, receiver_ty: Ty<'tcx>, ) -> bool { - let trait_ref = ty::TraitRef { + let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id: receiver_trait_def_id, substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]), - }; + }); let obligation = traits::Obligation::new( cause, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1bc7bc3e063d4..1ec094d6ef953 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -607,7 +607,8 @@ fn type_param_predicates( ItemKind::Trait(_, _, ref generics, ..) => { // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { - let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); + let identity_trait_ref = + ty::Binder::dummy(ty::TraitRef::identity(tcx, item_def_id)); extend = Some((identity_trait_ref.without_const().to_predicate(tcx), item.span)); } @@ -2002,11 +2003,14 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { // *current* state of an external file. span = tcx.sess.source_map().guess_head_span(span); } - result.predicates = - tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( - ty::TraitRef::identity(tcx, def_id).without_const().to_predicate(tcx), + result.predicates = tcx.arena.alloc_from_iter( + result.predicates.iter().copied().chain(std::iter::once(( + ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id)) + .without_const() + .to_predicate(tcx), span, - )))); + ))), + ); } debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result @@ -2238,8 +2242,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP } _ => bug!(), }; - let pred = ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)) - .to_predicate(icx.tcx); + let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives( + ty::OutlivesPredicate(r1, r2), + )) + .to_predicate(icx.tcx); (pred, span) })) @@ -2304,7 +2310,8 @@ fn const_evaluatable_predicates_of<'tcx>( assert_eq!(uv.promoted, None); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::PredicateKind::ConstEvaluatable(uv.shrink()).to_predicate(self.tcx), + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) + .to_predicate(self.tcx), span, )); } diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs index b7ede0e4bf251..39bcf8999323d 100644 --- a/compiler/rustc_typeck/src/hir_wf_check.rs +++ b/compiler/rustc_typeck/src/hir_wf_check.rs @@ -83,7 +83,8 @@ fn diagnostic_hir_wf_check<'tcx>( traits::Obligation::new( cause, self.param_env, - ty::PredicateKind::WellFormed(tcx_ty.into()).to_predicate(self.tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into())) + .to_predicate(self.tcx), ), ); diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index 70a2ba7fcd9d9..9c6efffdaf0fe 100644 --- a/compiler/rustc_typeck/src/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs @@ -104,13 +104,15 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { |(ty::OutlivesPredicate(kind1, region2), &span)| { match kind1.unpack() { GenericArgKind::Type(ty1) => Some(( - ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty1, region2)) - .to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::TypeOutlives( + ty::OutlivesPredicate(ty1, region2), + )) + .to_predicate(tcx), span, )), GenericArgKind::Lifetime(region1) => Some(( - ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate( - region1, region2, + ty::Binder::dummy(ty::PredicateKind::RegionOutlives( + ty::OutlivesPredicate(region1, region2), )) .to_predicate(tcx), span, From c065f571117dab63c2a7a07475dd1962b0104f8c Mon Sep 17 00:00:00 2001 From: jackh726 Date: Wed, 15 Sep 2021 22:55:10 -0400 Subject: [PATCH 02/18] Remove ToPolyTraitRef impl for TraitRef --- compiler/rustc_middle/src/ty/mod.rs | 6 ----- compiler/rustc_middle/src/ty/sty.rs | 7 ++++-- .../src/traits/object_safety.rs | 13 +++++----- .../src/traits/project.rs | 6 ++--- .../src/traits/select/confirmation.rs | 3 ++- compiler/rustc_typeck/src/check/method/mod.rs | 4 +-- .../rustc_typeck/src/check/method/probe.rs | 8 +++--- .../rustc_typeck/src/check/method/suggest.rs | 6 ++--- compiler/rustc_typeck/src/collect.rs | 25 ++++++++----------- 9 files changed, 33 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ab27bd6caa7df..3fd9a3c14f8fc 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -769,12 +769,6 @@ pub trait ToPolyTraitRef<'tcx> { fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>; } -impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> { - fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { - ty::Binder::dummy(*self) - } -} - impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { self.map_bound_ref(|trait_pred| trait_pred.trait_ref) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0fbaf81c21e40..9825309fc8a27 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -844,8 +844,11 @@ impl<'tcx> TraitRef<'tcx> { /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` /// are the parameters defined on trait. - pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> { - TraitRef { def_id, substs: InternalSubsts::identity_for_item(tcx, def_id) } + pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> { + ty::Binder::dummy(TraitRef { + def_id, + substs: InternalSubsts::identity_for_item(tcx, def_id), + }) } #[inline] diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8bc67f0d17df6..0bb00dfeb43ad 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -250,7 +250,7 @@ fn predicates_reference_self( trait_def_id: DefId, supertraits_only: bool, ) -> SmallVec<[Span; 1]> { - let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); + let trait_ref = ty::TraitRef::identity(tcx, trait_def_id); let predicates = if supertraits_only { tcx.super_predicates_of(trait_def_id) } else { @@ -554,11 +554,11 @@ fn object_ty_for_trait<'tcx>( let trait_ref = ty::TraitRef::identity(tcx, trait_def_id); - let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait( - ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref), - )); + let trait_predicate = trait_ref.map_bound(|trait_ref| { + ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)) + }); - let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref)) + let mut associated_types = traits::supertraits(tcx, trait_ref) .flat_map(|super_trait_ref| { tcx.associated_items(super_trait_ref.def_id()) .in_definition_order() @@ -791,8 +791,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // Compute supertraits of current trait lazily. if self.supertraits.is_none() { - let trait_ref = - ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id)); + let trait_ref = ty::TraitRef::identity(self.tcx, self.trait_def_id); self.supertraits = Some( traits::supertraits(self.tcx, trait_ref).map(|t| t.def_id()).collect(), ); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 4f22543950c0b..da6ef8bf9ab2e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -27,7 +27,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_span::symbol::sym; use std::collections::BTreeMap; @@ -1020,7 +1020,7 @@ fn normalize_to_error<'a, 'tcx>( cause: ObligationCause<'tcx>, depth: usize, ) -> NormalizedTy<'tcx> { - let trait_ref = projection_ty.trait_ref(selcx.tcx()).to_poly_trait_ref(); + let trait_ref = ty::Binder::dummy(projection_ty.trait_ref(selcx.tcx())); let trait_obligation = Obligation { cause, recursion_depth: depth, @@ -1282,7 +1282,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // If we are resolving `>::Item == Type`, // start out by selecting the predicate `T as TraitRef<...>`: - let poly_trait_ref = obligation.predicate.trait_ref(selcx.tcx()).to_poly_trait_ref(); + let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx())); let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate()); let _ = selcx.infcx().commit_if_ok(|_| { let impl_source = match selcx.select(&trait_obligation) { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4e86807ba183e..9e1211336a4b0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -141,6 +141,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let placeholder_trait_predicate = self.infcx().replace_bound_vars_with_placeholders(trait_predicate); let placeholder_self_ty = placeholder_trait_predicate.self_ty(); + let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); let (def_id, substs) = match *placeholder_self_ty.kind() { ty::Projection(proj) => (proj.item_def_id, proj.substs), ty::Opaque(def_id, substs) => (def_id, substs), @@ -164,7 +165,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations.extend(self.infcx.commit_if_ok(|_| { self.infcx .at(&obligation.cause, obligation.param_env) - .sup(placeholder_trait_predicate.trait_ref.to_poly_trait_ref(), candidate.value) + .sup(placeholder_trait_predicate.to_poly_trait_ref(), candidate.value) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| Unimplemented) })?); diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 8c547c74426e6..2c4c80a1a910b 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -21,7 +21,7 @@ use rustc_infer::infer::{self, InferOk}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness}; +use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable, WithConstness}; use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits; @@ -330,7 +330,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_ref = ty::TraitRef::new(trait_def_id, substs); // Construct an obligation - let poly_trait_ref = trait_ref.to_poly_trait_ref(); + let poly_trait_ref = ty::Binder::dummy(trait_ref); let obligation = traits::Obligation::misc( span, self.body_id, diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index bf83191ad57b1..5aa579f33a9d2 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -21,9 +21,7 @@ use rustc_infer::infer::{self, InferOk, TyCtxtInferExt}; use rustc_middle::middle::stability; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{ - self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, -}; +use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::lev_distance::{find_best_match_for_name, lev_distance}; @@ -967,7 +965,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if self.tcx.is_trait_alias(trait_def_id) { // For trait aliases, assume all super-traits are relevant. - let bounds = iter::once(trait_ref.to_poly_trait_ref()); + let bounds = iter::once(ty::Binder::dummy(trait_ref)); self.elaborate_bounds(bounds, |this, new_trait_ref, item| { let new_trait_ref = this.erase_late_bound_regions(new_trait_ref); @@ -1372,7 +1370,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { trait_ref: ty::TraitRef<'tcx>, ) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> { let cause = traits::ObligationCause::misc(self.span, self.body_id); - let predicate = trait_ref.to_poly_trait_ref().to_poly_trait_predicate(); + let predicate = ty::Binder::dummy(trait_ref).to_poly_trait_predicate(); let obligation = traits::Obligation::new(cause, self.param_env, predicate); traits::SelectionContext::new(self).select(&obligation) } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 9744f4f6483c7..91a164ce063ea 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -12,9 +12,7 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::{ - self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, -}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_span::lev_distance; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{source_map, FileName, Span}; @@ -53,7 +51,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into()], ); let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); - let poly_trait_ref = trait_ref.to_poly_trait_ref(); + let poly_trait_ref = ty::Binder::dummy(trait_ref); let obligation = Obligation::misc( span, self.body_id, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1ec094d6ef953..a2d749fffe0b0 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -40,7 +40,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::Discr; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, Ty, TyCtxt}; use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness}; use rustc_session::lint; use rustc_session::parse::feature_err; @@ -607,8 +607,7 @@ fn type_param_predicates( ItemKind::Trait(_, _, ref generics, ..) => { // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { - let identity_trait_ref = - ty::Binder::dummy(ty::TraitRef::identity(tcx, item_def_id)); + let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); extend = Some((identity_trait_ref.without_const().to_predicate(tcx), item.span)); } @@ -2003,14 +2002,11 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { // *current* state of an external file. span = tcx.sess.source_map().guess_head_span(span); } - result.predicates = tcx.arena.alloc_from_iter( - result.predicates.iter().copied().chain(std::iter::once(( - ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id)) - .without_const() - .to_predicate(tcx), + result.predicates = + tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( + ty::TraitRef::identity(tcx, def_id).without_const().to_predicate(tcx), span, - ))), - ); + )))); } debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result @@ -2046,7 +2042,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP match item.kind { ItemKind::Impl(ref impl_) => { if impl_.defaultness.is_default() { - is_default_impl_trait = tcx.impl_trait_ref(def_id); + is_default_impl_trait = tcx + .impl_trait_ref(def_id) + .map(|trait_ref| ty::Binder::dummy(trait_ref)); } &impl_.generics } @@ -2126,10 +2124,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP // (see below). Recall that a default impl is not itself an impl, but rather a // set of defaults that can be incorporated into another impl. if let Some(trait_ref) = is_default_impl_trait { - predicates.insert(( - trait_ref.to_poly_trait_ref().without_const().to_predicate(tcx), - tcx.def_span(def_id), - )); + predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id))); } // Collect the region predicates that were declared inline as From b73c8b823f88b156bb85364c88383643decde132 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Wed, 15 Sep 2021 23:43:19 -0400 Subject: [PATCH 03/18] Fix rustdoc --- src/librustdoc/clean/blanket_impl.rs | 6 +++++- src/librustdoc/clean/mod.rs | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 15d4563ad7461..f9bf8d6f08b57 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -64,7 +64,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .instantiate(self.cx.tcx, impl_substs) .predicates .into_iter() - .chain(Some(trait_ref.without_const().to_predicate(infcx.tcx))); + .chain(Some( + ty::Binder::dummy(trait_ref) + .without_const() + .to_predicate(infcx.tcx), + )); for predicate in predicates { debug!("testing predicate {:?}", predicate); let obligation = traits::Obligation::new( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e281bbc59c255..98ef64faeb566 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -132,7 +132,7 @@ impl Clean for hir::GenericBound<'_> { hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { let def_id = cx.tcx.require_lang_item(lang_item, Some(span)); - let trait_ref = ty::TraitRef::identity(cx.tcx, def_id); + let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder(); let generic_args = generic_args.clean(cx); let bindings = match generic_args { From 553f6496f2988d0383e501314cee10ec097c5ebd Mon Sep 17 00:00:00 2001 From: jackh726 Date: Thu, 16 Sep 2021 00:12:56 -0400 Subject: [PATCH 04/18] Fix clippy --- src/tools/clippy/clippy_lints/src/escape.rs | 2 +- src/tools/clippy/clippy_lints/src/methods/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 1ba241d377616..6bbac6d9a2468 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { // be sure we have `self` parameter in this function if let AssocItemKind::Fn { has_self: true } = trait_item.kind { trait_self_ty = - Some(TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id()).self_ty()); + Some(TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id()).self_ty().skip_binder()); } } } diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index e89b2d295b923..a04b325b56e3a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -2061,7 +2061,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { then { let first_arg_span = first_arg_ty.span; let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty); - let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty(); + let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder(); wrong_self_convention::check( cx, &item.ident.name.as_str(), @@ -2078,7 +2078,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if item.ident.name == sym::new; if let TraitItemKind::Fn(_, _) = item.kind; let ret_ty = return_ty(cx, item.hir_id()); - let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty(); + let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder(); if !contains_ty(cx.tcx, ret_ty, self_ty); then { From 9886c233d84c231030af76419d002996df981ebc Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 18 Sep 2021 18:01:36 +0200 Subject: [PATCH 05/18] Remove Symbol::len It is used exactly once and can be replaced with the equally fast .as_str().len() --- compiler/rustc_expand/src/proc_macro_server.rs | 2 +- compiler/rustc_span/src/symbol.rs | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 52b60c3047e1c..5cb97198765fe 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -577,7 +577,7 @@ impl server::Literal for Rustc<'_> { } // Synthesize a new symbol that includes the minus sign. - let symbol = Symbol::intern(&s[..1 + lit.symbol.len()]); + let symbol = Symbol::intern(&s[..1 + lit.symbol.as_str().len()]); lit = token::Lit::new(lit.kind, symbol, lit.suffix); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7c2a09e0a32e0..eaf92487bfff7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1642,10 +1642,6 @@ impl Symbol { self.0.as_u32() } - pub fn len(self) -> usize { - with_session_globals(|session_globals| session_globals.symbol_interner.get(self).len()) - } - pub fn is_empty(self) -> bool { self == kw::Empty } From 4e0ee2a1bab796703cbb74d98f7d9742e64c032a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 18 Sep 2021 18:03:58 +0200 Subject: [PATCH 06/18] Avoid a couple of Symbol::as_str calls in cg_llvm --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 37b3279fb8096..be55a0c868a46 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -96,7 +96,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let arg_tys = sig.inputs(); let ret_ty = sig.output(); let name = tcx.item_name(def_id); - let name_str = &*name.as_str(); let llret_ty = self.layout_of(ret_ty).llvm_type(self); let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); @@ -230,9 +229,14 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { &[args[0].immediate(), y], ) } - sym::ctlz_nonzero | sym::cttz_nonzero => { + sym::ctlz_nonzero => { let y = self.const_bool(true); - let llvm_name = &format!("llvm.{}.i{}", &name_str[..4], width); + let llvm_name = &format!("llvm.ctlz.i{}", width); + self.call_intrinsic(llvm_name, &[args[0].immediate(), y]) + } + sym::cttz_nonzero => { + let y = self.const_bool(true); + let llvm_name = &format!("llvm.cttz.i{}", width); self.call_intrinsic(llvm_name, &[args[0].immediate(), y]) } sym::ctpop => self.call_intrinsic( @@ -353,7 +357,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { return; } - _ if name_str.starts_with("simd_") => { + _ if name.as_str().starts_with("simd_") => { match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { Ok(llval) => llval, Err(()) => return, @@ -843,7 +847,6 @@ fn generic_simd_intrinsic( let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); - let name_str = &*name.as_str(); if name == sym::simd_select_bitmask { let in_ty = arg_tys[0]; @@ -917,7 +920,7 @@ fn generic_simd_intrinsic( )); } - if let Some(stripped) = name_str.strip_prefix("simd_shuffle") { + if let Some(stripped) = name.as_str().strip_prefix("simd_shuffle") { // If this intrinsic is the older "simd_shuffleN" form, simply parse the integer. // If there is no suffix, use the index array length. let n: u64 = if stripped.is_empty() { From df727490b6adf58dc9ceb50440d930a989bd9729 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 18 Sep 2021 18:04:20 +0200 Subject: [PATCH 07/18] Make SymbolIndex private --- compiler/rustc_span/src/symbol.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index eaf92487bfff7..89b50c9afb236 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1616,7 +1616,7 @@ impl fmt::Display for MacroRulesNormalizedIdent { pub struct Symbol(SymbolIndex); rustc_index::newtype_index! { - pub struct SymbolIndex { .. } + struct SymbolIndex { .. } } impl Symbol { From 0222556c077110516356c205948d1dd12edc5588 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 19 Sep 2021 14:02:38 -0400 Subject: [PATCH 08/18] Simplify scoped_thread Avoids a bunch of manual pointer manipulation. --- compiler/rustc_interface/src/lib.rs | 1 + compiler/rustc_interface/src/util.rs | 24 +++++------------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index c7424b9e2a120..2fc3759968fd3 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -1,6 +1,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(internal_output_capture)] +#![feature(thread_spawn_unchecked)] #![feature(nll)] #![feature(once_cell)] #![recursion_limit = "256"] diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 3d90a6c934536..24975702b875d 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -115,25 +115,11 @@ fn get_stack_size() -> Option { /// for `'static` bounds. #[cfg(not(parallel_compiler))] pub fn scoped_thread R + Send, R: Send>(cfg: thread::Builder, f: F) -> R { - struct Ptr(*mut ()); - unsafe impl Send for Ptr {} - unsafe impl Sync for Ptr {} - - let mut f = Some(f); - let run = Ptr(&mut f as *mut _ as *mut ()); - let mut result = None; - let result_ptr = Ptr(&mut result as *mut _ as *mut ()); - - let thread = cfg.spawn(move || { - let _ = (&run, &result_ptr); - let run = unsafe { (*(run.0 as *mut Option)).take().unwrap() }; - let result = unsafe { &mut *(result_ptr.0 as *mut Option) }; - *result = Some(run()); - }); - - match thread.unwrap().join() { - Ok(()) => result.unwrap(), - Err(p) => panic::resume_unwind(p), + // SAFETY: join() is called immediately, so any closure captures are still + // alive. + match unsafe { cfg.spawn_unchecked(f) }.unwrap().join() { + Ok(v) => v, + Err(e) => panic::resume_unwind(e), } } From 7a3e450df45d2e40cff0ab6a4928084d6f61e993 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 23 Sep 2021 15:15:51 -0400 Subject: [PATCH 09/18] Add tests to verify the drop order of fields in fully captured upvars --- .../preserve_field_drop_order.rs | 98 ++++++++ .../preserve_field_drop_order.stderr | 228 ++++++++++++++++++ .../preserve_field_drop_order2.rs | 28 +++ ...eld_drop_order2.twenty_eighteen.run.stdout | 3 + ...ld_drop_order2.twenty_twentyone.run.stdout | 3 + 5 files changed, 360 insertions(+) create mode 100644 src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout create mode 100644 src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs new file mode 100644 index 0000000000000..ecc265208c56e --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs @@ -0,0 +1,98 @@ +// edition:2021 + +// Tests that in cases where we individually capture all the fields of a type, +// we still drop them in the order they would have been dropped in the 2018 edition. + +#![feature(rustc_attrs)] + +#[derive(Debug)] +struct HasDrop; +impl Drop for HasDrop { + fn drop(&mut self) { + println!("dropped"); + } +} + +fn test_one() { + let a = (HasDrop, HasDrop); + let b = (HasDrop, HasDrop); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{:?}", a.0); + //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + println!("{:?}", a.1); + //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + + println!("{:?}", b.0); + //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + println!("{:?}", b.1); + //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + }; +} + +fn test_two() { + let a = (HasDrop, HasDrop); + let b = (HasDrop, HasDrop); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{:?}", a.1); + //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + println!("{:?}", a.0); + //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + + println!("{:?}", b.1); + //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + println!("{:?}", b.0); + //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + }; +} + +fn test_three() { + let a = (HasDrop, HasDrop); + let b = (HasDrop, HasDrop); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{:?}", b.1); + //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + println!("{:?}", a.1); + //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + println!("{:?}", a.0); + //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + + println!("{:?}", b.0); + //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + }; +} + +fn main() { + test_one(); + test_two(); + test_three(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr new file mode 100644 index 0000000000000..7fdeab6a74d71 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr @@ -0,0 +1,228 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/preserve_field_drop_order.rs:20:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error[E0658]: attributes on expressions are experimental + --> $DIR/preserve_field_drop_order.rs:46:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error[E0658]: attributes on expressions are experimental + --> $DIR/preserve_field_drop_order.rs:72:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error: First Pass analysis includes: + --> $DIR/preserve_field_drop_order.rs:23:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.0); +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:26:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Capturing a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:29:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Capturing b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:33:26 + | +LL | println!("{:?}", b.0); + | ^^^ +note: Capturing b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:36:26 + | +LL | println!("{:?}", b.1); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/preserve_field_drop_order.rs:23:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.0); +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:26:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:29:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Min Capture b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:33:26 + | +LL | println!("{:?}", b.0); + | ^^^ +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:36:26 + | +LL | println!("{:?}", b.1); + | ^^^ + +error: First Pass analysis includes: + --> $DIR/preserve_field_drop_order.rs:49:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:52:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Capturing a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:55:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Capturing b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:59:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Capturing b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:62:26 + | +LL | println!("{:?}", b.0); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/preserve_field_drop_order.rs:49:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:52:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Min Capture a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:55:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:59:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Min Capture b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:62:26 + | +LL | println!("{:?}", b.0); + | ^^^ + +error: First Pass analysis includes: + --> $DIR/preserve_field_drop_order.rs:75:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", b.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:78:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Capturing a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:81:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Capturing a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:84:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Capturing b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:88:26 + | +LL | println!("{:?}", b.0); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/preserve_field_drop_order.rs:75:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", b.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:78:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Min Capture b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:88:26 + | +LL | println!("{:?}", b.0); + | ^^^ +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:81:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Min Capture a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:84:26 + | +LL | println!("{:?}", a.0); + | ^^^ + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs new file mode 100644 index 0000000000000..bc5c92122c6c8 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs @@ -0,0 +1,28 @@ +// run-pass +// check-run-results +// revisions: twenty_eighteen twenty_twentyone +// [twenty_eighteen]compile-flags: --edition 2018 +// [twenty_twentyone]compile-flags: --edition 2021 + +#[derive(Debug)] +struct Dropable(String); + +impl Drop for Dropable { + fn drop(&mut self) { + println!("Dropping {}", self.0) + } +} + +#[derive(Debug)] +struct A { + x: Dropable, + y: Dropable, +} + +fn main() { + let a = A { x: Dropable(format!("x")), y: Dropable(format!("y")) }; + + let c = move || println!("{:?} {:?}", a.y, a.x); + + c(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout new file mode 100644 index 0000000000000..e393169651817 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout @@ -0,0 +1,3 @@ +Dropable("y") Dropable("x") +Dropping x +Dropping y diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout new file mode 100644 index 0000000000000..90b1200fd08d1 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout @@ -0,0 +1,3 @@ +Dropable("y") Dropable("x") +Dropping y +Dropping x From ab8aef40b1e3a7151daebe7acea2c8b0117a8c9f Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 23 Sep 2021 16:36:49 -0400 Subject: [PATCH 10/18] Drop fully captured upvars in the same order as the regular drop code Currently, with the new 2021 edition, if a closure captures all of the fields of an upvar, we'll drop those fields in the order they are used within the closure instead of the normal drop order (the definition order of the fields in the type). This changes that so we sort the captured fields by the definition order which causes them to drop in that same order as well. Fixes https://github.com/rust-lang/project-rfc-2229/issues/42 --- compiler/rustc_typeck/src/check/upvar.rs | 42 ++++++++++++++++++- .../preserve_field_drop_order.stderr | 32 +++++++------- ...ld_drop_order2.twenty_twentyone.run.stdout | 2 +- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 53b99a14f379d..036e103738364 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -602,7 +602,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - debug!("For closure={:?}, min_captures={:#?}", closure_def_id, root_var_min_capture_list); + debug!( + "For closure={:?}, min_captures before sorting={:?}", + closure_def_id, root_var_min_capture_list + ); + + // Now that we have the minimized list of captures, sort the captures by field id. + // This causes the closure to capture the upvars in the same order as the fields are + // declared which is also the drop order. Thus, in situations where we capture all the + // fields of some type, the obserable drop order will remain the same as it previously + // was even though we're dropping each capture individually. + // See https://github.com/rust-lang/project-rfc-2229/issues/42 and + // `src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs`. + for (_, captures) in &mut root_var_min_capture_list { + captures.sort_by(|capture1, capture2| { + for (p1, p2) in capture1.place.projections.iter().zip(&capture2.place.projections) { + match (p1.kind, p2.kind) { + // Paths are the same, continue to next loop. + (ProjectionKind::Deref, ProjectionKind::Deref) => {} + (ProjectionKind::Field(i1, _), ProjectionKind::Field(i2, _)) + if i1 == i2 => {} + + // Fields are different, compare them. + (ProjectionKind::Field(i1, _), ProjectionKind::Field(i2, _)) => { + return i1.cmp(&i2); + } + + (l, r) => bug!("ProjectionKinds were different: ({:?}, {:?})", l, r), + } + } + + unreachable!( + "we captured two identical projections: capture1 = {:?}, capture2 = {:?}", + capture1, capture2 + ); + }); + } + + debug!( + "For closure={:?}, min_captures after sorting={:#?}", + closure_def_id, root_var_min_capture_list + ); typeck_results.closure_min_captures.insert(closure_def_id, root_var_min_capture_list); } diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr index 7fdeab6a74d71..559580ec05995 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr @@ -136,26 +136,26 @@ LL | | LL | | }; | |_____^ | -note: Min Capture a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:52:26 - | -LL | println!("{:?}", a.1); - | ^^^ note: Min Capture a[(0, 0)] -> ImmBorrow --> $DIR/preserve_field_drop_order.rs:55:26 | LL | println!("{:?}", a.0); | ^^^ -note: Min Capture b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:59:26 +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:52:26 | -LL | println!("{:?}", b.1); +LL | println!("{:?}", a.1); | ^^^ note: Min Capture b[(0, 0)] -> ImmBorrow --> $DIR/preserve_field_drop_order.rs:62:26 | LL | println!("{:?}", b.0); | ^^^ +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:59:26 + | +LL | println!("{:?}", b.1); + | ^^^ error: First Pass analysis includes: --> $DIR/preserve_field_drop_order.rs:75:5 @@ -202,26 +202,26 @@ LL | | LL | | }; | |_____^ | -note: Min Capture b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:78:26 - | -LL | println!("{:?}", b.1); - | ^^^ note: Min Capture b[(0, 0)] -> ImmBorrow --> $DIR/preserve_field_drop_order.rs:88:26 | LL | println!("{:?}", b.0); | ^^^ -note: Min Capture a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:81:26 +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:78:26 | -LL | println!("{:?}", a.1); +LL | println!("{:?}", b.1); | ^^^ note: Min Capture a[(0, 0)] -> ImmBorrow --> $DIR/preserve_field_drop_order.rs:84:26 | LL | println!("{:?}", a.0); | ^^^ +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:81:26 + | +LL | println!("{:?}", a.1); + | ^^^ error: aborting due to 9 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout index 90b1200fd08d1..e393169651817 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout @@ -1,3 +1,3 @@ Dropable("y") Dropable("x") -Dropping y Dropping x +Dropping y From d63e0f0e477654cb39036eb6f8b45e2dd6f4d371 Mon Sep 17 00:00:00 2001 From: Takashi Idobe Date: Thu, 23 Sep 2021 17:58:02 -0500 Subject: [PATCH 11/18] Add time complexities to linked_list.rs --- library/alloc/src/collections/linked_list.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 9d45c5082db43..e98b32703362e 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -631,6 +631,8 @@ impl LinkedList { /// Returns `true` if the `LinkedList` contains an element equal to the /// given value. /// + /// This operation should compute in *O*(*n*) time. + /// /// # Examples /// /// ``` @@ -655,6 +657,8 @@ impl LinkedList { /// Provides a reference to the front element, or `None` if the list is /// empty. + /// + /// This operation should compute in *O*(*1*) time. /// /// # Examples /// @@ -675,6 +679,8 @@ impl LinkedList { /// Provides a mutable reference to the front element, or `None` if the list /// is empty. + /// + /// This operation should compute in *O*(*1*) time. /// /// # Examples /// @@ -701,6 +707,8 @@ impl LinkedList { /// Provides a reference to the back element, or `None` if the list is /// empty. + /// + /// This operation should compute in *O*(*1*) time. /// /// # Examples /// @@ -721,6 +729,8 @@ impl LinkedList { /// Provides a mutable reference to the back element, or `None` if the list /// is empty. + /// + /// This operation should compute in *O*(*1*) time. /// /// # Examples /// From b146525140a8776aec1f7852643ec2abd787a197 Mon Sep 17 00:00:00 2001 From: Takashi Idobe Date: Thu, 23 Sep 2021 18:20:46 -0500 Subject: [PATCH 12/18] remove trailing whitespace --- library/alloc/src/collections/linked_list.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index e98b32703362e..dfd0039baf64d 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -657,7 +657,7 @@ impl LinkedList { /// Provides a reference to the front element, or `None` if the list is /// empty. - /// + /// /// This operation should compute in *O*(*1*) time. /// /// # Examples @@ -679,7 +679,7 @@ impl LinkedList { /// Provides a mutable reference to the front element, or `None` if the list /// is empty. - /// + /// /// This operation should compute in *O*(*1*) time. /// /// # Examples @@ -707,7 +707,7 @@ impl LinkedList { /// Provides a reference to the back element, or `None` if the list is /// empty. - /// + /// /// This operation should compute in *O*(*1*) time. /// /// # Examples @@ -729,7 +729,7 @@ impl LinkedList { /// Provides a mutable reference to the back element, or `None` if the list /// is empty. - /// + /// /// This operation should compute in *O*(*1*) time. /// /// # Examples From 389365631d3e6d2f533f896635e7768f26359575 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 23 Sep 2021 22:15:12 -0400 Subject: [PATCH 13/18] Fix tidy and respond to some feedback --- compiler/rustc_typeck/src/check/upvar.rs | 33 ++++++++++++++++++- .../preserve_field_drop_order.rs | 2 +- .../preserve_field_drop_order2.rs | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 036e103738364..917bf4ecd8c4a 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -617,6 +617,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (_, captures) in &mut root_var_min_capture_list { captures.sort_by(|capture1, capture2| { for (p1, p2) in capture1.place.projections.iter().zip(&capture2.place.projections) { + // We do not need to look at the `Projection.ty` fields here because at each + // step of the iteration, the projections will either be the same and therefore + // the types must be as well or the current projection will be different and + // we will return the result of comparing the field indexes. match (p1.kind, p2.kind) { // Paths are the same, continue to next loop. (ProjectionKind::Deref, ProjectionKind::Deref) => {} @@ -628,7 +632,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return i1.cmp(&i2); } - (l, r) => bug!("ProjectionKinds were different: ({:?}, {:?})", l, r), + // We should have either a pair of `Deref`s or a pair of `Field`s. + // Anything else is a bug. + ( + l @ (ProjectionKind::Deref | ProjectionKind::Field(..)), + r @ (ProjectionKind::Deref | ProjectionKind::Field(..)), + ) => bug!( + "ProjectionKinds Deref and Field were mismatched: ({:?}, {:?})", + l, + r + ), + ( + l + @ + (ProjectionKind::Index + | ProjectionKind::Subslice + | ProjectionKind::Deref + | ProjectionKind::Field(..)), + r + @ + (ProjectionKind::Index + | ProjectionKind::Subslice + | ProjectionKind::Deref + | ProjectionKind::Field(..)), + ) => bug!( + "ProjectionKinds Index or Subslice were unexpected: ({:?}, {:?})", + l, + r + ), } } diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs index ecc265208c56e..ca3bfff2cf30a 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs @@ -94,5 +94,5 @@ fn test_three() { fn main() { test_one(); test_two(); - test_three(); + test_three(); } diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs index bc5c92122c6c8..3d39cb7ed481b 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs @@ -23,6 +23,6 @@ fn main() { let a = A { x: Dropable(format!("x")), y: Dropable(format!("y")) }; let c = move || println!("{:?} {:?}", a.y, a.x); - + c(); } From 9fa59e19e519a87b8e110948d783052ab89ba4ca Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Sep 2021 12:05:35 +0200 Subject: [PATCH 14/18] Enable "generate-link-to-definition" option on rust tools docs as well --- src/bootstrap/doc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index af3774b7c7586..14e3b31592418 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -743,6 +743,7 @@ macro_rules! tool_doc { cargo.rustdocflag("--document-private-items"); cargo.rustdocflag("--enable-index-page"); cargo.rustdocflag("--show-type-layout"); + cargo.rustdocflag("--generate-link-to-definition"); cargo.rustdocflag("-Zunstable-options"); builder.run(&mut cargo.into()); } From cebba31d4ae6bd1dea410dc7d74e496846f5980d Mon Sep 17 00:00:00 2001 From: Takashi Idobe Date: Fri, 24 Sep 2021 08:33:49 -0500 Subject: [PATCH 15/18] unitalicize O(1) complexities --- library/alloc/src/collections/linked_list.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index dfd0039baf64d..c5c32674eec15 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -658,7 +658,7 @@ impl LinkedList { /// Provides a reference to the front element, or `None` if the list is /// empty. /// - /// This operation should compute in *O*(*1*) time. + /// This operation should compute in *O*(1) time. /// /// # Examples /// @@ -680,7 +680,7 @@ impl LinkedList { /// Provides a mutable reference to the front element, or `None` if the list /// is empty. /// - /// This operation should compute in *O*(*1*) time. + /// This operation should compute in *O*(1) time. /// /// # Examples /// @@ -708,7 +708,7 @@ impl LinkedList { /// Provides a reference to the back element, or `None` if the list is /// empty. /// - /// This operation should compute in *O*(*1*) time. + /// This operation should compute in *O*(1) time. /// /// # Examples /// @@ -730,7 +730,7 @@ impl LinkedList { /// Provides a mutable reference to the back element, or `None` if the list /// is empty. /// - /// This operation should compute in *O*(*1*) time. + /// This operation should compute in *O*(1) time. /// /// # Examples /// From ed3b751799b0d9a754846bd754d9b43cf6c7394b Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Fri, 24 Sep 2021 13:31:01 +0100 Subject: [PATCH 16/18] Give better error for `macro_rules! name!` --- compiler/rustc_parse/src/parser/item.rs | 14 ++++++++++++++ src/test/ui/macros/bang-after-name.fixed | 8 ++++++++ src/test/ui/macros/bang-after-name.rs | 8 ++++++++ src/test/ui/macros/bang-after-name.stderr | 8 ++++++++ 4 files changed, 38 insertions(+) create mode 100644 src/test/ui/macros/bang-after-name.fixed create mode 100644 src/test/ui/macros/bang-after-name.rs create mode 100644 src/test/ui/macros/bang-after-name.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0e2222bf84093..624390a406ff2 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1547,6 +1547,20 @@ impl<'a> Parser<'a> { self.expect(&token::Not)?; // `!` let ident = self.parse_ident()?; + + if self.eat(&token::Not) { + // Handle macro_rules! foo! + let span = self.prev_token.span; + self.struct_span_err(span, "macro names aren't followed by a `!`") + .span_suggestion( + span, + "remove the `!`", + "".to_owned(), + Applicability::MachineApplicable, + ) + .emit(); + } + let body = self.parse_mac_args()?; self.eat_semi_for_macro_if_needed(&body); self.complain_if_pub_macro(vis, true); diff --git a/src/test/ui/macros/bang-after-name.fixed b/src/test/ui/macros/bang-after-name.fixed new file mode 100644 index 0000000000000..c107ddd5d03bd --- /dev/null +++ b/src/test/ui/macros/bang-after-name.fixed @@ -0,0 +1,8 @@ +// run-rustfix +#[allow(unused_macros)] + +macro_rules! foo { //~ ERROR macro names aren't followed by a `!` + () => {}; +} + +fn main() {} diff --git a/src/test/ui/macros/bang-after-name.rs b/src/test/ui/macros/bang-after-name.rs new file mode 100644 index 0000000000000..7654d8c440390 --- /dev/null +++ b/src/test/ui/macros/bang-after-name.rs @@ -0,0 +1,8 @@ +// run-rustfix +#[allow(unused_macros)] + +macro_rules! foo! { //~ ERROR macro names aren't followed by a `!` + () => {}; +} + +fn main() {} diff --git a/src/test/ui/macros/bang-after-name.stderr b/src/test/ui/macros/bang-after-name.stderr new file mode 100644 index 0000000000000..f609c4943ef21 --- /dev/null +++ b/src/test/ui/macros/bang-after-name.stderr @@ -0,0 +1,8 @@ +error: macro names aren't followed by a `!` + --> $DIR/bang-after-name.rs:4:17 + | +LL | macro_rules! foo! { + | ^ help: remove the `!` + +error: aborting due to previous error + From a307dcc9626b6493b83ca73c3ce35afcffc17e2f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 12 Sep 2021 15:13:54 -0400 Subject: [PATCH 17/18] Add 1.56.0 release notes Co-authored-by: Josh Triplett --- RELEASES.md | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index c0851a1506e13..82a0cda9f6b74 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,188 @@ +Rust 1.56.0 (2021-10-21) +======================== + +Language +-------- + +- [The 2021 Edition is now stable.][rust#88100] + See [the edition guide][rust-2021-edition-guide] for more details. +- [You can now specify explicit discriminant values on any Rust enum.][rust#86860] +- [The pattern in `binding @ pattern` can now also introduce new bindings.][rust#85305] +- [Union field access is permitted in `const fn`.][rust#85769] + +[rust-2021-edition-guide]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/index.html + +Compiler +-------- + +- [Upgrade to LLVM 13.][rust#87570] +- [Support memory, address, and thread sanitizers on aarch64-unknown-freebsd.][rust#88023] +- [Allow specifying an deployment target version for all iOS targets][rust#87699] +- [Warnings can be forced on with `--force-warn`.][rust#87472] + This feature is primarily intended for usage by `cargo fix`, rather than end users. +- [Promote `aarch64-apple-ios-sim` to Tier 2\*.][rust#87760] +- [Add `powerpc-unknown-freebsd` at Tier 3\*.][rust#87370] + +\* Refer to Rust's [platform support page][platform-support-doc] for more +information on Rust's tiered platform support. + +Libraries +--------- + +- [Allow writing of incomplete UTF-8 sequences via stdout/stderr on Windows.][rust#83342] + The Windows console still requires valid Unicode, but this change allows + splitting a UTF-8 character across multiple write calls. This allows, for + instance, programs that just read and write data buffers (e.g. copying a file + to stdout) without regard for Unicode or character boundaries. +- [Prefer `AtomicU{64,128}` over Mutex for Instant backsliding protection.][rust#83093] + For this use case, atomics scale much better under contention. +- [Implement `Extend<(A, B)>` for `(Extend, Extend)`][rust#85835] +- [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744] +- [`impl From<[(K, V); N]>` for all collections.][rust#84111] +- [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363] +- [Treat invalid environment variable names as non-existent.][rust#86183] + Previously, the environment functions would panic if given a variable name + with an internal null character or equal sign (`=`). Now, these functions will + just treat such names as non-existent variables, since the OS cannot represent + the existence of a variable with such a name. + +Stabilised APIs +--------------- + +- [`std::os::unix::fs::chroot`] +- [`Iterator::intersperse`] +- [`Iterator::intersperse_with`] +- [`UnsafeCell::raw_get`] +- [`BufWriter::into_parts`] +- [`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`] + These APIs were previously stable in `std`, but are now also available in `core`. +- [`Vec::shrink_to`] +- [`String::shrink_to`] +- [`OsString::shrink_to`] +- [`PathBuf::shrink_to`] +- [`BinaryHeap::shrink_to`] +- [`VecDeque::shrink_to`] +- [`HashMap::shrink_to`] +- [`HashSet::shrink_to`] +- [`task::ready!`] + +These APIs are now usable in const contexts: + +- [`std::mem::transmute`] +- [`[T]::first`][`slice::first`] +- [`[T]::split_first`][`slice::split_first`] +- [`[T]::last`][`slice::last`] +- [`[T]::split_last`][`slice::split_last`] + +Cargo +----- + +- [Cargo supports specifying a minimum supported Rust version in Cargo.toml.][`rust-version`] + This has no effect at present on dependency version selection. + We encourage crates to specify their minimum supported Rust version, and we encourage CI systems + that support Rust code to include a crate's specified minimum version in the text matrix for that + crate by default. + +Compatibility notes +------------------- + +- [Update to new argument parsing rules on Windows.][rust#87580] + This adjusts Rust's standard library to match the behavior of the standard + libraries for C/C++. The rules have changed slightly over time, and this PR + brings us to the latest set of rules (changed in 2008). +- [Disallow the aapcs calling convention on aarch64][rust#88399] + This was already not supported by LLVM; this change surfaces this lack of + support with a better error message. +- [Make `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` warn by default][rust#87385] +- [Warn when an escaped newline skips multiple lines.][rust#87671] +- [Calls to `libc::getpid` / `std::process::id` from `Command::pre_exec` + may return different values on glibc <= 2.24.][rust#81825] + Rust now invokes the `clone3` system call directly, when available, to use new functionality + available via that system call. Older versions of glibc cache the result of `getpid`, and only + update that cache when calling glibc's clone/fork functions, so a direct system call bypasses + that cache update. glibc 2.25 and newer no longer cache `getpid` for exactly this reason. + +Internal changes +---------------- +These changes provide no direct user facing benefits, but represent significant +improvements to the internals and overall performance of rustc +and related tools. + +- [LLVM is compiled with PGO in published x86_64-unknown-linux-gnu artifacts.][rust#88069] + This improves the performance of most Rust builds. +- [Unify representation of macros in internal data structures.][rust#88019] + This change fixes a host of bugs with the handling of macros by the compiler, + as well as rustdoc. + +[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html +[`Iterator::intersperse`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse +[`Iterator::intersperse_with`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse +[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get +[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts +[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: https://github.com/rust-lang/rust/pull/84662 +[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to +[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to +[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to +[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to +[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to +[`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to +[`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to +[`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to +[`task::ready!`]: https://doc.rust-lang.org/stable/std/task/macro.ready.html +[`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html +[`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first +[`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first +[`slice::last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last +[`slice::split_last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_last +[`rust-version`]: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field +[rust#87671]: https://github.com/rust-lang/rust/pull/87671 +[rust#86183]: https://github.com/rust-lang/rust/pull/86183 +[rust#87385]: https://github.com/rust-lang/rust/pull/87385 +[rust#88100]: https://github.com/rust-lang/rust/pull/88100 +[rust#86860]: https://github.com/rust-lang/rust/pull/86860 +[rust#84039]: https://github.com/rust-lang/rust/pull/84039 +[rust#86492]: https://github.com/rust-lang/rust/pull/86492 +[rust#88363]: https://github.com/rust-lang/rust/pull/88363 +[rust#85305]: https://github.com/rust-lang/rust/pull/85305 +[rust#87832]: https://github.com/rust-lang/rust/pull/87832 +[rust#88069]: https://github.com/rust-lang/rust/pull/88069 +[rust#87472]: https://github.com/rust-lang/rust/pull/87472 +[rust#87699]: https://github.com/rust-lang/rust/pull/87699 +[rust#87570]: https://github.com/rust-lang/rust/pull/87570 +[rust#88023]: https://github.com/rust-lang/rust/pull/88023 +[rust#87760]: https://github.com/rust-lang/rust/pull/87760 +[rust#87370]: https://github.com/rust-lang/rust/pull/87370 +[rust#87580]: https://github.com/rust-lang/rust/pull/87580 +[rust#83342]: https://github.com/rust-lang/rust/pull/83342 +[rust#83093]: https://github.com/rust-lang/rust/pull/83093 +[rust#88177]: https://github.com/rust-lang/rust/pull/88177 +[rust#88548]: https://github.com/rust-lang/rust/pull/88548 +[rust#88551]: https://github.com/rust-lang/rust/pull/88551 +[rust#88299]: https://github.com/rust-lang/rust/pull/88299 +[rust#88220]: https://github.com/rust-lang/rust/pull/88220 +[rust#85835]: https://github.com/rust-lang/rust/pull/85835 +[rust#86879]: https://github.com/rust-lang/rust/pull/86879 +[rust#86744]: https://github.com/rust-lang/rust/pull/86744 +[rust#84662]: https://github.com/rust-lang/rust/pull/84662 +[rust#86593]: https://github.com/rust-lang/rust/pull/86593 +[rust#81050]: https://github.com/rust-lang/rust/pull/81050 +[rust#81363]: https://github.com/rust-lang/rust/pull/81363 +[rust#84111]: https://github.com/rust-lang/rust/pull/84111 +[rust#85769]: https://github.com/rust-lang/rust/pull/85769#issuecomment-854363720 +[rust#88490]: https://github.com/rust-lang/rust/pull/88490 +[rust#88269]: https://github.com/rust-lang/rust/pull/88269 +[rust#84176]: https://github.com/rust-lang/rust/pull/84176 +[rust#88399]: https://github.com/rust-lang/rust/pull/88399 +[rust#88227]: https://github.com/rust-lang/rust/pull/88227 +[rust#88200]: https://github.com/rust-lang/rust/pull/88200 +[rust#82776]: https://github.com/rust-lang/rust/pull/82776 +[rust#88077]: https://github.com/rust-lang/rust/pull/88077 +[rust#87728]: https://github.com/rust-lang/rust/pull/87728 +[rust#87050]: https://github.com/rust-lang/rust/pull/87050 +[rust#87619]: https://github.com/rust-lang/rust/pull/87619 +[rust#81825]: https://github.com/rust-lang/rust/pull/81825#issuecomment-808406918 +[rust#88019]: https://github.com/rust-lang/rust/pull/88019 + Version 1.55.0 (2021-09-09) ============================ From dd918048a56577dcd7a396065f645a921c3b8e79 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 24 Sep 2021 12:26:24 -0400 Subject: [PATCH 18/18] Update and add more tests --- .../preserve_field_drop_order.rs | 63 +++++++++--------- .../preserve_field_drop_order.stderr | 66 +++++++++---------- .../preserve_field_drop_order2.rs | 34 +++++++++- ...eld_drop_order2.twenty_eighteen.run.stdout | 10 +++ ...ld_drop_order2.twenty_twentyone.run.stdout | 10 +++ 5 files changed, 118 insertions(+), 65 deletions(-) diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs index ca3bfff2cf30a..2f8cddc06bab1 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs @@ -3,6 +3,9 @@ // Tests that in cases where we individually capture all the fields of a type, // we still drop them in the order they would have been dropped in the 2018 edition. +// NOTE: It is *critical* that the order of the min capture NOTES in the stderr output +// does *not* change! + #![feature(rustc_attrs)] #[derive(Debug)] @@ -21,21 +24,21 @@ fn test_one() { //~^ ERROR: attributes on expressions are experimental //~| NOTE: see issue #15701 || { - //~^ ERROR: First Pass analysis includes: - //~| ERROR: Min Capture analysis includes: + //~^ ERROR: Min Capture analysis includes: + //~| ERROR println!("{:?}", a.0); - //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow - //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + //~^ NOTE: Min Capture a[(0, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", a.1); - //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow - //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + //~^ NOTE: Min Capture a[(1, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", b.0); - //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow - //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + //~^ NOTE: Min Capture b[(0, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", b.1); - //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow - //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + //~^ NOTE: Min Capture b[(1, 0)] -> ImmBorrow + //~| NOTE }; } @@ -47,21 +50,21 @@ fn test_two() { //~^ ERROR: attributes on expressions are experimental //~| NOTE: see issue #15701 || { - //~^ ERROR: First Pass analysis includes: - //~| ERROR: Min Capture analysis includes: + //~^ ERROR: Min Capture analysis includes: + //~| ERROR println!("{:?}", a.1); - //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow - //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + //~^ NOTE: Min Capture a[(1, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", a.0); - //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow - //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + //~^ NOTE: Min Capture a[(0, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", b.1); - //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow - //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + //~^ NOTE: Min Capture b[(1, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", b.0); - //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow - //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + //~^ NOTE: Min Capture b[(0, 0)] -> ImmBorrow + //~| NOTE }; } @@ -73,21 +76,21 @@ fn test_three() { //~^ ERROR: attributes on expressions are experimental //~| NOTE: see issue #15701 || { - //~^ ERROR: First Pass analysis includes: - //~| ERROR: Min Capture analysis includes: + //~^ ERROR: Min Capture analysis includes: + //~| ERROR println!("{:?}", b.1); - //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow - //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + //~^ NOTE: Min Capture b[(1, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", a.1); - //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow - //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + //~^ NOTE: Min Capture a[(1, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", a.0); - //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow - //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + //~^ NOTE: Min Capture a[(0, 0)] -> ImmBorrow + //~| NOTE println!("{:?}", b.0); - //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow - //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + //~^ NOTE: Min Capture b[(0, 0)] -> ImmBorrow + //~| NOTE }; } diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr index 559580ec05995..2d1dc8727c255 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes on expressions are experimental - --> $DIR/preserve_field_drop_order.rs:20:13 + --> $DIR/preserve_field_drop_order.rs:23:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental - --> $DIR/preserve_field_drop_order.rs:46:13 + --> $DIR/preserve_field_drop_order.rs:49:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error[E0658]: attributes on expressions are experimental - --> $DIR/preserve_field_drop_order.rs:72:13 + --> $DIR/preserve_field_drop_order.rs:75:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error: First Pass analysis includes: - --> $DIR/preserve_field_drop_order.rs:23:5 + --> $DIR/preserve_field_drop_order.rs:26:5 | LL | / || { LL | | @@ -38,28 +38,28 @@ LL | | }; | |_____^ | note: Capturing a[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:26:26 + --> $DIR/preserve_field_drop_order.rs:29:26 | LL | println!("{:?}", a.0); | ^^^ note: Capturing a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:29:26 + --> $DIR/preserve_field_drop_order.rs:32:26 | LL | println!("{:?}", a.1); | ^^^ note: Capturing b[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:33:26 + --> $DIR/preserve_field_drop_order.rs:36:26 | LL | println!("{:?}", b.0); | ^^^ note: Capturing b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:36:26 + --> $DIR/preserve_field_drop_order.rs:39:26 | LL | println!("{:?}", b.1); | ^^^ error: Min Capture analysis includes: - --> $DIR/preserve_field_drop_order.rs:23:5 + --> $DIR/preserve_field_drop_order.rs:26:5 | LL | / || { LL | | @@ -71,28 +71,28 @@ LL | | }; | |_____^ | note: Min Capture a[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:26:26 + --> $DIR/preserve_field_drop_order.rs:29:26 | LL | println!("{:?}", a.0); | ^^^ note: Min Capture a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:29:26 + --> $DIR/preserve_field_drop_order.rs:32:26 | LL | println!("{:?}", a.1); | ^^^ note: Min Capture b[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:33:26 + --> $DIR/preserve_field_drop_order.rs:36:26 | LL | println!("{:?}", b.0); | ^^^ note: Min Capture b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:36:26 + --> $DIR/preserve_field_drop_order.rs:39:26 | LL | println!("{:?}", b.1); | ^^^ error: First Pass analysis includes: - --> $DIR/preserve_field_drop_order.rs:49:5 + --> $DIR/preserve_field_drop_order.rs:52:5 | LL | / || { LL | | @@ -104,28 +104,28 @@ LL | | }; | |_____^ | note: Capturing a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:52:26 + --> $DIR/preserve_field_drop_order.rs:55:26 | LL | println!("{:?}", a.1); | ^^^ note: Capturing a[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:55:26 + --> $DIR/preserve_field_drop_order.rs:58:26 | LL | println!("{:?}", a.0); | ^^^ note: Capturing b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:59:26 + --> $DIR/preserve_field_drop_order.rs:62:26 | LL | println!("{:?}", b.1); | ^^^ note: Capturing b[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:62:26 + --> $DIR/preserve_field_drop_order.rs:65:26 | LL | println!("{:?}", b.0); | ^^^ error: Min Capture analysis includes: - --> $DIR/preserve_field_drop_order.rs:49:5 + --> $DIR/preserve_field_drop_order.rs:52:5 | LL | / || { LL | | @@ -137,28 +137,28 @@ LL | | }; | |_____^ | note: Min Capture a[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:55:26 + --> $DIR/preserve_field_drop_order.rs:58:26 | LL | println!("{:?}", a.0); | ^^^ note: Min Capture a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:52:26 + --> $DIR/preserve_field_drop_order.rs:55:26 | LL | println!("{:?}", a.1); | ^^^ note: Min Capture b[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:62:26 + --> $DIR/preserve_field_drop_order.rs:65:26 | LL | println!("{:?}", b.0); | ^^^ note: Min Capture b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:59:26 + --> $DIR/preserve_field_drop_order.rs:62:26 | LL | println!("{:?}", b.1); | ^^^ error: First Pass analysis includes: - --> $DIR/preserve_field_drop_order.rs:75:5 + --> $DIR/preserve_field_drop_order.rs:78:5 | LL | / || { LL | | @@ -170,28 +170,28 @@ LL | | }; | |_____^ | note: Capturing b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:78:26 + --> $DIR/preserve_field_drop_order.rs:81:26 | LL | println!("{:?}", b.1); | ^^^ note: Capturing a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:81:26 + --> $DIR/preserve_field_drop_order.rs:84:26 | LL | println!("{:?}", a.1); | ^^^ note: Capturing a[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:84:26 + --> $DIR/preserve_field_drop_order.rs:87:26 | LL | println!("{:?}", a.0); | ^^^ note: Capturing b[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:88:26 + --> $DIR/preserve_field_drop_order.rs:91:26 | LL | println!("{:?}", b.0); | ^^^ error: Min Capture analysis includes: - --> $DIR/preserve_field_drop_order.rs:75:5 + --> $DIR/preserve_field_drop_order.rs:78:5 | LL | / || { LL | | @@ -203,22 +203,22 @@ LL | | }; | |_____^ | note: Min Capture b[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:88:26 + --> $DIR/preserve_field_drop_order.rs:91:26 | LL | println!("{:?}", b.0); | ^^^ note: Min Capture b[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:78:26 + --> $DIR/preserve_field_drop_order.rs:81:26 | LL | println!("{:?}", b.1); | ^^^ note: Min Capture a[(0, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:84:26 + --> $DIR/preserve_field_drop_order.rs:87:26 | LL | println!("{:?}", a.0); | ^^^ note: Min Capture a[(1, 0)] -> ImmBorrow - --> $DIR/preserve_field_drop_order.rs:81:26 + --> $DIR/preserve_field_drop_order.rs:84:26 | LL | println!("{:?}", a.1); | ^^^ diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs index 3d39cb7ed481b..1cae776dd68bc 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs @@ -5,7 +5,7 @@ // [twenty_twentyone]compile-flags: --edition 2021 #[derive(Debug)] -struct Dropable(String); +struct Dropable(&'static str); impl Drop for Dropable { fn drop(&mut self) { @@ -19,10 +19,40 @@ struct A { y: Dropable, } +#[derive(Debug)] +struct B { + c: A, + d: A, +} + +#[derive(Debug)] +struct R<'a> { + c: &'a A, + d: &'a A, +} + fn main() { - let a = A { x: Dropable(format!("x")), y: Dropable(format!("y")) }; + let a = A { x: Dropable("x"), y: Dropable("y") }; let c = move || println!("{:?} {:?}", a.y, a.x); c(); + + let b = B { + c: A { x: Dropable("b.c.x"), y: Dropable("b.c.y") }, + d: A { x: Dropable("b.d.x"), y: Dropable("b.d.y") }, + }; + + let d = move || println!("{:?} {:?} {:?} {:?}", b.d.y, b.d.x, b.c.y, b.c.x); + + d(); + + let r = R { + c: &A { x: Dropable("r.c.x"), y: Dropable("r.c.y") }, + d: &A { x: Dropable("r.d.x"), y: Dropable("r.d.y") }, + }; + + let e = move || println!("{:?} {:?} {:?} {:?}", r.d.y, r.d.x, r.c.y, r.c.x); + + e(); } diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout index e393169651817..557d047c1d524 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout @@ -1,3 +1,13 @@ Dropable("y") Dropable("x") +Dropable("b.d.y") Dropable("b.d.x") Dropable("b.c.y") Dropable("b.c.x") +Dropable("r.d.y") Dropable("r.d.x") Dropable("r.c.y") Dropable("r.c.x") +Dropping r.d.x +Dropping r.d.y +Dropping r.c.x +Dropping r.c.y +Dropping b.c.x +Dropping b.c.y +Dropping b.d.x +Dropping b.d.y Dropping x Dropping y diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout index e393169651817..557d047c1d524 100644 --- a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout @@ -1,3 +1,13 @@ Dropable("y") Dropable("x") +Dropable("b.d.y") Dropable("b.d.x") Dropable("b.c.y") Dropable("b.c.x") +Dropable("r.d.y") Dropable("r.d.x") Dropable("r.c.y") Dropable("r.c.x") +Dropping r.d.x +Dropping r.d.y +Dropping r.c.x +Dropping r.c.y +Dropping b.c.x +Dropping b.c.y +Dropping b.d.x +Dropping b.d.y Dropping x Dropping y