Skip to content

Commit a7e2981

Browse files
committed
builtin dyn impl no guide inference
1 parent bbd3a5a commit a7e2981

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1917,12 +1917,23 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
19171917
// impl `impl<T: ?Sized> Any for T { .. }`. This really shouldn't exist but is
19181918
// necessary due to #57893. We again arbitrarily prefer the applicable candidate
19191919
// with the lowest index.
1920+
//
1921+
// We do not want to use these impls to guide inference in case a user-written impl
1922+
// may also apply.
19201923
let object_bound = candidates
19211924
.iter()
19221925
.filter_map(|c| if let ObjectCandidate(i) = c.candidate { Some(i) } else { None })
19231926
.try_reduce(|c1, c2| if has_non_region_infer { None } else { Some(c1.min(c2)) });
19241927
match object_bound {
1925-
Some(Some(index)) => return Some(ObjectCandidate(index)),
1928+
Some(Some(index)) => {
1929+
return if has_non_region_infer
1930+
&& candidates.iter().any(|c| matches!(c.candidate, ImplCandidate(_)))
1931+
{
1932+
None
1933+
} else {
1934+
Some(ObjectCandidate(index))
1935+
};
1936+
}
19261937
Some(None) => {}
19271938
None => return None,
19281939
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0283]: type annotations needed
2+
--> $DIR/no-incomplete-inference.rs:16:5
3+
|
4+
LL | impls_equals::<dyn Equals<u32>, _>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_equals`
6+
|
7+
= note: cannot satisfy `dyn Equals<u32>: Equals<_>`
8+
note: required by a bound in `impls_equals`
9+
--> $DIR/no-incomplete-inference.rs:13:20
10+
|
11+
LL | fn impls_equals<T: Equals<U> + ?Sized, U: ?Sized>() {}
12+
| ^^^^^^^^^ required by this bound in `impls_equals`
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0283`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0283]: type annotations needed
2+
--> $DIR/no-incomplete-inference.rs:16:5
3+
|
4+
LL | impls_equals::<dyn Equals<u32>, _>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_equals`
6+
|
7+
= note: cannot satisfy `dyn Equals<u32>: Equals<_>`
8+
note: required by a bound in `impls_equals`
9+
--> $DIR/no-incomplete-inference.rs:13:20
10+
|
11+
LL | fn impls_equals<T: Equals<U> + ?Sized, U: ?Sized>() {}
12+
| ^^^^^^^^^ required by this bound in `impls_equals`
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0283`.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
5+
6+
// Make sure that having an applicable user-written
7+
// and builtin impl is ambiguous.
8+
9+
trait Equals<T: ?Sized> {}
10+
11+
impl<T: ?Sized> Equals<T> for T {}
12+
13+
fn impls_equals<T: Equals<U> + ?Sized, U: ?Sized>() {}
14+
15+
fn main() {
16+
impls_equals::<dyn Equals<u32>, _>();
17+
//~^ ERROR type annotations needed
18+
}

0 commit comments

Comments
 (0)