diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-09-17 12:15:48 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-09-26 09:38:26 -0400 |
| commit | 9b63dcc7731e1023c525e795ba36472a3e4bd21b (patch) | |
| tree | 11fc4c0173b32d39cfc57d106a843a30940489f8 | |
| parent | b0e1fec33251c02080403f89a11a78ba452464c0 (diff) | |
| download | rust-9b63dcc7731e1023c525e795ba36472a3e4bd21b.tar.gz rust-9b63dcc7731e1023c525e795ba36472a3e4bd21b.zip | |
split out getting the declared bounds from the env versus trait
Right now, we just concatenate them
| -rw-r--r-- | src/librustc/infer/outlives/obligations.rs | 30 | ||||
| -rw-r--r-- | src/librustc/infer/outlives/verify.rs | 31 |
2 files changed, 38 insertions, 23 deletions
diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index c19c8f57d2d..2db1c5e3d30 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -391,16 +391,18 @@ where // Compute the bounds we can derive from the environment or trait // definition. We know that the projection outlives all the // regions in this list. - let env_bounds = self.verify_bound.projection_declared_bounds(projection_ty); + let mut declared_bounds = self.verify_bound + .projection_declared_bounds_from_env(projection_ty); - debug!("projection_must_outlive: env_bounds={:?}", env_bounds); + declared_bounds.extend( + self.verify_bound + .projection_declared_bounds_from_trait(projection_ty), + ); - // If we know that the projection outlives 'static, then we're - // done here. - if env_bounds.contains(&&ty::ReStatic) { - debug!("projection_must_outlive: 'static as declared bound"); - return; - } + debug!( + "projection_must_outlive: declared_bounds={:?}", + declared_bounds + ); // If declared bounds list is empty, the only applicable rule is // OutlivesProjectionComponent. If there are inference variables, @@ -417,7 +419,7 @@ where // inference variables, we use a verify constraint instead of adding // edges, which winds up enforcing the same condition. let needs_infer = projection_ty.needs_infer(); - if env_bounds.is_empty() && needs_infer { + if declared_bounds.is_empty() && needs_infer { debug!("projection_must_outlive: no declared bounds"); for component_ty in projection_ty.substs.types() { @@ -440,8 +442,12 @@ where // the requirement that `'b:'r` // - OutlivesProjectionComponent: this would require `'b:'r` in addition to // other conditions - if !env_bounds.is_empty() && env_bounds[1..].iter().all(|b| *b == env_bounds[0]) { - let unique_bound = env_bounds[0]; + if !declared_bounds.is_empty() + && declared_bounds[1..] + .iter() + .all(|b| *b == declared_bounds[0]) + { + let unique_bound = declared_bounds[0]; debug!( "projection_must_outlive: unique declared bound = {:?}", unique_bound @@ -449,7 +455,7 @@ where if projection_ty .substs .regions() - .any(|r| env_bounds.contains(&r)) + .any(|r| declared_bounds.contains(&r)) { debug!("projection_must_outlive: unique declared bound appears in trait ref"); self.delegate diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 3a1e2057931..cd4f3c3e5dc 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -72,22 +72,26 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> { VerifyBound::AnyRegion(param_bounds) } + /// Given a projection like `T::Item`, searches the environment + /// for where-clauses like `T::Item: 'a`. Returns the set of + /// regions `'a` that it finds. This is a "conservative" check -- + /// it may not find all applicable bounds, but all the bounds it + /// returns can be relied upon. + pub fn projection_declared_bounds_from_env( + &self, + projection_ty: ty::ProjectionTy<'tcx>, + ) -> Vec<ty::Region<'tcx>> { + self.declared_generic_bounds_from_env(GenericKind::Projection(projection_ty)) + } + /// Searches the where clauses in scope for regions that /// `projection_ty` is known to outlive. Currently requires an /// exact match. - pub fn projection_declared_bounds( + pub fn projection_declared_bounds_from_trait( &self, projection_ty: ty::ProjectionTy<'tcx>, ) -> Vec<ty::Region<'tcx>> { - // First assemble bounds from where clauses and traits. - - let mut declared_bounds = - self.declared_generic_bounds_from_env(GenericKind::Projection(projection_ty)); - - declared_bounds - .extend_from_slice(&self.declared_projection_bounds_from_trait(projection_ty)); - - declared_bounds + self.declared_projection_bounds_from_trait(projection_ty) } pub fn projection_bound( @@ -99,7 +103,12 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> { projection_ty ); - let declared_bounds = self.projection_declared_bounds(projection_ty); + let mut declared_bounds = + self.projection_declared_bounds_from_env(projection_ty); + + declared_bounds.extend( + self.projection_declared_bounds_from_trait(projection_ty) + ); debug!("projection_bound: declared_bounds = {:?}", declared_bounds); |
