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/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/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/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/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/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/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/glb.rs b/src/librustc/infer/glb.rs index fd14e0e40e234..f6c6844ffe9f2 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -15,20 +15,22 @@ 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) 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 } } } @@ -48,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), } } @@ -76,16 +78,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 +85,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) } } } @@ -116,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 a317e0699b4bb..3459e91cac3b1 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -11,27 +11,19 @@ //! Helper routines for higher-ranked things. See the `doc` module at //! the end of the file for details. -use super::{CombinedSnapshot, - InferCtxt, - HigherRankedType, - SubregionOrigin, - SkolemizationMap}; +use super::{InferCtxt, + HigherRankedType}; 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::{self, Binder, TypeFoldable}; 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) + 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> { @@ -48,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( @@ -59,725 +56,40 @@ 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, snapshot); - debug!("a_prime={:?}", a_prime); 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)?; - - // 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); + let result = self.sub(param_env, a_is_expected).relate(&a_prime, &b_prime)?; debug!("higher_ranked_sub: OK result={:?}", result); 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 }) - }); - } - - 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>, - 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> { - 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, - snapshot: &CombinedSnapshot<'a, 'tcx>) - -> (T, SkolemizationMap<'tcx>) + binder: &ty::Binder) + -> T 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) + 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.tcx, &skol_regions, &snapshot.region_constraints_snapshot); - if !skol_map.is_empty() { - self.projection_cache.borrow_mut().rollback_skolemized( - &snapshot.projection_cache_snapshot); - } - } } 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/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 00b2ac7449f7e..e047aa652c690 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::VarOrigins; -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; @@ -37,7 +34,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 +44,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 +100,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 +129,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 @@ -232,16 +229,48 @@ 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 {:?}", + "Expanding value of {:?} from {:?} to {:?} \ + (lub_universe={:?}, b_universe={:?})", b_vid, cur_region, - lub + lub, + lub_universe, + b_universe ); *b_data = VarValue::Value(lub); @@ -279,7 +308,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 +605,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 +627,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/lub.rs b/src/librustc/infer/lub.rs index 55c7eef607bbe..f7d99288a13f6 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -15,20 +15,22 @@ 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) 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 } } } @@ -48,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), } } @@ -76,16 +78,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 +85,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) } } } @@ -116,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 fe919775da0b4..385e521d9b97d 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -39,9 +39,8 @@ 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, 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; @@ -182,6 +181,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. + universe: Cell, } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -454,6 +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: Cell::new(ty::UniverseIndex::ROOT), })) } } @@ -488,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>>, } @@ -567,13 +579,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(), } } @@ -617,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. @@ -634,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() @@ -666,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; @@ -713,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 { @@ -808,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) = - self.skolemize_late_bound_regions(predicate, snapshot); + 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()) })) } @@ -825,37 +837,27 @@ 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, snapshot); - 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, - 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(self.universe(), 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 { @@ -878,12 +880,14 @@ 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. 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. @@ -910,13 +914,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, + .new_var(self.universe(), false, TypeVariableOrigin::TypeParameterDefinition(span, def.name)); @@ -926,14 +929,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) }) } @@ -1013,12 +1015,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()); @@ -1066,13 +1068,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 { @@ -1233,40 +1235,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>, @@ -1365,6 +1334,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> { diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 0c8e49fda1840..555ffa86b0454 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -22,18 +22,14 @@ 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::{ReLateBound, ReVar}; use std::collections::BTreeMap; -use std::fmt; -use std::mem; -use std::u32; - -mod taint; +use std::{cmp, fmt, mem}; pub struct RegionConstraintCollector<'tcx> { - /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. - var_origins: IndexVec, + /// For each `RegionVid`, the corresponding `RegionVariableInfo`. + var_infos: IndexVec, data: RegionConstraintData<'tcx>, @@ -47,13 +43,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, - /// The undo log records actions that might later be undone. /// /// Note: when the undo_log is empty, we are not actively @@ -76,7 +65,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 @@ -212,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)] @@ -230,62 +211,31 @@ enum CombineMapType { type CombineMap<'tcx> = FxHashMap, RegionVid>; +#[derive(Debug, Clone, Copy)] +pub struct RegionVariableInfo { + pub origin: RegionVariableOrigin, + pub universe: ty::UniverseIndex, +} + 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 -/// 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 { - var_origins: VarOrigins::default(), + var_infos: VarInfos::default(), data: RegionConstraintData::default(), lubs: FxHashMap(), glbs: FxHashMap(), - skolemization_count: ty::UniverseIndex::ROOT, - bound_count: 0, undo_log: Vec::new(), unification_table: ut::UnificationTable::new(), } } - 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 +245,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,18 +269,14 @@ 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, - skolemization_count, - bound_count: _, undo_log: _, unification_table, } = self; - assert_eq!(skolemization_count.as_usize(), 0); - // 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 @@ -343,7 +289,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 }); } @@ -365,7 +311,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> { RegionSnapshot { length, region_snapshot: self.unification_table.snapshot(), - skolemization_count: self.skolemization_count, } } @@ -373,12 +318,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); @@ -398,7 +337,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); } @@ -407,12 +345,12 @@ impl<'tcx> RegionConstraintCollector<'tcx> { OpenSnapshot => { panic!("Failure to observe stack discipline"); } - Purged | CommitedSnapshot => { + CommitedSnapshot => { // 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); @@ -433,8 +371,13 @@ impl<'tcx> RegionConstraintCollector<'tcx> { } } - pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid { - let vid = self.var_origins.push(origin.clone()); + 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 .new_key(unify_key::RegionVidKey { min_vid: vid }); @@ -443,169 +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 origin for the given variable. - pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { - self.var_origins[vid].clone() - } - - /// 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>, - skols: &FxHashSet>, - snapshot: &RegionSnapshot, - ) { - debug!("pop_skolemized_regions(skols={:?})", skols); - - assert!(self.in_snapshot()); - assert!(self.undo_log[snapshot.length] == OpenSnapshot); - assert!( - self.skolemization_count.as_usize() >= skols.len(), - "popping more skolemized variables than actually exist, \ - sc now = {}, skols.len = {}", - self.skolemization_count.as_usize(), - 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)); - - 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 { - ty::ReSkolemized(universe, _) => - universe >= first_to_pop && - universe < last_to_pop, - _ => - false - }), - "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}", - snapshot.skolemization_count, - self.skolemization_count, - 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); - } - - self.skolemization_count = snapshot.skolemization_count; - 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!( @@ -803,7 +591,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 = 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); if self.in_snapshot() { self.undo_log.push(AddCombination(t, vars)); @@ -828,47 +619,29 @@ 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 { + 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), + ty::ReCanonical(..) => + bug!("region_universe(): encountered canonical region {:?}", region), } } 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) } } @@ -900,18 +673,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), @@ -921,7 +682,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), @@ -939,16 +700,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/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) } } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 66360ea50bbe0..bb5bf4cdecb25 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -81,12 +81,6 @@ pub enum TypeVariableValue<'tcx> { Unknown { universe: ty::UniverseIndex }, } -#[derive(Copy, Clone, Debug)] -pub enum ProbeTyValue<'tcx> { - Ty(Ty<'tcx>), - Vid(ty::TyVid), -} - impl<'tcx> TypeVariableValue<'tcx> { /// If this value is known, returns the type it is known to be. /// Otherwise, `None`. @@ -97,14 +91,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, @@ -453,9 +439,9 @@ 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. + // If both sides are *unknown*, it hardly matters, does it? (&TypeVariableValue::Unknown { universe: universe1 }, - &TypeVariableValue::Unknown { universe: universe2 }) => { + &TypeVariableValue::Unknown { universe: universe2 }) => { let universe = cmp::min(universe1, universe2); Ok(TypeVariableValue::Unknown { universe }) } 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/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/traits/project.rs b/src/librustc/traits/project.rs index a9dc491574379..8b299987be84d 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}; @@ -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.skolemize_late_bound_regions(&obligation.predicate, snapshot); + 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) }) } @@ -477,7 +464,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 +784,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, @@ -1424,17 +1409,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, } } @@ -1444,7 +1437,7 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>( "Failed to unify obligation `{:?}` \ with poly_projection `{:?}`: {:?}", obligation, - poly_projection, + poly_cache_entry, e); } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index f2f54dcedfd65..4068556b919b6 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) = - self.infcx().skolemize_late_bound_regions(&poly_trait_predicate, snapshot); + 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 { .. }) => 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,9 +2268,9 @@ 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) = - this.infcx().skolemize_late_bound_regions(&ty, snapshot); + 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, param_env, @@ -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) = - this.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot); + 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,13 +3053,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Err(()); } - let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions( - &obligation.predicate, - snapshot); + let skol_obligation = self.infcx().skolemize_late_bound_regions( + &obligation.predicate); 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(), @@ -3118,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, @@ -3263,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); @@ -3305,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 } } 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/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/mod.rs b/src/librustc/ty/mod.rs index fc1d26b0e0910..3a21b8fce0df1 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1334,7 +1334,7 @@ pub struct UniverseIndex(u32); impl UniverseIndex { /// The root universe, where things that the user defined are /// visible. - pub const 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`: @@ -1351,10 +1351,6 @@ impl UniverseIndex { UniverseIndex(self.0.checked_add(1).unwrap()) } - pub fn from(v: u32) -> UniverseIndex { - UniverseIndex(v) - } - pub fn as_u32(&self) -> u32 { self.0 } @@ -1363,11 +1359,16 @@ impl UniverseIndex { self.0 as usize } - /// 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 + /// 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 { + fn from(index: u32) -> Self { + UniverseIndex(index) } } @@ -1385,17 +1386,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> { @@ -1404,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 @@ -1415,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 @@ -2722,8 +2711,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..53a3f8f380d1d 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, } }) @@ -453,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), }) } } @@ -737,29 +735,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> { @@ -1150,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/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index efa53c775ae25..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, bound_region) + ty::ReSkolemized(universe, ref bound_region) => { + write!(f, "ReSkolemized({:?}, {:?})", universe, bound_region) } ty::ReEmpty => write!(f, "ReEmpty"), 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)); 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 { 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/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, 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)); 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 '{:?}' \ 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/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)); -} - 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/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() { -} 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() { -}