Skip to content

Commit 705435f

Browse files
authored
Rollup merge of #109619 - compiler-errors:new-solver-still-further-specializable, r=BoxyUwU
Still-further-specializable projections are ambiguous in new solver Fixes https://github.com/rust-lang/rust/pull/108896/files#r1148450781 r? ``@BoxyUwU`` (though feel free to re-roll) --- This can be used to create an unsound transmute function with the new solver: ```rust #![feature(specialization)] trait Default { type Id; fn intu(&self) -> &Self::Id; } impl<T> Default for T { default type Id = T; fn intu(&self) -> &Self::Id { self } } fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U { *t.intu() } use std::num::NonZeroU8; fn main() { let s = transmute::<u8, Option<NonZeroU8>>(0); assert_eq!(s, None); } ```
2 parents 2361786 + 3310f72 commit 705435f

File tree

6 files changed

+111
-3
lines changed

6 files changed

+111
-3
lines changed

compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,8 @@ pub enum AliasRelationDirection {
653653
impl std::fmt::Display for AliasRelationDirection {
654654
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
655655
match self {
656-
AliasRelationDirection::Equate => write!(f, " == "),
657-
AliasRelationDirection::Subtype => write!(f, " <: "),
656+
AliasRelationDirection::Equate => write!(f, "=="),
657+
AliasRelationDirection::Subtype => write!(f, "<:"),
658658
}
659659
}
660660
}

compiler/rustc_trait_selection/src/solve/project_goals.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
174174
goal.predicate.def_id(),
175175
impl_def_id
176176
)? else {
177-
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
177+
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
178178
};
179179

180180
if !assoc_def.item.defaultness(tcx).has_value() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// compile-flags: -Ztrait-solver=next
2+
3+
#![feature(specialization)]
4+
//~^ WARN the feature `specialization` is incomplete
5+
6+
trait Default {
7+
type Id;
8+
9+
fn intu(&self) -> &Self::Id;
10+
}
11+
12+
impl<T> Default for T {
13+
default type Id = T;
14+
15+
fn intu(&self) -> &Self::Id {
16+
self
17+
//~^ ERROR cannot satisfy `T <: <T as Default>::Id`
18+
}
19+
}
20+
21+
fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U {
22+
*t.intu()
23+
}
24+
25+
use std::num::NonZeroU8;
26+
fn main() {
27+
let s = transmute::<u8, Option<NonZeroU8>>(0);
28+
//~^ ERROR cannot satisfy `<u8 as Default>::Id == Option<NonZeroU8>
29+
assert_eq!(s, None);
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/specialization-transmute.rs:3:12
3+
|
4+
LL | #![feature(specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
error[E0284]: type annotations needed: cannot satisfy `T <: <T as Default>::Id`
12+
--> $DIR/specialization-transmute.rs:16:9
13+
|
14+
LL | self
15+
| ^^^^ cannot satisfy `T <: <T as Default>::Id`
16+
17+
error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZeroU8>`
18+
--> $DIR/specialization-transmute.rs:27:13
19+
|
20+
LL | let s = transmute::<u8, Option<NonZeroU8>>(0);
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZeroU8>`
22+
|
23+
note: required by a bound in `transmute`
24+
--> $DIR/specialization-transmute.rs:21:25
25+
|
26+
LL | fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U {
27+
| ^^^^^^ required by this bound in `transmute`
28+
29+
error: aborting due to 2 previous errors; 1 warning emitted
30+
31+
For more information about this error, try `rustc --explain E0284`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// compile-flags: -Ztrait-solver=next
2+
3+
#![feature(specialization)]
4+
//~^ WARN the feature `specialization` is incomplete
5+
6+
// Do not treat the RHS of a projection-goal as an unconstrained `Certainty::Yes` response
7+
// if the impl is still further specializable.
8+
9+
trait Default {
10+
type Id;
11+
}
12+
13+
impl<T> Default for T {
14+
default type Id = T;
15+
}
16+
17+
fn test<T: Default<Id = U>, U>() {}
18+
19+
fn main() {
20+
test::<u32, ()>();
21+
//~^ ERROR cannot satisfy `<u32 as Default>::Id == ()`
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/specialization-unconstrained.rs:3:12
3+
|
4+
LL | #![feature(specialization)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
8+
= help: consider using `min_specialization` instead, which is more stable and complete
9+
= note: `#[warn(incomplete_features)]` on by default
10+
11+
error[E0284]: type annotations needed: cannot satisfy `<u32 as Default>::Id == ()`
12+
--> $DIR/specialization-unconstrained.rs:20:5
13+
|
14+
LL | test::<u32, ()>();
15+
| ^^^^^^^^^^^^^^^ cannot satisfy `<u32 as Default>::Id == ()`
16+
|
17+
note: required by a bound in `test`
18+
--> $DIR/specialization-unconstrained.rs:17:20
19+
|
20+
LL | fn test<T: Default<Id = U>, U>() {}
21+
| ^^^^^^ required by this bound in `test`
22+
23+
error: aborting due to previous error; 1 warning emitted
24+
25+
For more information about this error, try `rustc --explain E0284`.

0 commit comments

Comments
 (0)