Skip to content

Commit 9b63dcc

Browse files
committed
split out getting the declared bounds from the env versus trait
Right now, we just concatenate them
1 parent b0e1fec commit 9b63dcc

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

src/librustc/infer/outlives/obligations.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -391,16 +391,18 @@ where
391391
// Compute the bounds we can derive from the environment or trait
392392
// definition. We know that the projection outlives all the
393393
// regions in this list.
394-
let env_bounds = self.verify_bound.projection_declared_bounds(projection_ty);
394+
let mut declared_bounds = self.verify_bound
395+
.projection_declared_bounds_from_env(projection_ty);
395396

396-
debug!("projection_must_outlive: env_bounds={:?}", env_bounds);
397+
declared_bounds.extend(
398+
self.verify_bound
399+
.projection_declared_bounds_from_trait(projection_ty),
400+
);
397401

398-
// If we know that the projection outlives 'static, then we're
399-
// done here.
400-
if env_bounds.contains(&&ty::ReStatic) {
401-
debug!("projection_must_outlive: 'static as declared bound");
402-
return;
403-
}
402+
debug!(
403+
"projection_must_outlive: declared_bounds={:?}",
404+
declared_bounds
405+
);
404406

405407
// If declared bounds list is empty, the only applicable rule is
406408
// OutlivesProjectionComponent. If there are inference variables,
@@ -417,7 +419,7 @@ where
417419
// inference variables, we use a verify constraint instead of adding
418420
// edges, which winds up enforcing the same condition.
419421
let needs_infer = projection_ty.needs_infer();
420-
if env_bounds.is_empty() && needs_infer {
422+
if declared_bounds.is_empty() && needs_infer {
421423
debug!("projection_must_outlive: no declared bounds");
422424

423425
for component_ty in projection_ty.substs.types() {
@@ -440,16 +442,20 @@ where
440442
// the requirement that `'b:'r`
441443
// - OutlivesProjectionComponent: this would require `'b:'r` in addition to
442444
// other conditions
443-
if !env_bounds.is_empty() && env_bounds[1..].iter().all(|b| *b == env_bounds[0]) {
444-
let unique_bound = env_bounds[0];
445+
if !declared_bounds.is_empty()
446+
&& declared_bounds[1..]
447+
.iter()
448+
.all(|b| *b == declared_bounds[0])
449+
{
450+
let unique_bound = declared_bounds[0];
445451
debug!(
446452
"projection_must_outlive: unique declared bound = {:?}",
447453
unique_bound
448454
);
449455
if projection_ty
450456
.substs
451457
.regions()
452-
.any(|r| env_bounds.contains(&r))
458+
.any(|r| declared_bounds.contains(&r))
453459
{
454460
debug!("projection_must_outlive: unique declared bound appears in trait ref");
455461
self.delegate

src/librustc/infer/outlives/verify.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,26 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
7272
VerifyBound::AnyRegion(param_bounds)
7373
}
7474

75+
/// Given a projection like `T::Item`, searches the environment
76+
/// for where-clauses like `T::Item: 'a`. Returns the set of
77+
/// regions `'a` that it finds. This is a "conservative" check --
78+
/// it may not find all applicable bounds, but all the bounds it
79+
/// returns can be relied upon.
80+
pub fn projection_declared_bounds_from_env(
81+
&self,
82+
projection_ty: ty::ProjectionTy<'tcx>,
83+
) -> Vec<ty::Region<'tcx>> {
84+
self.declared_generic_bounds_from_env(GenericKind::Projection(projection_ty))
85+
}
86+
7587
/// Searches the where clauses in scope for regions that
7688
/// `projection_ty` is known to outlive. Currently requires an
7789
/// exact match.
78-
pub fn projection_declared_bounds(
90+
pub fn projection_declared_bounds_from_trait(
7991
&self,
8092
projection_ty: ty::ProjectionTy<'tcx>,
8193
) -> Vec<ty::Region<'tcx>> {
82-
// First assemble bounds from where clauses and traits.
83-
84-
let mut declared_bounds =
85-
self.declared_generic_bounds_from_env(GenericKind::Projection(projection_ty));
86-
87-
declared_bounds
88-
.extend_from_slice(&self.declared_projection_bounds_from_trait(projection_ty));
89-
90-
declared_bounds
94+
self.declared_projection_bounds_from_trait(projection_ty)
9195
}
9296

9397
pub fn projection_bound(
@@ -99,7 +103,12 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
99103
projection_ty
100104
);
101105

102-
let declared_bounds = self.projection_declared_bounds(projection_ty);
106+
let mut declared_bounds =
107+
self.projection_declared_bounds_from_env(projection_ty);
108+
109+
declared_bounds.extend(
110+
self.projection_declared_bounds_from_trait(projection_ty)
111+
);
103112

104113
debug!("projection_bound: declared_bounds = {:?}", declared_bounds);
105114

0 commit comments

Comments
 (0)