Skip to content

Commit 9578b59

Browse files
Only select true errors in impossible_predicates
1 parent 36ad75b commit 9578b59

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

compiler/rustc_trait_selection/src/traits/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -701,9 +701,15 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
701701
let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate);
702702
ocx.register_obligation(obligation);
703703
}
704-
let errors = ocx.select_all_or_error();
705704

706-
if !errors.is_empty() {
705+
// Use `select_where_possible` to only return impossible for true errors,
706+
// and not ambiguities or overflows. Since the new trait solver forces
707+
// some currently undetected overlap between `dyn Trait: Trait` built-in
708+
// vs user-written impls to AMBIGUOUS, this may return ambiguity even
709+
// with no infer vars. There may also be ways to encounter ambiguity due
710+
// to post-mono overflow.
711+
let true_errors = ocx.select_where_possible();
712+
if !true_errors.is_empty() {
707713
return true;
708714
}
709715

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// In this example below, we have two overlapping candidates for `dyn Q: Q`.
2+
// Specifically, the user written impl for `<dyn Q as Mirror>::Assoc` and the
3+
// built-in impl for object types. Since they differ by their region responses,
4+
// the goal is ambiguous. This affects codegen since impossible obligations
5+
// for method dispatch will lead to a segfault, since we end up emitting dummy
6+
// call vtable offsets due to <https://github.com/rust-lang/rust/pull/136311>.
7+
8+
// Test for <https://github.com/rust-lang/rust/issues/141119>.
9+
10+
//@ run-pass
11+
12+
trait Mirror {
13+
type Assoc: ?Sized;
14+
}
15+
impl<T: ?Sized> Mirror for T {
16+
type Assoc = T;
17+
}
18+
19+
trait Q: 'static {
20+
fn q(&self);
21+
}
22+
23+
impl Q for i32 {
24+
fn q(&self) { println!("i32"); }
25+
}
26+
27+
impl Q for <dyn Q as Mirror>::Assoc where Self: 'static {
28+
fn q(&self) { println!("dyn Q"); }
29+
}
30+
31+
fn foo<T: Q + ?Sized>(t: &T) {
32+
t.q();
33+
}
34+
35+
fn main() {
36+
foo(&1 as &dyn Q);
37+
}

0 commit comments

Comments
 (0)