diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index c95652f274e36..2a012c5274191 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -231,6 +231,12 @@ rustc_queries! { cycle_delay_bug } + query trivial_dropck_outlives(ty: Ty<'tcx>) -> bool { + anon + no_force + desc { "checking if `{:?}` has trivial dropck", ty } + } + query adt_dtorck_constraint( _: DefId ) -> Result, NoSolution> {} diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index eaf5971e4592f..e84c91daf293f 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -5,6 +5,7 @@ use std::iter::FromIterator; use syntax::source_map::Span; use crate::ty::subst::GenericArg; use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::query::Providers; impl<'cx, 'tcx> At<'cx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set @@ -33,7 +34,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { // Quick check: there are a number of cases that we know do not require // any destructor. let tcx = self.infcx.tcx; - if trivial_dropck_outlives(tcx, ty) { + if tcx.trivial_dropck_outlives(ty) { return InferOk { value: vec![], obligations: vec![], @@ -207,15 +208,15 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { | ty::Error => true, // [T; N] and [T] have same properties as T. - ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty), + ty::Array(ty, _) | ty::Slice(ty) => tcx.trivial_dropck_outlives(ty), // (T1..Tn) and closures have same properties as T1..Tn -- // check if *any* of those are trivial. - ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())), + ty::Tuple(ref tys) => tys.iter().all(|t| tcx.trivial_dropck_outlives(t.expect_ty())), ty::Closure(def_id, ref substs) => substs .as_closure() .upvar_tys(def_id, tcx) - .all(|t| trivial_dropck_outlives(tcx, t)), + .all(|t| tcx.trivial_dropck_outlives(t)), ty::Adt(def, _) => { if Some(def.did) == tcx.lang_items().manually_drop() { @@ -243,3 +244,10 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), } } + +crate fn provide(p: &mut Providers<'_>) { + *p = Providers { + trivial_dropck_outlives, + ..*p + }; +} diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index 9b956f3e55408..86a32d68fc09e 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -1,5 +1,4 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; -use crate::traits::query::dropck_outlives::trivial_dropck_outlives; use crate::traits::query::dropck_outlives::DropckOutlivesResult; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; @@ -22,7 +21,7 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>, ) -> Option { - if trivial_dropck_outlives(tcx, key.value.dropped_ty) { + if tcx.trivial_dropck_outlives(key.value.dropped_ty) { Some(DropckOutlivesResult::default()) } else { None diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index cfd859c33c2ef..01b7cda6fe914 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3394,6 +3394,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { layout::provide(providers); util::provide(providers); constness::provide(providers); + crate::traits::query::dropck_outlives::provide(providers); *providers = ty::query::Providers { asyncness, associated_item, diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 88e62db9a10d8..e751c94f23d11 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -166,6 +166,10 @@ fn dtorck_constraint_for_ty<'tcx>( }); } + if tcx.trivial_dropck_outlives(ty) { + return Ok(DtorckConstraint::empty()); + } + let result = match ty.kind { ty::Bool | ty::Char