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 244abb407982..f03e8bd7ac15 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -19,7 +19,7 @@ use rustc::infer::region_constraints::{GenericKind, VarOrigins}; use rustc::mir::{ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Location, Mir}; use rustc::traits::ObligationCause; -use rustc::ty::{self, RegionVid, TypeFoldable}; +use rustc::ty::{self, RegionVid, Ty, TypeFoldable}; use rustc_data_structures::indexed_vec::IndexVec; use std::fmt; use std::rc::Rc; @@ -478,7 +478,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { propagated_outlives_requirements: &mut Vec>, ) -> bool { let tcx = infcx.tcx; - let gcx = tcx.global_tcx(); let TypeTest { generic_kind, @@ -488,80 +487,158 @@ impl<'tcx> RegionInferenceContext<'tcx> { test: _, } = type_test; - // TODO. For now, just fail to promote anything with a - // region. This is obviously too strict: we will for example - // fail to promote `>::Bar` to our - // caller. But it is always sound not to promote, that just - // means more errors, and ignoring regions is a convenient - // starting point. This is because we would want to promote to - // a type that references the region-vids of the closure, for - // which we have no global representation just now. let generic_ty = generic_kind.to_ty(tcx); - if generic_ty.has_free_regions() { - return false; - } - let generic_ty = gcx.lift(&generic_ty).unwrap(); + let subject = match self.try_promote_type_test_subject(infcx, generic_ty) { + Some(s) => s, + None => return false, + }; // Find some bounding subject-region R+ that is a super-region // of the existing subject-region R. This should be a non-local, universal // region, which ensures it can be encoded in a `ClosureOutlivesRequirement`. - let lower_bound_plus = self.promoted_type_test_bound(*lower_bound); + let lower_bound_plus = self.non_local_universal_upper_bound(*lower_bound); assert!(self.universal_regions.is_universal_region(lower_bound_plus)); assert!(!self.universal_regions .is_local_free_region(lower_bound_plus)); propagated_outlives_requirements.push(ClosureOutlivesRequirement { - subject: ClosureOutlivesSubject::Ty(generic_ty), + subject, outlived_free_region: lower_bound_plus, blame_span: *span, }); true } - /// Here, `lower_bound` (henceforth, `'r`) represents the bound from - /// some type-test `T: 'r`. We are a closure and have found that - /// `T: 'r` is not locally satisfiable, so we want to propagate - /// this constraint to our creator. It is sound for us to do so - /// with some `'r+` known to our creator, where `'r+: 'r`. + /// When we promote a type test `T: 'r`, we have to convert the + /// type `T` into something we can store in a query result (so + /// something allocated for `'gcx`). This is problematic if `ty` + /// contains regions. During the course of NLL region checking, we + /// will have replaced all of those regions with fresh inference + /// variables. To create a test subject, we want to replace those + /// inference variables with some region from the closure + /// signature -- this is not always possible, so this is a + /// fallible process. Presuming we do find a suitable region, we + /// will represent it with a `ReClosureBound`, which is a + /// `RegionKind` variant that can be allocated in the gcx. + fn try_promote_type_test_subject<'gcx>( + &self, + infcx: &InferCtxt<'_, 'gcx, 'tcx>, + ty: Ty<'tcx>, + ) -> Option> { + let tcx = infcx.tcx; + let gcx = tcx.global_tcx(); + let inferred_values = self.inferred_values + .as_ref() + .expect("region values not yet inferred"); + + debug!("try_promote_type_test_subject(ty = {:?})", ty); + + let ty = tcx.fold_regions(&ty, &mut false, |r, _depth| { + let region_vid = self.to_region_vid(r); + + // The challenge if this. We have some region variable `r` + // whose value is a set of CFG points and universal + // regions. We want to find if that set is *equivalent* to + // any of the named regions found in the closure. + // + // To do so, we compute the + // `non_local_universal_upper_bound`. This will be a + // non-local, universal region that is greater than `r`. + // However, it might not be *contained* within `r`, so + // then we further check whether this bound is contained + // in `r`. If so, we can say that `r` is equivalent to the + // bound. + // + // Let's work through a few examples. For these, imagine + // that we have 3 non-local regions (I'll denote them as + // `'static`, `'a`, and `'b`, though of course in the code + // they would be represented with indices) where: + // + // - `'static: 'a` + // - `'static: 'b` + // + // First, let's assume that `r` is some existential + // variable with an inferred value `{'a, 'static}` (plus + // some CFG nodes). In this case, the non-local upper + // bound is `'static`, since that outlives `'a`. `'static` + // is also a member of `r` and hence we consider `r` + // equivalent to `'static` (and replace it with + // `'static`). + // + // Now let's consider the inferred value `{'a, 'b}`. This + // means `r` is effectively `'a | 'b`. I'm not sure if + // this can come about, actually, but assuming it did, we + // would get a non-local upper bound of `'static`. Since + // `'static` is not contained in `r`, we would fail to + // find an equivalent. + let upper_bound = self.non_local_universal_upper_bound(region_vid); + if inferred_values.contains(region_vid, upper_bound) { + tcx.mk_region(ty::ReClosureBound(upper_bound)) + } else { + // In the case of a failure, use a `ReVar` + // result. This will cause the `lift` later on to + // fail. + r + } + }); + debug!("try_promote_type_test_subject: folded ty = {:?}", ty); + + // `lift` will only fail if we failed to promote some region. + let ty = gcx.lift(&ty)?; + + Some(ClosureOutlivesSubject::Ty(ty)) + } + + /// Given some universal or existential region `r`, finds a + /// non-local, universal region `r+` that outlives `r` at entry to (and + /// exit from) the closure. In the worst case, this will be + /// `'static`. /// - /// The tricky bit here: this region `'r` may contain (a) any - /// number of points in the CFG and (b) any number of `end('x)` - /// elements of universally quantified regions. To communicate with - /// our creator, however, we have to pick exactly one universally - /// quantified region -- in other words, exactly one `end('x)` - /// element -- that they understand and which will be `'r+`. + /// This is used for two purposes. First, if we are propagated + /// some requirement `T: r`, we can use this method to enlarge `r` + /// to something we can encode for our creator (which only knows + /// about non-local, universal regions). It is also used when + /// encoding `T` as part of `try_promote_type_test_subject` (see + /// that fn for details). /// - /// We do this as follows: + /// Since `r` is (potentially) an existential region, it has some + /// value which may include (a) any number of points in the CFG + /// and (b) any number of `end('x)` elements of universally + /// quantified regions. To convert this into a single universal + /// region we do as follows: /// /// - Ignore the CFG points in `'r`. All universally quantified regions /// include the CFG anyhow. /// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding /// a result `'y`. /// - Finally, we take the non-local upper bound of `'y`. - fn promoted_type_test_bound(&self, lower_bound: RegionVid) -> RegionVid { + /// - This uses `UniversalRegions::non_local_upper_bound`, which + /// is similar to this method but only works on universal + /// regions). + fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid { let inferred_values = self.inferred_values.as_ref().unwrap(); debug!( - "promoted_type_test_bound(lower_bound={:?}={})", - lower_bound, - inferred_values.region_value_str(lower_bound) + "non_local_universal_upper_bound(r={:?}={})", + r, + inferred_values.region_value_str(r) ); // Find the smallest universal region that contains all other // universal regions within `region`. let mut lub = self.universal_regions.fr_fn_body; - for ur in inferred_values.universal_regions_outlived_by(lower_bound) { + for ur in inferred_values.universal_regions_outlived_by(r) { lub = self.universal_regions.postdom_upper_bound(lub, ur); } - debug!("promoted_type_test_bound: lub={:?}", lub); + debug!("non_local_universal_upper_bound: lub={:?}", lub); // Grow further to get smallest universal region known to // creator. let non_local_lub = self.universal_regions.non_local_upper_bound(lub); debug!( - "promoted_type_test_bound: non_local_lub={:?}", + "non_local_universal_upper_bound: non_local_lub={:?}", non_local_lub ); @@ -680,32 +757,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Go through each of the universal regions `fr` and check that // they did not grow too large, accumulating any requirements // for our caller into the `outlives_requirements` vector. - let mut outlives_requirements = vec![]; for (fr, _) in universal_definitions { - self.check_universal_region(infcx, fr, &mut outlives_requirements); - - // Propagate unsatisfied requirements if possible, else - // report them. - if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements { - propagated_outlives_requirements.extend(outlives_requirements.drain(..)); - } else { - for outlives_requirement in outlives_requirements.drain(..) { - let fr = match outlives_requirement.subject { - ClosureOutlivesSubject::Region(fr) => fr, - _ => span_bug!( - outlives_requirement.blame_span, - "check_universal_region() produced requirement w/ non-region subject" - ), - }; - - self.report_error( - infcx, - fr, - outlives_requirement.outlived_free_region, - outlives_requirement.blame_span, - ); - } - } + self.check_universal_region(infcx, fr, &mut propagated_outlives_requirements); } } @@ -721,7 +774,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, longer_fr: RegionVid, - propagated_outlives_requirements: &mut Vec>, + propagated_outlives_requirements: &mut Option<&mut Vec>>, ) { let inferred_values = self.inferred_values.as_ref().unwrap(); @@ -743,33 +796,39 @@ impl<'tcx> RegionInferenceContext<'tcx> { let blame_span = self.blame_span(longer_fr, shorter_fr); - // Shrink `fr` until we find a non-local region (if we do). - // We'll call that `fr-` -- it's ever so slightly smaller than `fr`. - if let Some(fr_minus) = self.universal_regions.non_local_lower_bound(longer_fr) { - debug!("check_universal_region: fr_minus={:?}", fr_minus); + if let Some(propagated_outlives_requirements) = propagated_outlives_requirements { + // Shrink `fr` until we find a non-local region (if we do). + // We'll call that `fr-` -- it's ever so slightly smaller than `fr`. + if let Some(fr_minus) = self.universal_regions.non_local_lower_bound(longer_fr) { + debug!("check_universal_region: fr_minus={:?}", fr_minus); - // Grow `shorter_fr` until we find a non-local - // regon. (We always will.) We'll call that - // `shorter_fr+` -- it's ever so slightly larger than - // `fr`. - let shorter_fr_plus = self.universal_regions.non_local_upper_bound(shorter_fr); - debug!( - "check_universal_region: shorter_fr_plus={:?}", - shorter_fr_plus - ); + // Grow `shorter_fr` until we find a non-local + // regon. (We always will.) We'll call that + // `shorter_fr+` -- it's ever so slightly larger than + // `fr`. + let shorter_fr_plus = self.universal_regions.non_local_upper_bound(shorter_fr); + debug!( + "check_universal_region: shorter_fr_plus={:?}", + shorter_fr_plus + ); - // Push the constraint `fr-: shorter_fr+` - propagated_outlives_requirements.push(ClosureOutlivesRequirement { - subject: ClosureOutlivesSubject::Region(fr_minus), - outlived_free_region: shorter_fr_plus, - blame_span: blame_span, - }); - return; + // Push the constraint `fr-: shorter_fr+` + propagated_outlives_requirements.push(ClosureOutlivesRequirement { + subject: ClosureOutlivesSubject::Region(fr_minus), + outlived_free_region: shorter_fr_plus, + blame_span: blame_span, + }); + return; + } } - // If we could not shrink `fr` to something smaller that - // the external users care about, then we can't pass the - // buck; just report an error. + // If we are not in a context where we can propagate + // errors, or we could not shrink `fr` to something + // smaller, then just report an error. + // + // Note: in this case, we use the unapproximated regions + // to report the error. This gives better error messages + // in some cases. self.report_error(infcx, longer_fr, shorter_fr, blame_span); } } @@ -878,8 +937,8 @@ impl fmt::Debug for Constraint { } } -pub trait ClosureRegionRequirementsExt<'gcx> { - fn apply_requirements<'tcx>( +pub trait ClosureRegionRequirementsExt<'gcx, 'tcx> { + fn apply_requirements( &self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, body_id: ast::NodeId, @@ -887,9 +946,18 @@ pub trait ClosureRegionRequirementsExt<'gcx> { closure_def_id: DefId, closure_substs: ty::ClosureSubsts<'tcx>, ); + + fn subst_closure_mapping( + &self, + infcx: &InferCtxt<'_, 'gcx, 'tcx>, + closure_mapping: &IndexVec>, + value: &T, + ) -> T + where + T: TypeFoldable<'tcx>; } -impl<'gcx> ClosureRegionRequirementsExt<'gcx> for ClosureRegionRequirements<'gcx> { +impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequirements<'gcx> { /// Given an instance T of the closure type, this method /// instantiates the "extra" requirements that we computed for the /// closure into the inference context. This has the effect of @@ -902,7 +970,7 @@ impl<'gcx> ClosureRegionRequirementsExt<'gcx> for ClosureRegionRequirements<'gcx /// a vector. Then we can just index into that vector to extract /// out the corresponding region from T and apply the /// requirements. - fn apply_requirements<'tcx>( + fn apply_requirements( &self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, body_id: ast::NodeId, @@ -927,7 +995,7 @@ impl<'gcx> ClosureRegionRequirementsExt<'gcx> for ClosureRegionRequirements<'gcx // into a vector. These are the regions that we will be // relating to one another. let closure_mapping = - UniversalRegions::closure_mapping(infcx, user_closure_ty, self.num_external_vids); + &UniversalRegions::closure_mapping(infcx, user_closure_ty, self.num_external_vids); debug!("apply_requirements: closure_mapping={:?}", closure_mapping); // Create the predicates. @@ -943,15 +1011,24 @@ impl<'gcx> ClosureRegionRequirementsExt<'gcx> for ClosureRegionRequirements<'gcx debug!( "apply_requirements: region={:?} \ outlived_region={:?} \ - outlives_requirements={:?}", + outlives_requirement={:?}", region, outlived_region, - outlives_requirement + outlives_requirement, ); infcx.sub_regions(origin, outlived_region, region); } ClosureOutlivesSubject::Ty(ty) => { + let ty = self.subst_closure_mapping(infcx, closure_mapping, &ty); + debug!( + "apply_requirements: ty={:?} \ + outlived_region={:?} \ + outlives_requirement={:?}", + ty, + outlived_region, + outlives_requirement, + ); infcx.register_region_obligation( body_id, RegionObligation { @@ -964,4 +1041,22 @@ impl<'gcx> ClosureRegionRequirementsExt<'gcx> for ClosureRegionRequirements<'gcx } } } + + fn subst_closure_mapping( + &self, + infcx: &InferCtxt<'_, 'gcx, 'tcx>, + closure_mapping: &IndexVec>, + value: &T, + ) -> T + where + T: TypeFoldable<'tcx> + { + infcx.tcx.fold_regions(value, &mut false, |r, _depth| { + if let ty::ReClosureBound(vid) = r { + closure_mapping[*vid] + } else { + bug!("subst_closure_mapping: encountered non-closure bound free region {:?}", r) + } + }) + } } diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index d3e75626e63c..5f4a72542b20 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -247,17 +247,24 @@ impl<'tcx> UniversalRegions<'tcx> { (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::new) } - /// True if `r` is classied as a global region. + /// True if `r` is classified as a global region. pub fn is_global_free_region(&self, r: RegionVid) -> bool { self.region_classification(r) == Some(RegionClassification::Global) } - /// True if `r` is classied as an external region. + /// True if `r` is classified as an external region. pub fn is_extern_free_region(&self, r: RegionVid) -> bool { self.region_classification(r) == Some(RegionClassification::External) } - /// True if `r` is classied as an local region. + /// True if `r` is a free region that is classified as global or + /// extern. This is an important category, because these regions + /// can be referenced in `ClosureRegionRequirements`. + pub fn is_non_local_free_region(&self, r: RegionVid) -> bool { + self.region_classification(r) == Some(RegionClassification::Local) + } + + /// True if `r` is classified as an local region. pub fn is_local_free_region(&self, r: RegionVid) -> bool { self.region_classification(r) == Some(RegionClassification::Local) } @@ -324,6 +331,10 @@ impl<'tcx> UniversalRegions<'tcx> { relation: &TransitiveRelation, fr0: RegionVid, ) -> Option { + // This method assumes that `fr0` is one of the universally + // quantified region variables. + assert!(self.is_universal_region(fr0)); + let mut external_parents = vec![]; let mut queue = vec![&fr0]; 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 new file mode 100644 index 000000000000..b91c01fb6713 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs @@ -0,0 +1,68 @@ +// 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 failed type test +} + +#[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 failed type test +} + +#[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-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr new file mode 100644 index 000000000000..1d124f2d49a0 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -0,0 +1,157 @@ +warning: not reporting region error due to -Znll + --> $DIR/projection-no-regions-closure.rs:36:31 + | +36 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^ + +warning: not reporting region error due to -Znll + --> $DIR/projection-no-regions-closure.rs:54:31 + | +54 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^ + +note: External requirements + --> $DIR/projection-no-regions-closure.rs:36:23 + | +36 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:15 ~ projection_no_regions_closure[317d]::no_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box + ] + = note: number of external vids: 3 + = note: where ::Item: '_#2r + +note: External requirements + --> $DIR/projection-no-regions-closure.rs:46:23 + | +46 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:18 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box + ] + = note: number of external vids: 3 + = note: where ::Item: '_#2r + +note: External requirements + --> $DIR/projection-no-regions-closure.rs:54:23 + | +54 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box + ] + = note: number of external vids: 4 + = note: where ::Item: '_#3r + +note: External requirements + --> $DIR/projection-no-regions-closure.rs:65:23 + | +65 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:26 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box + ] + = note: number of external vids: 4 + = note: where ::Item: '_#3r + +error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#4r, point: bb0[5], span: $DIR/projection-no-regions-closure.rs:36:23: 36:49, test: IsOutlivedByAnyRegionIn(['_#2r]) } + --> $DIR/projection-no-regions-closure.rs:36:23 + | +36 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: No external requirements + --> $DIR/projection-no-regions-closure.rs:32:1 + | +32 | / fn no_region<'a, T>(x: Box) -> Box +33 | | where +34 | | T: Iterator, +35 | | { +... | +38 | | //~| ERROR failed type test +39 | | } + | |_^ + | + = note: defining type: DefId(0/0:6 ~ projection_no_regions_closure[317d]::no_region[0]) with substs [ + '_#1r, + T + ] + +note: No external requirements + --> $DIR/projection-no-regions-closure.rs:42:1 + | +42 | / fn correct_region<'a, T>(x: Box) -> Box +43 | | where +44 | | T: 'a + Iterator, +45 | | { +46 | | with_signature(x, |mut y| Box::new(y.next())) +47 | | } + | |_^ + | + = note: defining type: DefId(0/0:7 ~ projection_no_regions_closure[317d]::correct_region[0]) with substs [ + '_#1r, + T + ] + +error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#6r, point: bb0[5], span: $DIR/projection-no-regions-closure.rs:54:23: 54:49, test: IsOutlivedByAnyRegionIn(['_#2r, '_#3r]) } + --> $DIR/projection-no-regions-closure.rs:54:23 + | +54 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: No external requirements + --> $DIR/projection-no-regions-closure.rs:50:1 + | +50 | / fn wrong_region<'a, 'b, T>(x: Box) -> Box +51 | | where +52 | | T: 'b + Iterator, +53 | | { +... | +56 | | //~| ERROR failed type test +57 | | } + | |_^ + | + = note: defining type: DefId(0/0:8 ~ projection_no_regions_closure[317d]::wrong_region[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +note: No external requirements + --> $DIR/projection-no-regions-closure.rs:60:1 + | +60 | / fn outlives_region<'a, 'b, T>(x: Box) -> Box +61 | | where +62 | | T: 'b + Iterator, +63 | | 'b: 'a, +64 | | { +65 | | with_signature(x, |mut y| Box::new(y.next())) +66 | | } + | |_^ + | + = note: defining type: DefId(0/0:9 ~ projection_no_regions_closure[317d]::outlives_region[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/nll/ty-outlives/projection-fn.rs b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs similarity index 96% rename from src/test/ui/nll/ty-outlives/projection-fn.rs rename to src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs index 677d13527884..b7822eb259b6 100644 --- a/src/test/ui/nll/ty-outlives/projection-fn.rs +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:-Znll -Zborrowck=mir +// compile-flags:-Znll -Zborrowck=mir -Zverbose #![allow(warnings)] #![feature(dyn_trait)] diff --git a/src/test/ui/nll/ty-outlives/projection-fn.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr similarity index 54% rename from src/test/ui/nll/ty-outlives/projection-fn.stderr rename to src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr index 77eabef65456..5c3bd04f3b1e 100644 --- a/src/test/ui/nll/ty-outlives/projection-fn.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr @@ -1,23 +1,23 @@ warning: not reporting region error due to -Znll - --> $DIR/projection-fn.rs:24:5 + --> $DIR/projection-no-regions-fn.rs:24:5 | 24 | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ warning: not reporting region error due to -Znll - --> $DIR/projection-fn.rs:40:5 + --> $DIR/projection-no-regions-fn.rs:40:5 | 40 | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ -error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1695 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#4r, point: bb5[0], span: $DIR/projection-fn.rs:24:5: 24:23, test: IsOutlivedByAnyRegionIn(['_#2r]) } - --> $DIR/projection-fn.rs:24:5 +error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#4r, point: bb5[0], span: $DIR/projection-no-regions-fn.rs:24:5: 24:23, test: IsOutlivedByAnyRegionIn(['_#2r]) } + --> $DIR/projection-no-regions-fn.rs:24:5 | 24 | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ -error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1695 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#5r, point: bb5[0], span: $DIR/projection-fn.rs:40:5: 40:23, test: IsOutlivedByAnyRegionIn(['_#2r, '_#3r]) } - --> $DIR/projection-fn.rs:40:5 +error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T]), item_def_id: DefId(2/0:1697 ~ core[2633]::iter[0]::iterator[0]::Iterator[0]::Item[0]) }, lower_bound: '_#5r, point: bb5[0], span: $DIR/projection-no-regions-fn.rs:40:5: 40:23, test: IsOutlivedByAnyRegionIn(['_#2r, '_#3r]) } + --> $DIR/projection-no-regions-fn.rs:40:5 | 40 | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ 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 new file mode 100644 index 000000000000..cd9b1c2a8ced --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs @@ -0,0 +1,106 @@ +// 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 failed type test + //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` +} + +#[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 failed type test + //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` +} + +#[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 failed type test + //~| 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-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr new file mode 100644 index 000000000000..d187a094ec62 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -0,0 +1,194 @@ +warning: not reporting region error due to -Znll + --> $DIR/projection-one-region-closure.rs:56:39 + | +56 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +warning: not reporting region error due to -Znll + --> $DIR/projection-one-region-closure.rs:68:39 + | +68 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +warning: not reporting region error due to -Znll + --> $DIR/projection-one-region-closure.rs:90:39 + | +90 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +note: External requirements + --> $DIR/projection-one-region-closure.rs:56:29 + | +56 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:19 ~ projection_one_region_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 T: '_#2r + = note: where '_#1r: '_#2r + +note: External requirements + --> $DIR/projection-one-region-closure.rs:68:29 + | +68 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:23 ~ projection_one_region_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 T: '_#3r + = note: where '_#2r: '_#3r + +note: External requirements + --> $DIR/projection-one-region-closure.rs:90:29 + | +90 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:27 ~ projection_one_region_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 T: '_#3r + = note: where '_#2r: '_#3r + +note: External requirements + --> $DIR/projection-one-region-closure.rs:103:29 + | +103 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:31 ~ projection_one_region_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 T: '_#3r + = note: where '_#2r: '_#3r + +error: failed type test: TypeTest { generic_kind: T/#1, lower_bound: '_#5r, point: bb0[5], span: $DIR/projection-one-region-closure.rs:56:29: 56:55, test: IsOutlivedByAnyRegionIn(['_#3r]) } + --> $DIR/projection-one-region-closure.rs:56:29 + | +56 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` + --> $DIR/projection-one-region-closure.rs:56:20 + | +56 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^ + +note: No external requirements + --> $DIR/projection-one-region-closure.rs:52:1 + | +52 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +53 | | where +54 | | T: Anything<'b>, +55 | | { +... | +59 | | //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` +60 | | } + | |_^ + | + = note: defining type: DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]) with substs [ + '_#1r, + T + ] + +error: failed type test: TypeTest { generic_kind: T/#2, lower_bound: '_#6r, point: bb0[5], span: $DIR/projection-one-region-closure.rs:68:29: 68:55, test: IsOutlivedByAnyRegionIn(['_#3r]) } + --> $DIR/projection-one-region-closure.rs:68:29 + | +68 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` + --> $DIR/projection-one-region-closure.rs:68:20 + | +68 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^ + +note: No external requirements + --> $DIR/projection-one-region-closure.rs:63:1 + | +63 | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +64 | | where +65 | | T: Anything<'b>, +66 | | 'a: 'a, +... | +71 | | //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` +72 | | } + | |_^ + | + = note: defining type: DefId(0/0:9 ~ projection_one_region_closure[317d]::no_relationships_early[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +error: failed type test: TypeTest { generic_kind: T/#2, lower_bound: '_#6r, point: bb0[5], span: $DIR/projection-one-region-closure.rs:90:29: 90:55, test: IsOutlivedByAnyRegionIn(['_#3r]) } + --> $DIR/projection-one-region-closure.rs:90:29 + | +90 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` + --> $DIR/projection-one-region-closure.rs:90:20 + | +90 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^ + +note: No external requirements + --> $DIR/projection-one-region-closure.rs:75:1 + | +75 | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +76 | | where +77 | | T: Anything<'b>, +78 | | T::AssocType: 'a, +... | +93 | | //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` +94 | | } + | |_^ + | + = note: defining type: DefId(0/0:10 ~ projection_one_region_closure[317d]::projection_outlives[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +note: No external requirements + --> $DIR/projection-one-region-closure.rs:97:1 + | +97 | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +98 | | where +99 | | T: Anything<'b>, +100 | | T: 'a, +... | +103 | | with_signature(cell, t, |cell, t| require(cell, t)); +104 | | } + | |_^ + | + = note: defining type: DefId(0/0:11 ~ projection_one_region_closure[317d]::elements_outlive[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +error: aborting due to 6 previous errors + 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 new file mode 100644 index 000000000000..e179927dfb0b --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs @@ -0,0 +1,106 @@ +// 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 free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` +} + +#[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 free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` +} + +#[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 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>, + '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 new file mode 100644 index 000000000000..1088ae846fee --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -0,0 +1,204 @@ +warning: not reporting region error due to -Znll + --> $DIR/projection-one-region-trait-bound-closure.rs:48:39 + | +48 | 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 + | +59 | 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 + | +80 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:48:29 + | +48 | 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 + +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:59:29 + | +59 | 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 + +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:80:29 + | +80 | 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 + +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:91:29 + | +91 | 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: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:103:29 + | +103 | 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 + +error: free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` + --> $DIR/projection-one-region-trait-bound-closure.rs:48:20 + | +48 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^ + +note: No external requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:44:1 + | +44 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +45 | | where +46 | | T: Anything<'b>, +47 | | { +... | +50 | | //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` +51 | | } + | |_^ + | + = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [ + '_#1r, + T + ] + +error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` + --> $DIR/projection-one-region-trait-bound-closure.rs:59:20 + | +59 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^ + +note: No external requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:54:1 + | +54 | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +55 | | where +56 | | T: Anything<'b>, +57 | | 'a: 'a, +... | +61 | | //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` +62 | | } + | |_^ + | + = note: defining type: DefId(0/0:9 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` + --> $DIR/projection-one-region-trait-bound-closure.rs:80:20 + | +80 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^ + +note: No external requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:65:1 + | +65 | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +66 | | where +67 | | T: Anything<'b>, +68 | | T::AssocType: 'a, +... | +82 | | //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` +83 | | } + | |_^ + | + = note: defining type: DefId(0/0:10 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +note: No external requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:86:1 + | +86 | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +87 | | where +88 | | T: Anything<'b>, +89 | | 'b: 'a, +90 | | { +91 | | with_signature(cell, t, |cell, t| require(cell, t)); +92 | | } + | |_^ + | + = note: defining type: DefId(0/0:11 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +note: No external requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:95:1 + | +95 | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) +96 | | where +97 | | T: Anything<'a>, +98 | | { +... | +103 | | with_signature(cell, t, |cell, t| require(cell, t)); +104 | | } + | |_^ + | + = 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 new file mode 100644 index 000000000000..67e28af11469 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs @@ -0,0 +1,99 @@ +// 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 new file mode 100644 index 000000000000..986676d28d92 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr @@ -0,0 +1,155 @@ +note: No external requirements + --> $DIR/projection-one-region-trait-bound-static-closure.rs:47:29 + | +47 | 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:56:29 + | +56 | 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:75:29 + | +75 | 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:84:29 + | +84 | 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:96:29 + | +96 | 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:43:1 + | +43 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +44 | | where +45 | | T: Anything<'b>, +46 | | { +47 | | with_signature(cell, t, |cell, t| require(cell, t)); +48 | | } + | |_^ + | + = 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:51:1 + | +51 | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +52 | | where +53 | | T: Anything<'b>, +54 | | 'a: 'a, +55 | | { +56 | | with_signature(cell, t, |cell, t| require(cell, t)); +57 | | } + | |_^ + | + = 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:60:1 + | +60 | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +61 | | where +62 | | T: Anything<'b>, +63 | | T::AssocType: 'a, +... | +75 | | with_signature(cell, t, |cell, t| require(cell, t)); +76 | | } + | |_^ + | + = 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:79:1 + | +79 | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +80 | | where +81 | | T: Anything<'b>, +82 | | 'b: 'a, +83 | | { +84 | | with_signature(cell, t, |cell, t| require(cell, t)); +85 | | } + | |_^ + | + = 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:88:1 + | +88 | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) +89 | | where +90 | | T: Anything<'a>, +91 | | { +... | +96 | | with_signature(cell, t, |cell, t| require(cell, t)); +97 | | } + | |_^ + | + = 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 new file mode 100644 index 000000000000..f8f3065fff43 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs @@ -0,0 +1,135 @@ +// 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 failed type test +} + +#[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 failed type test +} + +#[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 failed type test +} + +#[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 free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` +} + +#[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/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr new file mode 100644 index 000000000000..026502141292 --- /dev/null +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -0,0 +1,326 @@ +warning: not reporting region error due to -Znll + --> $DIR/projection-two-region-trait-bound-closure.rs:49:39 + | +49 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +warning: not reporting region error due to -Znll + --> $DIR/projection-two-region-trait-bound-closure.rs:60:39 + | +60 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +warning: not reporting region error due to -Znll + --> $DIR/projection-two-region-trait-bound-closure.rs:81:39 + | +81 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +warning: not reporting region error due to -Znll + --> $DIR/projection-two-region-trait-bound-closure.rs:109:39 + | +109 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^ + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:49:29 + | +49 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:22 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[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 >::AssocType: '_#3r + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:60:29 + | +60 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:27 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:81:29 + | +81 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:32 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:92:29 + | +92 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:37 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:101:29 + | +101 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:42 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:109:29 + | +109 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:46 ~ projection_two_region_trait_bound_closure[317d]::two_regions[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 >::AssocType: '_#2r + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:120:29 + | +120 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:50 ~ projection_two_region_trait_bound_closure[317d]::two_regions_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 >::AssocType: '_#3r + +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:132:29 + | +132 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:53 ~ projection_two_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 >::AssocType: '_#2r + +error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T, '_#5r, '_#6r]), item_def_id: DefId(0/0:5 ~ projection_two_region_trait_bound_closure[317d]::Anything[0]::AssocType[0]) }, lower_bound: '_#7r, point: bb0[5], span: $DIR/projection-two-region-trait-bound-closure.rs:49:29: 49:55, test: Any([IsOutlivedByAnyRegionIn(['_#6r, '_#5r]), All([IsOutlivedByAnyRegionIn(['_#4r]), IsOutlivedByAllRegionsIn(['_#5r, '_#6r])])]) } + --> $DIR/projection-two-region-trait-bound-closure.rs:49:29 + | +49 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:45:1 + | +45 | / fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +46 | | where +47 | | T: Anything<'b, 'c>, +48 | | { +... | +51 | | //~| ERROR failed type test +52 | | } + | |_^ + | + = note: defining type: DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T, '_#6r, '_#7r]), item_def_id: DefId(0/0:5 ~ projection_two_region_trait_bound_closure[317d]::Anything[0]::AssocType[0]) }, lower_bound: '_#8r, point: bb0[5], span: $DIR/projection-two-region-trait-bound-closure.rs:60:29: 60:55, test: Any([IsOutlivedByAnyRegionIn(['_#7r, '_#6r]), All([IsOutlivedByAnyRegionIn(['_#4r]), IsOutlivedByAllRegionsIn(['_#6r, '_#7r])])]) } + --> $DIR/projection-two-region-trait-bound-closure.rs:60:29 + | +60 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:55:1 + | +55 | / fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +56 | | where +57 | | T: Anything<'b, 'c>, +58 | | 'a: 'a, +... | +62 | | //~| ERROR failed type test +63 | | } + | |_^ + | + = note: defining type: DefId(0/0:9 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [ + '_#1r, + '_#2r, + '_#3r, + T + ] + +error: failed type test: TypeTest { generic_kind: ProjectionTy { substs: Slice([T, '_#6r, '_#7r]), item_def_id: DefId(0/0:5 ~ projection_two_region_trait_bound_closure[317d]::Anything[0]::AssocType[0]) }, lower_bound: '_#8r, point: bb0[5], span: $DIR/projection-two-region-trait-bound-closure.rs:81:29: 81:55, test: Any([IsOutlivedByAnyRegionIn(['_#7r, '_#6r]), All([IsOutlivedByAnyRegionIn(['_#4r]), IsOutlivedByAllRegionsIn(['_#6r, '_#7r])])]) } + --> $DIR/projection-two-region-trait-bound-closure.rs:81:29 + | +81 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:66:1 + | +66 | / fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +67 | | where +68 | | T: Anything<'b, 'c>, +69 | | T::AssocType: 'a, +... | +83 | | //~| ERROR failed type test +84 | | } + | |_^ + | + = note: defining type: DefId(0/0:10 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [ + '_#1r, + '_#2r, + '_#3r, + T + ] + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:87:1 + | +87 | / fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +88 | | where +89 | | T: Anything<'b, 'c>, +90 | | 'b: 'a, +91 | | { +92 | | with_signature(cell, t, |cell, t| require(cell, t)); +93 | | } + | |_^ + | + = note: defining type: DefId(0/0:11 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]) with substs [ + '_#1r, + '_#2r, + '_#3r, + T + ] + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:96:1 + | +96 | / fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +97 | | where +98 | | T: Anything<'b, 'c>, +99 | | 'c: 'a, +100 | | { +101 | | with_signature(cell, t, |cell, t| require(cell, t)); +102 | | } + | |_^ + | + = note: defining type: DefId(0/0:12 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]) with substs [ + '_#1r, + '_#2r, + '_#3r, + T + ] + +error: free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` + --> $DIR/projection-two-region-trait-bound-closure.rs:109:20 + | +109 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^ + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:105:1 + | +105 | / fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +106 | | where +107 | | T: Anything<'b, 'b>, +108 | | { +... | +111 | | //~| ERROR free region `ReEarlyBound(0, 'b)` does not outlive free region `'_#2r` +112 | | } + | |_^ + | + = note: defining type: DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]) with substs [ + '_#1r, + T + ] + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:115:1 + | +115 | / fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +116 | | where +117 | | T: Anything<'b, 'b>, +118 | | 'b: 'a, +119 | | { +120 | | with_signature(cell, t, |cell, t| require(cell, t)); +121 | | } + | |_^ + | + = note: defining type: DefId(0/0:14 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]) with substs [ + '_#1r, + '_#2r, + T + ] + +note: No external requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:124:1 + | +124 | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) +125 | | where +126 | | T: Anything<'a, 'a>, +127 | | { +... | +132 | | with_signature(cell, t, |cell, t| require(cell, t)); +133 | | } + | |_^ + | + = note: defining type: DefId(0/0:15 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]) with substs [ + '_#1r, + T + ] + +error: aborting due to 4 previous errors +