Skip to content

Commit 72bca5e

Browse files
committed
Auto merge of #56003 - nikomatsakis:issue-54467-infer-outlives-bounds-and-trait-objects, r=eddyb
do not propagate inferred bounds on trait objects if they involve `Self` Fixes #54467, which is a Rust 2018 Release blocking issue. r? @eddyb
2 parents 6b9b97b + 6575988 commit 72bca5e

File tree

5 files changed

+66
-10
lines changed

5 files changed

+66
-10
lines changed

src/librustc/traits/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,12 @@ fn do_normalize_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
700700
predicates: Vec<ty::Predicate<'tcx>>)
701701
-> Result<Vec<ty::Predicate<'tcx>>, ErrorReported>
702702
{
703-
debug!("do_normalize_predicates({:?})", predicates);
703+
debug!(
704+
"do_normalize_predicates(predicates={:?}, region_context={:?}, cause={:?})",
705+
predicates,
706+
region_context,
707+
cause,
708+
);
704709
let span = cause.span;
705710
tcx.infer_ctxt().enter(|infcx| {
706711
// FIXME. We should really... do something with these region

src/librustc_typeck/collect.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1608,10 +1608,21 @@ fn predicates_defined_on<'a, 'tcx>(
16081608
tcx: TyCtxt<'a, 'tcx, 'tcx>,
16091609
def_id: DefId,
16101610
) -> Lrc<ty::GenericPredicates<'tcx>> {
1611+
debug!("predicates_defined_on({:?})", def_id);
16111612
let mut result = tcx.explicit_predicates_of(def_id);
1613+
debug!(
1614+
"predicates_defined_on: explicit_predicates_of({:?}) = {:?}",
1615+
def_id,
1616+
result,
1617+
);
16121618
let inferred_outlives = tcx.inferred_outlives_of(def_id);
16131619
if !inferred_outlives.is_empty() {
16141620
let span = tcx.def_span(def_id);
1621+
debug!(
1622+
"predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
1623+
def_id,
1624+
inferred_outlives,
1625+
);
16151626
Lrc::make_mut(&mut result)
16161627
.predicates
16171628
.extend(inferred_outlives.iter().map(|&p| (p, span)));

src/librustc_typeck/outlives/implicit_infer.rs

+29-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc::hir::def_id::DefId;
1414
use rustc::hir::itemlikevisit::ItemLikeVisitor;
1515
use rustc::ty::subst::{Kind, Subst, UnpackedKind};
1616
use rustc::ty::{self, Ty, TyCtxt};
17+
use rustc::ty::fold::TypeFoldable;
1718
use rustc::util::nodemap::FxHashMap;
1819

1920
use super::explicit::ExplicitPredicatesMap;
@@ -245,6 +246,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
245246
}
246247
}
247248

249+
#[derive(Debug)]
248250
pub struct IgnoreSelfTy(bool);
249251

250252
/// We also have to check the explicit predicates
@@ -270,10 +272,18 @@ pub fn check_explicit_predicates<'tcx>(
270272
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
271273
ignore_self_ty: IgnoreSelfTy,
272274
) {
273-
debug!("def_id = {:?}", &def_id);
274-
debug!("substs = {:?}", &substs);
275-
debug!("explicit_map = {:?}", explicit_map);
276-
debug!("required_predicates = {:?}", required_predicates);
275+
debug!(
276+
"check_explicit_predicates(def_id={:?}, \
277+
substs={:?}, \
278+
explicit_map={:?}, \
279+
required_predicates={:?}, \
280+
ignore_self_ty={:?})",
281+
def_id,
282+
substs,
283+
explicit_map,
284+
required_predicates,
285+
ignore_self_ty,
286+
);
277287
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);
278288

279289
for outlives_predicate in explicit_predicates.iter() {
@@ -302,13 +312,23 @@ pub fn check_explicit_predicates<'tcx>(
302312
//
303313
// Note that we do this check for self **before** applying `substs`. In the
304314
// case that `substs` come from a `dyn Trait` type, our caller will have
305-
// included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
315+
// included `Self = usize` as the value for `Self`. If we were
306316
// to apply the substs, and not filter this predicate, we might then falsely
307317
// conclude that e.g. `X: 'x` was a reasonable inferred requirement.
308-
if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
309-
if ty.is_self() && ignore_self_ty.0 {
310-
debug!("skipping self ty = {:?}", &ty);
311-
continue;
318+
//
319+
// Another similar case is where we have a inferred
320+
// requirement like `<Self as Trait>::Foo: 'b`. We presently
321+
// ignore such requirements as well (cc #54467)-- though
322+
// conceivably it might be better if we could extract the `Foo
323+
// = X` binding from the object type (there must be such a
324+
// binding) and thus infer an outlives requirement that `X:
325+
// 'b`.
326+
if ignore_self_ty.0 {
327+
if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
328+
if ty.has_self_ty() {
329+
debug!("skipping self ty = {:?}", &ty);
330+
continue;
331+
}
312332
}
313333
}
314334

src/librustc_typeck/outlives/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ fn inferred_outlives_of<'a, 'tcx>(
6767
}
6868
err.emit();
6969
}
70+
71+
debug!("inferred_outlives_of({:?}) = {:?}", item_def_id, predicates);
72+
7073
predicates
7174
}
7275

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Regression test for #54467:
2+
//
3+
// Here, the trait object has an "inferred outlives" requirement that
4+
// `<Self as MyIterator<'a>>::Item: 'a`; but since we don't know what
5+
// `Self` is, we were (incorrectly) messing things up, leading to
6+
// strange errors. This test ensures that we do not give compilation
7+
// errors.
8+
//
9+
// compile-pass
10+
11+
trait MyIterator<'a>: Iterator where Self::Item: 'a { }
12+
13+
struct MyStruct<'a, A> {
14+
item: Box<dyn MyIterator<'a, Item = A>>
15+
}
16+
17+
fn main() { }

0 commit comments

Comments
 (0)