From 24e14dd8b40a2434fc2343342c30d8d5748d1c5a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 5 Nov 2023 13:36:00 +0000 Subject: [PATCH] Only check predicates for late-bound non-lifetime vars in object candidate assembly --- .../src/traits/select/candidate_assembly.rs | 5 ++++- .../disqualifying-object-candidates.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/non_lifetime_binders/disqualifying-object-candidates.rs diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 5c67188dd24..ba551127ce1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -628,7 +628,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } self.infcx.probe(|_snapshot| { - if obligation.has_non_region_late_bound() { + // FIXME(non_lifetime_binders): Really, we care only to check that we don't + // have any non-region *escaping* bound vars, but that's hard to check and + // we shouldn't really ever encounter those anyways. + if obligation.self_ty().has_non_region_late_bound() { return; } diff --git a/tests/ui/traits/non_lifetime_binders/disqualifying-object-candidates.rs b/tests/ui/traits/non_lifetime_binders/disqualifying-object-candidates.rs new file mode 100644 index 00000000000..b999f251d33 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/disqualifying-object-candidates.rs @@ -0,0 +1,19 @@ +// check-pass + +trait Foo { + type Bar + where + dyn Send + 'static: Send; +} + +impl Foo for () { + type Bar = i32; + // We take `<() as Foo>::Bar: Sized` and normalize it under the where clause + // of `for <() as Foo>::Bar = i32`. This gives us back `i32: Send` with + // the nested obligation `(dyn Send + 'static): Send`. However, during candidate + // assembly for object types, we disqualify any obligations that has non-region + // late-bound vars in the param env(!), rather than just the predicate. This causes + // the where clause to not hold even though it trivially should. +} + +fn main() {}