From 48df57626f2e01f15a268ca3edb89c3d9f46c8e7 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 09:02:29 -0700 Subject: [PATCH 01/22] Revert "change skolemizations to use universe index" This reverts commit 755bdaa19084c3ae116ad8320b99a6932fa7f0b1. --- src/librustc/infer/region_constraints/mod.rs | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 0c8e49fda1840..a44ffc24cb0e0 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -48,7 +48,7 @@ pub struct RegionConstraintCollector<'tcx> { glbs: CombineMap<'tcx>, /// Number of skolemized variables currently active. - skolemization_count: ty::UniverseIndex, + skolemization_count: u32, /// Global counter used during the GLB algorithm to create unique /// names for fresh bound regions @@ -233,7 +233,7 @@ type CombineMap<'tcx> = FxHashMap, RegionVid>; pub struct RegionSnapshot { length: usize, region_snapshot: ut::Snapshot>, - skolemization_count: ty::UniverseIndex, + skolemization_count: u32, } /// When working with skolemized regions, we often wish to find all of @@ -277,7 +277,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { data: RegionConstraintData::default(), lubs: FxHashMap(), glbs: FxHashMap(), - skolemization_count: ty::UniverseIndex::ROOT, + skolemization_count: 0, bound_count: 0, undo_log: Vec::new(), unification_table: ut::UnificationTable::new(), @@ -329,7 +329,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { unification_table, } = self; - assert_eq!(skolemization_count.as_usize(), 0); + assert_eq!(*skolemization_count, 0); // Clear the tables of (lubs, glbs), so that we will create // fresh regions if we do a LUB operation. As it happens, @@ -375,7 +375,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.undo_log[snapshot.length] == OpenSnapshot); assert!( self.skolemization_count == snapshot.skolemization_count, - "failed to pop skolemized regions: {:?} now vs {:?} at start", + "failed to pop skolemized regions: {} now vs {} at start", self.skolemization_count, snapshot.skolemization_count ); @@ -483,9 +483,9 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); assert!(self.undo_log[snapshot.length] == OpenSnapshot); - let universe = self.skolemization_count.subuniverse(); - self.skolemization_count = universe; - tcx.mk_region(ReSkolemized(universe, br)) + let sc = self.skolemization_count; + self.skolemization_count = sc + 1; + tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br)) } /// Removes all the edges to/from the skolemized regions that are @@ -503,20 +503,20 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); assert!(self.undo_log[snapshot.length] == OpenSnapshot); assert!( - self.skolemization_count.as_usize() >= skols.len(), + self.skolemization_count as usize >= skols.len(), "popping more skolemized variables than actually exist, \ sc now = {}, skols.len = {}", - self.skolemization_count.as_usize(), + self.skolemization_count, skols.len() ); - let last_to_pop = self.skolemization_count.subuniverse(); - let first_to_pop = ty::UniverseIndex::from(last_to_pop.as_u32() - (skols.len() as u32)); + let last_to_pop = self.skolemization_count; + let first_to_pop = last_to_pop - (skols.len() as u32); assert!( first_to_pop >= snapshot.skolemization_count, "popping more regions than snapshot contains, \ - sc now = {:?}, sc then = {:?}, skols.len = {}", + sc now = {}, sc then = {}, skols.len = {}", self.skolemization_count, snapshot.skolemization_count, skols.len() @@ -524,13 +524,13 @@ impl<'tcx> RegionConstraintCollector<'tcx> { debug_assert! { skols.iter() .all(|&k| match *k { - ty::ReSkolemized(universe, _) => - universe >= first_to_pop && - universe < last_to_pop, + ty::ReSkolemized(index, _) => + index.index >= first_to_pop && + index.index < last_to_pop, _ => false }), - "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}", + "invalid skolemization keys or keys out of range ({}..{}): {:?}", snapshot.skolemization_count, self.skolemization_count, skols @@ -865,7 +865,7 @@ impl fmt::Debug for RegionSnapshot { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "RegionSnapshot(length={},skolemization={:?})", + "RegionSnapshot(length={},skolemization={})", self.length, self.skolemization_count ) From 50bd71cfdce877712cfcb5c11e251a9ed4a9201e Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 09:02:31 -0700 Subject: [PATCH 02/22] Revert "fix tests in `librustc_driver`" This reverts commit 17df455c2eda9717e2d7ff2f43809b553852d7e6. --- src/librustc_driver/test.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index fb48f900be522..23008315ec723 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -455,8 +455,7 @@ fn sub_free_bound_false_infer() { //! does NOT hold for any instantiation of `_#1`. test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { - let t_infer1 = env.infcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(DUMMY_SP)); + let t_infer1 = env.infcx.next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP)); let t_rptr_bound1 = env.t_rptr_late_bound(1); env.check_not_sub(env.t_fn(&[t_infer1], env.tcx().types.isize), env.t_fn(&[t_rptr_bound1], env.tcx().types.isize)); From 5dad682c75fd3853058f62c248f9a2dc6a4b46cb Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 09:02:33 -0700 Subject: [PATCH 03/22] Revert "fix tidy error" This reverts commit a985634fc08893d9e1255e287ad4bacc2cefa2ce. --- src/librustc/infer/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index fe919775da0b4..f9ffdd5271290 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -851,10 +851,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.mk_var(self.next_ty_var_id(universe, false, origin)) } - pub fn next_diverging_ty_var(&self, - universe: ty::UniverseIndex, - origin: TypeVariableOrigin) - -> Ty<'tcx> { + pub fn next_diverging_ty_var(&self, universe: ty::UniverseIndex, origin: TypeVariableOrigin) -> Ty<'tcx> { self.tcx.mk_var(self.next_ty_var_id(universe, true, origin)) } From 2a94f30061bac39c81911f26e6d9e60d48f343cb Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 09:02:35 -0700 Subject: [PATCH 04/22] Revert "change skolemizations to use universe index" This reverts commit 35e78b5cddc04c6bd13da2a1290d27cfb8ae8db8. --- src/librustc/ty/mod.rs | 18 +++--------------- src/librustc/ty/sty.rs | 7 ++++++- src/librustc/util/ppaux.rs | 2 +- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index fc1d26b0e0910..bd4086b975996 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -67,7 +67,7 @@ pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const}; pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; pub use self::sty::RegionKind; -pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid}; +pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}; pub use self::sty::BoundRegion::*; pub use self::sty::InferTy::*; pub use self::sty::RegionKind::*; @@ -1328,7 +1328,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> { /// type name in a non-zero universe is a skolemized type -- an /// idealized representative of "types in general" that we use for /// checking generic functions. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct UniverseIndex(u32); impl UniverseIndex { @@ -1348,19 +1348,7 @@ impl UniverseIndex { /// region `'a`, but that region was not nameable from `U` because /// it was not in scope there. pub fn subuniverse(self) -> UniverseIndex { - UniverseIndex(self.0.checked_add(1).unwrap()) - } - - pub fn from(v: u32) -> UniverseIndex { - UniverseIndex(v) - } - - pub fn as_u32(&self) -> u32 { - self.0 - } - - pub fn as_usize(&self) -> usize { - self.0 as usize + UniverseIndex(self.0 + 1) } /// Gets the "depth" of this universe in the universe tree. This diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 109422564c84d..6b95c8662c3c0 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1028,7 +1028,7 @@ pub enum RegionKind { /// A skolemized region - basically the higher-ranked version of ReFree. /// Should not exist after typeck. - ReSkolemized(ty::UniverseIndex, BoundRegion), + ReSkolemized(SkolemizedRegionVid, BoundRegion), /// Empty lifetime is for data that is never accessed. /// Bottom in the region lattice. We treat ReEmpty somewhat @@ -1082,6 +1082,11 @@ newtype_index!(RegionVid DEBUG_FORMAT = custom, }); +#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)] +pub struct SkolemizedRegionVid { + pub index: u32, +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum InferTy { TyVar(TyVid), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index efa53c775ae25..7e00912a21780 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -793,7 +793,7 @@ define_print! { } ty::ReSkolemized(id, ref bound_region) => { - write!(f, "ReSkolemized({:?}, {:?})", id, bound_region) + write!(f, "ReSkolemized({}, {:?})", id.index, bound_region) } ty::ReEmpty => write!(f, "ReEmpty"), From f6e6d230589a4d90477718f85ecf86f96f223a32 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 09:03:33 -0700 Subject: [PATCH 05/22] Revert "introduce `UniverseIndex` into `ParamEnv`" This reverts commit d4df52cacbee5d95e912a43188192a5054d36b4f. --- src/librustc/ich/impls_ty.rs | 10 -------- src/librustc/traits/mod.rs | 7 ++---- src/librustc/ty/mod.rs | 25 ++++---------------- src/librustc/ty/structural_impls.rs | 26 ++------------------- src/librustc_typeck/check/compare_method.rs | 3 +-- 5 files changed, 9 insertions(+), 62 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 4eb4f0edafe40..c196d80cf2686 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1066,7 +1066,6 @@ for ty::steal::Steal impl_stable_hash_for!(struct ty::ParamEnv<'tcx> { caller_bounds, - universe, reveal }); @@ -1237,15 +1236,6 @@ for traits::VtableGeneratorData<'gcx, N> where N: HashStable HashStable> -for ty::UniverseIndex { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher) { - self.depth().hash_stable(hcx, hasher); - } -} - impl_stable_hash_for!( impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> { variables, value diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index a2a5aa246cf77..09695c69a2c14 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -546,8 +546,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, predicates); let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates), - unnormalized_env.reveal, - unnormalized_env.universe); + unnormalized_env.reveal); tcx.infer_ctxt().enter(|infcx| { // FIXME. We should really... do something with these region @@ -621,9 +620,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("normalize_param_env_or_error: resolved predicates={:?}", predicates); - ty::ParamEnv::new(tcx.intern_predicates(&predicates), - unnormalized_env.reveal, - unnormalized_env.universe) + ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal) }) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index bd4086b975996..7459c0369053e 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1334,7 +1334,9 @@ pub struct UniverseIndex(u32); impl UniverseIndex { /// The root universe, where things that the user defined are /// visible. - pub const ROOT: UniverseIndex = UniverseIndex(0); + pub fn root() -> UniverseIndex { + UniverseIndex(0) + } /// A "subuniverse" corresponds to being inside a `forall` quantifier. /// So, for example, suppose we have this type in universe `U`: @@ -1350,13 +1352,6 @@ impl UniverseIndex { pub fn subuniverse(self) -> UniverseIndex { UniverseIndex(self.0 + 1) } - - /// Gets the "depth" of this universe in the universe tree. This - /// is not really useful except for e.g. the `HashStable` - /// implementation - pub fn depth(&self) -> u32 { - self.0 - } } /// When type checking, we use the `ParamEnv` to track @@ -1373,17 +1368,6 @@ pub struct ParamEnv<'tcx> { /// want `Reveal::All` -- note that this is always paired with an /// empty environment. To get that, use `ParamEnv::reveal()`. pub reveal: traits::Reveal, - - /// What is the innermost universe we have created? Starts out as - /// `UniverseIndex::root()` but grows from there as we enter - /// universal quantifiers. - /// - /// NB: At present, we exclude the universal quantifiers on the - /// item we are type-checking, and just consider those names as - /// part of the root universe. So this would only get incremented - /// when we enter into a higher-ranked (`for<..>`) type or trait - /// bound. - pub universe: UniverseIndex, } impl<'tcx> ParamEnv<'tcx> { @@ -2710,8 +2694,7 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // sure that this will succeed without errors anyway. let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates), - traits::Reveal::UserFacing, - ty::UniverseIndex::ROOT); + traits::Reveal::UserFacing); let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| { tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 0627bcdfb0ec1..0bfb9cc8acd99 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -279,7 +279,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { tcx.lift(&self.caller_bounds).map(|caller_bounds| { ty::ParamEnv { reveal: self.reveal, - universe: self.universe, caller_bounds, } }) @@ -737,29 +736,8 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { } } -impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::ParamEnv { - reveal: self.reveal, - caller_bounds: self.caller_bounds.fold_with(folder), - universe: self.universe.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - let &ty::ParamEnv { reveal: _, ref universe, ref caller_bounds } = self; - universe.super_visit_with(visitor) || caller_bounds.super_visit_with(visitor) - } -} - -impl<'tcx> TypeFoldable<'tcx> for ty::UniverseIndex { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { - *self - } - - fn super_visit_with>(&self, _visitor: &mut V) -> bool { - false - } +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { reveal, caller_bounds } } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index b6459b624104f..9b2abf32b6449 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -218,8 +218,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // the new hybrid bounds we computed. let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id); let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), - Reveal::UserFacing, - ty::UniverseIndex::ROOT); + Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, impl_m.def_id, param_env, From 26d1fc7246278555da8be78d54f84d5136016f6b Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 09:07:27 -0700 Subject: [PATCH 06/22] Revert "add universes to type inference variables" This reverts commit 13efaf0481275dba18f1d18f4b59b664b2d2031a. --- src/librustc/infer/anon_types/mod.rs | 3 +- src/librustc/infer/combine.rs | 4 +-- src/librustc/infer/fudge.rs | 6 +--- src/librustc/infer/lattice.rs | 12 +++---- src/librustc/infer/mod.rs | 23 +++++-------- src/librustc/infer/type_variable.rs | 29 +++------------- src/librustc/traits/coherence.rs | 4 +-- src/librustc/traits/error_reporting.rs | 17 +++------- src/librustc/traits/project.rs | 2 -- src/librustc/traits/select.rs | 3 +- src/librustc/traits/specialize/mod.rs | 2 +- src/librustc_typeck/check/_match.rs | 11 ++---- src/librustc_typeck/check/closure.rs | 3 +- src/librustc_typeck/check/coercion.rs | 3 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/method/confirm.rs | 4 +-- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 7 ++-- src/librustc_typeck/check/method/suggest.rs | 3 +- src/librustc_typeck/check/mod.rs | 37 ++++++++------------- src/librustc_typeck/check/op.rs | 9 ++--- 21 files changed, 55 insertions(+), 131 deletions(-) diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index eb26f0c1188bf..a749d0dddd7ee 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -600,8 +600,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { return anon_defn.concrete_ty; } let span = tcx.def_span(def_id); - let ty_var = infcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(span)); + let ty_var = infcx.next_ty_var(TypeVariableOrigin::TypeInference(span)); let predicates_of = tcx.predicates_of(def_id); let bounds = predicates_of.instantiate(tcx, substs); diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 1c581c44464e7..c2167751a27e7 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -407,7 +407,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' drop(variables); self.relate(&u, &u) } - TypeVariableValue::Unknown { universe } => { + TypeVariableValue::Unknown { .. } => { match self.ambient_variance { // Invariant: no need to make a fresh type variable. ty::Invariant => return Ok(t), @@ -424,7 +424,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' } let origin = *variables.var_origin(vid); - let new_var_id = variables.new_var(universe, false, origin); + let new_var_id = variables.new_var(false, origin); let u = self.tcx().mk_var(new_var_id); debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs index 48eb253415cdf..961dd70a46852 100644 --- a/src/librustc/infer/fudge.rs +++ b/src/librustc/infer/fudge.rs @@ -141,11 +141,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> { // This variable was created during the // fudging. Recreate it with a fresh variable // here. - // - // The ROOT universe is fine because we only - // ever invoke this routine at the - // "item-level" of inference. - self.infcx.next_ty_var(ty::UniverseIndex::ROOT, origin) + self.infcx.next_ty_var(origin) } } } diff --git a/src/librustc/infer/lattice.rs b/src/librustc/infer/lattice.rs index c4722f9a7f96c..28aba51ab3724 100644 --- a/src/librustc/infer/lattice.rs +++ b/src/librustc/infer/lattice.rs @@ -88,17 +88,13 @@ pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L, // is (e.g.) `Box`. A more obvious solution might be to // iterate on the subtype obligations that are returned, but I // think this suffices. -nmatsakis - (&ty::TyInfer(TyVar(a_vid)), _) => { - let universe = infcx.type_variables.borrow_mut().probe(a_vid).universe().unwrap(); - let v = infcx.next_ty_var(universe, - TypeVariableOrigin::LatticeVariable(this.cause().span)); + (&ty::TyInfer(TyVar(..)), _) => { + let v = infcx.next_ty_var(TypeVariableOrigin::LatticeVariable(this.cause().span)); this.relate_bound(v, b, a)?; Ok(v) } - (_, &ty::TyInfer(TyVar(b_vid))) => { - let universe = infcx.type_variables.borrow_mut().probe(b_vid).universe().unwrap(); - let v = infcx.next_ty_var(universe, - TypeVariableOrigin::LatticeVariable(this.cause().span)); + (_, &ty::TyInfer(TyVar(..))) => { + let v = infcx.next_ty_var(TypeVariableOrigin::LatticeVariable(this.cause().span)); this.relate_bound(v, a, b)?; Ok(v) } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index f9ffdd5271290..032a5c59d2dca 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -837,22 +837,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }) } - pub fn next_ty_var_id(&self, - universe: ty::UniverseIndex, - diverging: bool, - origin: TypeVariableOrigin) - -> TyVid { + pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid { self.type_variables .borrow_mut() - .new_var(universe, diverging, origin) + .new_var(diverging, origin) } - pub fn next_ty_var(&self, universe: ty::UniverseIndex, origin: TypeVariableOrigin) -> Ty<'tcx> { - self.tcx.mk_var(self.next_ty_var_id(universe, false, origin)) + pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { + self.tcx.mk_var(self.next_ty_var_id(false, origin)) } - pub fn next_diverging_ty_var(&self, universe: ty::UniverseIndex, origin: TypeVariableOrigin) -> Ty<'tcx> { - self.tcx.mk_var(self.next_ty_var_id(universe, true, origin)) + pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { + self.tcx.mk_var(self.next_ty_var_id(true, origin)) } pub fn next_int_var_id(&self) -> IntVid { @@ -907,14 +903,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// use an inference variable for `C` with `[T, U]` /// as the substitutions for the default, `(T, U)`. pub fn type_var_for_def(&self, - universe: ty::UniverseIndex, span: Span, def: &ty::TypeParameterDef) -> Ty<'tcx> { let ty_var_id = self.type_variables .borrow_mut() - .new_var(universe, - false, + .new_var(false, TypeVariableOrigin::TypeParameterDefinition(span, def.name)); self.tcx.mk_var(ty_var_id) @@ -923,14 +917,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// Given a set of generics defined on a type or impl, returns a substitution mapping each /// type/region parameter to a fresh inference variable. pub fn fresh_substs_for_item(&self, - universe: ty::UniverseIndex, span: Span, def_id: DefId) -> &'tcx Substs<'tcx> { Substs::for_item(self.tcx, def_id, |def, _| { self.region_var_for_def(span, def) }, |def, _| { - self.type_var_for_def(universe, span, def) + self.type_var_for_def(span, def) }) } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 66360ea50bbe0..91df6cabf3a8b 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -78,18 +78,10 @@ struct TypeVariableData { #[derive(Copy, Clone, Debug)] pub enum TypeVariableValue<'tcx> { Known { value: Ty<'tcx> }, - Unknown { universe: ty::UniverseIndex }, -} - -#[derive(Copy, Clone, Debug)] -pub enum ProbeTyValue<'tcx> { - Ty(Ty<'tcx>), - Vid(ty::TyVid), + Unknown, } impl<'tcx> TypeVariableValue<'tcx> { - /// If this value is known, returns the type it is known to be. - /// Otherwise, `None`. pub fn known(&self) -> Option> { match *self { TypeVariableValue::Unknown { .. } => None, @@ -97,14 +89,6 @@ impl<'tcx> TypeVariableValue<'tcx> { } } - /// If this value is unknown, returns the universe, otherwise `None`. - pub fn universe(&self) -> Option { - match *self { - TypeVariableValue::Unknown { universe } => Some(universe), - TypeVariableValue::Known { .. } => None, - } - } - pub fn is_unknown(&self) -> bool { match *self { TypeVariableValue::Unknown { .. } => true, @@ -197,11 +181,10 @@ impl<'tcx> TypeVariableTable<'tcx> { /// The code in this module doesn't care, but it can be useful /// for improving error messages. pub fn new_var(&mut self, - universe: ty::UniverseIndex, diverging: bool, origin: TypeVariableOrigin) -> ty::TyVid { - let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown { universe }); + let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown); let sub_key = self.sub_relations.new_key(()); assert_eq!(eq_key.vid, sub_key); @@ -453,12 +436,8 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { (&TypeVariableValue::Known { .. }, &TypeVariableValue::Unknown { .. }) => Ok(*value1), (&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2), - // If both sides are unknown, we need to pick the most restrictive universe. - (&TypeVariableValue::Unknown { universe: universe1 }, - &TypeVariableValue::Unknown { universe: universe2 }) => { - let universe = cmp::min(universe1, universe2); - Ok(TypeVariableValue::Unknown { universe }) - } + // If both sides are *unknown*, it hardly matters, does it? + (&TypeVariableValue::Unknown, &TypeVariableValue::Unknown) => Ok(*value1), } } } diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 06926b1648df5..31f8af1f96872 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -92,9 +92,7 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, ' -> ty::ImplHeader<'tcx> { let tcx = selcx.tcx(); - let impl_substs = selcx.infcx().fresh_substs_for_item(param_env.universe, - DUMMY_SP, - impl_def_id); + let impl_substs = selcx.infcx().fresh_substs_for_item(DUMMY_SP, impl_def_id); let header = ty::ImplHeader { impl_def_id, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b8455b97fa41f..a2161c3edbb29 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -290,9 +290,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.for_each_relevant_impl( trait_ref.def_id, trait_self_ty, |def_id| { - let impl_substs = self.fresh_substs_for_item(param_env.universe, - obligation.cause.span, - def_id); + let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); let impl_trait_ref = tcx .impl_trait_ref(def_id) .unwrap() @@ -1184,7 +1182,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { -> bool { struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, var_map: FxHashMap, Ty<'tcx>> } @@ -1194,14 +1191,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if let ty::TyParam(ty::ParamTy {name, ..}) = ty.sty { let infcx = self.infcx; - let param_env = self.param_env; - self.var_map - .entry(ty) - .or_insert_with(|| { - let origin = TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP, - name); - infcx.next_ty_var(param_env.universe, origin) - }) + self.var_map.entry(ty).or_insert_with(|| + infcx.next_ty_var( + TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP, name))) } else { ty.super_fold_with(self) } @@ -1213,7 +1205,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let cleaned_pred = pred.fold_with(&mut ParamToVarFolder { infcx: self, - param_env, var_map: FxHashMap() }); diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index a9dc491574379..2a62d0b5ee39a 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -477,7 +477,6 @@ pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>( let tcx = selcx.infcx().tcx; let def_id = projection_ty.item_def_id; let ty_var = selcx.infcx().next_ty_var( - param_env.universe, TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id))); let projection = ty::Binder(ty::ProjectionPredicate { projection_ty, @@ -798,7 +797,6 @@ fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tc let tcx = selcx.infcx().tcx; let def_id = projection_ty.item_def_id; let new_value = selcx.infcx().next_ty_var( - param_env.universe, TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id))); Normalized { value: new_value, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index f2f54dcedfd65..99e2c73062049 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -3088,8 +3088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { snapshot); let skol_obligation_trait_ref = skol_obligation.trait_ref; - let impl_substs = self.infcx.fresh_substs_for_item(obligation.param_env.universe, - obligation.cause.span, + let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); let impl_trait_ref = impl_trait_ref.subst(self.tcx(), diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 5ea089abb8e86..2be1258f1c9f5 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -221,7 +221,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, target_impl: DefId) -> Result<&'tcx Substs<'tcx>, ()> { let selcx = &mut SelectionContext::new(&infcx); - let target_substs = infcx.fresh_substs_for_item(param_env.universe, DUMMY_SP, target_impl); + let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl); let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx, param_env, target_impl, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index eb02c05fd3957..fa9ef07059a93 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -329,7 +329,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let element_tys_iter = (0..max_len).map(|_| self.next_ty_var( // FIXME: MiscVariable for now, obtaining the span and name information // from all tuple elements isn't trivial. - ty::UniverseIndex::ROOT, TypeVariableOrigin::TypeInference(pat.span))); let element_tys = tcx.mk_type_list(element_tys_iter); let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys, false)); @@ -340,8 +339,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pat_ty } PatKind::Box(ref inner) => { - let inner_ty = self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(inner.span)); + let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span)); let uniq_ty = tcx.mk_box(inner_ty); if self.check_dereferencable(pat.span, expected, &inner) { @@ -374,7 +372,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } _ => { let inner_ty = self.next_ty_var( - ty::UniverseIndex::ROOT, TypeVariableOrigin::TypeInference(inner.span)); let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl }; let region = self.next_region_var(infer::PatternRegion(pat.span)); @@ -633,8 +630,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // ...but otherwise we want to use any supertype of the // discriminant. This is sort of a workaround, see note (*) in // `check_pat` for some details. - discrim_ty = self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(discrim.span)); + discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span)); self.check_expr_has_type_or_error(discrim, discrim_ty); }; @@ -695,8 +691,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // arm for inconsistent arms or to the whole match when a `()` type // is required). Expectation::ExpectHasType(ety) if ety != self.tcx.mk_nil() => ety, - _ => self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(expr.span)), + _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)), }; CoerceMany::with_coercion_sites(coerce_first, arms) }; diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 72e4b726a22b4..7e25a97ed44aa 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -110,8 +110,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { |_, _| span_bug!(expr.span, "closure has region param"), |_, _| { self.infcx - .next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::ClosureSynthetic(expr.span)) + .next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)) }, ); let substs = ty::ClosureSubsts { substs }; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index abb0acd699cba..3a153bafe8f50 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -177,7 +177,6 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // micro-optimization: no need for this if `b` is // already resolved in some way. let diverging_ty = self.next_diverging_ty_var( - ty::UniverseIndex::ROOT, TypeVariableOrigin::AdjustmentType(self.cause.span)); self.unify_and(&b, &diverging_ty, simple(Adjust::NeverToAny)) } else { @@ -511,7 +510,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // We only have the latter, so we use an inference variable // for the former and let type inference do the rest. let origin = TypeVariableOrigin::MiscVariable(self.cause.span); - let coerce_target = self.next_ty_var(ty::UniverseIndex::ROOT, origin); + let coerce_target = self.next_ty_var(origin); let mut coercion = self.unify_and(coerce_target, target, |target| { let unsize = Adjustment { kind: Adjust::Unsize, diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 67c9832cbf9f4..bb1439ac760b8 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -90,7 +90,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( let drop_impl_span = tcx.def_span(drop_impl_did); let fresh_impl_substs = - infcx.fresh_substs_for_item(ty::UniverseIndex::ROOT, drop_impl_span, drop_impl_did); + infcx.fresh_substs_for_item(drop_impl_span, drop_impl_did); let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs); let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index b777ac30920cd..a3233c8d86599 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -259,7 +259,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // the process we will unify the transformed-self-type // of the method with the actual type in order to // unify some of these variables. - self.fresh_substs_for_item(ty::UniverseIndex::ROOT, self.span, trait_def_id) + self.fresh_substs_for_item(self.span, trait_def_id) } probe::WhereClausePick(ref poly_trait_ref) => { @@ -336,7 +336,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { { self.to_ty(ast_ty) } else { - self.type_var_for_def(ty::UniverseIndex::ROOT, self.span, def) + self.type_var_for_def(self.span, def) } }) } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f7bb1a6a23239..06b8e509a4cac 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -255,7 +255,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else if let Some(ref input_types) = opt_input_types { input_types[def.index as usize - 1] } else { - self.type_var_for_def(ty::UniverseIndex::ROOT, span, def) + self.type_var_for_def(span, def) } }); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 4d344eb279903..b68b6ab28dd9b 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -729,9 +729,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { Def::Method(def_id) => { let fty = self.tcx.fn_sig(def_id); self.probe(|_| { - let substs = self.fresh_substs_for_item(ty::UniverseIndex::ROOT, - self.span, - method.def_id); + let substs = self.fresh_substs_for_item(self.span, method.def_id); let fty = fty.subst(self.tcx, substs); let (fty, _) = self.replace_late_bound_regions_with_fresh_var( self.span, infer::FnCall, &fty); @@ -1310,7 +1308,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { if i < substs.len() { substs.type_at(i) } else { - self.type_var_for_def(ty::UniverseIndex::ROOT, self.span, def) + self.type_var_for_def(self.span, def) } }); xform_fn_sig.subst(self.tcx, substs) @@ -1327,7 +1325,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { def_id, |_, _| self.tcx.types.re_erased, |_, _| self.next_ty_var( - ty::UniverseIndex::ROOT, TypeVariableOrigin::SubstitutionPlaceholder( self.tcx.def_span(def_id)))) } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 5c20490f82303..4556b5a42b3d6 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -54,8 +54,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.autoderef(span, ty).any(|(ty, _)| { self.probe(|_| { let fn_once_substs = tcx.mk_substs_trait(ty, - &[self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(span))]); + &[self.next_ty_var(TypeVariableOrigin::MiscVariable(span))]); let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); let poly_trait_ref = trait_ref.to_poly_trait_ref(); let obligation = diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 48591998a1fb8..be36ce15adc3e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -362,8 +362,7 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> { /// hard constraint exists, creates a fresh type variable. fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> { self.only_has_type(fcx) - .unwrap_or_else(|| fcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(span))) + .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span))) } } @@ -922,8 +921,7 @@ impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> { match ty_opt { None => { // infer the variable's type - let var_ty = self.fcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(span)); + let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)); self.fcx.locals.borrow_mut().insert(nid, var_ty); var_ty } @@ -1027,8 +1025,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, let span = body.value.span; if body.is_generator && can_be_generator.is_some() { - let yield_ty = fcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(span)); + let yield_ty = fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)); fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType); fcx.yield_ty = Some(yield_ty); } @@ -1061,8 +1058,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, // This ensures that all nested generators appear before the entry of this generator. // resolve_generator_interiors relies on this property. let gen_ty = if can_be_generator.is_some() && body.is_generator { - let witness = fcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(span)); + let witness = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)); let interior = ty::GeneratorInterior { witness, movable: can_be_generator.unwrap() == hir::GeneratorMovability::Movable, @@ -1100,7 +1096,6 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, let mut actual_return_ty = coercion.complete(&fcx); if actual_return_ty.is_never() { actual_return_ty = fcx.next_diverging_ty_var( - ty::UniverseIndex::ROOT, TypeVariableOrigin::DivergingFn(span)); } fcx.demand_suptype(span, ret_ty, actual_return_ty); @@ -1692,14 +1687,13 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { } fn ty_infer(&self, span: Span) -> Ty<'tcx> { - self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(span)) + self.next_ty_var(TypeVariableOrigin::TypeInference(span)) } fn ty_infer_for_def(&self, ty_param_def: &ty::TypeParameterDef, span: Span) -> Ty<'tcx> { - self.type_var_for_def(ty::UniverseIndex::ROOT, span, ty_param_def) + self.type_var_for_def(span, ty_param_def) } fn projected_ty_from_poly_trait_ref(&self, @@ -2321,8 +2315,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If some lookup succeeds, write callee into table and extract index/element // type from the method signature. // If some lookup succeeded, install method in table - let input_ty = self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::AutoDeref(base_expr.span)); + let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span)); let method = self.try_overloaded_place_op( expr.span, self_ty, &[input_ty], needs, PlaceOp::Index); @@ -2761,7 +2754,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id), "expression with never type wound up being adjusted"); let adj_ty = self.next_diverging_ty_var( - ty::UniverseIndex::ROOT, TypeVariableOrigin::AdjustmentType(expr.span)); self.apply_adjustments(expr, vec![Adjustment { kind: Adjust::NeverToAny, @@ -2839,7 +2831,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let ity = self.tcx.type_of(did); debug!("impl_self_ty: ity={:?}", ity); - let substs = self.fresh_substs_for_item(ty::UniverseIndex::ROOT, span, did); + let substs = self.fresh_substs_for_item(span, did); let substd_ty = self.instantiate_type_scheme(span, &substs, &ity); TypeAndSubsts { substs: substs, ty: substd_ty } @@ -3979,8 +3971,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let element_ty = if !args.is_empty() { let coerce_to = uty.unwrap_or_else( - || self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(expr.span))); + || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))); let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args); assert_eq!(self.diverges.get(), Diverges::Maybe); for e in args { @@ -3990,8 +3981,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } coerce.complete(self) } else { - self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(expr.span)) + self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)) }; tcx.mk_array(element_ty, args.len() as u64) } @@ -4031,8 +4021,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (uty, uty) } None => { - let t: Ty = self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(element.span)); + let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span)); let element_ty = self.check_expr_has_type_or_error(&element, t); (element_ty, t) } @@ -4811,7 +4800,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Handle Self first, so we can adjust the index to match the AST. if has_self && i == 0 { return opt_self_ty.unwrap_or_else(|| { - self.type_var_for_def(ty::UniverseIndex::ROOT, span, def) + self.type_var_for_def(span, def) }); } i -= has_self as usize; @@ -4844,7 +4833,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // This can also be reached in some error cases: // We prefer to use inference variables instead of // TyError to let type inference recover somewhat. - self.type_var_for_def(ty::UniverseIndex::ROOT, span, def) + self.type_var_for_def(span, def) } }); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 47a229cbd3b5b..990dfaa1e56a1 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -174,10 +174,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // trait matching creating lifetime constraints that are too strict. // E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result // in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`. - let lhs_ty = self.check_expr_coercable_to_type_with_needs( - lhs_expr, - self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(lhs_expr.span)), + let lhs_ty = self.check_expr_coercable_to_type_with_needs(lhs_expr, + self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span)), lhs_needs); let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty); @@ -187,8 +185,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // using this variable as the expected type, which sometimes lets // us do better coercions than we would be able to do otherwise, // particularly for things like `String + &String`. - let rhs_ty_var = self.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::MiscVariable(rhs_expr.span)); + let rhs_ty_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(rhs_expr.span)); let result = self.lookup_op_method(lhs_ty, &[rhs_ty_var], Op::Binary(op, is_assign)); From 3d4791b68c0f9b3fbd83e3f6ebdcf0c171c838a3 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 7 Feb 2018 10:16:44 -0700 Subject: [PATCH 07/22] introduce `UniverseIndex` into `InferCtxt` Always using root environment for now. --- src/librustc/infer/mod.rs | 12 ++++++++++++ src/librustc/ty/mod.rs | 4 +--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 032a5c59d2dca..afb8d5e6e61ed 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -182,6 +182,17 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // obligations within. This is expected to be done 'late enough' // that all type inference variables have been bound and so forth. pub region_obligations: RefCell)>>, + + /// What is the innermost universe we have created? Starts out as + /// `UniverseIndex::root()` but grows from there as we enter + /// universal quantifiers. + /// + /// NB: At present, we exclude the universal quantifiers on the + /// item we are type-checking, and just consider those names as + /// part of the root universe. So this would only get incremented + /// when we enter into a higher-ranked (`for<..>`) type or trait + /// bound. + pub universe: ty::UniverseIndex, } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -454,6 +465,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { err_count_on_creation: tcx.sess.err_count(), in_snapshot: Cell::new(false), region_obligations: RefCell::new(vec![]), + universe: ty::UniverseIndex::ROOT, })) } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7459c0369053e..2a0cfe90cd294 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1334,9 +1334,7 @@ pub struct UniverseIndex(u32); impl UniverseIndex { /// The root universe, where things that the user defined are /// visible. - pub fn root() -> UniverseIndex { - UniverseIndex(0) - } + pub const ROOT: Self = UniverseIndex(0); /// A "subuniverse" corresponds to being inside a `forall` quantifier. /// So, for example, suppose we have this type in universe `U`: From ff17bd722b637ba9e5665589d62987023903f0da Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 7 Feb 2018 10:27:42 -0700 Subject: [PATCH 08/22] add universes to type inference variables This gives each type inference variable a notion of universe but doesn't do anything with it. We can always get the "current universe" from infer_ctxt. This relies on the property of type variables that they can never interact with siblings. --- src/librustc/infer/combine.rs | 4 ++-- src/librustc/infer/mod.rs | 5 +++-- src/librustc/infer/type_variable.rs | 13 ++++++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index c2167751a27e7..1c581c44464e7 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -407,7 +407,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' drop(variables); self.relate(&u, &u) } - TypeVariableValue::Unknown { .. } => { + TypeVariableValue::Unknown { universe } => { match self.ambient_variance { // Invariant: no need to make a fresh type variable. ty::Invariant => return Ok(t), @@ -424,7 +424,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' } let origin = *variables.var_origin(vid); - let new_var_id = variables.new_var(false, origin); + let new_var_id = variables.new_var(universe, false, origin); let u = self.tcx().mk_var(new_var_id); debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index afb8d5e6e61ed..e4710442ebb32 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -852,7 +852,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid { self.type_variables .borrow_mut() - .new_var(diverging, origin) + .new_var(self.universe, diverging, origin) } pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { @@ -920,7 +920,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { -> Ty<'tcx> { let ty_var_id = self.type_variables .borrow_mut() - .new_var(false, + .new_var(self.universe, + false, TypeVariableOrigin::TypeParameterDefinition(span, def.name)); self.tcx.mk_var(ty_var_id) diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 91df6cabf3a8b..bb5bf4cdecb25 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -78,10 +78,12 @@ struct TypeVariableData { #[derive(Copy, Clone, Debug)] pub enum TypeVariableValue<'tcx> { Known { value: Ty<'tcx> }, - Unknown, + Unknown { universe: ty::UniverseIndex }, } impl<'tcx> TypeVariableValue<'tcx> { + /// If this value is known, returns the type it is known to be. + /// Otherwise, `None`. pub fn known(&self) -> Option> { match *self { TypeVariableValue::Unknown { .. } => None, @@ -181,10 +183,11 @@ impl<'tcx> TypeVariableTable<'tcx> { /// The code in this module doesn't care, but it can be useful /// for improving error messages. pub fn new_var(&mut self, + universe: ty::UniverseIndex, diverging: bool, origin: TypeVariableOrigin) -> ty::TyVid { - let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown); + let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown { universe }); let sub_key = self.sub_relations.new_key(()); assert_eq!(eq_key.vid, sub_key); @@ -437,7 +440,11 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { (&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2), // If both sides are *unknown*, it hardly matters, does it? - (&TypeVariableValue::Unknown, &TypeVariableValue::Unknown) => Ok(*value1), + (&TypeVariableValue::Unknown { universe: universe1 }, + &TypeVariableValue::Unknown { universe: universe2 }) => { + let universe = cmp::min(universe1, universe2); + Ok(TypeVariableValue::Unknown { universe }) + } } } } From 66520ff4b4d6f190624bf5f0a8c4c36b7a251251 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 7 Feb 2018 11:17:31 -0700 Subject: [PATCH 09/22] change skolemizations to use universe index This is sort of confusing "side step". All it does is to change the representation of a skolemized region. but the source of that universe index is not the inference context, which is what we eventually want, but rather an internal counter in the region inference context. We'll patch that up later. But doing this now ought to help with confusing diffs later. --- src/librustc/infer/region_constraints/mod.rs | 36 ++++++++++---------- src/librustc/ty/mod.rs | 20 +++++++++-- src/librustc/ty/sty.rs | 7 +--- src/librustc/util/ppaux.rs | 4 +-- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index a44ffc24cb0e0..96c7dc5da5e00 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -48,7 +48,7 @@ pub struct RegionConstraintCollector<'tcx> { glbs: CombineMap<'tcx>, /// Number of skolemized variables currently active. - skolemization_count: u32, + skolemization_count: ty::UniverseIndex, /// Global counter used during the GLB algorithm to create unique /// names for fresh bound regions @@ -233,7 +233,7 @@ type CombineMap<'tcx> = FxHashMap, RegionVid>; pub struct RegionSnapshot { length: usize, region_snapshot: ut::Snapshot>, - skolemization_count: u32, + skolemization_count: ty::UniverseIndex, } /// When working with skolemized regions, we often wish to find all of @@ -277,7 +277,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { data: RegionConstraintData::default(), lubs: FxHashMap(), glbs: FxHashMap(), - skolemization_count: 0, + skolemization_count: ty::UniverseIndex::ROOT, bound_count: 0, undo_log: Vec::new(), unification_table: ut::UnificationTable::new(), @@ -329,7 +329,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { unification_table, } = self; - assert_eq!(*skolemization_count, 0); + assert_eq!(*skolemization_count, ty::UniverseIndex::ROOT); // Clear the tables of (lubs, glbs), so that we will create // fresh regions if we do a LUB operation. As it happens, @@ -375,7 +375,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.undo_log[snapshot.length] == OpenSnapshot); assert!( self.skolemization_count == snapshot.skolemization_count, - "failed to pop skolemized regions: {} now vs {} at start", + "failed to pop skolemized regions: {:?} now vs {:?} at start", self.skolemization_count, snapshot.skolemization_count ); @@ -483,9 +483,9 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); assert!(self.undo_log[snapshot.length] == OpenSnapshot); - let sc = self.skolemization_count; - self.skolemization_count = sc + 1; - tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br)) + let universe = self.skolemization_count.subuniverse(); + self.skolemization_count = universe; + tcx.mk_region(ReSkolemized(universe, br)) } /// Removes all the edges to/from the skolemized regions that are @@ -503,20 +503,20 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); assert!(self.undo_log[snapshot.length] == OpenSnapshot); assert!( - self.skolemization_count as usize >= skols.len(), + self.skolemization_count.as_usize() >= skols.len(), "popping more skolemized variables than actually exist, \ - sc now = {}, skols.len = {}", + sc now = {:?}, skols.len = {:?}", self.skolemization_count, skols.len() ); - let last_to_pop = self.skolemization_count; - let first_to_pop = last_to_pop - (skols.len() as u32); + let last_to_pop = self.skolemization_count.subuniverse(); + let first_to_pop = ty::UniverseIndex::from(last_to_pop.as_u32() - skols.len() as u32); assert!( first_to_pop >= snapshot.skolemization_count, "popping more regions than snapshot contains, \ - sc now = {}, sc then = {}, skols.len = {}", + sc now = {:?}, sc then = {:?}, skols.len = {:?}", self.skolemization_count, snapshot.skolemization_count, skols.len() @@ -524,13 +524,13 @@ impl<'tcx> RegionConstraintCollector<'tcx> { debug_assert! { skols.iter() .all(|&k| match *k { - ty::ReSkolemized(index, _) => - index.index >= first_to_pop && - index.index < last_to_pop, + ty::ReSkolemized(universe, _) => + universe >= first_to_pop && + universe < last_to_pop, _ => false }), - "invalid skolemization keys or keys out of range ({}..{}): {:?}", + "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}", snapshot.skolemization_count, self.skolemization_count, skols @@ -865,7 +865,7 @@ impl fmt::Debug for RegionSnapshot { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "RegionSnapshot(length={},skolemization={})", + "RegionSnapshot(length={},skolemization={:?})", self.length, self.skolemization_count ) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 2a0cfe90cd294..a813bce0c124c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -67,7 +67,7 @@ pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const}; pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; pub use self::sty::RegionKind; -pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}; +pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid}; pub use self::sty::BoundRegion::*; pub use self::sty::InferTy::*; pub use self::sty::RegionKind::*; @@ -1328,7 +1328,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> { /// type name in a non-zero universe is a skolemized type -- an /// idealized representative of "types in general" that we use for /// checking generic functions. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub struct UniverseIndex(u32); impl UniverseIndex { @@ -1348,7 +1348,21 @@ impl UniverseIndex { /// region `'a`, but that region was not nameable from `U` because /// it was not in scope there. pub fn subuniverse(self) -> UniverseIndex { - UniverseIndex(self.0 + 1) + UniverseIndex(self.0.checked_add(1).unwrap()) + } + + pub fn as_u32(&self) -> u32 { + self.0 + } + + pub fn as_usize(&self) -> usize { + self.0 as usize + } +} + +impl From for UniverseIndex { + fn from(index: u32) -> Self { + UniverseIndex(index) } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 6b95c8662c3c0..109422564c84d 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1028,7 +1028,7 @@ pub enum RegionKind { /// A skolemized region - basically the higher-ranked version of ReFree. /// Should not exist after typeck. - ReSkolemized(SkolemizedRegionVid, BoundRegion), + ReSkolemized(ty::UniverseIndex, BoundRegion), /// Empty lifetime is for data that is never accessed. /// Bottom in the region lattice. We treat ReEmpty somewhat @@ -1082,11 +1082,6 @@ newtype_index!(RegionVid DEBUG_FORMAT = custom, }); -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)] -pub struct SkolemizedRegionVid { - pub index: u32, -} - #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum InferTy { TyVar(TyVid), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 7e00912a21780..06ecc09f39126 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -792,8 +792,8 @@ define_print! { write!(f, "'?{}", c.index()) } - ty::ReSkolemized(id, ref bound_region) => { - write!(f, "ReSkolemized({}, {:?})", id.index, bound_region) + ty::ReSkolemized(universe, ref bound_region) => { + write!(f, "ReSkolemized({:?}, {:?})", universe, bound_region) } ty::ReEmpty => write!(f, "ReEmpty"), From 534d5d173907fc39547cffa9799b4b03f85d2bb4 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 7 Feb 2018 11:47:57 -0700 Subject: [PATCH 10/22] store RegionVariableInfo and not just RegionVariableOrigin --- .../infer/lexical_region_resolve/mod.rs | 16 ++++----- src/librustc/infer/mod.rs | 18 +++++----- src/librustc/infer/region_constraints/mod.rs | 33 +++++++++++-------- .../borrow_check/nll/region_infer/mod.rs | 10 +++--- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 00b2ac7449f7e..5984a831e6fa0 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -15,7 +15,7 @@ use infer::RegionVariableOrigin; use infer::region_constraints::Constraint; use infer::region_constraints::GenericKind; use infer::region_constraints::RegionConstraintData; -use infer::region_constraints::VarOrigins; +use infer::region_constraints::VarInfos; use infer::region_constraints::VerifyBound; use middle::free_region::RegionRelations; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; @@ -37,7 +37,7 @@ mod graphviz; /// all the variables as well as a set of errors that must be reported. pub fn resolve<'tcx>( region_rels: &RegionRelations<'_, '_, 'tcx>, - var_origins: VarOrigins, + var_infos: VarInfos, data: RegionConstraintData<'tcx>, ) -> ( LexicalRegionResolutions<'tcx>, @@ -47,7 +47,7 @@ pub fn resolve<'tcx>( let mut errors = vec![]; let mut resolver = LexicalResolver { region_rels, - var_origins, + var_infos, data, }; let values = resolver.infer_variable_values(&mut errors); @@ -103,7 +103,7 @@ type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>; struct LexicalResolver<'cx, 'gcx: 'tcx, 'tcx: 'cx> { region_rels: &'cx RegionRelations<'cx, 'gcx, 'tcx>, - var_origins: VarOrigins, + var_infos: VarInfos, data: RegionConstraintData<'tcx>, } @@ -132,7 +132,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { } fn num_vars(&self) -> usize { - self.var_origins.len() + self.var_infos.len() } /// Initially, the value for all variables is set to `'empty`, the @@ -279,7 +279,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { (&ReVar(v_id), _) | (_, &ReVar(v_id)) => { span_bug!( - self.var_origins[v_id].span(), + self.var_infos[v_id].origin.span(), "lub_concrete_regions invoked with non-concrete \ regions: {:?}, {:?}", a, @@ -576,7 +576,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { if !self.region_rels .is_subregion_of(lower_bound.region, upper_bound.region) { - let origin = self.var_origins[node_idx].clone(); + let origin = self.var_infos[node_idx].origin.clone(); debug!( "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \ sup: {:?}", @@ -598,7 +598,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { } span_bug!( - self.var_origins[node_idx].span(), + self.var_infos[node_idx].origin.span(), "collect_error_for_expanding_node() could not find \ error for var {:?}, lower_bounds={:?}, \ upper_bounds={:?}", diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index e4710442ebb32..4a1dbc3ec8788 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -41,7 +41,7 @@ use arena::DroplessArena; use self::combine::CombineFields; use self::higher_ranked::HrMatchResult; use self::region_constraints::{RegionConstraintCollector, RegionSnapshot}; -use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarOrigins}; +use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarInfos}; use self::lexical_region_resolve::LexicalRegionResolutions; use self::outlives::env::OutlivesEnvironment; use self::type_variable::TypeVariableOrigin; @@ -888,7 +888,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// Number of region variables created so far. pub fn num_region_vars(&self) -> usize { - self.borrow_region_constraints().var_origins().len() + self.borrow_region_constraints().num_region_vars() } /// Just a convenient wrapper of `next_region_var` for using during NLL. @@ -1016,12 +1016,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { region_context, region_map, outlives_env.free_region_map()); - let (var_origins, data) = self.region_constraints.borrow_mut() + let (var_infos, data) = self.region_constraints.borrow_mut() .take() .expect("regions already resolved") - .into_origins_and_data(); + .into_infos_and_data(); let (lexical_region_resolutions, errors) = - lexical_region_resolve::resolve(region_rels, var_origins, data); + lexical_region_resolve::resolve(region_rels, var_infos, data); let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); assert!(old_value.is_none()); @@ -1069,13 +1069,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// hence that `resolve_regions_and_report_errors` can never be /// called. This is used only during NLL processing to "hand off" ownership /// of the set of region vairables into the NLL region context. - pub fn take_region_var_origins(&self) -> VarOrigins { - let (var_origins, data) = self.region_constraints.borrow_mut() + pub fn take_region_var_origins(&self) -> VarInfos { + let (var_infos, data) = self.region_constraints.borrow_mut() .take() .expect("regions already resolved") - .into_origins_and_data(); + .into_infos_and_data(); assert!(data.is_empty()); - var_origins + var_infos } pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 96c7dc5da5e00..b0959ebecfa2e 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -33,7 +33,7 @@ mod taint; pub struct RegionConstraintCollector<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. - var_origins: IndexVec, + var_infos: IndexVec, data: RegionConstraintData<'tcx>, @@ -76,7 +76,7 @@ pub struct RegionConstraintCollector<'tcx> { unification_table: ut::UnificationTable>, } -pub type VarOrigins = IndexVec; +pub type VarInfos = IndexVec; /// The full set of region constraints gathered up by the collector. /// Describes constraints between the region variables and other @@ -230,6 +230,11 @@ enum CombineMapType { type CombineMap<'tcx> = FxHashMap, RegionVid>; +#[derive(Debug, Clone, Copy)] +pub struct RegionVariableInfo { + pub origin: RegionVariableOrigin, +} + pub struct RegionSnapshot { length: usize, region_snapshot: ut::Snapshot>, @@ -273,7 +278,7 @@ impl TaintDirections { impl<'tcx> RegionConstraintCollector<'tcx> { pub fn new() -> RegionConstraintCollector<'tcx> { RegionConstraintCollector { - var_origins: VarOrigins::default(), + var_infos: VarInfos::default(), data: RegionConstraintData::default(), lubs: FxHashMap(), glbs: FxHashMap(), @@ -284,8 +289,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } } - pub fn var_origins(&self) -> &VarOrigins { - &self.var_origins + pub fn num_region_vars(&self) -> usize { + self.var_infos.len() } pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> { @@ -295,9 +300,9 @@ impl<'tcx> RegionConstraintCollector<'tcx> { /// Once all the constraints have been gathered, extract out the final data. /// /// Not legal during a snapshot. - pub fn into_origins_and_data(self) -> (VarOrigins, RegionConstraintData<'tcx>) { + pub fn into_infos_and_data(self) -> (VarInfos, RegionConstraintData<'tcx>) { assert!(!self.in_snapshot()); - (self.var_origins, self.data) + (self.var_infos, self.data) } /// Takes (and clears) the current set of constraints. Note that @@ -319,7 +324,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { // should think carefully about whether it needs to be cleared // or updated in some way. let RegionConstraintCollector { - var_origins, + var_infos, data, lubs, glbs, @@ -343,7 +348,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { // also insert `a <= b` and a `b <= a` edges, so the // `RegionConstraintData` contains the relationship here. *unification_table = ut::UnificationTable::new(); - for vid in var_origins.indices() { + for vid in var_infos.indices() { unification_table.new_key(unify_key::RegionVidKey { min_vid: vid }); } @@ -411,8 +416,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { // nothing to do here } AddVar(vid) => { - self.var_origins.pop().unwrap(); - assert_eq!(self.var_origins.len(), vid.index() as usize); + self.var_infos.pop().unwrap(); + assert_eq!(self.var_infos.len(), vid.index() as usize); } AddConstraint(ref constraint) => { self.data.constraints.remove(constraint); @@ -434,7 +439,9 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid { - let vid = self.var_origins.push(origin.clone()); + let vid = self.var_infos.push(RegionVariableInfo { + origin, + }); let u_vid = self.unification_table .new_key(unify_key::RegionVidKey { min_vid: vid }); @@ -452,7 +459,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { /// Returns the origin for the given variable. pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { - self.var_origins[vid].clone() + self.var_infos[vid].origin } /// Creates a new skolemized region. Skolemized regions are fresh diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 66776a94ff01f..d5af819a8ac7e 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -18,7 +18,7 @@ use rustc::infer::RegionObligation; use rustc::infer::RegionVariableOrigin; use rustc::infer::SubregionOrigin; use rustc::infer::error_reporting::nice_region_error::NiceRegionError; -use rustc::infer::region_constraints::{GenericKind, VarOrigins}; +use rustc::infer::region_constraints::{GenericKind, VarInfos}; use rustc::mir::{ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location, Mir}; use rustc::traits::ObligationCause; @@ -239,19 +239,19 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// of those will be constant regions representing the free /// regions defined in `universal_regions`. pub(crate) fn new( - var_origins: VarOrigins, + var_infos: VarInfos, universal_regions: UniversalRegions<'tcx>, mir: &Mir<'tcx>, ) -> Self { - let num_region_variables = var_origins.len(); + let num_region_variables = var_infos.len(); let num_universal_regions = universal_regions.len(); let elements = &Rc::new(RegionValueElements::new(mir, num_universal_regions)); // Create a RegionDefinition for each inference variable. - let definitions = var_origins + let definitions = var_infos .into_iter() - .map(|origin| RegionDefinition::new(origin)) + .map(|info| RegionDefinition::new(info.origin)) .collect(); let mut result = Self { From 59f3b20e8c0bf0b33027ffd25e94f717881f0dde Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 7 Feb 2018 12:22:47 -0700 Subject: [PATCH 11/22] give a universe to region variables --- src/librustc/infer/mod.rs | 4 ++- src/librustc/infer/region_constraints/mod.rs | 36 +++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 4a1dbc3ec8788..bd1f382dceb18 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -883,7 +883,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// during diagnostics / error-reporting. pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx> { - self.tcx.mk_region(ty::ReVar(self.borrow_region_constraints().new_region_var(origin))) + let region_var = self.borrow_region_constraints() + .new_region_var(self.universe, origin); + self.tcx.mk_region(ty::ReVar(region_var)) } /// Number of region variables created so far. diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index b0959ebecfa2e..a382c1371d447 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -25,9 +25,7 @@ use ty::ReStatic; use ty::{BrFresh, ReLateBound, ReSkolemized, ReVar}; use std::collections::BTreeMap; -use std::fmt; -use std::mem; -use std::u32; +use std::{cmp, fmt, mem, u32}; mod taint; @@ -233,6 +231,7 @@ type CombineMap<'tcx> = FxHashMap, RegionVid>; #[derive(Debug, Clone, Copy)] pub struct RegionVariableInfo { pub origin: RegionVariableOrigin, + pub universe: ty::UniverseIndex, } pub struct RegionSnapshot { @@ -438,9 +437,12 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } } - pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid { + pub fn new_region_var(&mut self, + universe: ty::UniverseIndex, + origin: RegionVariableOrigin) -> RegionVid { let vid = self.var_infos.push(RegionVariableInfo { origin, + universe, }); let u_vid = self.unification_table @@ -457,6 +459,11 @@ impl<'tcx> RegionConstraintCollector<'tcx> { return vid; } + /// Returns the universe for the given variable. + pub fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex { + self.var_infos[vid].universe + } + /// Returns the origin for the given variable. pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { self.var_infos[vid].origin @@ -810,7 +817,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> { if let Some(&c) = self.combine_map(t).get(&vars) { return tcx.mk_region(ReVar(c)); } - let c = self.new_region_var(MiscVariable(origin.span())); + let a_universe = self.universe(a); + let b_universe = self.universe(b); + let c_universe = cmp::max(a_universe, b_universe); + let c = self.new_region_var(c_universe, MiscVariable(origin.span())); self.combine_map(t).insert(vars, c); if self.in_snapshot() { self.undo_log.push(AddCombination(t, vars)); @@ -826,6 +836,22 @@ impl<'tcx> RegionConstraintCollector<'tcx> { new_r } + fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex { + match *region { + ty::ReScope(..) | + ty::ReStatic | + ty::ReEmpty | + ty::ReErased | + ty::ReFree(..) | + ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT, + ty::ReSkolemized(universe, _) => universe, + ty::ReClosureBound(vid) | + ty::ReVar(vid) => self.var_universe(vid), + ty::ReLateBound(..) => + bug!("universe(): encountered bound region {:?}", region), + } + } + pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec { self.undo_log[mark.length..] .iter() From ad9e9d9670f27c15441ff490f2029b23ac49c039 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 7 Feb 2018 13:43:47 -0700 Subject: [PATCH 12/22] make solving "universe aware", in a simplistic way This simple change says that if you have a constraint like ``` exists<'a> { for<'b> { 'a: 'b } } ``` you can solve it by making 'a static. This is "good enough" for now, though not super smart, since for example ``` exists<'a> { for<'b> { if ('a: 'b) { 'a: 'b } } } ``` will still force 'a to be 'static, though it should not. (We don't intend to fix that in this PR series; current rustc kind of sidesteps the need to consider such concerns at the moment.) --- .../infer/lexical_region_resolve/mod.rs | 38 ++++++++++++++++--- src/librustc/infer/region_constraints/mod.rs | 38 +++++++++---------- src/librustc/ty/mod.rs | 6 +++ 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 5984a831e6fa0..d2389f97adba1 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -12,11 +12,8 @@ use infer::SubregionOrigin; use infer::RegionVariableOrigin; -use infer::region_constraints::Constraint; -use infer::region_constraints::GenericKind; -use infer::region_constraints::RegionConstraintData; -use infer::region_constraints::VarInfos; -use infer::region_constraints::VerifyBound; +use infer::region_constraints::{Constraint, GenericKind, RegionConstraintData, + VarInfos, VerifyBound, region_universe}; use middle::free_region::RegionRelations; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::fx::FxHashSet; @@ -232,11 +229,40 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { match *b_data { VarValue::Value(cur_region) => { - let lub = self.lub_concrete_regions(a_region, cur_region); + let b_universe = self.var_infos[b_vid].universe; + let mut lub = self.lub_concrete_regions(a_region, cur_region); if lub == cur_region { return false; } + // Find the universe of the new value (`lub`) and + // check whether this value is something that we can + // legally name in this variable. If not, promote the + // variable to `'static`, which is surely greater than + // or equal to `lub`. This is obviously a kind of sub-optimal + // choice -- in the future, when we incorporate a knowledge + // of the parameter environment, we might be able to find a + // tighter bound than `'static`. + // + // To make this more concrete, imagine a bound like: + // + // for<'a> '0: 'a + // + // Here we have that `'0` must outlive `'a` -- no + // matter what `'a` is. When solving such a + // constraint, we would initially assign `'0` to be + // `'empty`. We would then compute the LUB of `'empty` + // and `'a` (which is something like `ReSkolemized(1)`), + // resulting in `'a`. + // + // At this point, `lub_universe` would be `1` and + // `b_universe` would be `0`, and hence we would wind + // up promoting `lub` to `'static`. + let lub_universe = region_universe(&self.var_infos, lub); + if !lub_universe.is_visible_in(b_universe) { + lub = self.region_rels.tcx.types.re_static; + } + debug!( "Expanding value of {:?} from {:?} to {:?}", b_vid, diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index a382c1371d447..c0852a1d3995d 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -30,7 +30,7 @@ use std::{cmp, fmt, mem, u32}; mod taint; pub struct RegionConstraintCollector<'tcx> { - /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. + /// For each `RegionVid`, the corresponding `RegionVariableInfo`. var_infos: IndexVec, data: RegionConstraintData<'tcx>, @@ -817,8 +817,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { if let Some(&c) = self.combine_map(t).get(&vars) { return tcx.mk_region(ReVar(c)); } - let a_universe = self.universe(a); - let b_universe = self.universe(b); + let a_universe = region_universe(&self.var_infos, a); + let b_universe = region_universe(&self.var_infos, b); let c_universe = cmp::max(a_universe, b_universe); let c = self.new_region_var(c_universe, MiscVariable(origin.span())); self.combine_map(t).insert(vars, c); @@ -836,22 +836,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { new_r } - fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex { - match *region { - ty::ReScope(..) | - ty::ReStatic | - ty::ReEmpty | - ty::ReErased | - ty::ReFree(..) | - ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT, - ty::ReSkolemized(universe, _) => universe, - ty::ReClosureBound(vid) | - ty::ReVar(vid) => self.var_universe(vid), - ty::ReLateBound(..) => - bug!("universe(): encountered bound region {:?}", region), - } - } - pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec { self.undo_log[mark.length..] .iter() @@ -894,6 +878,22 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } } +pub fn region_universe(var_infos: &VarInfos, region: Region<'_>) -> ty::UniverseIndex { + match *region { + ty::ReScope(..) | + ty::ReStatic | + ty::ReEmpty | + ty::ReErased | + ty::ReFree(..) | + ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT, + ty::ReSkolemized(universe, _) => universe, + ty::ReClosureBound(vid) | + ty::ReVar(vid) => var_infos[vid].universe, + ty::ReLateBound(..) => + bug!("region_universe(): encountered bound region {:?}", region), + } +} + impl fmt::Debug for RegionSnapshot { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a813bce0c124c..896c7a94d951b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1358,6 +1358,12 @@ impl UniverseIndex { pub fn as_usize(&self) -> usize { self.0 as usize } + + /// Indicates whether a name in this universe is visible in the + /// universe `other`. + pub fn is_visible_in(self, other: UniverseIndex) -> bool { + self <= other + } } impl From for UniverseIndex { From 24478c46bccfea1bc6be0bcf82279d0960b14a54 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Wed, 7 Feb 2018 14:15:32 -0700 Subject: [PATCH 13/22] kill higher_ranked_lub and higher_ranked_glb These are only used to provide a better hint for code that was phased out long ago. We can just remove it. It's been long enough. --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/infer/glb.rs | 19 +- src/librustc/infer/higher_ranked/mod.rs | 256 ---------------------- src/librustc/infer/lub.rs | 19 +- src/librustc/ty/error.rs | 21 +- src/librustc/ty/structural_impls.rs | 4 +- src/test/ui/lub-glb/old-lub-glb-hr.rs | 36 --- src/test/ui/lub-glb/old-lub-glb-object.rs | 38 ---- 8 files changed, 11 insertions(+), 384 deletions(-) delete mode 100644 src/test/ui/lub-glb/old-lub-glb-hr.rs delete mode 100644 src/test/ui/lub-glb/old-lub-glb-object.rs diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 96c2309882108..01a9cd32aa580 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -933,7 +933,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } self.check_and_note_conflicting_crates(diag, terr, span); - self.tcx.note_and_explain_type_err(diag, terr, span); + self.tcx.note_and_explain_type_err(diag, terr); // It reads better to have the error origin as the final // thing. diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index fd14e0e40e234..83808085fa412 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -15,7 +15,6 @@ use super::Subtype; use traits::ObligationCause; use ty::{self, Ty, TyCtxt}; -use ty::error::TypeError; use ty::relate::{Relate, RelateResult, TypeRelation}; /// "Greatest lower bound" (common subtype) @@ -76,16 +75,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> where T: Relate<'tcx> { debug!("binders(a={:?}, b={:?})", a, b); - let was_error = self.infcx().probe(|_snapshot| { - // Subtle: use a fresh combine-fields here because we recover - // from Err. Doing otherwise could propagate obligations out - // through our `self.obligations` field. - self.infcx() - .combine_fields(self.fields.trace.clone(), self.fields.param_env) - .higher_ranked_glb(a, b, self.a_is_expected) - .is_err() - }); - debug!("binders: was_error={:?}", was_error); // When higher-ranked types are involved, computing the LUB is // very challenging, switch to invariance. This is obviously @@ -93,12 +82,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> match self.relate_with_variance(ty::Variance::Invariant, a, b) { Ok(_) => Ok(a.clone()), Err(err) => { - debug!("binders: error occurred, was_error={:?}", was_error); - if !was_error { - Err(TypeError::OldStyleLUB(Box::new(err))) - } else { - Err(err) - } + debug!("binders: error occurred"); + Err(err) } } } diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index a317e0699b4bb..b6264822c0ff2 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -19,7 +19,6 @@ use super::{CombinedSnapshot, use super::combine::CombineFields; use super::region_constraints::{TaintDirections}; -use std::collections::BTreeMap; use ty::{self, TyCtxt, Binder, TypeFoldable}; use ty::error::TypeError; use ty::relate::{Relate, RelateResult, TypeRelation}; @@ -200,261 +199,6 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { Ok(HrMatchResult { value: a_value }) }); } - - pub fn higher_ranked_lub(&mut self, a: &Binder, b: &Binder, a_is_expected: bool) - -> RelateResult<'tcx, Binder> - where T: Relate<'tcx> - { - // Start a snapshot so we can examine "all bindings that were - // created as part of this type comparison". - return self.infcx.commit_if_ok(|snapshot| { - // Instantiate each bound region with a fresh region variable. - let span = self.trace.cause.span; - let (a_with_fresh, a_map) = - self.infcx.replace_late_bound_regions_with_fresh_var( - span, HigherRankedType, a); - let (b_with_fresh, _) = - self.infcx.replace_late_bound_regions_with_fresh_var( - span, HigherRankedType, b); - - // Collect constraints. - let result0 = - self.lub(a_is_expected).relate(&a_with_fresh, &b_with_fresh)?; - let result0 = - self.infcx.resolve_type_vars_if_possible(&result0); - debug!("lub result0 = {:?}", result0); - - // Generalize the regions appearing in result0 if possible - let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot); - let span = self.trace.cause.span; - let result1 = - fold_regions_in( - self.tcx(), - &result0, - |r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn, - &new_vars, &a_map, r)); - - debug!("lub({:?},{:?}) = {:?}", - a, - b, - result1); - - Ok(ty::Binder(result1)) - }); - - fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, - span: Span, - snapshot: &CombinedSnapshot<'a, 'tcx>, - debruijn: ty::DebruijnIndex, - new_vars: &[ty::RegionVid], - a_map: &BTreeMap>, - r0: ty::Region<'tcx>) - -> ty::Region<'tcx> { - // Regions that pre-dated the LUB computation stay as they are. - if !is_var_in_set(new_vars, r0) { - assert!(!r0.is_late_bound()); - debug!("generalize_region(r0={:?}): not new variable", r0); - return r0; - } - - let tainted = infcx.tainted_regions(snapshot, r0, TaintDirections::both()); - - // Variables created during LUB computation which are - // *related* to regions that pre-date the LUB computation - // stay as they are. - if !tainted.iter().all(|&r| is_var_in_set(new_vars, r)) { - debug!("generalize_region(r0={:?}): \ - non-new-variables found in {:?}", - r0, tainted); - assert!(!r0.is_late_bound()); - return r0; - } - - // Otherwise, the variable must be associated with at - // least one of the variables representing bound regions - // in both A and B. Replace the variable with the "first" - // bound region from A that we find it to be associated - // with. - for (a_br, a_r) in a_map { - if tainted.iter().any(|x| x == a_r) { - debug!("generalize_region(r0={:?}): \ - replacing with {:?}, tainted={:?}", - r0, *a_br, tainted); - return infcx.tcx.mk_region(ty::ReLateBound(debruijn, *a_br)); - } - } - - span_bug!( - span, - "region {:?} is not associated with any bound region from A!", - r0) - } - } - - pub fn higher_ranked_glb(&mut self, a: &Binder, b: &Binder, a_is_expected: bool) - -> RelateResult<'tcx, Binder> - where T: Relate<'tcx> - { - debug!("higher_ranked_glb({:?}, {:?})", - a, b); - - // Make a snapshot so we can examine "all bindings that were - // created as part of this type comparison". - return self.infcx.commit_if_ok(|snapshot| { - // Instantiate each bound region with a fresh region variable. - let (a_with_fresh, a_map) = - self.infcx.replace_late_bound_regions_with_fresh_var( - self.trace.cause.span, HigherRankedType, a); - let (b_with_fresh, b_map) = - self.infcx.replace_late_bound_regions_with_fresh_var( - self.trace.cause.span, HigherRankedType, b); - let a_vars = var_ids(self, &a_map); - let b_vars = var_ids(self, &b_map); - - // Collect constraints. - let result0 = - self.glb(a_is_expected).relate(&a_with_fresh, &b_with_fresh)?; - let result0 = - self.infcx.resolve_type_vars_if_possible(&result0); - debug!("glb result0 = {:?}", result0); - - // Generalize the regions appearing in result0 if possible - let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot); - let span = self.trace.cause.span; - let result1 = - fold_regions_in( - self.tcx(), - &result0, - |r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn, - &new_vars, - &a_map, &a_vars, &b_vars, - r)); - - debug!("glb({:?},{:?}) = {:?}", - a, - b, - result1); - - Ok(ty::Binder(result1)) - }); - - fn generalize_region<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, - span: Span, - snapshot: &CombinedSnapshot<'a, 'tcx>, - debruijn: ty::DebruijnIndex, - new_vars: &[ty::RegionVid], - a_map: &BTreeMap>, - a_vars: &[ty::RegionVid], - b_vars: &[ty::RegionVid], - r0: ty::Region<'tcx>) - -> ty::Region<'tcx> { - if !is_var_in_set(new_vars, r0) { - assert!(!r0.is_late_bound()); - return r0; - } - - let tainted = infcx.tainted_regions(snapshot, r0, TaintDirections::both()); - - let mut a_r = None; - let mut b_r = None; - let mut only_new_vars = true; - for r in &tainted { - if is_var_in_set(a_vars, *r) { - if a_r.is_some() { - return fresh_bound_variable(infcx, debruijn); - } else { - a_r = Some(*r); - } - } else if is_var_in_set(b_vars, *r) { - if b_r.is_some() { - return fresh_bound_variable(infcx, debruijn); - } else { - b_r = Some(*r); - } - } else if !is_var_in_set(new_vars, *r) { - only_new_vars = false; - } - } - - // NB---I do not believe this algorithm computes - // (necessarily) the GLB. As written it can - // spuriously fail. In particular, if there is a case - // like: |fn(&a)| and fn(fn(&b)), where a and b are - // free, it will return fn(&c) where c = GLB(a,b). If - // however this GLB is not defined, then the result is - // an error, even though something like - // "fn(fn(&X))" where X is bound would be a - // subtype of both of those. - // - // The problem is that if we were to return a bound - // variable, we'd be computing a lower-bound, but not - // necessarily the *greatest* lower-bound. - // - // Unfortunately, this problem is non-trivial to solve, - // because we do not know at the time of computing the GLB - // whether a GLB(a,b) exists or not, because we haven't - // run region inference (or indeed, even fully computed - // the region hierarchy!). The current algorithm seems to - // works ok in practice. - - if a_r.is_some() && b_r.is_some() && only_new_vars { - // Related to exactly one bound variable from each fn: - return rev_lookup(infcx, span, a_map, a_r.unwrap()); - } else if a_r.is_none() && b_r.is_none() { - // Not related to bound variables from either fn: - assert!(!r0.is_late_bound()); - return r0; - } else { - // Other: - return fresh_bound_variable(infcx, debruijn); - } - } - - fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, - span: Span, - a_map: &BTreeMap>, - r: ty::Region<'tcx>) -> ty::Region<'tcx> - { - for (a_br, a_r) in a_map { - if *a_r == r { - return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), *a_br)); - } - } - span_bug!( - span, - "could not find original bound region for {:?}", - r); - } - - fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, - debruijn: ty::DebruijnIndex) - -> ty::Region<'tcx> { - infcx.borrow_region_constraints().new_bound(infcx.tcx, debruijn) - } - } -} - -fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>, - map: &BTreeMap>) - -> Vec { - map.iter() - .map(|(_, &r)| match *r { - ty::ReVar(r) => { r } - _ => { - span_bug!( - fields.trace.cause.span, - "found non-region-vid: {:?}", - r); - } - }) - .collect() -} - -fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool { - match *r { - ty::ReVar(ref v) => new_vars.iter().any(|x| x == v), - _ => false - } } fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index 55c7eef607bbe..4e963d53ab4d7 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -15,7 +15,6 @@ use super::Subtype; use traits::ObligationCause; use ty::{self, Ty, TyCtxt}; -use ty::error::TypeError; use ty::relate::{Relate, RelateResult, TypeRelation}; /// "Least upper bound" (common supertype) @@ -76,16 +75,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> where T: Relate<'tcx> { debug!("binders(a={:?}, b={:?})", a, b); - let was_error = self.infcx().probe(|_snapshot| { - // Subtle: use a fresh combine-fields here because we recover - // from Err. Doing otherwise could propagate obligations out - // through our `self.obligations` field. - self.infcx() - .combine_fields(self.fields.trace.clone(), self.fields.param_env) - .higher_ranked_lub(a, b, self.a_is_expected) - .is_err() - }); - debug!("binders: was_error={:?}", was_error); // When higher-ranked types are involved, computing the LUB is // very challenging, switch to invariance. This is obviously @@ -93,12 +82,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> match self.relate_with_variance(ty::Variance::Invariant, a, b) { Ok(_) => Ok(a.clone()), Err(err) => { - debug!("binders: error occurred, was_error={:?}", was_error); - if !was_error { - Err(TypeError::OldStyleLUB(Box::new(err))) - } else { - Err(err) - } + debug!("binders: error occurred"); + Err(err) } } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 8a0253ed2f115..e8e55ee8ffe60 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -14,7 +14,6 @@ use std::fmt; use syntax::abi; use syntax::ast; use errors::DiagnosticBuilder; -use syntax_pos::Span; use hir; @@ -52,8 +51,6 @@ pub enum TypeError<'tcx> { ProjectionMismatched(ExpectedFound), ProjectionBoundsLength(ExpectedFound), ExistentialMismatch(ExpectedFound<&'tcx ty::Slice>>), - - OldStyleLUB(Box>), } #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] @@ -165,9 +162,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { report_maybe_different(f, format!("trait `{}`", values.expected), format!("trait `{}`", values.found)) } - OldStyleLUB(ref err) => { - write!(f, "{}", err) - } } } } @@ -239,10 +233,11 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - pub fn note_and_explain_type_err(self, - db: &mut DiagnosticBuilder, - err: &TypeError<'tcx>, - sp: Span) { + pub fn note_and_explain_type_err( + self, + db: &mut DiagnosticBuilder, + err: &TypeError<'tcx>, + ) { use self::TypeError::*; match err.clone() { @@ -254,12 +249,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { db.help("consider boxing your closure and/or using it as a trait object"); } }, - OldStyleLUB(err) => { - db.note("this was previously accepted by the compiler but has been phased out"); - db.note("for more information, see https://github.com/rust-lang/rust/issues/45852"); - - self.note_and_explain_type_err(db, &err, sp); - } CyclicTy(ty) => { // Watch out for various cases of cyclic types and try to explain. if ty.is_closure() || ty.is_generator() { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 0bfb9cc8acd99..53a3f8f380d1d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -452,8 +452,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { ProjectionBoundsLength(x) => ProjectionBoundsLength(x), Sorts(ref x) => return tcx.lift(x).map(Sorts), - OldStyleLUB(ref x) => return tcx.lift(x).map(OldStyleLUB), - ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch) + ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch), }) } } @@ -1128,7 +1127,6 @@ EnumTypeFoldableImpl! { (ty::error::TypeError::ProjectionBoundsLength)(x), (ty::error::TypeError::Sorts)(x), (ty::error::TypeError::ExistentialMismatch)(x), - (ty::error::TypeError::OldStyleLUB)(x), } } diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.rs b/src/test/ui/lub-glb/old-lub-glb-hr.rs deleted file mode 100644 index 7526b2f946c12..0000000000000 --- a/src/test/ui/lub-glb/old-lub-glb-hr.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we give a note when the old LUB/GLB algorithm would have -// succeeded but the new code (which is stricter) gives an error. - -fn foo( - x: fn(&u8, &u8), - y: for<'a> fn(&'a u8, &'a u8), -) { - let z = match 22 { //~ ERROR incompatible types - 0 => x, - _ => y, - }; -} - -fn bar( - x: fn(&u8, &u8), - y: for<'a> fn(&'a u8, &'a u8), -) { - let z = match 22 { - // No error with an explicit cast: - 0 => x as for<'a> fn(&'a u8, &'a u8), - _ => y, - }; -} - -fn main() { -} diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs deleted file mode 100644 index 63dcfa3fc1e91..0000000000000 --- a/src/test/ui/lub-glb/old-lub-glb-object.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we give a note when the old LUB/GLB algorithm would have -// succeeded but the new code (which is stricter) gives an error. - -trait Foo { } - -fn foo( - x: &for<'a, 'b> Foo<&'a u8, &'b u8>, - y: &for<'a> Foo<&'a u8, &'a u8>, -) { - let z = match 22 { //~ ERROR incompatible types - 0 => x, - _ => y, - }; -} - -fn bar( - x: &for<'a, 'b> Foo<&'a u8, &'b u8>, - y: &for<'a> Foo<&'a u8, &'a u8>, -) { - // Accepted with explicit case: - let z = match 22 { - 0 => x as &for<'a> Foo<&'a u8, &'a u8>, - _ => y, - }; -} - -fn main() { -} From 367be87db300ddfe0242b1b0fba8d4cf87a26dfd Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 23 Aug 2017 09:19:18 -0400 Subject: [PATCH 14/22] remove `hr_match` -- no longer needed --- src/librustc/infer/higher_ranked/mod.rs | 144 +----------------------- src/librustc/infer/mod.rs | 36 +----- src/librustc/traits/project.rs | 24 ++-- 3 files changed, 18 insertions(+), 186 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index b6264822c0ff2..12dd3d030c04f 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -14,21 +14,16 @@ use super::{CombinedSnapshot, InferCtxt, HigherRankedType, - SubregionOrigin, SkolemizationMap}; use super::combine::CombineFields; use super::region_constraints::{TaintDirections}; -use ty::{self, TyCtxt, Binder, TypeFoldable}; +use ty::{self, Binder, TypeFoldable}; use ty::error::TypeError; use ty::relate::{Relate, RelateResult, TypeRelation}; use syntax_pos::Span; use util::nodemap::{FxHashMap, FxHashSet}; -pub struct HrMatchResult { - pub value: U, -} - impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { pub fn higher_ranked_sub(&mut self, a: &Binder, b: &Binder, a_is_expected: bool) -> RelateResult<'tcx, Binder> @@ -82,143 +77,6 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { Ok(ty::Binder(result)) }); } - - /// The value consists of a pair `(t, u)` where `t` is the - /// *matcher* and `u` is a *value*. The idea is to find a - /// substitution `S` such that `S(t) == b`, and then return - /// `S(u)`. In other words, find values for the late-bound regions - /// in `a` that can make `t == b` and then replace the LBR in `u` - /// with those values. - /// - /// This routine is (as of this writing) used in trait matching, - /// particularly projection. - /// - /// NB. It should not happen that there are LBR appearing in `U` - /// that do not appear in `T`. If that happens, those regions are - /// unconstrained, and this routine replaces them with `'static`. - pub fn higher_ranked_match(&mut self, - a_pair: &Binder<(T, U)>, - b_match: &T, - a_is_expected: bool) - -> RelateResult<'tcx, HrMatchResult> - where T: Relate<'tcx>, - U: TypeFoldable<'tcx> - { - debug!("higher_ranked_match(a={:?}, b={:?})", - a_pair, b_match); - - // Start a snapshot so we can examine "all bindings that were - // created as part of this type comparison". - return self.infcx.commit_if_ok(|snapshot| { - // First, we instantiate each bound region in the matcher - // with a skolemized region. - let ((a_match, a_value), skol_map) = - self.infcx.skolemize_late_bound_regions(a_pair, snapshot); - - debug!("higher_ranked_match: a_match={:?}", a_match); - debug!("higher_ranked_match: skol_map={:?}", skol_map); - - // Equate types now that bound regions have been replaced. - self.equate(a_is_expected).relate(&a_match, &b_match)?; - - // Map each skolemized region to a vector of other regions that it - // must be equated with. (Note that this vector may include other - // skolemized regions from `skol_map`.) - let skol_resolution_map: FxHashMap<_, _> = - skol_map - .iter() - .map(|(&br, &skol)| { - let tainted_regions = - self.infcx.tainted_regions(snapshot, - skol, - TaintDirections::incoming()); // [1] - - // [1] this routine executes after the skolemized - // regions have been *equated* with something - // else, so examining the incoming edges ought to - // be enough to collect all constraints - - (skol, (br, tainted_regions)) - }) - .collect(); - - // For each skolemized region, pick a representative -- which can - // be any region from the sets above, except for other members of - // `skol_map`. There should always be a representative if things - // are properly well-formed. - let skol_representatives: FxHashMap<_, _> = - skol_resolution_map - .iter() - .map(|(&skol, &(_, ref regions))| { - let representative = - regions.iter() - .filter(|&&r| !skol_resolution_map.contains_key(r)) - .cloned() - .next() - .unwrap_or_else(|| { - bug!("no representative region for `{:?}` in `{:?}`", - skol, regions) - }); - - (skol, representative) - }) - .collect(); - - // Equate all the members of each skolemization set with the - // representative. - for (skol, &(_br, ref regions)) in &skol_resolution_map { - let representative = &skol_representatives[skol]; - debug!("higher_ranked_match: \ - skol={:?} representative={:?} regions={:?}", - skol, representative, regions); - for region in regions.iter() - .filter(|&r| !skol_resolution_map.contains_key(r)) - .filter(|&r| r != representative) - { - let origin = SubregionOrigin::Subtype(self.trace.clone()); - self.infcx.borrow_region_constraints() - .make_eqregion(origin, - *representative, - *region); - } - } - - // Replace the skolemized regions appearing in value with - // their representatives - let a_value = - fold_regions_in( - self.tcx(), - &a_value, - |r, _| skol_representatives.get(&r).cloned().unwrap_or(r)); - - debug!("higher_ranked_match: value={:?}", a_value); - - // We are now done with these skolemized variables. - self.infcx.pop_skolemized(skol_map, snapshot); - - Ok(HrMatchResult { value: a_value }) - }); - } -} - -fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - unbound_value: &T, - mut fldr: F) - -> T - where T: TypeFoldable<'tcx>, - F: FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, -{ - tcx.fold_regions(unbound_value, &mut false, |region, current_depth| { - // we should only be encountering "escaping" late-bound regions here, - // because the ones at the current level should have been replaced - // with fresh variables - assert!(match *region { - ty::ReLateBound(..) => false, - _ => true - }); - - fldr(region, ty::DebruijnIndex::new(current_depth)) - }) } impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index bd1f382dceb18..ca76ce311f574 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -39,7 +39,6 @@ use util::nodemap::FxHashMap; use arena::DroplessArena; use self::combine::CombineFields; -use self::higher_ranked::HrMatchResult; use self::region_constraints::{RegionConstraintCollector, RegionSnapshot}; use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarInfos}; use self::lexical_region_resolve::LexicalRegionResolutions; @@ -1238,40 +1237,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { |br| self.next_region_var(LateBoundRegion(span, br, lbrct))) } - /// Given a higher-ranked projection predicate like: - /// - /// for<'a> >::Output = &'a u32 - /// - /// and a target trait-ref like: - /// - /// > - /// - /// find a substitution `S` for the higher-ranked regions (here, - /// `['a => 'x]`) such that the predicate matches the trait-ref, - /// and then return the value (here, `&'a u32`) but with the - /// substitution applied (hence, `&'x u32`). - /// - /// See `higher_ranked_match` in `higher_ranked/mod.rs` for more - /// details. - pub fn match_poly_projection_predicate(&self, - cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - match_a: ty::PolyProjectionPredicate<'tcx>, - match_b: ty::TraitRef<'tcx>) - -> InferResult<'tcx, HrMatchResult>> - { - let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty)); - let trace = TypeTrace { - cause, - values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b)) - }; - - let mut combine = self.combine_fields(trace, param_env); - let result = combine.higher_ranked_match(&match_pair, &match_b, true)?; - Ok(InferOk { value: result, obligations: combine.obligations }) - } - - /// See `verify_generic_bound` method in `region_constraints` + /// See `verify_generic_bound` method in `region_inference` pub fn verify_generic_bound(&self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 2a62d0b5ee39a..369da2f721445 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -26,7 +26,7 @@ use super::VtableImplData; use super::util; use hir::def_id::DefId; -use infer::{InferCtxt, InferOk}; +use infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use infer::type_variable::TypeVariableOrigin; use middle::const_val::ConstVal; use mir::interpret::{GlobalId}; @@ -1422,17 +1422,25 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>( fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>( selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - poly_projection: ty::PolyProjectionPredicate<'tcx>) + poly_cache_entry: ty::PolyProjectionPredicate<'tcx>) -> Progress<'tcx> { let infcx = selcx.infcx(); - let cause = obligation.cause.clone(); + let cause = &obligation.cause; let param_env = obligation.param_env; - let trait_ref = obligation.predicate.trait_ref(infcx.tcx); - match infcx.match_poly_projection_predicate(cause, param_env, poly_projection, trait_ref) { - Ok(InferOk { value: ty_match, obligations }) => { + + let (cache_entry, _skol_map) = + infcx.replace_late_bound_regions_with_fresh_var( + cause.span, + LateBoundRegionConversionTime::HigherRankedType, + &poly_cache_entry); + + let cache_trait_ref = cache_entry.projection_ty.trait_ref(infcx.tcx); + let obligation_trait_ref = obligation.predicate.trait_ref(infcx.tcx); + match infcx.at(cause, param_env).eq(cache_trait_ref, obligation_trait_ref) { + Ok(InferOk { value: _, obligations }) => { Progress { - ty: ty_match.value, + ty: cache_entry.ty, obligations, } } @@ -1442,7 +1450,7 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>( "Failed to unify obligation `{:?}` \ with poly_projection `{:?}`: {:?}", obligation, - poly_projection, + poly_cache_entry, e); } } From 5aca3b9c260fb877c8cbf7f9f1252bae08f5c433 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 20 Aug 2017 23:06:36 -0700 Subject: [PATCH 15/22] move param-env from CombineFields into the individual operations --- src/librustc/infer/at.rs | 16 +++++------ src/librustc/infer/combine.rs | 38 ++++++++++++++++--------- src/librustc/infer/equate.rs | 23 +++++++++++---- src/librustc/infer/glb.rs | 15 ++++++---- src/librustc/infer/higher_ranked/mod.rs | 8 ++++-- src/librustc/infer/lub.rs | 15 ++++++---- src/librustc/infer/mod.rs | 3 +- src/librustc/infer/sub.rs | 28 ++++++++++++------ 8 files changed, 94 insertions(+), 52 deletions(-) diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs index 89dbc76c8a65c..f27e6e615f120 100644 --- a/src/librustc/infer/at.rs +++ b/src/librustc/infer/at.rs @@ -209,8 +209,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> { debug!("sub({:?} <: {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.sub(a_is_expected) + let mut fields = at.infcx.combine_fields(trace); + fields.sub(at.param_env, a_is_expected) .relate(a, b) .map(move |_| InferOk { value: (), obligations: fields.obligations }) }) @@ -227,8 +227,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> { debug!("eq({:?} == {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.equate(a_is_expected) + let mut fields = at.infcx.combine_fields(trace); + fields.equate(at.param_env, a_is_expected) .relate(a, b) .map(move |_| InferOk { value: (), obligations: fields.obligations }) }) @@ -243,8 +243,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> { debug!("lub({:?} \\/ {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.lub(a_is_expected) + let mut fields = at.infcx.combine_fields(trace); + fields.lub(at.param_env, a_is_expected) .relate(a, b) .map(move |t| InferOk { value: t, obligations: fields.obligations }) }) @@ -259,8 +259,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> { debug!("glb({:?} /\\ {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { - let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.glb(a_is_expected) + let mut fields = at.infcx.combine_fields(trace); + fields.glb(at.param_env, a_is_expected) .relate(a, b) .map(move |t| InferOk { value: t, obligations: fields.obligations }) }) diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 1c581c44464e7..ddaa66770ee4a 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -55,7 +55,6 @@ pub struct CombineFields<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { pub infcx: &'infcx InferCtxt<'infcx, 'gcx, 'tcx>, pub trace: TypeTrace<'tcx>, pub cause: Option, - pub param_env: ty::ParamEnv<'tcx>, pub obligations: PredicateObligations<'tcx>, } @@ -159,20 +158,32 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { self.infcx.tcx } - pub fn equate<'a>(&'a mut self, a_is_expected: bool) -> Equate<'a, 'infcx, 'gcx, 'tcx> { - Equate::new(self, a_is_expected) + pub fn equate<'a>(&'a mut self, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) + -> Equate<'a, 'infcx, 'gcx, 'tcx> { + Equate::new(self, param_env, a_is_expected) } - pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'gcx, 'tcx> { - Sub::new(self, a_is_expected) + pub fn sub<'a>(&'a mut self, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) + -> Sub<'a, 'infcx, 'gcx, 'tcx> { + Sub::new(self, param_env, a_is_expected) } - pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'gcx, 'tcx> { - Lub::new(self, a_is_expected) + pub fn lub<'a>(&'a mut self, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) + -> Lub<'a, 'infcx, 'gcx, 'tcx> { + Lub::new(self, param_env, a_is_expected) } - pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'gcx, 'tcx> { - Glb::new(self, a_is_expected) + pub fn glb<'a>(&'a mut self, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) + -> Glb<'a, 'infcx, 'gcx, 'tcx> { + Glb::new(self, param_env, a_is_expected) } /// Here dir is either EqTo, SubtypeOf, or SupertypeOf. The @@ -185,6 +196,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { /// of `a_ty`. Generalization introduces other inference /// variables wherever subtyping could occur. pub fn instantiate(&mut self, + param_env: ty::ParamEnv<'tcx>, a_ty: Ty<'tcx>, dir: RelationDir, b_vid: ty::TyVid, @@ -216,7 +228,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { if needs_wf { self.obligations.push(Obligation::new(self.trace.cause.clone(), - self.param_env, + param_env, ty::Predicate::WellFormed(b_ty))); } @@ -227,9 +239,9 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { // to associate causes/spans with each of the relations in // the stack to get this right. match dir { - EqTo => self.equate(a_is_expected).relate(&a_ty, &b_ty), - SubtypeOf => self.sub(a_is_expected).relate(&a_ty, &b_ty), - SupertypeOf => self.sub(a_is_expected).relate_with_variance( + EqTo => self.equate(param_env, a_is_expected).relate(&a_ty, &b_ty), + SubtypeOf => self.sub(param_env, a_is_expected).relate(&a_ty, &b_ty), + SupertypeOf => self.sub(param_env, a_is_expected).relate_with_variance( ty::Contravariant, &a_ty, &b_ty), }?; diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 2ae8f8ae93357..4574005e1a423 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -22,13 +22,16 @@ use ty::relate::{self, Relate, RelateResult, TypeRelation}; pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool, + param_env: ty::ParamEnv<'tcx>, } impl<'combine, 'infcx, 'gcx, 'tcx> Equate<'combine, 'infcx, 'gcx, 'tcx> { - pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) + pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) -> Equate<'combine, 'infcx, 'gcx, 'tcx> { - Equate { fields: fields, a_is_expected: a_is_expected } + Equate { fields, a_is_expected, param_env } } } @@ -81,12 +84,20 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> } (&ty::TyInfer(TyVar(a_id)), _) => { - self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?; + self.fields.instantiate(self.param_env, + b, + RelationDir::EqTo, + a_id, + self.a_is_expected)?; Ok(a) } (_, &ty::TyInfer(TyVar(b_id))) => { - self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?; + self.fields.instantiate(self.param_env, + a, + RelationDir::EqTo, + b_id, + self.a_is_expected)?; Ok(a) } @@ -113,7 +124,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> -> RelateResult<'tcx, ty::Binder> where T: Relate<'tcx> { - self.fields.higher_ranked_sub(a, b, self.a_is_expected)?; - self.fields.higher_ranked_sub(b, a, self.a_is_expected) + self.fields.higher_ranked_sub(self.param_env, a, b, self.a_is_expected)?; + self.fields.higher_ranked_sub(self.param_env, b, a, self.a_is_expected) } } diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index 83808085fa412..f6c6844ffe9f2 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -21,13 +21,16 @@ use ty::relate::{Relate, RelateResult, TypeRelation}; pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool, + param_env: ty::ParamEnv<'tcx>, } impl<'combine, 'infcx, 'gcx, 'tcx> Glb<'combine, 'infcx, 'gcx, 'tcx> { - pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) - -> Glb<'combine, 'infcx, 'gcx, 'tcx> + pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) + -> Glb<'combine, 'infcx, 'gcx, 'tcx> { - Glb { fields: fields, a_is_expected: a_is_expected } + Glb { fields, a_is_expected, param_env } } } @@ -47,11 +50,11 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> -> RelateResult<'tcx, T> { match variance { - ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b), + ty::Invariant => self.fields.equate(self.param_env, self.a_is_expected).relate(a, b), ty::Covariant => self.relate(a, b), // FIXME(#41044) -- not correct, need test ty::Bivariant => Ok(a.clone()), - ty::Contravariant => self.fields.lub(self.a_is_expected).relate(a, b), + ty::Contravariant => self.fields.lub(self.param_env, self.a_is_expected).relate(a, b), } } @@ -101,7 +104,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx> } fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { - let mut sub = self.fields.sub(self.a_is_expected); + let mut sub = self.fields.sub(self.param_env, self.a_is_expected); sub.relate(&v, &a)?; sub.relate(&v, &b)?; Ok(()) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 12dd3d030c04f..2b3ac7bd5dbfd 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -25,7 +25,11 @@ use syntax_pos::Span; use util::nodemap::{FxHashMap, FxHashSet}; impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { - pub fn higher_ranked_sub(&mut self, a: &Binder, b: &Binder, a_is_expected: bool) + pub fn higher_ranked_sub(&mut self, + param_env: ty::ParamEnv<'tcx>, + a: &Binder, + b: &Binder, + a_is_expected: bool) -> RelateResult<'tcx, Binder> where T: Relate<'tcx> { @@ -62,7 +66,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { debug!("b_prime={:?}", b_prime); // Compare types now that bound regions have been replaced. - let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?; + let result = self.sub(param_env, a_is_expected).relate(&a_prime, &b_prime)?; // Presuming type comparison succeeds, we need to check // that the skolemized regions do not "leak". diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index 4e963d53ab4d7..f7d99288a13f6 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -21,13 +21,16 @@ use ty::relate::{Relate, RelateResult, TypeRelation}; pub struct Lub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool, + param_env: ty::ParamEnv<'tcx>, } impl<'combine, 'infcx, 'gcx, 'tcx> Lub<'combine, 'infcx, 'gcx, 'tcx> { - pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) - -> Lub<'combine, 'infcx, 'gcx, 'tcx> + pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) + -> Lub<'combine, 'infcx, 'gcx, 'tcx> { - Lub { fields: fields, a_is_expected: a_is_expected } + Lub { fields, a_is_expected, param_env } } } @@ -47,11 +50,11 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> -> RelateResult<'tcx, T> { match variance { - ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b), + ty::Invariant => self.fields.equate(self.param_env, self.a_is_expected).relate(a, b), ty::Covariant => self.relate(a, b), // FIXME(#41044) -- not correct, need test ty::Bivariant => Ok(a.clone()), - ty::Contravariant => self.fields.glb(self.a_is_expected).relate(a, b), + ty::Contravariant => self.fields.glb(self.param_env, self.a_is_expected).relate(a, b), } } @@ -101,7 +104,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx> } fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { - let mut sub = self.fields.sub(self.a_is_expected); + let mut sub = self.fields.sub(self.param_env, self.a_is_expected); sub.relate(&a, &v)?; sub.relate(&b, &v)?; Ok(()) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index ca76ce311f574..9b98140fb0892 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -578,13 +578,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return variables; } - fn combine_fields(&'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>) + fn combine_fields(&'a self, trace: TypeTrace<'tcx>) -> CombineFields<'a, 'gcx, 'tcx> { CombineFields { infcx: self, trace, cause: None, - param_env, obligations: PredicateObligations::new(), } } diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index f891f692c7d82..71b31c1838f69 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -22,13 +22,16 @@ use std::mem; pub struct Sub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> { fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool, + param_env: ty::ParamEnv<'tcx>, } impl<'combine, 'infcx, 'gcx, 'tcx> Sub<'combine, 'infcx, 'gcx, 'tcx> { - pub fn new(f: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool) - -> Sub<'combine, 'infcx, 'gcx, 'tcx> + pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + a_is_expected: bool) + -> Sub<'combine, 'infcx, 'gcx, 'tcx> { - Sub { fields: f, a_is_expected: a_is_expected } + Sub { fields, a_is_expected, param_env } } fn with_expected_switched R>(&mut self, f: F) -> R { @@ -64,7 +67,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> -> RelateResult<'tcx, T> { match variance { - ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b), + ty::Invariant => self.fields.equate(self.param_env, self.a_is_expected).relate(a, b), ty::Covariant => self.relate(a, b), ty::Bivariant => Ok(a.clone()), ty::Contravariant => self.with_expected_switched(|this| { this.relate(b, a) }), @@ -96,7 +99,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> self.fields.obligations.push( Obligation::new( self.fields.trace.cause.clone(), - self.fields.param_env, + self.param_env, ty::Predicate::Subtype( ty::Binder(ty::SubtypePredicate { a_is_expected: self.a_is_expected, @@ -107,12 +110,19 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> Ok(a) } (&ty::TyInfer(TyVar(a_id)), _) => { - self.fields - .instantiate(b, RelationDir::SupertypeOf, a_id, !self.a_is_expected)?; + self.fields.instantiate(self.param_env, + b, + RelationDir::SupertypeOf, + a_id, + !self.a_is_expected)?; Ok(a) } (_, &ty::TyInfer(TyVar(b_id))) => { - self.fields.instantiate(a, RelationDir::SubtypeOf, b_id, self.a_is_expected)?; + self.fields.instantiate(self.param_env, + a, + RelationDir::SubtypeOf, + b_id, + self.a_is_expected)?; Ok(a) } @@ -147,6 +157,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> -> RelateResult<'tcx, ty::Binder> where T: Relate<'tcx> { - self.fields.higher_ranked_sub(a, b, self.a_is_expected) + self.fields.higher_ranked_sub(self.param_env, a, b, self.a_is_expected) } } From afb4010dba6e3ee8f2aa9d7ecfe87405a6c87311 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 8 Feb 2018 13:14:24 -0700 Subject: [PATCH 16/22] Wrap `InferCtxt::universe` in a cell We'll need this in order to start tracking skolemizatoins here, and it's easier to update all the field accesses now rather than later. --- src/librustc/infer/mod.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 9b98140fb0892..19cf195e18cd5 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -191,7 +191,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// part of the root universe. So this would only get incremented /// when we enter into a higher-ranked (`for<..>`) type or trait /// bound. - pub universe: ty::UniverseIndex, + universe: Cell, } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -464,7 +464,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { err_count_on_creation: tcx.sess.err_count(), in_snapshot: Cell::new(false), region_obligations: RefCell::new(vec![]), - universe: ty::UniverseIndex::ROOT, + universe: Cell::new(ty::UniverseIndex::ROOT), })) } } @@ -850,7 +850,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid { self.type_variables .borrow_mut() - .new_var(self.universe, diverging, origin) + .new_var(self.universe(), diverging, origin) } pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { @@ -882,7 +882,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx> { let region_var = self.borrow_region_constraints() - .new_region_var(self.universe, origin); + .new_region_var(self.universe(), origin); self.tcx.mk_region(ty::ReVar(region_var)) } @@ -920,7 +920,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { -> Ty<'tcx> { let ty_var_id = self.type_variables .borrow_mut() - .new_var(self.universe, + .new_var(self.universe(), false, TypeVariableOrigin::TypeParameterDefinition(span, def.name)); @@ -1335,6 +1335,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.evaluation_cache.clear(); self.projection_cache.borrow_mut().clear(); } + + fn universe(&self) -> ty::UniverseIndex { + self.universe.get() + } } impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> { From 3b8008f8ae4a3215b19812b9ba18184a36094162 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 8 Feb 2018 14:12:32 -0700 Subject: [PATCH 17/22] track skol levels in the InferCtxt rather than via counter --- src/librustc/infer/higher_ranked/mod.rs | 12 +-- src/librustc/infer/mod.rs | 9 ++- src/librustc/infer/region_constraints/mod.rs | 79 ++------------------ src/librustc/traits/project.rs | 2 +- src/librustc/traits/select.rs | 9 +-- 5 files changed, 26 insertions(+), 85 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 2b3ac7bd5dbfd..e6b8c79d98ab4 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -60,7 +60,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // Second, we instantiate each bound region in the supertype with a // fresh concrete region. let (b_prime, skol_map) = - self.infcx.skolemize_late_bound_regions(b, snapshot); + self.infcx.skolemize_late_bound_regions(b); debug!("a_prime={:?}", a_prime); debug!("b_prime={:?}", b_prime); @@ -188,14 +188,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// /// See `README.md` for more details. pub fn skolemize_late_bound_regions(&self, - binder: &ty::Binder, - snapshot: &CombinedSnapshot<'a, 'tcx>) + binder: &ty::Binder) -> (T, SkolemizationMap<'tcx>) where T : TypeFoldable<'tcx> { let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| { - self.borrow_region_constraints() - .push_skolemized(self.tcx, br, &snapshot.region_constraints_snapshot) + self.universe.set(self.universe().subuniverse()); + self.tcx.mk_region(ty::ReSkolemized(self.universe(), br)) }); debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})", @@ -380,7 +379,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { debug!("pop_skolemized({:?})", skol_map); let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect(); self.borrow_region_constraints() - .pop_skolemized(self.tcx, &skol_regions, &snapshot.region_constraints_snapshot); + .pop_skolemized(self.universe(), &skol_regions, &snapshot.region_constraints_snapshot); + self.universe.set(snapshot.universe); if !skol_map.is_empty() { self.projection_cache.borrow_mut().rollback_skolemized( &snapshot.projection_cache_snapshot); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 19cf195e18cd5..813d1d1872cca 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -499,6 +499,7 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> { float_snapshot: ut::Snapshot>, region_constraints_snapshot: RegionSnapshot, region_obligations_snapshot: usize, + universe: ty::UniverseIndex, was_in_snapshot: bool, _in_progress_tables: Option>>, } @@ -627,6 +628,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { float_snapshot: self.float_unification_table.borrow_mut().snapshot(), region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(), region_obligations_snapshot: self.region_obligations.borrow().len(), + universe: self.universe(), was_in_snapshot: in_snapshot, // Borrow tables "in progress" (i.e. during typeck) // to ban writes from within a snapshot to them. @@ -644,10 +646,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { float_snapshot, region_constraints_snapshot, region_obligations_snapshot, + universe, was_in_snapshot, _in_progress_tables } = snapshot; self.in_snapshot.set(was_in_snapshot); + self.universe.set(universe); self.projection_cache .borrow_mut() @@ -676,6 +680,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { float_snapshot, region_constraints_snapshot, region_obligations_snapshot: _, + universe: _, was_in_snapshot, _in_progress_tables } = snapshot; @@ -820,7 +825,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Some(self.commit_if_ok(|snapshot| { let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) = - self.skolemize_late_bound_regions(predicate, snapshot); + self.skolemize_late_bound_regions(predicate); let cause_span = cause.span; let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; @@ -837,7 +842,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { { self.commit_if_ok(|snapshot| { let (ty::OutlivesPredicate(r_a, r_b), skol_map) = - self.skolemize_late_bound_regions(predicate, snapshot); + self.skolemize_late_bound_regions(predicate); let origin = SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span)); diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index c0852a1d3995d..990a6789b6768 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -22,7 +22,7 @@ use rustc_data_structures::unify as ut; use ty::{self, Ty, TyCtxt}; use ty::{Region, RegionVid}; use ty::ReStatic; -use ty::{BrFresh, ReLateBound, ReSkolemized, ReVar}; +use ty::{BrFresh, ReLateBound, ReVar}; use std::collections::BTreeMap; use std::{cmp, fmt, mem, u32}; @@ -45,9 +45,6 @@ pub struct RegionConstraintCollector<'tcx> { /// exist). This prevents us from making many such regions. glbs: CombineMap<'tcx>, - /// Number of skolemized variables currently active. - skolemization_count: ty::UniverseIndex, - /// Global counter used during the GLB algorithm to create unique /// names for fresh bound regions bound_count: u32, @@ -237,7 +234,6 @@ pub struct RegionVariableInfo { pub struct RegionSnapshot { length: usize, region_snapshot: ut::Snapshot>, - skolemization_count: ty::UniverseIndex, } /// When working with skolemized regions, we often wish to find all of @@ -281,7 +277,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { data: RegionConstraintData::default(), lubs: FxHashMap(), glbs: FxHashMap(), - skolemization_count: ty::UniverseIndex::ROOT, bound_count: 0, undo_log: Vec::new(), unification_table: ut::UnificationTable::new(), @@ -327,14 +322,11 @@ impl<'tcx> RegionConstraintCollector<'tcx> { data, lubs, glbs, - skolemization_count, bound_count: _, undo_log: _, unification_table, } = self; - assert_eq!(*skolemization_count, ty::UniverseIndex::ROOT); - // Clear the tables of (lubs, glbs), so that we will create // fresh regions if we do a LUB operation. As it happens, // LUB/GLB are not performed by the MIR type-checker, which is @@ -369,7 +361,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { RegionSnapshot { length, region_snapshot: self.unification_table.snapshot(), - skolemization_count: self.skolemization_count, } } @@ -377,12 +368,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { debug!("RegionConstraintCollector: commit({})", snapshot.length); assert!(self.undo_log.len() > snapshot.length); assert!(self.undo_log[snapshot.length] == OpenSnapshot); - assert!( - self.skolemization_count == snapshot.skolemization_count, - "failed to pop skolemized regions: {:?} now vs {:?} at start", - self.skolemization_count, - snapshot.skolemization_count - ); if snapshot.length == 0 { self.undo_log.truncate(0); @@ -402,7 +387,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } let c = self.undo_log.pop().unwrap(); assert!(c == OpenSnapshot); - self.skolemization_count = snapshot.skolemization_count; self.unification_table.rollback_to(snapshot.region_snapshot); } @@ -469,46 +453,13 @@ impl<'tcx> RegionConstraintCollector<'tcx> { self.var_infos[vid].origin } - /// Creates a new skolemized region. Skolemized regions are fresh - /// regions used when performing higher-ranked computations. They - /// must be used in a very particular way and are never supposed - /// to "escape" out into error messages or the code at large. - /// - /// The idea is to always create a snapshot. Skolemized regions - /// can be created in the context of this snapshot, but before the - /// snapshot is committed or rolled back, they must be popped - /// (using `pop_skolemized_regions`), so that their numbers can be - /// recycled. Normally you don't have to think about this: you use - /// the APIs in `higher_ranked/mod.rs`, such as - /// `skolemize_late_bound_regions` and `plug_leaks`, which will - /// guide you on this path (ensure that the `SkolemizationMap` is - /// consumed and you are good). There are also somewhat extensive - /// comments in `higher_ranked/README.md`. - /// - /// The `snapshot` argument to this function is not really used; - /// it's just there to make it explicit which snapshot bounds the - /// skolemized region that results. It should always be the top-most snapshot. - pub fn push_skolemized( - &mut self, - tcx: TyCtxt<'_, '_, 'tcx>, - br: ty::BoundRegion, - snapshot: &RegionSnapshot, - ) -> Region<'tcx> { - assert!(self.in_snapshot()); - assert!(self.undo_log[snapshot.length] == OpenSnapshot); - - let universe = self.skolemization_count.subuniverse(); - self.skolemization_count = universe; - tcx.mk_region(ReSkolemized(universe, br)) - } - /// Removes all the edges to/from the skolemized regions that are /// in `skols`. This is used after a higher-ranked operation /// completes to remove all trace of the skolemized regions /// created in that time. pub fn pop_skolemized( &mut self, - _tcx: TyCtxt<'_, '_, 'tcx>, + skolemization_count: ty::UniverseIndex, skols: &FxHashSet>, snapshot: &RegionSnapshot, ) { @@ -517,24 +468,16 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); assert!(self.undo_log[snapshot.length] == OpenSnapshot); assert!( - self.skolemization_count.as_usize() >= skols.len(), + skolemization_count.as_usize() >= skols.len(), "popping more skolemized variables than actually exist, \ sc now = {:?}, skols.len = {:?}", - self.skolemization_count, + skolemization_count, skols.len() ); - let last_to_pop = self.skolemization_count.subuniverse(); + let last_to_pop = skolemization_count.subuniverse(); let first_to_pop = ty::UniverseIndex::from(last_to_pop.as_u32() - skols.len() as u32); - assert!( - first_to_pop >= snapshot.skolemization_count, - "popping more regions than snapshot contains, \ - sc now = {:?}, sc then = {:?}, skols.len = {:?}", - self.skolemization_count, - snapshot.skolemization_count, - skols.len() - ); debug_assert! { skols.iter() .all(|&k| match *k { @@ -545,8 +488,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { false }), "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}", - snapshot.skolemization_count, - self.skolemization_count, + first_to_pop, + last_to_pop, skols } @@ -563,7 +506,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { self.rollback_undo_entry(undo_entry); } - self.skolemization_count = snapshot.skolemization_count; return; fn kill_constraint<'tcx>( @@ -896,12 +838,7 @@ pub fn region_universe(var_infos: &VarInfos, region: Region<'_>) -> ty::Universe impl fmt::Debug for RegionSnapshot { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "RegionSnapshot(length={},skolemization={:?})", - self.length, - self.skolemization_count - ) + write!(f, "RegionSnapshot(length={})", self.length) } } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 369da2f721445..5b59678f853e0 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -188,7 +188,7 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>( let infcx = selcx.infcx(); infcx.commit_if_ok(|snapshot| { let (skol_predicate, skol_map) = - infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot); + infcx.skolemize_late_bound_regions(&obligation.predicate); let skol_obligation = obligation.with(skol_predicate); let r = match project_and_unify_type(selcx, &skol_obligation) { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 99e2c73062049..0b53db399a1ac 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1454,7 +1454,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let poly_trait_predicate = self.infcx().resolve_type_vars_if_possible(&obligation.predicate); let (skol_trait_predicate, skol_map) = - self.infcx().skolemize_late_bound_regions(&poly_trait_predicate, snapshot); + self.infcx().skolemize_late_bound_regions(&poly_trait_predicate); debug!("match_projection_obligation_against_definition_bounds: \ skol_trait_predicate={:?} skol_map={:?}", skol_trait_predicate, @@ -2282,7 +2282,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.in_snapshot(|this, snapshot| { let (skol_ty, skol_map) = - this.infcx().skolemize_late_bound_regions(&ty, snapshot); + this.infcx().skolemize_late_bound_regions(&ty); let Normalized { value: normalized_ty, mut obligations } = project::normalize_with_depth(this, param_env, @@ -2502,7 +2502,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let trait_obligations = self.in_snapshot(|this, snapshot| { let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); let (trait_ref, skol_map) = - this.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot); + this.infcx().skolemize_late_bound_regions(&poly_trait_ref); let cause = obligation.derived_cause(ImplDerivedObligation); this.impl_or_trait_obligations(cause, obligation.recursion_depth + 1, @@ -3084,8 +3084,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions( - &obligation.predicate, - snapshot); + &obligation.predicate); let skol_obligation_trait_ref = skol_obligation.trait_ref; let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, From 0bc324a7e9421f5c82e7456ae1853f8b3c5f6073 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Thu, 8 Feb 2018 15:22:39 -0700 Subject: [PATCH 18/22] remove pop_skolemized and friends --- src/librustc/infer/higher_ranked/mod.rs | 320 +----------------- .../infer/lexical_region_resolve/mod.rs | 7 +- src/librustc/infer/mod.rs | 26 +- src/librustc/infer/region_constraints/mod.rs | 235 +------------ src/librustc/traits/project.rs | 19 +- src/librustc/traits/select.rs | 126 +++---- 6 files changed, 81 insertions(+), 652 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index e6b8c79d98ab4..3459e91cac3b1 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -11,18 +11,12 @@ //! Helper routines for higher-ranked things. See the `doc` module at //! the end of the file for details. -use super::{CombinedSnapshot, - InferCtxt, - HigherRankedType, - SkolemizationMap}; +use super::{InferCtxt, + HigherRankedType}; use super::combine::CombineFields; -use super::region_constraints::{TaintDirections}; use ty::{self, Binder, TypeFoldable}; -use ty::error::TypeError; use ty::relate::{Relate, RelateResult, TypeRelation}; -use syntax_pos::Span; -use util::nodemap::{FxHashMap, FxHashSet}; impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { pub fn higher_ranked_sub(&mut self, @@ -46,10 +40,15 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // Start a snapshot so we can examine "all bindings that were // created as part of this type comparison". - return self.infcx.commit_if_ok(|snapshot| { + return self.infcx.commit_if_ok(|_snapshot| { let span = self.trace.cause.span; - // First, we instantiate each bound region in the subtype with a fresh + // First, we instantiate each bound region in the supertype with a + // fresh concrete region. + let b_prime = + self.infcx.skolemize_late_bound_regions(b); + + // Second, we instantiate each bound region in the subtype with a fresh // region variable. let (a_prime, _) = self.infcx.replace_late_bound_regions_with_fresh_var( @@ -57,25 +56,12 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { HigherRankedType, a); - // Second, we instantiate each bound region in the supertype with a - // fresh concrete region. - let (b_prime, skol_map) = - self.infcx.skolemize_late_bound_regions(b); - debug!("a_prime={:?}", a_prime); debug!("b_prime={:?}", b_prime); // Compare types now that bound regions have been replaced. let result = self.sub(param_env, a_is_expected).relate(&a_prime, &b_prime)?; - // Presuming type comparison succeeds, we need to check - // that the skolemized regions do not "leak". - self.infcx.leak_check(!a_is_expected, span, &skol_map, snapshot)?; - - // We are finished with the skolemized regions now so pop - // them off. - self.infcx.pop_skolemized(skol_map, snapshot); - debug!("higher_ranked_sub: OK result={:?}", result); Ok(ty::Binder(result)) @@ -84,306 +70,26 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { } impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { - fn tainted_regions(&self, - snapshot: &CombinedSnapshot<'a, 'tcx>, - r: ty::Region<'tcx>, - directions: TaintDirections) - -> FxHashSet> { - self.borrow_region_constraints().tainted( - self.tcx, - &snapshot.region_constraints_snapshot, - r, - directions) - } - - fn region_vars_confined_to_snapshot(&self, - snapshot: &CombinedSnapshot<'a, 'tcx>) - -> Vec - { - /*! - * Returns the set of region variables that do not affect any - * types/regions which existed before `snapshot` was - * started. This is used in the sub/lub/glb computations. The - * idea here is that when we are computing lub/glb of two - * regions, we sometimes create intermediate region variables. - * Those region variables may touch some of the skolemized or - * other "forbidden" regions we created to replace bound - * regions, but they don't really represent an "external" - * constraint. - * - * However, sometimes fresh variables are created for other - * purposes too, and those *may* represent an external - * constraint. In particular, when a type variable is - * instantiated, we create region variables for all the - * regions that appear within, and if that type variable - * pre-existed the snapshot, then those region variables - * represent external constraints. - * - * An example appears in the unit test - * `sub_free_bound_false_infer`. In this test, we want to - * know whether - * - * ```rust - * fn(_#0t) <: for<'a> fn(&'a int) - * ``` - * - * Note that the subtype has a type variable. Because the type - * variable can't be instantiated with a region that is bound - * in the fn signature, this comparison ought to fail. But if - * we're not careful, it will succeed. - * - * The reason is that when we walk through the subtyping - * algorith, we begin by replacing `'a` with a skolemized - * variable `'1`. We then have `fn(_#0t) <: fn(&'1 int)`. This - * can be made true by unifying `_#0t` with `&'1 int`. In the - * process, we create a fresh variable for the skolemized - * region, `'$2`, and hence we have that `_#0t == &'$2 - * int`. However, because `'$2` was created during the sub - * computation, if we're not careful we will erroneously - * assume it is one of the transient region variables - * representing a lub/glb internally. Not good. - * - * To prevent this, we check for type variables which were - * unified during the snapshot, and say that any region - * variable created during the snapshot but which finds its - * way into a type variable is considered to "escape" the - * snapshot. - */ - - let mut region_vars = - self.borrow_region_constraints().vars_created_since_snapshot( - &snapshot.region_constraints_snapshot); - - let escaping_types = - self.type_variables.borrow_mut().types_escaping_snapshot(&snapshot.type_snapshot); - - let mut escaping_region_vars = FxHashSet(); - for ty in &escaping_types { - self.tcx.collect_regions(ty, &mut escaping_region_vars); - } - - region_vars.retain(|®ion_vid| { - let r = ty::ReVar(region_vid); - !escaping_region_vars.contains(&r) - }); - - debug!("region_vars_confined_to_snapshot: region_vars={:?} escaping_types={:?}", - region_vars, - escaping_types); - - region_vars - } - /// Replace all regions bound by `binder` with skolemized regions and /// return a map indicating which bound-region was replaced with what /// skolemized region. This is the first step of checking subtyping /// when higher-ranked things are involved. /// - /// **Important:** you must call this function from within a snapshot. - /// Moreover, before committing the snapshot, you must eventually call - /// either `plug_leaks` or `pop_skolemized` to remove the skolemized - /// regions. If you rollback the snapshot (or are using a probe), then - /// the pop occurs as part of the rollback, so an explicit call is not - /// needed (but is also permitted). - /// /// See `README.md` for more details. pub fn skolemize_late_bound_regions(&self, binder: &ty::Binder) - -> (T, SkolemizationMap<'tcx>) + -> T where T : TypeFoldable<'tcx> { - let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| { + let (result, _) = self.tcx.replace_late_bound_regions(binder, |br| { self.universe.set(self.universe().subuniverse()); self.tcx.mk_region(ty::ReSkolemized(self.universe(), br)) }); - debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})", + debug!("skolemize_bound_regions(binder={:?}, result={:?})", binder, - result, - map); - - (result, map) - } - - /// Searches the region constraints created since `snapshot` was started - /// and checks to determine whether any of the skolemized regions created - /// in `skol_map` would "escape" -- meaning that they are related to - /// other regions in some way. If so, the higher-ranked subtyping doesn't - /// hold. See `README.md` for more details. - pub fn leak_check(&self, - overly_polymorphic: bool, - _span: Span, - skol_map: &SkolemizationMap<'tcx>, - snapshot: &CombinedSnapshot<'a, 'tcx>) - -> RelateResult<'tcx, ()> - { - debug!("leak_check: skol_map={:?}", - skol_map); - - let new_vars = self.region_vars_confined_to_snapshot(snapshot); - for (&skol_br, &skol) in skol_map { - // The inputs to a skolemized variable can only - // be itself or other new variables. - let incoming_taints = self.tainted_regions(snapshot, - skol, - TaintDirections::both()); - for &tainted_region in &incoming_taints { - // Each skolemized should only be relatable to itself - // or new variables: - match *tainted_region { - ty::ReVar(vid) => { - if new_vars.contains(&vid) { - continue; - } - } - _ => { - if tainted_region == skol { continue; } - } - }; - - debug!("{:?} (which replaced {:?}) is tainted by {:?}", - skol, - skol_br, - tainted_region); - - return Err(if overly_polymorphic { - debug!("Overly polymorphic!"); - TypeError::RegionsOverlyPolymorphic(skol_br, tainted_region) - } else { - debug!("Not as polymorphic!"); - TypeError::RegionsInsufficientlyPolymorphic(skol_br, tainted_region) - }) - } - } - - Ok(()) - } - - /// This code converts from skolemized regions back to late-bound - /// regions. It works by replacing each region in the taint set of a - /// skolemized region with a bound-region. The bound region will be bound - /// by the outer-most binder in `value`; the caller must ensure that there is - /// such a binder and it is the right place. - /// - /// This routine is only intended to be used when the leak-check has - /// passed; currently, it's used in the trait matching code to create - /// a set of nested obligations frmo an impl that matches against - /// something higher-ranked. More details can be found in - /// `librustc/middle/traits/README.md`. - /// - /// As a brief example, consider the obligation `for<'a> Fn(&'a int) - /// -> &'a int`, and the impl: - /// - /// impl Fn for SomethingOrOther - /// where A : Clone - /// { ... } - /// - /// Here we will have replaced `'a` with a skolemized region - /// `'0`. This means that our substitution will be `{A=>&'0 - /// int, R=>&'0 int}`. - /// - /// When we apply the substitution to the bounds, we will wind up with - /// `&'0 int : Clone` as a predicate. As a last step, we then go and - /// replace `'0` with a late-bound region `'a`. The depth is matched - /// to the depth of the predicate, in this case 1, so that the final - /// predicate is `for<'a> &'a int : Clone`. - pub fn plug_leaks(&self, - skol_map: SkolemizationMap<'tcx>, - snapshot: &CombinedSnapshot<'a, 'tcx>, - value: T) -> T - where T : TypeFoldable<'tcx> - { - debug!("plug_leaks(skol_map={:?}, value={:?})", - skol_map, - value); - - if skol_map.is_empty() { - return value; - } - - // Compute a mapping from the "taint set" of each skolemized - // region back to the `ty::BoundRegion` that it originally - // represented. Because `leak_check` passed, we know that - // these taint sets are mutually disjoint. - let inv_skol_map: FxHashMap, ty::BoundRegion> = - skol_map - .iter() - .flat_map(|(&skol_br, &skol)| { - self.tainted_regions(snapshot, skol, TaintDirections::both()) - .into_iter() - .map(move |tainted_region| (tainted_region, skol_br)) - }) - .collect(); - - debug!("plug_leaks: inv_skol_map={:?}", - inv_skol_map); - - // Remove any instantiated type variables from `value`; those can hide - // references to regions from the `fold_regions` code below. - let value = self.resolve_type_vars_if_possible(&value); - - // Map any skolemization byproducts back to a late-bound - // region. Put that late-bound region at whatever the outermost - // binder is that we encountered in `value`. The caller is - // responsible for ensuring that (a) `value` contains at least one - // binder and (b) that binder is the one we want to use. - let result = self.tcx.fold_regions(&value, &mut false, |r, current_depth| { - match inv_skol_map.get(&r) { - None => r, - Some(br) => { - // It is the responsibility of the caller to ensure - // that each skolemized region appears within a - // binder. In practice, this routine is only used by - // trait checking, and all of the skolemized regions - // appear inside predicates, which always have - // binders, so this assert is satisfied. - assert!(current_depth > 1); - - // since leak-check passed, this skolemized region - // should only have incoming edges from variables - // (which ought not to escape the snapshot, but we - // don't check that) or itself - assert!( - match *r { - ty::ReVar(_) => true, - ty::ReSkolemized(_, ref br1) => br == br1, - _ => false, - }, - "leak-check would have us replace {:?} with {:?}", - r, br); - - self.tcx.mk_region(ty::ReLateBound( - ty::DebruijnIndex::new(current_depth - 1), br.clone())) - } - } - }); - - self.pop_skolemized(skol_map, snapshot); - - debug!("plug_leaks: result={:?}", result); + result); result } - - /// Pops the skolemized regions found in `skol_map` from the region - /// inference context. Whenever you create skolemized regions via - /// `skolemize_late_bound_regions`, they must be popped before you - /// commit the enclosing snapshot (if you do not commit, e.g. within a - /// probe or as a result of an error, then this is not necessary, as - /// popping happens as part of the rollback). - /// - /// Note: popping also occurs implicitly as part of `leak_check`. - pub fn pop_skolemized(&self, - skol_map: SkolemizationMap<'tcx>, - snapshot: &CombinedSnapshot<'a, 'tcx>) { - debug!("pop_skolemized({:?})", skol_map); - let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect(); - self.borrow_region_constraints() - .pop_skolemized(self.universe(), &skol_regions, &snapshot.region_constraints_snapshot); - self.universe.set(snapshot.universe); - if !skol_map.is_empty() { - self.projection_cache.borrow_mut().rollback_skolemized( - &snapshot.projection_cache_snapshot); - } - } } diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index d2389f97adba1..e047aa652c690 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -264,10 +264,13 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { } debug!( - "Expanding value of {:?} from {:?} to {:?}", + "Expanding value of {:?} from {:?} to {:?} \ + (lub_universe={:?}, b_universe={:?})", b_vid, cur_region, - lub + lub, + lub_universe, + b_universe ); *b_data = VarValue::Value(lub); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 813d1d1872cca..385e521d9b97d 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -728,7 +728,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { r } - // Execute `f` in a snapshot, and commit the bindings it creates + /// Execute `f` in a snapshot, and commit the bindings it creates pub fn in_snapshot(&self, f: F) -> T where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T { @@ -823,14 +823,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return None; } - Some(self.commit_if_ok(|snapshot| { - let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) = + Some(self.commit_if_ok(|_snapshot| { + let ty::SubtypePredicate { a_is_expected, a, b} = self.skolemize_late_bound_regions(predicate); - let cause_span = cause.span; let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; - self.leak_check(false, cause_span, &skol_map, snapshot)?; - self.pop_skolemized(skol_map, snapshot); Ok(ok.unit()) })) } @@ -840,16 +837,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { predicate: &ty::PolyRegionOutlivesPredicate<'tcx>) -> UnitResult<'tcx> { - self.commit_if_ok(|snapshot| { - let (ty::OutlivesPredicate(r_a, r_b), skol_map) = - self.skolemize_late_bound_regions(predicate); - let origin = - SubregionOrigin::from_obligation_cause(cause, - || RelateRegionParamBound(cause.span)); - self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` - self.leak_check(false, cause.span, &skol_map, snapshot)?; - Ok(self.pop_skolemized(skol_map, snapshot)) - }) + let ty::OutlivesPredicate(r_a, r_b) = + self.skolemize_late_bound_regions(predicate); + let origin = + SubregionOrigin::from_obligation_cause(cause, + || RelateRegionParamBound(cause.span)); + self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` + Ok(()) } pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid { diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 990a6789b6768..632a0c5851e79 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -22,12 +22,10 @@ use rustc_data_structures::unify as ut; use ty::{self, Ty, TyCtxt}; use ty::{Region, RegionVid}; use ty::ReStatic; -use ty::{BrFresh, ReLateBound, ReVar}; +use ty::{ReLateBound, ReVar}; use std::collections::BTreeMap; -use std::{cmp, fmt, mem, u32}; - -mod taint; +use std::{cmp, fmt, mem}; pub struct RegionConstraintCollector<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableInfo`. @@ -45,10 +43,6 @@ pub struct RegionConstraintCollector<'tcx> { /// exist). This prevents us from making many such regions. glbs: CombineMap<'tcx>, - /// Global counter used during the GLB algorithm to create unique - /// names for fresh bound regions - bound_count: u32, - /// The undo log records actions that might later be undone. /// /// Note: when the undo_log is empty, we are not actively @@ -207,14 +201,6 @@ enum UndoLogEntry<'tcx> { /// We added a GLB/LUB "combination variable" AddCombination(CombineMapType, TwoRegions<'tcx>), - - /// During skolemization, we sometimes purge entries from the undo - /// log in a kind of minisnapshot (unlike other snapshots, this - /// purging actually takes place *on success*). In that case, we - /// replace the corresponding entry with `Noop` so as to avoid the - /// need to do a bunch of swapping. (We can't use `swap_remove` as - /// the order of the vector is important.) - Purged, } #[derive(Copy, Clone, PartialEq)] @@ -236,40 +222,6 @@ pub struct RegionSnapshot { region_snapshot: ut::Snapshot>, } -/// When working with skolemized regions, we often wish to find all of -/// the regions that are either reachable from a skolemized region, or -/// which can reach a skolemized region, or both. We call such regions -/// *tained* regions. This struct allows you to decide what set of -/// tainted regions you want. -#[derive(Debug)] -pub struct TaintDirections { - incoming: bool, - outgoing: bool, -} - -impl TaintDirections { - pub fn incoming() -> Self { - TaintDirections { - incoming: true, - outgoing: false, - } - } - - pub fn outgoing() -> Self { - TaintDirections { - incoming: false, - outgoing: true, - } - } - - pub fn both() -> Self { - TaintDirections { - incoming: true, - outgoing: true, - } - } -} - impl<'tcx> RegionConstraintCollector<'tcx> { pub fn new() -> RegionConstraintCollector<'tcx> { RegionConstraintCollector { @@ -277,7 +229,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { data: RegionConstraintData::default(), lubs: FxHashMap(), glbs: FxHashMap(), - bound_count: 0, undo_log: Vec::new(), unification_table: ut::UnificationTable::new(), } @@ -322,7 +273,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { data, lubs, glbs, - bound_count: _, undo_log: _, unification_table, } = self; @@ -395,7 +345,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { OpenSnapshot => { panic!("Failure to observe stack discipline"); } - Purged | CommitedSnapshot => { + CommitedSnapshot => { // nothing to do here } AddVar(vid) => { @@ -436,132 +386,14 @@ impl<'tcx> RegionConstraintCollector<'tcx> { self.undo_log.push(AddVar(vid)); } debug!( - "created new region variable {:?} with origin {:?}", + "created new region variable {:?} with origin {:?} in universe {:?}", vid, - origin + origin, + universe ); return vid; } - /// Returns the universe for the given variable. - pub fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex { - self.var_infos[vid].universe - } - - /// Returns the origin for the given variable. - pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { - self.var_infos[vid].origin - } - - /// Removes all the edges to/from the skolemized regions that are - /// in `skols`. This is used after a higher-ranked operation - /// completes to remove all trace of the skolemized regions - /// created in that time. - pub fn pop_skolemized( - &mut self, - skolemization_count: ty::UniverseIndex, - skols: &FxHashSet>, - snapshot: &RegionSnapshot, - ) { - debug!("pop_skolemized_regions(skols={:?})", skols); - - assert!(self.in_snapshot()); - assert!(self.undo_log[snapshot.length] == OpenSnapshot); - assert!( - skolemization_count.as_usize() >= skols.len(), - "popping more skolemized variables than actually exist, \ - sc now = {:?}, skols.len = {:?}", - skolemization_count, - skols.len() - ); - - let last_to_pop = skolemization_count.subuniverse(); - let first_to_pop = ty::UniverseIndex::from(last_to_pop.as_u32() - skols.len() as u32); - - debug_assert! { - skols.iter() - .all(|&k| match *k { - ty::ReSkolemized(universe, _) => - universe >= first_to_pop && - universe < last_to_pop, - _ => - false - }), - "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}", - first_to_pop, - last_to_pop, - skols - } - - let constraints_to_kill: Vec = self.undo_log - .iter() - .enumerate() - .rev() - .filter(|&(_, undo_entry)| kill_constraint(skols, undo_entry)) - .map(|(index, _)| index) - .collect(); - - for index in constraints_to_kill { - let undo_entry = mem::replace(&mut self.undo_log[index], Purged); - self.rollback_undo_entry(undo_entry); - } - - return; - - fn kill_constraint<'tcx>( - skols: &FxHashSet>, - undo_entry: &UndoLogEntry<'tcx>, - ) -> bool { - match undo_entry { - &AddConstraint(Constraint::VarSubVar(..)) => false, - &AddConstraint(Constraint::RegSubVar(a, _)) => skols.contains(&a), - &AddConstraint(Constraint::VarSubReg(_, b)) => skols.contains(&b), - &AddConstraint(Constraint::RegSubReg(a, b)) => { - skols.contains(&a) || skols.contains(&b) - } - &AddGiven(..) => false, - &AddVerify(_) => false, - &AddCombination(_, ref two_regions) => { - skols.contains(&two_regions.a) || skols.contains(&two_regions.b) - } - &AddVar(..) | &OpenSnapshot | &Purged | &CommitedSnapshot => false, - } - } - } - - pub fn new_bound( - &mut self, - tcx: TyCtxt<'_, '_, 'tcx>, - debruijn: ty::DebruijnIndex, - ) -> Region<'tcx> { - // Creates a fresh bound variable for use in GLB computations. - // See discussion of GLB computation in the large comment at - // the top of this file for more details. - // - // This computation is potentially wrong in the face of - // rollover. It's conceivable, if unlikely, that one might - // wind up with accidental capture for nested functions in - // that case, if the outer function had bound regions created - // a very long time before and the inner function somehow - // wound up rolling over such that supposedly fresh - // identifiers were in fact shadowed. For now, we just assert - // that there is no rollover -- eventually we should try to be - // robust against this possibility, either by checking the set - // of bound identifiers that appear in a given expression and - // ensure that we generate one that is distinct, or by - // changing the representation of bound regions in a fn - // declaration - - let sc = self.bound_count; - self.bound_count = sc + 1; - - if sc >= self.bound_count { - bug!("rollover in RegionInference new_bound()"); - } - - tcx.mk_region(ReLateBound(debruijn, BrFresh(sc))) - } - fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) { // cannot add constraints once regions are resolved debug!( @@ -787,37 +619,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { }) .collect() } - - /// Computes all regions that have been related to `r0` since the - /// mark `mark` was made---`r0` itself will be the first - /// entry. The `directions` parameter controls what kind of - /// relations are considered. For example, one can say that only - /// "incoming" edges to `r0` are desired, in which case one will - /// get the set of regions `{r|r <= r0}`. This is used when - /// checking whether skolemized regions are being improperly - /// related to other regions. - pub fn tainted( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - mark: &RegionSnapshot, - r0: Region<'tcx>, - directions: TaintDirections, - ) -> FxHashSet> { - debug!( - "tainted(mark={:?}, r0={:?}, directions={:?})", - mark, - r0, - directions - ); - - // `result_set` acts as a worklist: we explore all outgoing - // edges and add any new regions we find to result_set. This - // is not a terribly efficient implementation. - let mut taint_set = taint::TaintSet::new(directions, r0); - taint_set.fixed_point(tcx, &self.undo_log[mark.length..], &self.data.verifys); - debug!("tainted: result={:?}", taint_set); - return taint_set.into_set(); - } } pub fn region_universe(var_infos: &VarInfos, region: Region<'_>) -> ty::UniverseIndex { @@ -870,18 +671,6 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> { } impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { - fn for_each_region(&self, f: &mut dyn FnMut(ty::Region<'tcx>)) { - match self { - &VerifyBound::AnyRegion(ref rs) | &VerifyBound::AllRegions(ref rs) => for &r in rs { - f(r); - }, - - &VerifyBound::AnyBound(ref bs) | &VerifyBound::AllBounds(ref bs) => for b in bs { - b.for_each_region(f); - }, - } - } - pub fn must_hold(&self) -> bool { match self { &VerifyBound::AnyRegion(ref bs) => bs.contains(&&ty::ReStatic), @@ -891,7 +680,7 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { } } - pub fn cannot_hold(&self) -> bool { + fn cannot_hold(&self) -> bool { match self { &VerifyBound::AnyRegion(ref bs) => bs.is_empty(), &VerifyBound::AllRegions(ref bs) => bs.contains(&&ty::ReEmpty), @@ -909,16 +698,6 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { VerifyBound::AnyBound(vec![self, vb]) } } - - pub fn and(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> { - if self.must_hold() && vb.must_hold() { - self - } else if self.cannot_hold() && vb.cannot_hold() { - self - } else { - VerifyBound::AllBounds(vec![self, vb]) - } - } } impl<'tcx> RegionConstraintData<'tcx> { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 5b59678f853e0..8b299987be84d 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -186,25 +186,12 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>( obligation); let infcx = selcx.infcx(); - infcx.commit_if_ok(|snapshot| { - let (skol_predicate, skol_map) = + infcx.commit_if_ok(|_snapshot| { + let skol_predicate = infcx.skolemize_late_bound_regions(&obligation.predicate); let skol_obligation = obligation.with(skol_predicate); - let r = match project_and_unify_type(selcx, &skol_obligation) { - Ok(result) => { - let span = obligation.cause.span; - match infcx.leak_check(false, span, &skol_map, snapshot) { - Ok(()) => Ok(infcx.plug_leaks(skol_map, snapshot, result)), - Err(e) => Err(MismatchedProjectionTypes { err: e }), - } - } - Err(e) => { - Err(e) - } - }; - - r + project_and_unify_type(selcx, &skol_obligation) }) } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 0b53db399a1ac..fe0c87a1ea75e 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1435,9 +1435,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { _ => return } - let result = self.probe(|this, snapshot| { - this.match_projection_obligation_against_definition_bounds(obligation, - snapshot) + let result = self.probe(|this, _snapshot| { + this.match_projection_obligation_against_definition_bounds(obligation) }); if result { @@ -1447,18 +1446,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn match_projection_obligation_against_definition_bounds( &mut self, - obligation: &TraitObligation<'tcx>, - snapshot: &infer::CombinedSnapshot<'cx, 'tcx>) + obligation: &TraitObligation<'tcx>) -> bool { let poly_trait_predicate = self.infcx().resolve_type_vars_if_possible(&obligation.predicate); - let (skol_trait_predicate, skol_map) = + let skol_trait_predicate = self.infcx().skolemize_late_bound_regions(&poly_trait_predicate); debug!("match_projection_obligation_against_definition_bounds: \ - skol_trait_predicate={:?} skol_map={:?}", - skol_trait_predicate, - skol_map); + skol_trait_predicate={:?}", + skol_trait_predicate); let (def_id, substs) = match skol_trait_predicate.trait_ref.self_ty().sty { ty::TyProjection(ref data) => @@ -1489,9 +1486,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { |bound| self.probe( |this, _| this.match_projection(obligation, bound.clone(), - skol_trait_predicate.trait_ref.clone(), - &skol_map, - snapshot))); + skol_trait_predicate.trait_ref.clone()))); debug!("match_projection_obligation_against_definition_bounds: \ matching_bound={:?}", @@ -1502,11 +1497,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // Repeat the successful match, if any, this time outside of a probe. let result = self.match_projection(obligation, bound, - skol_trait_predicate.trait_ref.clone(), - &skol_map, - snapshot); - - self.infcx.pop_skolemized(skol_map, snapshot); + skol_trait_predicate.trait_ref.clone()); assert!(result); true @@ -1517,18 +1508,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn match_projection(&mut self, obligation: &TraitObligation<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>, - skol_trait_ref: ty::TraitRef<'tcx>, - skol_map: &infer::SkolemizationMap<'tcx>, - snapshot: &infer::CombinedSnapshot<'cx, 'tcx>) + skol_trait_ref: ty::TraitRef<'tcx>) -> bool { assert!(!skol_trait_ref.has_escaping_regions()); - if let Err(_) = self.infcx.at(&obligation.cause, obligation.param_env) - .sup(ty::Binder(skol_trait_ref), trait_bound) { - return false; + match self.infcx.at(&obligation.cause, obligation.param_env) + .sup(ty::Binder(skol_trait_ref), trait_bound) { + Ok(InferOk { obligations, .. }) => true, + Err(_) => false, } - - self.infcx.leak_check(false, obligation.cause.span, skol_map, snapshot).is_ok() } /// Given an obligation like ``, search the obligations that the caller @@ -1706,8 +1694,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.predicate.def_id(), obligation.predicate.0.trait_ref.self_ty(), |impl_def_id| { - self.probe(|this, snapshot| { /* [1] */ - match this.match_impl(impl_def_id, obligation, snapshot) { + self.probe(|this, _snapshot| { /* [1] */ + match this.match_impl(impl_def_id, obligation) { Ok(skol_map) => { candidates.vec.push(ImplCandidate(impl_def_id)); @@ -2280,8 +2268,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { types.skip_binder().into_iter().flat_map(|ty| { // binder moved -\ let ty: ty::Binder> = ty::Binder(ty); // <----------/ - self.in_snapshot(|this, snapshot| { - let (skol_ty, skol_map) = + self.in_snapshot(|this, _snapshot| { + let skol_ty = this.infcx().skolemize_late_bound_regions(&ty); let Normalized { value: normalized_ty, mut obligations } = project::normalize_with_depth(this, @@ -2297,7 +2285,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { normalized_ty, &[]); obligations.push(skol_obligation); - this.infcx().plug_leaks(skol_map, snapshot, obligations) + obligations }) }).collect() } @@ -2386,10 +2374,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) { - self.in_snapshot(|this, snapshot| { + self.in_snapshot(|this, _snapshot| { let result = - this.match_projection_obligation_against_definition_bounds(obligation, - snapshot); + this.match_projection_obligation_against_definition_bounds(obligation); assert!(result); }) } @@ -2499,18 +2486,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { trait_def_id, nested); - let trait_obligations = self.in_snapshot(|this, snapshot| { + let trait_obligations = self.in_snapshot(|this, _snapshot| { let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); - let (trait_ref, skol_map) = + let trait_ref = this.infcx().skolemize_late_bound_regions(&poly_trait_ref); let cause = obligation.derived_cause(ImplDerivedObligation); this.impl_or_trait_obligations(cause, obligation.recursion_depth + 1, obligation.param_env, trait_def_id, - &trait_ref.substs, - skol_map, - snapshot) + &trait_ref.substs) }); obligations.extend(trait_obligations); @@ -2534,19 +2519,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // First, create the substitutions by matching the impl again, // this time not in a probe. - self.in_snapshot(|this, snapshot| { - let (substs, skol_map) = - this.rematch_impl(impl_def_id, obligation, - snapshot); + self.in_snapshot(|this, _snapshot| { + let substs = this.rematch_impl(impl_def_id, obligation); debug!("confirm_impl_candidate substs={:?}", substs); let cause = obligation.derived_cause(ImplDerivedObligation); this.vtable_impl(impl_def_id, substs, cause, obligation.recursion_depth + 1, - obligation.param_env, - skol_map, - snapshot) + obligation.param_env) }) } @@ -2555,25 +2536,20 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { mut substs: Normalized<'tcx, &'tcx Substs<'tcx>>, cause: ObligationCause<'tcx>, recursion_depth: usize, - param_env: ty::ParamEnv<'tcx>, - skol_map: infer::SkolemizationMap<'tcx>, - snapshot: &infer::CombinedSnapshot<'cx, 'tcx>) + param_env: ty::ParamEnv<'tcx>) -> VtableImplData<'tcx, PredicateObligation<'tcx>> { - debug!("vtable_impl(impl_def_id={:?}, substs={:?}, recursion_depth={}, skol_map={:?})", + debug!("vtable_impl(impl_def_id={:?}, substs={:?}, recursion_depth={})", impl_def_id, substs, - recursion_depth, - skol_map); + recursion_depth); let mut impl_obligations = self.impl_or_trait_obligations(cause, recursion_depth, param_env, impl_def_id, - &substs.value, - skol_map, - snapshot); + &substs.value); debug!("vtable_impl: impl_def_id={:?} impl_obligations={:?}", impl_def_id, @@ -3052,27 +3028,21 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn rematch_impl(&mut self, impl_def_id: DefId, - obligation: &TraitObligation<'tcx>, - snapshot: &infer::CombinedSnapshot<'cx, 'tcx>) - -> (Normalized<'tcx, &'tcx Substs<'tcx>>, - infer::SkolemizationMap<'tcx>) + obligation: &TraitObligation<'tcx>) + -> Normalized<'tcx, &'tcx Substs<'tcx>> { - match self.match_impl(impl_def_id, obligation, snapshot) { - Ok((substs, skol_map)) => (substs, skol_map), - Err(()) => { + self.match_impl(impl_def_id, obligation) + .unwrap_or_else(|()| { bug!("Impl {:?} was matchable against {:?} but now is not", impl_def_id, obligation); - } - } + }) } fn match_impl(&mut self, impl_def_id: DefId, - obligation: &TraitObligation<'tcx>, - snapshot: &infer::CombinedSnapshot<'cx, 'tcx>) - -> Result<(Normalized<'tcx, &'tcx Substs<'tcx>>, - infer::SkolemizationMap<'tcx>), ()> + obligation: &TraitObligation<'tcx>) + -> Result>, ()> { let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); @@ -3083,7 +3053,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Err(()); } - let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions( + let skol_obligation = self.infcx().skolemize_late_bound_regions( &obligation.predicate); let skol_obligation_trait_ref = skol_obligation.trait_ref; @@ -3116,19 +3086,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { })?; nested_obligations.extend(obligations); - if let Err(e) = self.infcx.leak_check(false, - obligation.cause.span, - &skol_map, - snapshot) { - debug!("match_impl: failed leak check due to `{}`", e); - return Err(()); - } - debug!("match_impl: success impl_substs={:?}", impl_substs); - Ok((Normalized { + Ok(Normalized { value: impl_substs, - obligations: nested_obligations - }, skol_map)) + obligations: nested_obligations, + }) } fn fast_reject_trait_refs(&mut self, @@ -3261,9 +3223,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { recursion_depth: usize, param_env: ty::ParamEnv<'tcx>, def_id: DefId, // of impl or trait - substs: &Substs<'tcx>, // for impl or trait - skol_map: infer::SkolemizationMap<'tcx>, - snapshot: &infer::CombinedSnapshot<'cx, 'tcx>) + substs: &Substs<'tcx>) // for impl or trait -> Vec> { debug!("impl_or_trait_obligations(def_id={:?})", def_id); @@ -3303,7 +3263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // types. let mut seen = FxHashSet(); predicates.retain(|i| seen.insert(i.clone())); - self.infcx().plug_leaks(skol_map, snapshot, predicates) + predicates } } From 17e0577f911744ffc75106a762aac7db78fd4f8b Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 09:42:25 -0700 Subject: [PATCH 19/22] DO NOT MERGE THIS COMMIT remove all failing tests so we can do a crater run --- .../compile-fail/associated-types-eq-hr.rs | 109 ---------- .../higher-ranked-projection.rs | 38 ---- ...hase-reservation-sharing-interference-2.rs | 37 ---- .../expect-fn-supply-fn.rs | 70 ------ src/test/compile-fail/hr-subtype.rs | 116 ---------- .../compile-fail/hrtb-conflate-regions.rs | 40 ---- ...tb-higher-ranker-supertraits-transitive.rs | 60 ------ .../hrtb-higher-ranker-supertraits.rs | 58 ----- src/test/compile-fail/hrtb-just-for-static.rs | 37 ---- .../compile-fail/hrtb-perfect-forwarding.rs | 66 ------ src/test/compile-fail/issue-40000.rs | 18 -- ...ion-lifetime-bounds-on-fns-where-clause.rs | 39 ---- ...ple-lifetime-bounds-on-fns-where-clause.rs | 41 ---- .../regions-fn-subtyping-return-static.rs | 67 ------ .../regions-lifetime-bounds-on-fns.rs | 39 ---- src/test/compile-fail/where-for-self-2.rs | 33 --- src/test/ui/generator/auto-trait-regions.rs | 58 ----- src/test/ui/generator/generator-with-nll.rs | 25 --- .../closure-arg-type-mismatch.rs | 22 -- .../ui/mismatched_types/closure-mismatch.rs | 20 -- src/test/ui/nll/borrow-use-issue-46875.rs | 30 --- src/test/ui/nll/borrowed-match-issue-45045.rs | 30 --- .../ui/nll/borrowed-referent-issue-38899.rs | 30 --- .../escape-argument-callee.rs | 53 ----- .../escape-argument-callee.stderr | 39 ---- .../propagate-approximated-fail-no-postdom.rs | 63 ------ ...pagate-approximated-fail-no-postdom.stderr | 45 ---- .../propagate-approximated-ref.rs | 61 ------ ...horter-to-static-comparing-against-free.rs | 51 ----- ...approximated-shorter-to-static-no-bound.rs | 53 ----- ...oximated-shorter-to-static-no-bound.stderr | 53 ----- ...roximated-shorter-to-static-wrong-bound.rs | 56 ----- ...mated-shorter-to-static-wrong-bound.stderr | 53 ----- .../propagate-approximated-val.rs | 54 ----- .../propagate-despite-same-free-region.rs | 60 ------ .../propagate-despite-same-free-region.stderr | 37 ---- ...te-fail-to-approximate-longer-no-bounds.rs | 53 ----- ...ail-to-approximate-longer-no-bounds.stderr | 45 ---- ...fail-to-approximate-longer-wrong-bounds.rs | 57 ----- ...-to-approximate-longer-wrong-bounds.stderr | 45 ---- .../propagate-from-trait-match.rs | 60 ------ ...region-lbr-anon-does-not-outlive-static.rs | 24 --- ...egion-lbr-named-does-not-outlive-static.rs | 24 --- ...n-lbr-named-does-not-outlive-static.stderr | 14 -- .../region-lbr1-does-not-outlive-ebr2.rs | 24 --- ...does-outlive-lbr2-because-implied-bound.rs | 23 -- .../return-wrong-bound-region.rs | 34 --- .../return-wrong-bound-region.stderr | 37 ---- src/test/ui/nll/constant.rs | 21 -- src/test/ui/nll/drop-may-dangle.rs | 46 ---- src/test/ui/nll/drop-may-dangle.stderr | 0 .../ui/nll/generator-distinct-lifetime.rs | 35 --- src/test/ui/nll/guarantor-issue-46974.rs | 31 --- src/test/ui/nll/issue-47022.rs | 47 ---- .../maybe-initialized-drop-uninitialized.rs | 29 --- ...aybe-initialized-drop-uninitialized.stderr | 0 src/test/ui/nll/projection-return.rs | 29 --- src/test/ui/nll/return-ref-mut-issue-46557.rs | 21 -- src/test/ui/nll/trait-associated-constant.rs | 42 ---- .../ui/nll/ty-outlives/impl-trait-captures.rs | 27 --- .../ui/nll/ty-outlives/impl-trait-outlives.rs | 51 ----- .../ty-outlives/projection-implied-bounds.rs | 56 ----- .../projection-no-regions-closure.rs | 68 ------ .../ty-outlives/projection-no-regions-fn.rs | 53 ----- .../projection-one-region-closure.rs | 106 --------- ...ojection-one-region-trait-bound-closure.rs | 106 --------- ...tion-one-region-trait-bound-closure.stderr | 204 ------------------ ...n-one-region-trait-bound-static-closure.rs | 99 --------- ...e-region-trait-bound-static-closure.stderr | 155 ------------- ...ojection-two-region-trait-bound-closure.rs | 135 ------------ ...y-param-closure-approximate-lower-bound.rs | 55 ----- ...param-closure-outlives-from-return-type.rs | 66 ------ ...aram-closure-outlives-from-where-clause.rs | 96 --------- .../ty-param-fn-body-nll-feature.rs | 41 ---- .../ui/nll/ty-outlives/ty-param-fn-body.rs | 41 ---- src/test/ui/nll/ty-outlives/ty-param-fn.rs | 51 ----- .../ty-outlives/ty-param-implied-bounds.rs | 42 ---- .../ty-param-implied-bounds.stderr | 0 .../ui/regions-fn-subtyping-return-static.rs | 57 ----- 79 files changed, 4011 deletions(-) delete mode 100644 src/test/compile-fail/associated-types-eq-hr.rs delete mode 100644 src/test/compile-fail/associated-types/higher-ranked-projection.rs delete mode 100644 src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs delete mode 100644 src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs delete mode 100644 src/test/compile-fail/hr-subtype.rs delete mode 100644 src/test/compile-fail/hrtb-conflate-regions.rs delete mode 100644 src/test/compile-fail/hrtb-higher-ranker-supertraits-transitive.rs delete mode 100644 src/test/compile-fail/hrtb-higher-ranker-supertraits.rs delete mode 100644 src/test/compile-fail/hrtb-just-for-static.rs delete mode 100644 src/test/compile-fail/hrtb-perfect-forwarding.rs delete mode 100644 src/test/compile-fail/issue-40000.rs delete mode 100644 src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs delete mode 100644 src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs delete mode 100644 src/test/compile-fail/regions-fn-subtyping-return-static.rs delete mode 100644 src/test/compile-fail/regions-lifetime-bounds-on-fns.rs delete mode 100644 src/test/compile-fail/where-for-self-2.rs delete mode 100644 src/test/ui/generator/auto-trait-regions.rs delete mode 100644 src/test/ui/generator/generator-with-nll.rs delete mode 100644 src/test/ui/mismatched_types/closure-arg-type-mismatch.rs delete mode 100644 src/test/ui/mismatched_types/closure-mismatch.rs delete mode 100644 src/test/ui/nll/borrow-use-issue-46875.rs delete mode 100644 src/test/ui/nll/borrowed-match-issue-45045.rs delete mode 100644 src/test/ui/nll/borrowed-referent-issue-38899.rs delete mode 100644 src/test/ui/nll/closure-requirements/escape-argument-callee.rs delete mode 100644 src/test/ui/nll/closure-requirements/escape-argument-callee.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-val.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs delete mode 100644 src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs delete mode 100644 src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs delete mode 100644 src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs delete mode 100644 src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr delete mode 100644 src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs delete mode 100644 src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs delete mode 100644 src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs delete mode 100644 src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr delete mode 100644 src/test/ui/nll/constant.rs delete mode 100644 src/test/ui/nll/drop-may-dangle.rs delete mode 100644 src/test/ui/nll/drop-may-dangle.stderr delete mode 100644 src/test/ui/nll/generator-distinct-lifetime.rs delete mode 100644 src/test/ui/nll/guarantor-issue-46974.rs delete mode 100644 src/test/ui/nll/issue-47022.rs delete mode 100644 src/test/ui/nll/maybe-initialized-drop-uninitialized.rs delete mode 100644 src/test/ui/nll/maybe-initialized-drop-uninitialized.stderr delete mode 100644 src/test/ui/nll/projection-return.rs delete mode 100644 src/test/ui/nll/return-ref-mut-issue-46557.rs delete mode 100644 src/test/ui/nll/trait-associated-constant.rs delete mode 100644 src/test/ui/nll/ty-outlives/impl-trait-captures.rs delete mode 100644 src/test/ui/nll/ty-outlives/impl-trait-outlives.rs delete mode 100644 src/test/ui/nll/ty-outlives/projection-implied-bounds.rs delete mode 100644 src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs delete mode 100644 src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs delete mode 100644 src/test/ui/nll/ty-outlives/projection-one-region-closure.rs delete mode 100644 src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs delete mode 100644 src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr delete mode 100644 src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs delete mode 100644 src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr delete mode 100644 src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-fn-body.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-fn.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs delete mode 100644 src/test/ui/nll/ty-outlives/ty-param-implied-bounds.stderr delete mode 100644 src/test/ui/regions-fn-subtyping-return-static.rs diff --git a/src/test/compile-fail/associated-types-eq-hr.rs b/src/test/compile-fail/associated-types-eq-hr.rs deleted file mode 100644 index 52a2ca9082d23..0000000000000 --- a/src/test/compile-fail/associated-types-eq-hr.rs +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Check testing of equality constraints in a higher-ranked context. - -pub trait TheTrait { - type A; - - fn get(&self, t: T) -> Self::A; -} - -struct IntStruct { - x: isize -} - -impl<'a> TheTrait<&'a isize> for IntStruct { - type A = &'a isize; - - fn get(&self, t: &'a isize) -> &'a isize { - t - } -} - -struct UintStruct { - x: isize -} - -impl<'a> TheTrait<&'a isize> for UintStruct { - type A = &'a usize; - - fn get(&self, t: &'a isize) -> &'a usize { - panic!() - } -} - -struct Tuple { -} - -impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple { - type A = &'a isize; - - fn get(&self, t: (&'a isize, &'a isize)) -> &'a isize { - t.0 - } -} - -fn foo() - where T : for<'x> TheTrait<&'x isize, A = &'x isize> -{ - // ok for IntStruct, but not UintStruct -} - -fn bar() - where T : for<'x> TheTrait<&'x isize, A = &'x usize> -{ - // ok for UintStruct, but not IntStruct -} - -fn tuple_one() - where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize> -{ - // not ok for tuple, two lifetimes and we pick first -} - -fn tuple_two() - where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize> -{ - // not ok for tuple, two lifetimes and we pick second -} - -fn tuple_three() - where T : for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize> -{ - // ok for tuple -} - -fn tuple_four() - where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)> -{ - // not ok for tuple, two lifetimes, and lifetime matching is invariant -} - -pub fn main() { - foo::(); - foo::(); //~ ERROR type mismatch - - bar::(); //~ ERROR type mismatch - bar::(); - - tuple_one::(); - //~^ ERROR E0277 - //~| ERROR type mismatch - - tuple_two::(); - //~^ ERROR E0277 - //~| ERROR type mismatch - - tuple_three::(); - - tuple_four::(); - //~^ ERROR E0277 -} diff --git a/src/test/compile-fail/associated-types/higher-ranked-projection.rs b/src/test/compile-fail/associated-types/higher-ranked-projection.rs deleted file mode 100644 index 12341fa8db38f..0000000000000 --- a/src/test/compile-fail/associated-types/higher-ranked-projection.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(rustc_attrs)] - -// revisions: good bad - -trait Mirror { - type Image; -} - -impl Mirror for T { - type Image = T; -} - -#[cfg(bad)] -fn foo(_t: T) - where for<'a> &'a T: Mirror -{} - -#[cfg(good)] -fn foo(_t: T) - where for<'a> &'a T: Mirror -{} - -#[rustc_error] -fn main() { //[good]~ ERROR compilation successful - foo(()); - //[bad]~^ ERROR type mismatch resolving `for<'a> <&'a _ as Mirror>::Image == _` - //[bad]~| expected bound lifetime parameter 'a, found concrete lifetime -} diff --git a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs deleted file mode 100644 index fc9100c8a9a86..0000000000000 --- a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// revisions: lxl nll -//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows -//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll - -// This is similar to two-phase-reservation-sharing-interference.rs -// in that it shows a reservation that overlaps with a shared borrow. -// -// Currently, this test fails with lexical lifetimes, but succeeds -// with non-lexical lifetimes. (The reason is because the activation -// of the mutable borrow ends up overlapping with a lexically-scoped -// shared borrow; but a non-lexical shared borrow can end before the -// activation occurs.) -// -// So this test is just making a note of the current behavior. - -#![feature(rustc_attrs)] - -#[rustc_error] -fn main() { //[nll]~ ERROR compilation successful - let mut v = vec![0, 1, 2]; - let shared = &v; - - v.push(shared.len()); - //[lxl]~^ ERROR cannot borrow `v` as mutable because it is also borrowed as immutable [E0502] - - assert_eq!(v, [0, 1, 2, 3]); -} diff --git a/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs b/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs deleted file mode 100644 index 645fd1f80babf..0000000000000 --- a/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(underscore_lifetimes)] - -fn with_closure_expecting_fn_with_free_region(_: F) - where F: for<'a> FnOnce(fn(&'a u32), &i32) -{ -} - -fn with_closure_expecting_fn_with_bound_region(_: F) - where F: FnOnce(fn(&u32), &i32) -{ -} - -fn expect_free_supply_free_from_fn<'x>(x: &'x u32) { - // Here, the type given for `'x` "obscures" a region from the - // expected signature that is bound at closure level. - with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {}); - //~^ ERROR mismatched types - //~| ERROR mismatched types -} - -fn expect_free_supply_free_from_closure() { - // A variant on the previous test. Here, the region `'a` will be - // bound at the closure level, just as is expected, so no error - // results. - type Foo<'a> = fn(&'a u32); - with_closure_expecting_fn_with_free_region(|_x: Foo<'_>, y| {}); -} - -fn expect_free_supply_bound() { - // Here, we are given a function whose region is bound at closure level, - // but we expect one bound in the argument. Error results. - with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); - //~^ ERROR type mismatch in closure arguments -} - -fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) { - // Here, we are given a `fn(&u32)` but we expect a `fn(&'x - // u32)`. In principle, this could be ok, but we demand equality. - with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); - //~^ ERROR type mismatch in closure arguments -} - -fn expect_bound_supply_free_from_closure() { - // A variant on the previous test. Here, the region `'a` will be - // bound at the closure level, but we expect something bound at - // the argument level. - type Foo<'a> = fn(&'a u32); - with_closure_expecting_fn_with_bound_region(|_x: Foo<'_>, y| {}); - //~^ ERROR type mismatch in closure arguments -} - -fn expect_bound_supply_bound<'x>(x: &'x u32) { - // No error in this case. The supplied type supplies the bound - // regions, and hence we are able to figure out the type of `y` - // from the expected type - with_closure_expecting_fn_with_bound_region(|x: for<'z> fn(&'z u32), y| { - }); -} - -fn main() { } diff --git a/src/test/compile-fail/hr-subtype.rs b/src/test/compile-fail/hr-subtype.rs deleted file mode 100644 index 86df2382732b5..0000000000000 --- a/src/test/compile-fail/hr-subtype.rs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Targeted tests for the higher-ranked subtyping code. - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -// revisions: bound_a_vs_bound_a -// revisions: bound_a_vs_bound_b -// revisions: bound_inv_a_vs_bound_inv_b -// revisions: bound_co_a_vs_bound_co_b -// revisions: bound_a_vs_free_x -// revisions: free_x_vs_free_x -// revisions: free_x_vs_free_y -// revisions: free_inv_x_vs_free_inv_y -// revisions: bound_a_b_vs_bound_a -// revisions: bound_co_a_b_vs_bound_co_a -// revisions: bound_contra_a_contra_b_ret_co_a -// revisions: bound_co_a_co_b_ret_contra_a -// revisions: bound_inv_a_b_vs_bound_inv_a -// revisions: bound_a_b_ret_a_vs_bound_a_ret_a - -fn gimme(_: Option) { } - -struct Inv<'a> { x: *mut &'a u32 } - -struct Co<'a> { x: fn(&'a u32) } - -struct Contra<'a> { x: &'a u32 } - -macro_rules! check { - ($rev:ident: ($t1:ty, $t2:ty)) => { - #[cfg($rev)] - fn subtype<'x,'y:'x,'z:'y>() { - gimme::<$t2>(None::<$t1>); - //[free_inv_x_vs_free_inv_y]~^ ERROR mismatched types - } - - #[cfg($rev)] - fn supertype<'x,'y:'x,'z:'y>() { - gimme::<$t1>(None::<$t2>); - //[bound_a_vs_free_x]~^ ERROR mismatched types - //[free_x_vs_free_y]~^^ ERROR mismatched types - //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR mismatched types - //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR mismatched types - //[free_inv_x_vs_free_inv_y]~^^^^^ ERROR mismatched types - //[bound_a_b_vs_bound_a]~^^^^^^ ERROR mismatched types - //[bound_co_a_b_vs_bound_co_a]~^^^^^^^ ERROR mismatched types - //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR mismatched types - //[bound_co_a_co_b_ret_contra_a]~^^^^^^^^^ ERROR mismatched types - } - } -} - -// If both have bound regions, they are equivalent, regardless of -// variant. -check! { bound_a_vs_bound_a: (for<'a> fn(&'a u32), - for<'a> fn(&'a u32)) } -check! { bound_a_vs_bound_b: (for<'a> fn(&'a u32), - for<'b> fn(&'b u32)) } -check! { bound_inv_a_vs_bound_inv_b: (for<'a> fn(Inv<'a>), - for<'b> fn(Inv<'b>)) } -check! { bound_co_a_vs_bound_co_b: (for<'a> fn(Co<'a>), - for<'b> fn(Co<'b>)) } - -// Bound is a subtype of free. -check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), - fn(&'x u32)) } - -// Two free regions are relatable if subtyping holds. -check! { free_x_vs_free_x: (fn(&'x u32), - fn(&'x u32)) } -check! { free_x_vs_free_y: (fn(&'x u32), - fn(&'y u32)) } -check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), - fn(Inv<'y>)) } - -// Somewhat surprisingly, a fn taking two distinct bound lifetimes and -// a fn taking one bound lifetime can be interchangeable, but only if -// we are co- or contra-variant with respect to both lifetimes. -// -// The reason is: -// - if we are covariant, then 'a and 'b can be set to the call-site -// intersection; -// - if we are contravariant, then 'a can be inferred to 'static. -check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), - for<'a> fn(&'a u32, &'a u32)) } -check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), - for<'a> fn(Co<'a>, Co<'a>)) } -check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, - for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } -check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, - for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } - -// If we make those lifetimes invariant, then the two types are not interchangeable. -check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), - for<'a> fn(Inv<'a>, Inv<'a>)) } -check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, - for<'a> fn(&'a u32, &'a u32) -> &'a u32) } - -#[rustc_error] -fn main() { -//[bound_a_vs_bound_a]~^ ERROR compilation successful -//[bound_a_vs_bound_b]~^^ ERROR compilation successful -//[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -//[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful -//[free_x_vs_free_x]~^^^^^ ERROR compilation successful -} diff --git a/src/test/compile-fail/hrtb-conflate-regions.rs b/src/test/compile-fail/hrtb-conflate-regions.rs deleted file mode 100644 index 845429d4b0c0b..0000000000000 --- a/src/test/compile-fail/hrtb-conflate-regions.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that an impl with only one bound region `'a` cannot be used to -// satisfy a constraint where there are two bound regions. - -trait Foo { - fn foo(&self, x: X) { } -} - -fn want_foo2() - where T : for<'a,'b> Foo<(&'a isize, &'b isize)> -{ -} - -fn want_foo1() - where T : for<'z> Foo<(&'z isize, &'z isize)> -{ -} - -/////////////////////////////////////////////////////////////////////////// -// Expressed as a where clause - -struct SomeStruct; - -impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct -{ -} - -fn a() { want_foo1::(); } // OK -- foo wants just one region -fn b() { want_foo2::(); } //~ ERROR E0277 - -fn main() { } diff --git a/src/test/compile-fail/hrtb-higher-ranker-supertraits-transitive.rs b/src/test/compile-fail/hrtb-higher-ranker-supertraits-transitive.rs deleted file mode 100644 index b55dccec2d56f..0000000000000 --- a/src/test/compile-fail/hrtb-higher-ranker-supertraits-transitive.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test HRTB supertraits with several levels of expansion required. - -trait Foo<'tcx> -{ - fn foo(&'tcx self) -> &'tcx isize; -} - -trait Bar<'ccx> - : for<'tcx> Foo<'tcx> -{ - fn bar(&'ccx self) -> &'ccx isize; -} - -trait Baz - : for<'ccx> Bar<'ccx> -{ - fn dummy(&self); -} - -trait Qux - : Bar<'static> -{ - fn dummy(&self); -} - -fn want_foo_for_any_tcx(f: &F) - where F : for<'tcx> Foo<'tcx> -{ -} - -fn want_bar_for_any_ccx(b: &B) - where B : for<'ccx> Bar<'ccx> -{ -} - -fn want_baz(b: &B) - where B : Baz -{ - want_foo_for_any_tcx(b); - want_bar_for_any_ccx(b); -} - -fn want_qux(b: &B) - where B : Qux -{ - want_foo_for_any_tcx(b); - want_bar_for_any_ccx(b); //~ ERROR E0277 -} - -fn main() {} diff --git a/src/test/compile-fail/hrtb-higher-ranker-supertraits.rs b/src/test/compile-fail/hrtb-higher-ranker-supertraits.rs deleted file mode 100644 index 4c5add4aceaaf..0000000000000 --- a/src/test/compile-fail/hrtb-higher-ranker-supertraits.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test a trait (`Bar`) with a higher-ranked supertrait. - -trait Foo<'tcx> -{ - fn foo(&'tcx self) -> &'tcx isize; -} - -trait Bar<'ccx> - : for<'tcx> Foo<'tcx> -{ - fn bar(&'ccx self) -> &'ccx isize; -} - -fn want_foo_for_some_tcx<'x,F>(f: &'x F) - where F : Foo<'x> -{ - want_foo_for_some_tcx(f); - want_foo_for_any_tcx(f); //~ ERROR E0277 -} - -fn want_foo_for_any_tcx(f: &F) - where F : for<'tcx> Foo<'tcx> -{ - want_foo_for_some_tcx(f); - want_foo_for_any_tcx(f); -} - -fn want_bar_for_some_ccx<'x,B>(b: &B) - where B : Bar<'x> -{ - want_foo_for_some_tcx(b); - want_foo_for_any_tcx(b); - - want_bar_for_some_ccx(b); - want_bar_for_any_ccx(b); //~ ERROR E0277 -} - -fn want_bar_for_any_ccx(b: &B) - where B : for<'ccx> Bar<'ccx> -{ - want_foo_for_some_tcx(b); - want_foo_for_any_tcx(b); - - want_bar_for_some_ccx(b); - want_bar_for_any_ccx(b); -} - -fn main() {} diff --git a/src/test/compile-fail/hrtb-just-for-static.rs b/src/test/compile-fail/hrtb-just-for-static.rs deleted file mode 100644 index aec950f992cf4..0000000000000 --- a/src/test/compile-fail/hrtb-just-for-static.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test a case where you have an impl of `Foo` for all `X` that -// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. - -trait Foo { - fn foo(&self, x: X) { } -} - -fn want_hrtb() - where T : for<'a> Foo<&'a isize> -{ -} - -// AnyInt implements Foo<&'a isize> for any 'a, so it is a match. -struct AnyInt; -impl<'a> Foo<&'a isize> for AnyInt { } -fn give_any() { - want_hrtb::() -} - -// StaticInt only implements Foo<&'static isize>, so it is an error. -struct StaticInt; -impl Foo<&'static isize> for StaticInt { } -fn give_static() { - want_hrtb::() //~ ERROR `for<'a> StaticInt: Foo<&'a isize>` is not satisfied -} - -fn main() { } diff --git a/src/test/compile-fail/hrtb-perfect-forwarding.rs b/src/test/compile-fail/hrtb-perfect-forwarding.rs deleted file mode 100644 index fcfbeefced06b..0000000000000 --- a/src/test/compile-fail/hrtb-perfect-forwarding.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test a case where you have an impl of `Foo` for all `X` that -// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. - -trait Foo { - fn foo(&mut self, x: X) { } -} - -trait Bar { - fn bar(&mut self, x: X) { } -} - -impl<'a,X,F> Foo for &'a mut F - where F : Foo + Bar -{ -} - -impl<'a,X,F> Bar for &'a mut F - where F : Bar -{ -} - -fn no_hrtb<'b,T>(mut t: T) - where T : Bar<&'b isize> -{ - // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that - // `&mut T : Bar<&'b isize>`. - no_hrtb(&mut t); -} - -fn bar_hrtb(mut t: T) - where T : for<'b> Bar<&'b isize> -{ - // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above - // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an - // example of a "perfect forwarding" impl. - bar_hrtb(&mut t); -} - -fn foo_hrtb_bar_not<'b,T>(mut t: T) - where T : for<'a> Foo<&'a isize> + Bar<&'b isize> -{ - // Not OK -- The forwarding impl for `Foo` requires that `Bar` also - // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a - // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where - // clause only specifies `T : Bar<&'b isize>`. - foo_hrtb_bar_not(&mut t); //~ ERROR `for<'a> T: Bar<&'a isize>` is not satisfied -} - -fn foo_hrtb_bar_hrtb(mut t: T) - where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> -{ - // OK -- now we have `T : for<'b> Bar&'b isize>`. - foo_hrtb_bar_hrtb(&mut t); -} - -fn main() { } diff --git a/src/test/compile-fail/issue-40000.rs b/src/test/compile-fail/issue-40000.rs deleted file mode 100644 index 7daf4bcbaa44b..0000000000000 --- a/src/test/compile-fail/issue-40000.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - let bar: fn(&mut u32) = |_| {}; - - fn foo(x: Box) {} - let bar = Box::new(|x: &i32| {}) as Box; - foo(bar); //~ ERROR mismatched types - //~| expected concrete lifetime, found bound lifetime parameter -} diff --git a/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs b/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs deleted file mode 100644 index e3d96f52e817b..0000000000000 --- a/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a { - // Note: this is legal because of the `'b:'a` declaration. - *x = *y; -} - -fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { - // Illegal now because there is no `'b:'a` declaration. - *x = *y; //~ ERROR E0623 -} - -fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { - // Here we try to call `foo` but do not know that `'a` and `'b` are - // related as required. - a(x, y); //~ ERROR 24:7: 24:8: lifetime mismatch [E0623] -} - -fn d() { - // 'a and 'b are early bound in the function `a` because they appear - // inconstraints: - let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types -} - -fn e() { - // 'a and 'b are late bound in the function `b` because there are - // no constraints: - let _: fn(&mut &isize, &mut &isize) = b; -} - -fn main() { } diff --git a/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs deleted file mode 100644 index d8d12444dddb3..0000000000000 --- a/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where 'b: 'a + 'c { - // Note: this is legal because of the `'b:'a` declaration. - *x = *y; - *z = *y; -} - -fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - // Illegal now because there is no `'b:'a` declaration. - *x = *y; //~ ERROR E0623 - *z = *y; //~ ERROR E0623 -} - -fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - // Here we try to call `foo` but do not know that `'a` and `'b` are - // related as required. - a(x, y, z); //~ ERROR 26:7: 26:8: lifetime mismatch [E0623] -} - -fn d() { - // 'a and 'b are early bound in the function `a` because they appear - // inconstraints: - let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR mismatched types -} - -fn e() { - // 'a and 'b are late bound in the function `b` because there are - // no constraints: - let _: fn(&mut &isize, &mut &isize, &mut &isize) = b; -} - -fn main() { } diff --git a/src/test/compile-fail/regions-fn-subtyping-return-static.rs b/src/test/compile-fail/regions-fn-subtyping-return-static.rs deleted file mode 100644 index 6be65a5e35905..0000000000000 --- a/src/test/compile-fail/regions-fn-subtyping-return-static.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// In this fn, the type `F` is a function that takes a reference to a -// struct and returns another reference with the same lifetime. -// -// Meanwhile, the bare fn `foo` takes a reference to a struct with -// *ANY* lifetime and returns a reference with the 'static lifetime. -// This can safely be considered to be an instance of `F` because all -// lifetimes are sublifetimes of 'static. - -#![allow(dead_code)] -#![allow(unused_variables)] - -struct S; - -// Given 'cx, return 'cx -type F = for<'cx> fn(&'cx S) -> &'cx S; -fn want_F(f: F) { } - -// Given anything, return 'static -type G = for<'cx> fn(&'cx S) -> &'static S; -fn want_G(f: G) { } - -// Should meet both. -fn foo(x: &S) -> &'static S { - panic!() -} - -// Should meet both. -fn bar<'a,'b>(x: &'a S) -> &'b S { - panic!() -} - -// Meets F, but not G. -fn baz(x: &S) -> &S { - panic!() -} - -fn supply_F() { - want_F(foo); - - // FIXME(#33684) -- this should be a subtype, but current alg. rejects it incorrectly - want_F(bar); //~ ERROR E0308 - - want_F(baz); -} - -fn supply_G() { - want_G(foo); - want_G(bar); - want_G(baz); - //~^ ERROR mismatched types - //~| expected type `for<'cx> fn(&'cx S) -> &'static S` - //~| found type `for<'r> fn(&'r S) -> &'r S {baz}` - //~| expected concrete lifetime, found bound lifetime parameter 'cx -} - -pub fn main() { -} diff --git a/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs b/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs deleted file mode 100644 index 5955619ea92ad..0000000000000 --- a/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn a<'a, 'b:'a>(x: &mut &'a isize, y: &mut &'b isize) { - // Note: this is legal because of the `'b:'a` declaration. - *x = *y; -} - -fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { - // Illegal now because there is no `'b:'a` declaration. - *x = *y; //~ ERROR E0623 -} - -fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { - // Here we try to call `foo` but do not know that `'a` and `'b` are - // related as required. - a(x, y); //~ ERROR 24:7: 24:8: lifetime mismatch [E0623] -} - -fn d() { - // 'a and 'b are early bound in the function `a` because they appear - // inconstraints: - let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types -} - -fn e() { - // 'a and 'b are late bound in the function `b` because there are - // no constraints: - let _: fn(&mut &isize, &mut &isize) = b; -} - -fn main() { } diff --git a/src/test/compile-fail/where-for-self-2.rs b/src/test/compile-fail/where-for-self-2.rs deleted file mode 100644 index bf8fc29217338..0000000000000 --- a/src/test/compile-fail/where-for-self-2.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we can quantify lifetimes outside a constraint (i.e., including -// the self type) in a where clause. Specifically, test that implementing for a -// specific lifetime is not enough to satisify the `for<'a> ...` constraint, which -// should require *all* lifetimes. - -static X: &'static u32 = &42; - -trait Bar { - fn bar(&self); -} - -impl Bar for &'static u32 { - fn bar(&self) {} -} - -fn foo(x: &T) - where for<'a> &'a T: Bar -{} - -fn main() { - foo(&X); - //~^ error: `for<'a> &'a _: Bar` is not satisfied -} diff --git a/src/test/ui/generator/auto-trait-regions.rs b/src/test/ui/generator/auto-trait-regions.rs deleted file mode 100644 index ac2a414b742c6..0000000000000 --- a/src/test/ui/generator/auto-trait-regions.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(generators)] -#![feature(optin_builtin_traits)] - -auto trait Foo {} - -struct No; - -impl !Foo for No {} - -struct A<'a, 'b>(&'a mut bool, &'b mut bool, No); - -impl<'a, 'b: 'a> Foo for A<'a, 'b> {} - -struct OnlyFooIfStaticRef(No); -impl Foo for &'static OnlyFooIfStaticRef {} - -struct OnlyFooIfRef(No); -impl<'a> Foo for &'a OnlyFooIfRef {} - -fn assert_foo(f: T) {} - -fn main() { - // Make sure 'static is erased for generator interiors so we can't match it in trait selection - let x: &'static _ = &OnlyFooIfStaticRef(No); - let gen = || { - let x = x; - yield; - assert_foo(x); - }; - assert_foo(gen); //~ ERROR the trait bound `No: Foo` is not satisfied - - // Allow impls which matches any lifetime - let x = &OnlyFooIfRef(No); - let gen = || { - let x = x; - yield; - assert_foo(x); - }; - assert_foo(gen); // ok - - // Disallow impls which relates lifetimes in the generator interior - let gen = || { - let a = A(&mut true, &mut true, No); - yield; - assert_foo(a); - }; - assert_foo(gen); //~ ERROR the requirement `for<'r, 's> 'r : 's` is not satisfied -} diff --git a/src/test/ui/generator/generator-with-nll.rs b/src/test/ui/generator/generator-with-nll.rs deleted file mode 100644 index 3223ff4dc8b59..0000000000000 --- a/src/test/ui/generator/generator-with-nll.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags: -Z borrowck=compare - -#![feature(generators)] -#![feature(nll)] - -fn main() { - || { - // The reference in `_a` is a Legal with NLL since it ends before the yield - let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast) - let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast) - //~^ borrow may still be in use when generator yields (Mir) - yield (); - println!("{}", b); - }; -} diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs deleted file mode 100644 index 566998c374e9e..0000000000000 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - let a = [(1u32, 2u32)]; - a.iter().map(|_: (u32, u32)| 45); //~ ERROR type mismatch - a.iter().map(|_: &(u16, u16)| 45); //~ ERROR type mismatch - a.iter().map(|_: (u16, u16)| 45); //~ ERROR type mismatch -} - -fn baz(_: F) {} -fn _test<'a>(f: fn(*mut &'a u32)) { - baz(f); //~ ERROR type mismatch - //~^ ERROR type mismatch -} diff --git a/src/test/ui/mismatched_types/closure-mismatch.rs b/src/test/ui/mismatched_types/closure-mismatch.rs deleted file mode 100644 index 5a74e8f933de0..0000000000000 --- a/src/test/ui/mismatched_types/closure-mismatch.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait Foo {} - -impl Foo for T {} - -fn baz(_: T) {} - -fn main() { - baz(|_| ()); //~ ERROR type mismatch - //~^ ERROR type mismatch -} diff --git a/src/test/ui/nll/borrow-use-issue-46875.rs b/src/test/ui/nll/borrow-use-issue-46875.rs deleted file mode 100644 index 47d69fe8e976c..0000000000000 --- a/src/test/ui/nll/borrow-use-issue-46875.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(nll)] - -// run-pass - -fn vec() { - let mut _x = vec!['c']; - let _y = &_x; - _x = Vec::new(); -} - -fn int() { - let mut _x = 5; - let _y = &_x; - _x = 7; -} - -fn main() { - vec(); - int(); -} diff --git a/src/test/ui/nll/borrowed-match-issue-45045.rs b/src/test/ui/nll/borrowed-match-issue-45045.rs deleted file mode 100644 index 4b95bbd5a052b..0000000000000 --- a/src/test/ui/nll/borrowed-match-issue-45045.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Regression test for issue #45045 - -#![feature(nll)] - -enum Xyz { - A, - B, -} - -fn main() { - let mut e = Xyz::A; - let f = &mut e; - let g = f; - match e { //~ cannot use `e` because it was mutably borrowed [E0503] - Xyz::A => println!("a"), - //~^ cannot use `e` because it was mutably borrowed [E0503] - Xyz::B => println!("b"), - }; - *g = Xyz::B; -} diff --git a/src/test/ui/nll/borrowed-referent-issue-38899.rs b/src/test/ui/nll/borrowed-referent-issue-38899.rs deleted file mode 100644 index d7c15851418b1..0000000000000 --- a/src/test/ui/nll/borrowed-referent-issue-38899.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Regression test for issue #38899 - -#![feature(nll)] -#![allow(dead_code)] - -pub struct Block<'a> { - current: &'a u8, - unrelated: &'a u8, -} - -fn bump<'a>(mut block: &mut Block<'a>) { - let x = &mut block; - println!("{}", x.current); - let p: &'a u8 = &*block.current; - //~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable - drop(x); - drop(p); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs b/src/test/ui/nll/closure-requirements/escape-argument-callee.rs deleted file mode 100644 index 41c744fec6e76..0000000000000 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test closure that: -// -// - takes an argument `y` with lifetime `'a` (in the code, it's anonymous) -// - stores `y` into another, longer-lived spot with lifetime `'b` -// -// Because `'a` and `'b` are two different, unrelated higher-ranked -// regions with no relationship to one another, this is an error. This -// error is reported by the closure itself and is not propagated to -// its creator: this is because `'a` and `'b` are higher-ranked -// (late-bound) regions and the closure is not allowed to propagate -// additional where clauses between higher-ranked regions, only those -// that appear free in its type (hence, we see it before the closure's -// "external requirements" report). - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -#[rustc_regions] -fn test() { - let x = 44; - let mut p = &x; - - { - let y = 22; - let mut closure = expect_sig(|p, y| *p = y); - //~^ ERROR does not outlive free region - //~| WARNING not reporting region error due to -Znll - closure(&mut p, &y); - } - - deref(p); -} - -fn expect_sig(f: F) -> F - where F: FnMut(&mut &i32, &i32) -{ - f -} - -fn deref(_p: &i32) { } - -fn main() { } diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr deleted file mode 100644 index 5f84001a8fb99..0000000000000 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ /dev/null @@ -1,39 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/escape-argument-callee.rs:36:50 - | -LL | let mut closure = expect_sig(|p, y| *p = y); - | ^ - -error: free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(3))` does not outlive free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(2))` - --> $DIR/escape-argument-callee.rs:36:45 - | -LL | let mut closure = expect_sig(|p, y| *p = y); - | ^^^^^^ - -note: No external requirements - --> $DIR/escape-argument-callee.rs:36:38 - | -LL | let mut closure = expect_sig(|p, y| *p = y); - | ^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) i32)) - ] - -note: No external requirements - --> $DIR/escape-argument-callee.rs:30:1 - | -LL | / fn test() { -LL | | let x = 44; -LL | | let mut p = &x; -LL | | -... | -LL | | deref(p); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:3 ~ escape_argument_callee[317d]::test[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs deleted file mode 100644 index 30a6dfc5b3edd..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test where we fail to approximate due to demanding a postdom -// relationship between our upper bounds. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'x: 'a -// 'x: 'b -// 'c: 'y -// -// we have to prove that `'x: 'y`. We currently can only approximate -// via a postdominator -- hence we fail to choose between `'a` and -// `'b` here and report the error in the closure. -fn establish_relationships<'a, 'b, 'c, F>( - _cell_a: Cell<&'a u32>, - _cell_b: Cell<&'b u32>, - _cell_c: Cell<&'c u32>, - _closure: F, -) where - F: for<'x, 'y> FnMut( - Cell<&'a &'x u32>, // shows that 'x: 'a - Cell<&'b &'x u32>, // shows that 'x: 'b - Cell<&'y &'c u32>, // shows that 'c: 'y - Cell<&'x u32>, - Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { - establish_relationships( - cell_a, - cell_b, - cell_c, - |_outlives1, _outlives2, _outlives3, x, y| { - // Only works if 'x: 'y: - let p = x.get(); - //~^ WARN not reporting region error due to -Znll - //~| ERROR does not outlive free region - demand_y(x, y, p) - }, - ); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr deleted file mode 100644 index 0c058e40a5086..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ /dev/null @@ -1,45 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-approximated-fail-no-postdom.rs:55:21 - | -LL | let p = x.get(); - | ^^^^^^^ - -error: free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(1))` does not outlive free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` - --> $DIR/propagate-approximated-fail-no-postdom.rs:55:17 - | -LL | let p = x.get(); - | ^ - -note: No external requirements - --> $DIR/propagate-approximated-fail-no-postdom.rs:53:9 - | -LL | / |_outlives1, _outlives2, _outlives3, x, y| { -LL | | // Only works if 'x: 'y: -LL | | let p = x.get(); -LL | | //~^ WARN not reporting region error due to -Znll -LL | | //~| ERROR does not outlive free region -LL | | demand_y(x, y, p) -LL | | }, - | |_________^ - | - = note: defining type: DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>)) - ] - -note: No external requirements - --> $DIR/propagate-approximated-fail-no-postdom.rs:48:1 - | -LL | / fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { -LL | | establish_relationships( -LL | | cell_a, -LL | | cell_b, -... | -LL | | ); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs deleted file mode 100644 index 91128035f3d95..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Rather convoluted setup where we infer a relationship between two -// free regions in the closure signature (`'a` and `'b`) on the basis -// of a relationship between two bound regions (`'x` and `'y`). -// -// The idea is that, thanks to invoking `demand_y`, `'x: 'y` must -// hold, where `'x` and `'y` are bound regions. The closure can't -// prove that directly, and because `'x` and `'y` are bound it cannot -// ask the caller to prove it either. But it has bounds on `'x` and -// `'y` in terms of `'a` and `'b`, and it can propagate a relationship -// between `'a` and `'b` to the caller. -// -// Note: the use of `Cell` here is to introduce invariance. One less -// variable. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'x: 'a -// 'b: 'y -// -// so if we are going to ensure that `'x: 'y`, then `'a: 'b` must -// hold. -fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) -where - F: for<'x, 'y> FnMut( - &Cell<&'a &'x u32>, // shows that 'x: 'a - &Cell<&'y &'b u32>, // shows that 'b: 'y - &Cell<&'x u32>, - &Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - //~^ ERROR lifetime mismatch - - // Only works if 'x: 'y: - demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll - }); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs deleted file mode 100644 index f210346a82a67..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test a case where we setup relationships like `'x: 'a` or `'a: 'x`, -// where `'x` is bound in closure type but `'a` is free. This forces -// us to approximate `'x` one way or the other. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -fn foo<'a, F>(_cell: Cell<&'a u32>, _f: F) -where - F: for<'x> FnOnce(Cell<&'a u32>, Cell<&'x u32>), -{ -} - -#[rustc_regions] -fn case1() { - let a = 0; - let cell = Cell::new(&a); - foo(cell, |cell_a, cell_x| { - //~^ WARNING not reporting region error due to -Znll - cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure - //~^ ERROR does not outlive free region - }) -} - -#[rustc_regions] -fn case2() { - let a = 0; - let cell = Cell::new(&a); - //~^ ERROR `a` does not live long enough - - // As you can see in the stderr output, this closure propoagates a - // requirement that `'a: 'static'. - foo(cell, |cell_a, cell_x| { - cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> borrow error - }) -} - -fn main() { } diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs deleted file mode 100644 index c66472d5ce9b1..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test a case where we are trying to prove `'x: 'y` and are forced to -// approximate the shorter end-point (`'y`) to with `'static`. This is -// because `'y` is higher-ranked but we know of no relations to other -// regions. Note that `'static` shows up in the stderr output as `'0`. -// -// FIXME(#45827) Because of shortcomings in the MIR type checker, -// these errors are not (yet) reported. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'x: 'a -// -// so the only way we can ensure that `'x: 'y` is to show that -// `'a: 'static`. -fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) -where - F: for<'x, 'y> FnMut( - &Cell<&'a &'x u32>, // shows that 'x: 'a - &Cell<&'x u32>, - &Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - //~^ ERROR does not outlive free region - - // Only works if 'x: 'y: - demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll - }); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr deleted file mode 100644 index 3131142ec73bf..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ /dev/null @@ -1,53 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:49:9 - | -LL | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll - | ^^^^^^^^^^^^^^^^^^^^^^^ - -note: External requirements - --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:47 - | -LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | _______________________________________________^ -LL | | //~^ ERROR does not outlive free region -LL | | -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll -LL | | }); - | |_____^ - | - = note: defining type: DefId(0/1:18 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) u32>)) - ] - = note: number of external vids: 2 - = note: where '_#1r: '_#0r - -error: free region `ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a))` does not outlive free region `ReStatic` - --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:47 - | -LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | _______________________________________________^ -LL | | //~^ ERROR does not outlive free region -LL | | -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll -LL | | }); - | |_____^ - -note: No external requirements - --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1 - | -LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { -LL | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { -LL | | //~^ ERROR does not outlive free region -LL | | -... | -LL | | }); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs deleted file mode 100644 index f4011a0e5335e..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test a case where we are trying to prove `'x: 'y` and are forced to -// approximate the shorter end-point (`'y`) to with `'static`. This is -// because `'y` is higher-ranked but we know of only irrelevant -// relations to other regions. Note that `'static` shows up in the -// stderr output as `'0`. -// -// FIXME(#45827) Because of shortcomings in the MIR type checker, -// these errors are not (yet) reported. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'x: 'a -// 'y: 'b -// -// so the only way we can ensure that `'x: 'y` is to show that -// `'a: 'static`. -fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) -where - F: for<'x, 'y> FnMut( - &Cell<&'a &'x u32>, // shows that 'x: 'a - &Cell<&'b &'y u32>, // shows that 'y: 'b - &Cell<&'x u32>, - &Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - //~^ ERROR does not outlive free region - // Only works if 'x: 'y: - demand_y(x, y, x.get()) - //~^ WARNING not reporting region error due to -Znll - }); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr deleted file mode 100644 index 5b038653b6068..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ /dev/null @@ -1,53 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:51:9 - | -LL | demand_y(x, y, x.get()) - | ^^^^^^^^^^^^^^^^^^^^^^^ - -note: External requirements - --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:47 - | -LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | _______________________________________________^ -LL | | //~^ ERROR does not outlive free region -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -LL | | //~^ WARNING not reporting region error due to -Znll -LL | | }); - | |_____^ - | - = note: defining type: DefId(0/1:18 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>)) - ] - = note: number of external vids: 3 - = note: where '_#1r: '_#0r - -error: free region `ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a))` does not outlive free region `ReStatic` - --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:47 - | -LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | _______________________________________________^ -LL | | //~^ ERROR does not outlive free region -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -LL | | //~^ WARNING not reporting region error due to -Znll -LL | | }); - | |_____^ - -note: No external requirements - --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1 - | -LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { -LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { -LL | | //~^ ERROR does not outlive free region -LL | | // Only works if 'x: 'y: -... | -LL | | }); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs deleted file mode 100644 index d163f304ae5b1..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// A simpler variant of `outlives-from-argument` where cells are -// passed by value. -// -// This is simpler because there are no "extraneous" region -// relationships. In the 'main' variant, there are a number of -// anonymous regions as well. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'x: 'a -// 'b: 'y -// -// so if we are going to ensure that `'x: 'y`, then `'a: 'b` must -// hold. -fn establish_relationships<'a, 'b, F>(_cell_a: Cell<&'a u32>, _cell_b: Cell<&'b u32>, _closure: F) -where - F: for<'x, 'y> FnMut( - Cell<&'a &'x u32>, // shows that 'x: 'a - Cell<&'y &'b u32>, // shows that 'b: 'y - Cell<&'x u32>, - Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_outlives1: Cell<&&'x u32>, _outlives2: Cell<&'y &u32>, _y: &'y u32) {} - -#[rustc_regions] -fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { - //~^ ERROR lifetime mismatch - - // Only works if 'x: 'y: - demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to -Znll - }); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs deleted file mode 100644 index ba4c287592eb4..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test where we might in theory be able to see that the relationship -// between two bound regions is true within closure and hence have no -// need to propagate; but in fact we do because identity of free -// regions is erased. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose -// must-compile-successfully - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// In theory, callee knows that: -// -// 'x: 'a -// 'a: 'y -// -// and hence could satisfy that `'x: 'y` locally. However, in our -// checking, we ignore the precise free regions that come into the -// region and just assign each position a distinct universally bound -// region. Hence, we propagate a constraint to our caller that will -// wind up being solvable. -fn establish_relationships<'a, F>( - _cell_a: Cell<&'a u32>, - _closure: F, -) where - F: for<'x, 'y> FnMut( - Cell<&'a &'x u32>, // shows that 'x: 'a - Cell<&'y &'a u32>, // shows that 'a: 'y - Cell<&'x u32>, - Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a>(cell_a: Cell<&'a u32>) { - establish_relationships( - cell_a, - |_outlives1, _outlives2, x, y| { - // Only works if 'x: 'y: - let p = x.get(); - demand_y(x, y, p) - }, - ); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr deleted file mode 100644 index ab4faaca75633..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ /dev/null @@ -1,37 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-despite-same-free-region.rs:54:21 - | -LL | let p = x.get(); - | ^^^^^^^ - -note: External requirements - --> $DIR/propagate-despite-same-free-region.rs:52:9 - | -LL | / |_outlives1, _outlives2, x, y| { -LL | | // Only works if 'x: 'y: -LL | | let p = x.get(); -LL | | demand_y(x, y, p) -LL | | }, - | |_________^ - | - = note: defining type: DefId(0/1:16 ~ propagate_despite_same_free_region[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>)) - ] - = note: number of external vids: 3 - = note: where '_#1r: '_#2r - -note: No external requirements - --> $DIR/propagate-despite-same-free-region.rs:49:1 - | -LL | / fn supply<'a>(cell_a: Cell<&'a u32>) { -LL | | establish_relationships( -LL | | cell_a, -LL | | |_outlives1, _outlives2, x, y| { -... | -LL | | ); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_despite_same_free_region[317d]::supply[0]) with substs [] - diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs deleted file mode 100644 index eb512a3b9b1fb..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Similarly to escape-argument-callee, a test case where the closure -// requires a relationship between 2 unrelated higher-ranked regions, -// with no helpful relations between the HRRs and free regions. -// -// In this case, the error is reported by the closure itself. This is -// because it is unable to approximate the higher-ranked region `'x`, -// as it knows of no relationships between `'x` and any -// non-higher-ranked regions. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'b: 'y -// -// but this doesn't really help us in proving that `'x: 'y`, so closure gets an error. -fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) -where - F: for<'x, 'y> FnMut( - &Cell<&'y &'b u32>, // shows that 'b: 'y - &Cell<&'x u32>, - &Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - // Only works if 'x: 'y: - demand_y(x, y, x.get()) - //~^ WARN not reporting region error due to -Znll - //~| ERROR does not outlive free region - }); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr deleted file mode 100644 index ce808f56b4297..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ /dev/null @@ -1,45 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9 - | -LL | demand_y(x, y, x.get()) - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(4))` does not outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` - --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:18 - | -LL | demand_y(x, y, x.get()) - | ^ - -note: No external requirements - --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47 - | -LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | _______________________________________________^ -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -LL | | //~^ WARN not reporting region error due to -Znll -LL | | //~| ERROR does not outlive free region -LL | | }); - | |_____^ - | - = note: defining type: DefId(0/1:18 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>)) - ] - -note: No external requirements - --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:44:1 - | -LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { -LL | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -... | -LL | | }); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs deleted file mode 100644 index 9307424642972..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Similarly to escape-argument-callee, a test case where the closure -// requires a relationship between 2 unrelated higher-ranked regions, -// with no helpful relations between the HRRs and free regions. -// -// In this case, the error is reported by the closure itself. This is -// because it is unable to approximate the higher-ranked region `'x`, -// as it only knows of regions that `'x` is outlived by, and none that -// `'x` outlives. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'a: 'x -// 'b: 'y -// -// but this doesn't really help us in proving that `'x: 'y`, so -// closure gets an error. In particular, we would need to know that -// `'x: 'a`, so that we could approximate `'x` "downwards" to `'a`. -fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) -where - F: for<'x, 'y> FnMut( - &Cell<&'x &'a u32>, // shows that 'a: 'x - &Cell<&'y &'b u32>, // shows that 'b: 'y - &Cell<&'x u32>, - &Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - // Only works if 'x: 'y: - demand_y(x, y, x.get()) - //~^ WARN not reporting region error due to -Znll - //~| ERROR does not outlive free region - }); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr deleted file mode 100644 index 547ff75bac62c..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ /dev/null @@ -1,45 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9 - | -LL | demand_y(x, y, x.get()) - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(4))` - --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:18 - | -LL | demand_y(x, y, x.get()) - | ^ - -note: No external requirements - --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47 - | -LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | _______________________________________________^ -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -LL | | //~^ WARN not reporting region error due to -Znll -LL | | //~| ERROR does not outlive free region -LL | | }); - | |_____^ - | - = note: defining type: DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>)) - ] - -note: No external requirements - --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:48:1 - | -LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { -LL | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { -LL | | // Only works if 'x: 'y: -LL | | demand_y(x, y, x.get()) -... | -LL | | }); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs deleted file mode 100644 index 91796355752a5..0000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that regions which appear only in the closure's generics (in -// this case, `'a`) are properly mapped to the creator's generics. In -// this case, the closure constrains its type parameter `T` to outlive -// the same `'a` for which it implements `Trait`, which can only be the `'a` -// from the function definition. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] -#![allow(dead_code)] - -trait Trait<'a> {} - -fn establish_relationships(value: T, closure: F) -where - F: FnOnce(T), -{ - closure(value) -} - -fn require<'a, T>(t: T) -where - T: Trait<'a> + 'a, -{ -} - -#[rustc_regions] -fn supply<'a, T>(value: T) -where - T: Trait<'a>, -{ - establish_relationships(value, |value| { - //~^ ERROR the parameter type `T` may not live long enough - - // This function call requires that - // - // (a) T: Trait<'a> - // - // and - // - // (b) T: 'a - // - // The latter does not hold. - - require(value); - //~^ WARNING not reporting region error due to -Znll - }); -} - -fn main() {} diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs deleted file mode 100644 index ac21fe25bd112..0000000000000 --- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Basic test for free regions in the NLL code. This test ought to -// report an error due to a reborrowing constraint. Right now, we get -// a variety of errors from the older, AST-based machinery (notably -// borrowck), and then we get the NLL error at the end. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -fn foo(x: &u32) -> &'static u32 { - &*x - //~^ WARN not reporting region error due to -Znll - //~| ERROR explicit lifetime required in the type of `x` -} - -fn main() { } diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs deleted file mode 100644 index a1be8e8518515..0000000000000 --- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Basic test for free regions in the NLL code. This test ought to -// report an error due to a reborrowing constraint. Right now, we get -// a variety of errors from the older, AST-based machinery (notably -// borrowck), and then we get the NLL error at the end. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -fn foo<'a>(x: &'a u32) -> &'static u32 { - &*x - //~^ WARN not reporting region error due to -Znll - //~| ERROR does not outlive free region -} - -fn main() { } diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr deleted file mode 100644 index ac3bf4b459fec..0000000000000 --- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr +++ /dev/null @@ -1,14 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5 - | -LL | &*x - | ^^^ - -error: free region `ReFree(DefId(0/0:3 ~ region_lbr_named_does_not_outlive_static[317d]::foo[0]), BrNamed(crate0:DefIndex(1:9), 'a))` does not outlive free region `ReStatic` - --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5 - | -LL | &*x - | ^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs deleted file mode 100644 index 00b09e2ab21ad..0000000000000 --- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Basic test for free regions in the NLL code. This test ought to -// report an error due to a reborrowing constraint. Right now, we get -// a variety of errors from the older, AST-based machinery (notably -// borrowck), and then we get the NLL error at the end. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { - &*x - //~^ WARN not reporting region error due to -Znll - //~| ERROR lifetime mismatch -} - -fn main() { } diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs b/src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs deleted file mode 100644 index ffb1935e75e32..0000000000000 --- a/src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Basic test for free regions in the NLL code. This test does not -// report an error because of the (implied) bound that `'b: 'a`. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose -// must-compile-successfully - -#![allow(warnings)] - -fn foo<'a, 'b>(x: &'a &'b u32) -> &'a u32 { - &**x -} - -fn main() { } diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs deleted file mode 100644 index 754df4f2c5db6..0000000000000 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test closure that takes two references and is supposed to return -// the first, but actually returns the second. This should fail within -// the closure. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![feature(rustc_attrs)] - -#[rustc_regions] -fn test() { - expect_sig(|a, b| b); // ought to return `a` - //~^ WARN not reporting region error due to -Znll - //~| ERROR does not outlive free region -} - -fn expect_sig(f: F) -> F - where F: for<'a> FnMut(&'a i32, &i32) -> &'a i32 -{ - f -} - -fn deref(_p: &i32) { } - -fn main() { } diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr deleted file mode 100644 index b34f4c470df49..0000000000000 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ /dev/null @@ -1,37 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/return-wrong-bound-region.rs:21:23 - | -LL | expect_sig(|a, b| b); // ought to return `a` - | ^ - -error: free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(1))` - --> $DIR/return-wrong-bound-region.rs:21:23 - | -LL | expect_sig(|a, b| b); // ought to return `a` - | ^ - -note: No external requirements - --> $DIR/return-wrong-bound-region.rs:21:16 - | -LL | expect_sig(|a, b| b); // ought to return `a` - | ^^^^^^^^ - | - = note: defining type: DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) i32)) -> &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) i32 - ] - -note: No external requirements - --> $DIR/return-wrong-bound-region.rs:20:1 - | -LL | / fn test() { -LL | | expect_sig(|a, b| b); // ought to return `a` -LL | | //~^ WARN not reporting region error due to -Znll -LL | | //~| ERROR does not outlive free region -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:3 ~ return_wrong_bound_region[317d]::test[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/nll/constant.rs b/src/test/ui/nll/constant.rs deleted file mode 100644 index ced06e5ea0504..0000000000000 --- a/src/test/ui/nll/constant.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that MIR borrowck and NLL analysis can handle constants of -// arbitrary types without ICEs. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose -// must-compile-successfully - -const HI: &str = "hi"; - -fn main() { - assert_eq!(HI, "hi"); -} diff --git a/src/test/ui/nll/drop-may-dangle.rs b/src/test/ui/nll/drop-may-dangle.rs deleted file mode 100644 index 2780b34746378..0000000000000 --- a/src/test/ui/nll/drop-may-dangle.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Basic test for liveness constraints: the region (`R1`) that appears -// in the type of `p` includes the points after `&v[0]` up to (but not -// including) the call to `use_x`. The `else` branch is not included. - -// compile-flags:-Znll -Zborrowck=mir -// must-compile-successfully - -#![allow(warnings)] -#![feature(dropck_eyepatch)] -#![feature(generic_param_attrs)] - -fn use_x(_: usize) -> bool { true } - -fn main() { - let mut v = [1, 2, 3]; - let p: WrapMayDangle<& /* R4 */ usize> = WrapMayDangle { value: &v[0] }; - if true { - // `p` will get dropped at end of this block. However, because of - // the `#[may_dangle]` attribute, we do not need to consider R4 - // live after this point. - use_x(*p.value); - } else { - v[0] += 1; - use_x(22); - } - - v[0] += 1; -} - -struct WrapMayDangle { - value: T -} - -unsafe impl<#[may_dangle] T> Drop for WrapMayDangle { - fn drop(&mut self) { } -} diff --git a/src/test/ui/nll/drop-may-dangle.stderr b/src/test/ui/nll/drop-may-dangle.stderr deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/src/test/ui/nll/generator-distinct-lifetime.rs b/src/test/ui/nll/generator-distinct-lifetime.rs deleted file mode 100644 index 60f67b1766c2c..0000000000000 --- a/src/test/ui/nll/generator-distinct-lifetime.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(generators, nll)] - -// Test for issue #47189. Here, both `s` and `t` are live for the -// generator's lifetime, but within the generator they have distinct -// lifetimes. We accept this code -- even though the borrow extends -// over a yield -- because the data that is borrowed (`*x`) is not -// stored on the stack. - -// must-compile-successfully - -fn foo(x: &mut u32) { - move || { - let s = &mut *x; - yield; - *s += 1; - - let t = &mut *x; - yield; - *t += 1; - }; -} - -fn main() { - foo(&mut 0); -} diff --git a/src/test/ui/nll/guarantor-issue-46974.rs b/src/test/ui/nll/guarantor-issue-46974.rs deleted file mode 100644 index 09ce42ce1b551..0000000000000 --- a/src/test/ui/nll/guarantor-issue-46974.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that NLL analysis propagates lifetimes correctly through -// field accesses, Box accesses, etc. - -#![feature(nll)] - -fn foo(s: &mut (i32,)) -> i32 { - let t = &mut *s; // this borrow should last for the entire function - let x = &t.0; - *s = (2,); //~ ERROR cannot assign to `*s` - *x -} - -fn bar(s: &Box<(i32,)>) -> &'static i32 { - // FIXME(#46983): error message should be better - &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621] -} - -fn main() { - foo(&mut (0,)); - bar(&Box::new((1,))); -} diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs deleted file mode 100644 index a7362c34c1751..0000000000000 --- a/src/test/ui/nll/issue-47022.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// must-compile-successfully - -#![allow(warnings)] -#![feature(nll)] - -struct LoadedObject { - bodies: Vec, - color: Color, -} - -struct Body; - -#[derive(Clone)] -struct Color; - -struct Graphic { - color: Color, -} - -fn convert(objects: Vec) -> (Vec, Vec) { - objects - .into_iter() - .flat_map(|LoadedObject { bodies, color, .. }| { - bodies.into_iter().map(move |body| { - ( - body, - Graphic { - color: color.clone(), - }, - ) - }) - }) - .unzip() -} - -fn main() {} - diff --git a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs deleted file mode 100644 index 92b29a98c1c49..0000000000000 --- a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//compile-flags: -Z emit-end-regions -Zborrowck=mir -Z nll -// must-compile-successfully - -#![allow(warnings)] - -struct Wrap<'p> { p: &'p mut i32 } - -impl<'p> Drop for Wrap<'p> { - fn drop(&mut self) { - *self.p += 1; - } -} - -fn main() { - let mut x = 0; - let wrap = Wrap { p: &mut x }; - std::mem::drop(wrap); - x = 1; // OK, drop is inert -} diff --git a/src/test/ui/nll/maybe-initialized-drop-uninitialized.stderr b/src/test/ui/nll/maybe-initialized-drop-uninitialized.stderr deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/src/test/ui/nll/projection-return.rs b/src/test/ui/nll/projection-return.rs deleted file mode 100644 index 31388cf50c558..0000000000000 --- a/src/test/ui/nll/projection-return.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -// must-compile-successfully - -#![feature(rustc_attrs)] - -trait Foo { - type Bar; -} - -impl Foo for () { - type Bar = u32; -} - -fn foo() -> <() as Foo>::Bar { - 22 -} - -fn main() { } - diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.rs b/src/test/ui/nll/return-ref-mut-issue-46557.rs deleted file mode 100644 index 79150f340cad8..0000000000000 --- a/src/test/ui/nll/return-ref-mut-issue-46557.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Regression test for issue #46557 - -#![feature(nll)] -#![allow(dead_code)] - -fn gimme_static_mut() -> &'static mut u32 { - let ref mut x = 1234543; //~ ERROR borrowed value does not live long enough [E0597] - x -} - -fn main() {} diff --git a/src/test/ui/nll/trait-associated-constant.rs b/src/test/ui/nll/trait-associated-constant.rs deleted file mode 100644 index b0f5fbf7160d1..0000000000000 --- a/src/test/ui/nll/trait-associated-constant.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test cases where we put various lifetime constraints on trait -// associated constants. - -#![feature(rustc_attrs)] - -use std::option::Option; - -trait Anything<'a: 'b, 'b> { - const AC: Option<&'b str>; -} - -struct OKStruct { } - -impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct { - const AC: Option<&'b str> = None; -} - -struct FailStruct1 { } - -impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 { - const AC: Option<&'c str> = None; - //~^ ERROR: mismatched types -} - -struct FailStruct2 { } - -impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { - const AC: Option<&'a str> = None; - //~^ ERROR: mismatched types -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs deleted file mode 100644 index 850cd1e7336d7..0000000000000 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(conservative_impl_trait)] - -trait Foo<'a> { -} - -impl<'a, T> Foo<'a> for T { } - -fn foo<'a, T>(x: &T) -> impl Foo<'a> { - x - //~^ WARNING not reporting region error due to -Znll - //~| ERROR explicit lifetime required in the type of `x` [E0621] -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs deleted file mode 100644 index 135805a733944..0000000000000 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(conservative_impl_trait)] - -use std::fmt::Debug; - -fn no_region<'a, T>(x: Box) -> impl Debug + 'a - //~^ WARNING not reporting region error due to -Znll -where - T: Debug, -{ - x - //~^ ERROR the parameter type `T` may not live long enough [E0309] -} - -fn correct_region<'a, T>(x: Box) -> impl Debug + 'a -where - T: 'a + Debug, -{ - x -} - -fn wrong_region<'a, 'b, T>(x: Box) -> impl Debug + 'a - //~^ WARNING not reporting region error due to -Znll -where - T: 'b + Debug, -{ - x - //~^ ERROR the parameter type `T` may not live long enough [E0309] -} - -fn outlives_region<'a, 'b, T>(x: Box) -> impl Debug + 'a -where - T: 'b + Debug, - 'b: 'a, -{ - x -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs b/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs deleted file mode 100644 index 0ec6d7b74ad5a..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -// Test that we can deduce when projections like `T::Item` outlive the -// function body. Test that this does not imply that `T: 'a` holds. - -#![allow(warnings)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -fn twice(mut value: T, mut f: F) -where - F: FnMut(&T, Cell<&Option>), - T: Iterator, -{ - let mut n = value.next(); - f(&value, Cell::new(&n)); - f(&value, Cell::new(&n)); -} - -#[rustc_errors] -fn generic1(value: T) { - // No error here: - twice(value, |value_ref, item| invoke1(item)); -} - -fn invoke1<'a, T>(x: Cell<&'a Option>) -where - T: 'a, -{ -} - -#[rustc_errors] -fn generic2(value: T) { - twice(value, |value_ref, item| invoke2(value_ref, item)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the parameter type `T` may not live long enough -} - -fn invoke2<'a, T, U>(a: &T, b: Cell<&'a Option>) -where - T: 'a, -{ -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs deleted file mode 100644 index 0493bd1ea0d9c..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -// Tests closures that propagate an outlives relationship to their -// creator where the subject is a projection with no regions (`::Item`, to be exact). - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -trait Anything { } - -impl Anything for T { } - -fn with_signature<'a, T, F>(x: Box, op: F) -> Box - where F: FnOnce(Box) -> Box -{ - op(x) -} - -#[rustc_regions] -fn no_region<'a, T>(x: Box) -> Box -where - T: Iterator, -{ - with_signature(x, |mut y| Box::new(y.next())) - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the associated type `::Item` may not live long enough -} - -#[rustc_regions] -fn correct_region<'a, T>(x: Box) -> Box -where - T: 'a + Iterator, -{ - with_signature(x, |mut y| Box::new(y.next())) -} - -#[rustc_regions] -fn wrong_region<'a, 'b, T>(x: Box) -> Box -where - T: 'b + Iterator, -{ - with_signature(x, |mut y| Box::new(y.next())) - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the associated type `::Item` may not live long enough -} - -#[rustc_regions] -fn outlives_region<'a, 'b, T>(x: Box) -> Box -where - T: 'b + Iterator, - 'b: 'a, -{ - with_signature(x, |mut y| Box::new(y.next())) -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs deleted file mode 100644 index 5f2e84e247a3c..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(dyn_trait)] - -trait Anything { } - -impl Anything for T { } - -fn no_region<'a, T>(mut x: T) -> Box -where - T: Iterator, -{ - Box::new(x.next()) - //~^ WARNING not reporting region error due to -Znll - //~| the associated type `::Item` may not live long enough -} - -fn correct_region<'a, T>(mut x: T) -> Box -where - T: 'a + Iterator, -{ - Box::new(x.next()) -} - -fn wrong_region<'a, 'b, T>(mut x: T) -> Box -where - T: 'b + Iterator, -{ - Box::new(x.next()) - //~^ WARNING not reporting region error due to -Znll - //~| the associated type `::Item` may not live long enough -} - -fn outlives_region<'a, 'b, T>(mut x: T) -> Box -where - T: 'b + Iterator, - 'b: 'a, -{ - Box::new(x.next()) -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs deleted file mode 100644 index 9a5e04deddfc9..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test cases where we constrain `>::AssocType` to -// outlive `'a` and there are no bounds in the trait definition of -// `Anything`. This means that the constraint can only be satisfied in two -// ways: -// -// - by ensuring that `T: 'a` and `'b: 'a`, or -// - by something in the where clauses. -// -// As of this writing, the where clause option does not work because -// of limitations in our region inferencing system (this is true both -// with and without NLL). See `projection_outlives`. -// -// Ensuring that both `T: 'a` and `'b: 'a` holds does work (`elements_outlive`). - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -trait Anything<'a> { - type AssocType; -} - -fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) -where - F: FnOnce(Cell<&'a ()>, T), -{ - op(cell, t) -} - -fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T) -where - T: Anything<'b>, - T::AssocType: 'a, -{ -} - -#[rustc_regions] -fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, -{ - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR does not outlive free region -} - -#[rustc_regions] -fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - 'a: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR does not outlive free region -} - -#[rustc_regions] -fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - T::AssocType: 'a, -{ - // This error is unfortunate. This code ought to type-check: we - // are projecting `>::AssocType`, and we know - // that this outlives `'a` because of the where-clause. However, - // the way the region checker works, we don't register this - // outlives obligation, and hence we get an error: this is because - // what we see is a projection like `>::AssocType`, and we don't yet know if `?0` will - // equal `'b` or not, so we ignore the where-clause. Obviously we - // can do better here with a more involved verification step. - - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` -} - -#[rustc_regions] -fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - T: 'a, - 'b: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs deleted file mode 100644 index 232025b57355c..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test cases where we constrain `>::AssocType` to -// outlive `'a` and there is a unique bound in the trait definition of -// `Anything` -- i.e., we know that `AssocType` outlives `'b`. In this -// case, the best way to satisfy the trait bound is to show that `'b: -// 'a`, which can be done in various ways. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -trait Anything<'a> { - type AssocType: 'a; -} - -fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) -where - F: FnOnce(Cell<&'a ()>, T), -{ - op(cell, t) -} - -fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T) -where - T: Anything<'b>, - T::AssocType: 'a, -{ -} - -#[rustc_regions] -fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, -{ - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR does not outlive free region -} - -#[rustc_regions] -fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - 'a: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR does not outlive free region -} - -#[rustc_regions] -fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - T::AssocType: 'a, -{ - // This error is unfortunate. This code ought to type-check: we - // are projecting `>::AssocType`, and we know - // that this outlives `'a` because of the where-clause. However, - // the way the region checker works, we don't register this - // outlives obligation, and hence we get an error: this is because - // what we see is a projection like `>::AssocType`, and we don't yet know if `?0` will - // equal `'b` or not, so we ignore the where-clause. Obviously we - // can do better here with a more involved verification step. - - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR does not outlive free region -} - -#[rustc_regions] -fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - 'b: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'a>, -{ - // Note that in this case the closure still propagates an external - // requirement between two variables in its signature, but the - // creator maps both those two region variables to `'a` on its - // side. - with_signature(cell, t, |cell, t| require(cell, t)); -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr deleted file mode 100644 index 7a8010ad8e0ea..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ /dev/null @@ -1,204 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/projection-one-region-trait-bound-closure.rs:48:39 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^ - -warning: not reporting region error due to -Znll - --> $DIR/projection-one-region-trait-bound-closure.rs:59:39 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^ - -warning: not reporting region error due to -Znll - --> $DIR/projection-one-region-trait-bound-closure.rs:80:39 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^ - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:48:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:19 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - = note: number of external vids: 3 - = note: where '_#1r: '_#2r - -error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))` - --> $DIR/projection-one-region-trait-bound-closure.rs:48:20 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^ - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:44:1 - | -LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | { -... | -LL | | //~| ERROR does not outlive free region -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [ - '_#1r, - T - ] - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:59:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where '_#2r: '_#3r - -error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` - --> $DIR/projection-one-region-trait-bound-closure.rs:59:20 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^ - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:54:1 - | -LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | 'a: 'a, -... | -LL | | //~| ERROR does not outlive free region -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:9 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [ - '_#1r, - '_#2r, - T - ] - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:80:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where '_#2r: '_#3r - -error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` - --> $DIR/projection-one-region-trait-bound-closure.rs:80:20 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^ - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:65:1 - | -LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | T::AssocType: 'a, -... | -LL | | //~| ERROR does not outlive free region -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:10 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [ - '_#1r, - '_#2r, - T - ] - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:91:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where '_#2r: '_#3r - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:86:1 - | -LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | 'b: 'a, -LL | | { -LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:11 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]) with substs [ - '_#1r, - '_#2r, - T - ] - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:103:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - = note: number of external vids: 3 - = note: where '_#1r: '_#2r - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:95:1 - | -LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'a>, -LL | | { -... | -LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:12 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]) with substs [ - '_#1r, - T - ] - -error: aborting due to 3 previous errors - diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs deleted file mode 100644 index 67e28af11469d..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test cases where we constrain `>::AssocType` to -// outlive `'static`. In this case, we don't get any errors, and in fact -// we don't even propagate constraints from the closures to the callers. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose -// must-compile-successfully - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -trait Anything<'a> { - type AssocType: 'static; -} - -fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) -where - F: FnOnce(Cell<&'a ()>, T), -{ - op(cell, t) -} - -fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T) -where - T: Anything<'b>, - T::AssocType: 'a, -{ -} - -#[rustc_regions] -fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - 'a: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - T::AssocType: 'a, -{ - // This error is unfortunate. This code ought to type-check: we - // are projecting `>::AssocType`, and we know - // that this outlives `'a` because of the where-clause. However, - // the way the region checker works, we don't register this - // outlives obligation, and hence we get an error: this is because - // what we see is a projection like `>::AssocType`, and we don't yet know if `?0` will - // equal `'b` or not, so we ignore the where-clause. Obviously we - // can do better here with a more involved verification step. - - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b>, - 'b: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'a>, -{ - // Note that in this case the closure still propagates an external - // requirement between two variables in its signature, but the - // creator maps both those two region variables to `'a` on its - // side. - with_signature(cell, t, |cell, t| require(cell, t)); -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr deleted file mode 100644 index 875907e6b39d5..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr +++ /dev/null @@ -1,155 +0,0 @@ -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:47:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:19 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:43:1 - | -LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | { -LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [ - '_#1r, - T - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:56:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:51:1 - | -LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | 'a: 'a, -LL | | { -LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:9 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]) with substs [ - '_#1r, - '_#2r, - T - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:75:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:60:1 - | -LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | T::AssocType: 'a, -... | -LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:10 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]) with substs [ - '_#1r, - '_#2r, - T - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:84:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:79:1 - | -LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'b>, -LL | | 'b: 'a, -LL | | { -LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:11 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]) with substs [ - '_#1r, - '_#2r, - T - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:96:29 - | -LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:88:1 - | -LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) -LL | | where -LL | | T: Anything<'a>, -LL | | { -... | -LL | | with_signature(cell, t, |cell, t| require(cell, t)); -LL | | } - | |_^ - | - = note: defining type: DefId(0/0:12 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]) with substs [ - '_#1r, - T - ] - diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs deleted file mode 100644 index e3cee00ed4eb3..0000000000000 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test cases where we constrain `>::AssocType` -// to outlive `'a` and there are two bounds in the trait definition of -// `Anything` -- i.e., we know that `AssocType` outlives `'a` and -// `'b`. In this case, it's not clear what is the best way to satisfy -// the trait bound, and hence we propagate it to the caller as a type -// test. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -trait Anything<'a, 'b> { - type AssocType: 'a + 'b; -} - -fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) -where - F: FnOnce(Cell<&'a ()>, T), -{ - op(cell, t) -} - -fn require<'a, 'b, 'c, T>(_cell: Cell<&'a ()>, _t: T) -where - T: Anything<'b, 'c>, - T::AssocType: 'a, -{ -} - -#[rustc_regions] -fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b, 'c>, -{ - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR associated type `>::AssocType` may not live long enough -} - -#[rustc_regions] -fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b, 'c>, - 'a: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR associated type `>::AssocType` may not live long enough -} - -#[rustc_regions] -fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b, 'c>, - T::AssocType: 'a, -{ - // This error is unfortunate. This code ought to type-check: we - // are projecting `>::AssocType`, and we know - // that this outlives `'a` because of the where-clause. However, - // the way the region checker works, we don't register this - // outlives obligation, and hence we get an error: this is because - // what we see is a projection like `>::AssocType`, and we don't yet know if `?0` will - // equal `'b` or not, so we ignore the where-clause. Obviously we - // can do better here with a more involved verification step. - - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR associated type `>::AssocType` may not live long enough -} - -#[rustc_regions] -fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b, 'c>, - 'b: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b, 'c>, - 'c: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b, 'b>, -{ - with_signature(cell, t, |cell, t| require(cell, t)); - //~^ WARNING not reporting region error due to -Znll - //~| ERROR does not outlive free region -} - -#[rustc_regions] -fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'b, 'b>, - 'b: 'a, -{ - with_signature(cell, t, |cell, t| require(cell, t)); -} - -#[rustc_regions] -fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) -where - T: Anything<'a, 'a>, -{ - // Note that in this case the closure still propagates an external - // requirement between two variables in its signature, but the - // creator maps both those two region variables to `'a` on its - // side. - with_signature(cell, t, |cell, t| require(cell, t)); -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs deleted file mode 100644 index 423747a6bd6cb..0000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Invoke in such a way that the callee knows: -// -// - 'a: 'x -// -// and it must prove that `T: 'x`. Callee passes along `T: 'a`. -fn twice<'a, F, T>(v: Cell<&'a ()>, value: T, mut f: F) -where - F: for<'x> FnMut(Option>, &T), -{ - f(None, &value); - f(None, &value); -} - -#[rustc_regions] -fn generic(value: T) { - let cell = Cell::new(&()); - twice(cell, value, |a, b| invoke(a, b)); - //~^ WARNING not reporting region error - // - // This error from the old region solver looks bogus. -} - -#[rustc_regions] -fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) { - twice(cell, value, |a, b| invoke(a, b)); - //~^ WARNING not reporting region error - //~| WARNING not reporting region error - //~| ERROR the parameter type `T` may not live long enough -} - -fn invoke<'a, 'x, T>(x: Option>, y: &T) -where - T: 'x, -{ -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs deleted file mode 100644 index 95a483b3c355d..0000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -use std::fmt::Debug; - -fn with_signature<'a, T, F>(x: Box, op: F) -> Box - where F: FnOnce(Box) -> Box -{ - op(x) -} - -#[rustc_regions] -fn no_region<'a, T>(x: Box) -> Box -where - T: Debug, -{ - // Here, the closure winds up being required to prove that `T: - // 'a`. In principle, it could know that, except that it is - // type-checked in a fully generic way, and hence it winds up with - // a propagated requirement that `T: '_#2`, where `'_#2` appears - // in the return type. The caller makes the mapping from `'_#2` to - // `'a` (and subsequently reports an error). - - with_signature(x, |y| y) - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the parameter type `T` may not live long enough -} - -fn correct_region<'a, T>(x: Box) -> Box -where - T: 'a + Debug, -{ - x -} - -fn wrong_region<'a, 'b, T>(x: Box) -> Box -where - T: 'b + Debug, -{ - x - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the parameter type `T` may not live long enough -} - -fn outlives_region<'a, 'b, T>(x: Box) -> Box -where - T: 'b + Debug, - 'b: 'a, -{ - x -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs deleted file mode 100644 index 1149f250a46e2..0000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we can propagate `T: 'a` obligations to our caller. See -// `correct_region` for an explanation of how this test is setup; it's -// somewhat intricate. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose - -#![allow(warnings)] -#![feature(dyn_trait)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -fn with_signature<'a, T, F>(a: Cell<&'a ()>, b: T, op: F) -where - F: FnOnce(Cell<&'a ()>, T), -{ - op(a, b) -} - -fn require<'a, T>(_a: &Cell<&'a ()>, _b: &T) -where - T: 'a, -{ -} - -#[rustc_regions] -fn no_region<'a, T>(a: Cell<&'a ()>, b: T) { - with_signature(a, b, |x, y| { - //~^ ERROR the parameter type `T` may not live long enough - // - // See `correct_region`, which explains the point of this - // test. The only difference is that, in the case of this - // function, there is no where clause *anywhere*, and hence we - // get an error (but reported by the closure creator). - require(&x, &y) - //~^ WARNING not reporting region error due to -Znll - }) -} - -#[rustc_regions] -fn correct_region<'a, T>(a: Cell<&'a ()>, b: T) -where - T: 'a, -{ - with_signature(a, b, |x, y| { - // Key point of this test: - // - // The *closure* is being type-checked with all of its free - // regions "universalized". In particular, it does not know - // that `x` has the type `Cell<&'a ()>`, but rather treats it - // as if the type of `x` is `Cell<&'A ()>`, where `'A` is some - // fresh, independent region distinct from the `'a` which - // appears in the environment. The call to `require` here - // forces us then to prove that `T: 'A`, but the closure - // cannot do it on its own. It has to surface this requirement - // to its creator (which knows that `'a == 'A`). - require(&x, &y) - }) -} - -#[rustc_regions] -fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) -where - T: 'b, -{ - with_signature(a, b, |x, y| { - //~^ ERROR the parameter type `T` may not live long enough - // See `correct_region` - require(&x, &y) - //~^ WARNING not reporting region error due to -Znll - }) -} - -#[rustc_regions] -fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) -where - T: 'b, - 'b: 'a, -{ - with_signature(a, b, |x, y| { - // See `correct_region` - require(&x, &y) - }) -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs b/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs deleted file mode 100644 index babe608354fb9..0000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we assume that universal types like `T` outlive the -// function body. Same as ty-param-fn-body, but uses `feature(nll)`, -// which affects error reporting. - -#![feature(nll)] - -#![allow(warnings)] -#![feature(dyn_trait)] - -use std::cell::Cell; - -// No errors here, because `'a` is local to the body. -fn region_within_body(t: T) { - let some_int = 22; - let cell = Cell::new(&some_int); - outlives(cell, t) -} - -// Error here, because T: 'a is not satisfied. -fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) { - outlives(cell, t) - //~^ ERROR the parameter type `T` may not live long enough -} - -fn outlives<'a, T>(x: Cell<&'a usize>, y: T) -where - T: 'a, -{ -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs b/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs deleted file mode 100644 index e66c1853b64b9..0000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir - -// Test that we assume that universal types like `T` outlive the -// function body. - -#![allow(warnings)] -#![feature(dyn_trait)] - -use std::cell::Cell; - -// No errors here, because `'a` is local to the body. -fn region_within_body(t: T) { - let some_int = 22; - let cell = Cell::new(&some_int); - outlives(cell, t) -} - -// Error here, because T: 'a is not satisfied. -fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) { - outlives(cell, t) - //~^ WARNING not reporting region error due to -Znll - //~| ERROR the parameter type `T` may not live long enough -} - -fn outlives<'a, T>(x: Cell<&'a usize>, y: T) -where - T: 'a, -{ -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn.rs b/src/test/ui/nll/ty-outlives/ty-param-fn.rs deleted file mode 100644 index aa3a03afa35cd..0000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-fn.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir - -#![allow(warnings)] -#![feature(dyn_trait)] - -use std::fmt::Debug; - -fn no_region<'a, T>(x: Box) -> Box -where - T: Debug, -{ - x - //~^ WARNING not reporting region error due to -Znll - //~| the parameter type `T` may not live long enough -} - -fn correct_region<'a, T>(x: Box) -> Box -where - T: 'a + Debug, -{ - x -} - -fn wrong_region<'a, 'b, T>(x: Box) -> Box -where - T: 'b + Debug, -{ - x - //~^ WARNING not reporting region error due to -Znll - //~| the parameter type `T` may not live long enough -} - -fn outlives_region<'a, 'b, T>(x: Box) -> Box -where - T: 'b + Debug, - 'b: 'a, -{ - x -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs deleted file mode 100644 index cab7ba7a50525..0000000000000 --- a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags:-Znll -Zborrowck=mir -Zverbose -// must-compile-successfully - -// Test that we assume that universal types like `T` outlive the -// function body. - -#![allow(warnings)] -#![feature(rustc_attrs)] - -use std::cell::Cell; - -fn twice(value: T, mut f: F) -where - F: FnMut(Cell<&T>), -{ - f(Cell::new(&value)); - f(Cell::new(&value)); -} - -#[rustc_errors] -fn generic(value: T) { - // No error here: - twice(value, |r| invoke(r)); -} - -fn invoke<'a, T>(x: Cell<&'a T>) -where - T: 'a, -{ -} - -fn main() {} diff --git a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.stderr deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/src/test/ui/regions-fn-subtyping-return-static.rs b/src/test/ui/regions-fn-subtyping-return-static.rs deleted file mode 100644 index 9098511186724..0000000000000 --- a/src/test/ui/regions-fn-subtyping-return-static.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// In this fn, the type `F` is a function that takes a reference to a -// struct and returns another reference with the same lifetime. -// -// Meanwhile, the bare fn `foo` takes a reference to a struct with -// *ANY* lifetime and returns a reference with the 'static lifetime. -// This can safely be considered to be an instance of `F` because all -// lifetimes are sublifetimes of 'static. - -#![allow(dead_code)] -#![allow(unused_variables)] - -struct S; - -// Given 'cx, return 'cx -type F = for<'cx> fn(&'cx S) -> &'cx S; -fn want_F(f: F) { } - -// Given anything, return 'static -type G = for<'cx> fn(&'cx S) -> &'static S; -fn want_G(f: G) { } - -// Should meet both. -fn foo(x: &S) -> &'static S { - panic!() -} - -// Should meet both. -fn bar<'a,'b>(x: &'a S) -> &'b S { - panic!() -} - -// Meets F, but not G. -fn baz(x: &S) -> &S { - panic!() -} - -fn supply_F() { - want_F(foo); - - // FIXME(#33684) -- this should be a subtype, but current alg. rejects it incorrectly - want_F(bar); //~ ERROR E0308 - - want_F(baz); -} - -pub fn main() { -} From bd90fb593d8cc32d4de07789d70faec3ad2b2f7c Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 15:37:15 -0700 Subject: [PATCH 20/22] Fix rustdoc breakage --- src/librustdoc/clean/auto_trait.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 370fc9bbca243..4cb8256aaf5ac 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -684,14 +684,12 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { new_env = ty::ParamEnv::new( tcx.mk_predicates(normalized_preds), param_env.reveal, - ty::UniverseIndex::ROOT, ); } let final_user_env = ty::ParamEnv::new( tcx.mk_predicates(user_computed_preds.into_iter()), user_env.reveal, - ty::UniverseIndex::ROOT, ); debug!( "evaluate_nested_obligations(ty_did={:?}, trait_did={:?}): succeeded with '{:?}' \ From 725eeb01e2e050552a651624e4037914c2ae091d Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 6 Mar 2018 18:07:05 -0700 Subject: [PATCH 21/22] [DO NOT MERGE THIS COMMIT] Remove more failing tests --- src/test/run-pass/nll/get_default.rs | 31 -------------- .../run-pass/nll/issue-47153-generic-const.rs | 27 ------------- src/test/run-pass/nll/issue-47589.rs | 33 --------------- src/test/run-pass/nll/mutating_references.rs | 34 ---------------- .../run-pass/nll/process_or_insert_default.rs | 37 ----------------- src/test/run-pass/nll/rc-loop.rs | 40 ------------------- 6 files changed, 202 deletions(-) delete mode 100644 src/test/run-pass/nll/get_default.rs delete mode 100644 src/test/run-pass/nll/issue-47153-generic-const.rs delete mode 100644 src/test/run-pass/nll/issue-47589.rs delete mode 100644 src/test/run-pass/nll/mutating_references.rs delete mode 100644 src/test/run-pass/nll/process_or_insert_default.rs delete mode 100644 src/test/run-pass/nll/rc-loop.rs diff --git a/src/test/run-pass/nll/get_default.rs b/src/test/run-pass/nll/get_default.rs deleted file mode 100644 index 13ef907d8d008..0000000000000 --- a/src/test/run-pass/nll/get_default.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(nll)] - -use std::collections::HashMap; - -fn get_default(map: &mut HashMap, key: usize) -> &mut String { - match map.get_mut(&key) { - Some(value) => value, - None => { - map.insert(key, "".to_string()); - map.get_mut(&key).unwrap() - } - } -} - -fn main() { - let map = &mut HashMap::new(); - map.insert(22, format!("Hello, world")); - map.insert(44, format!("Goodbye, world")); - assert_eq!(&*get_default(map, 22), "Hello, world"); - assert_eq!(&*get_default(map, 66), ""); -} diff --git a/src/test/run-pass/nll/issue-47153-generic-const.rs b/src/test/run-pass/nll/issue-47153-generic-const.rs deleted file mode 100644 index 9708ca1c14279..0000000000000 --- a/src/test/run-pass/nll/issue-47153-generic-const.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Regression test for #47153: constants in a generic context (such as -// a trait) used to ICE. - -#![feature(nll)] -#![allow(warnings)] - -trait Foo { - const B: bool = true; -} - -struct Bar { x: T } - -impl Bar { - const B: bool = true; -} - -fn main() { } diff --git a/src/test/run-pass/nll/issue-47589.rs b/src/test/run-pass/nll/issue-47589.rs deleted file mode 100644 index 393c18efad0ad..0000000000000 --- a/src/test/run-pass/nll/issue-47589.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(nll)] - -pub struct DescriptorSet<'a> { - pub slots: Vec> -} - -pub trait ResourcesTrait<'r>: Sized { - type DescriptorSet: 'r; -} - -pub struct Resources; - -impl<'a> ResourcesTrait<'a> for Resources { - type DescriptorSet = DescriptorSet<'a>; -} - -pub enum AttachInfo<'a, R: ResourcesTrait<'a>> { - NextDescriptorSet(Box) -} - -fn main() { - let _x = DescriptorSet {slots: Vec::new()}; -} diff --git a/src/test/run-pass/nll/mutating_references.rs b/src/test/run-pass/nll/mutating_references.rs deleted file mode 100644 index 96b7362e4d939..0000000000000 --- a/src/test/run-pass/nll/mutating_references.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(nll)] - -struct List { - value: T, - next: Option>>, -} - -fn to_refs(mut list: &mut List) -> Vec<&mut T> { - let mut result = vec![]; - loop { - result.push(&mut list.value); - if let Some(n) = list.next.as_mut() { - list = n; - } else { - return result; - } - } -} - -fn main() { - let mut list = List { value: 1, next: None }; - let vec = to_refs(&mut list); - assert_eq!(vec![&mut 1], vec); -} diff --git a/src/test/run-pass/nll/process_or_insert_default.rs b/src/test/run-pass/nll/process_or_insert_default.rs deleted file mode 100644 index a3a484402cc14..0000000000000 --- a/src/test/run-pass/nll/process_or_insert_default.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(nll)] - -use std::collections::HashMap; - -fn process_or_insert_default(map: &mut HashMap, key: usize) { - match map.get_mut(&key) { - Some(value) => { - process(value); - } - None => { - map.insert(key, "".to_string()); - } - } -} - -fn process(x: &str) { - assert_eq!(x, "Hello, world"); -} - -fn main() { - let map = &mut HashMap::new(); - map.insert(22, format!("Hello, world")); - map.insert(44, format!("Goodbye, world")); - process_or_insert_default(map, 22); - process_or_insert_default(map, 66); - assert_eq!(map[&66], ""); -} diff --git a/src/test/run-pass/nll/rc-loop.rs b/src/test/run-pass/nll/rc-loop.rs deleted file mode 100644 index 2b746fac4d426..0000000000000 --- a/src/test/run-pass/nll/rc-loop.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// A test for something that NLL enables. It sometimes happens that -// the `while let` pattern makes some borrows from a variable (in this -// case, `x`) that you need in order to compute the next value for -// `x`. The lexical checker makes this very painful. The NLL checker -// does not. - -#![feature(match_default_bindings)] -#![feature(nll)] - -use std::rc::Rc; - -#[derive(Debug, PartialEq, Eq)] -enum Foo { - Base(usize), - Next(Rc), -} - -fn find_base(mut x: Rc) -> Rc { - while let Foo::Next(n) = &*x { - x = n.clone(); - } - x -} - -fn main() { - let chain = Rc::new(Foo::Next(Rc::new(Foo::Base(44)))); - let base = find_base(chain); - assert_eq!(&*base, &Foo::Base(44)); -} - From 3f599ad55cb41b579d5be202b365933605464452 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Mon, 19 Mar 2018 11:04:05 -0600 Subject: [PATCH 22/22] Fix rebase issues --- src/librustc/infer/canonical.rs | 2 -- src/librustc/infer/region_constraints/mod.rs | 2 ++ src/librustc/traits/select.rs | 2 +- src/librustc/ty/mod.rs | 9 ++++----- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 9519baa3ff7bc..1196c9b44f25a 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -250,8 +250,6 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { let ty = match ty_kind { CanonicalTyVarKind::General => { self.next_ty_var( - // FIXME(#48696) this handling of universes is not right. - ty::UniverseIndex::ROOT, TypeVariableOrigin::MiscVariable(span), ) } diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 632a0c5851e79..555ffa86b0454 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -634,6 +634,8 @@ pub fn region_universe(var_infos: &VarInfos, region: Region<'_>) -> ty::Universe ty::ReVar(vid) => var_infos[vid].universe, ty::ReLateBound(..) => bug!("region_universe(): encountered bound region {:?}", region), + ty::ReCanonical(..) => + bug!("region_universe(): encountered canonical region {:?}", region), } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index fe0c87a1ea75e..4068556b919b6 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1514,7 +1514,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { assert!(!skol_trait_ref.has_escaping_regions()); match self.infcx.at(&obligation.cause, obligation.param_env) .sup(ty::Binder(skol_trait_ref), trait_bound) { - Ok(InferOk { obligations, .. }) => true, + Ok(InferOk { .. }) => true, Err(_) => false, } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 896c7a94d951b..3a21b8fce0df1 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1394,7 +1394,7 @@ impl<'tcx> ParamEnv<'tcx> { /// Trait`) are left hidden, so this is suitable for ordinary /// type-checking. pub fn empty() -> Self { - Self::new(ty::Slice::empty(), Reveal::UserFacing, ty::UniverseIndex::ROOT) + Self::new(ty::Slice::empty(), Reveal::UserFacing) } /// Construct a trait environment with no where clauses in scope @@ -1405,15 +1405,14 @@ impl<'tcx> ParamEnv<'tcx> { /// NB. If you want to have predicates in scope, use `ParamEnv::new`, /// or invoke `param_env.with_reveal_all()`. pub fn reveal_all() -> Self { - Self::new(ty::Slice::empty(), Reveal::All, ty::UniverseIndex::ROOT) + Self::new(ty::Slice::empty(), Reveal::All) } /// Construct a trait environment with the given set of predicates. pub fn new(caller_bounds: &'tcx ty::Slice>, - reveal: Reveal, - universe: ty::UniverseIndex) + reveal: Reveal) -> Self { - ty::ParamEnv { caller_bounds, reveal, universe } + ty::ParamEnv { caller_bounds, reveal } } /// Returns a new parameter environment with the same clauses, but