Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not assemble candidates for default impls #121047

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions compiler/rustc_trait_selection/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let mut consider_impls_for_simplified_type = |simp| {
if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
for &impl_def_id in impls_for_type {
// For every `default impl`, there's always a non-default `impl`
// that will *also* apply. There's no reason to register a candidate
// for this impl, since it is *not* proof that the trait goal holds.
if tcx.defaultness(impl_def_id).is_default() {
return;
}

match G::consider_impl_candidate(self, goal, impl_def_id) {
Ok(candidate) => candidates.push(candidate),
Err(NoSolution) => (),
Expand Down Expand Up @@ -441,6 +448,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let tcx = self.tcx();
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
for &impl_def_id in trait_impls.blanket_impls() {
// For every `default impl`, there's always a non-default `impl`
// that will *also* apply. There's no reason to register a candidate
// for this impl, since it is *not* proof that the trait goal holds.
if tcx.defaultness(impl_def_id).is_default() {
return;
}

match G::consider_impl_candidate(self, goal, impl_def_id) {
Ok(candidate) => candidates.push(candidate),
Err(NoSolution) => (),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
{
return;
}

// For every `default impl`, there's always a non-default `impl`
// that will *also* apply. There's no reason to register a candidate
// for this impl, since it is *not* proof that the trait goal holds.
if self.tcx().defaultness(impl_def_id).is_default() {
return;
}

if self.reject_fn_ptr_impls(
impl_def_id,
obligation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ default impl<T> Foo for T {

fn main() {
println!("{}", MyStruct.foo_one());
//~^ ERROR the method
//~^ ERROR no method named `foo_one` found for struct `MyStruct` in the current scope
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,15 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete
= note: `#[warn(incomplete_features)]` on by default

error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait bounds were not satisfied
error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope
--> $DIR/specialization-trait-not-implemented.rs:22:29
|
LL | struct MyStruct;
| --------------- method `foo_one` not found for this struct because it doesn't satisfy `MyStruct: Foo`
| --------------- method `foo_one` not found for this struct
...
LL | println!("{}", MyStruct.foo_one());
| ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds
| ^^^^^^^ method not found in `MyStruct`
|
note: trait bound `MyStruct: Foo` was not satisfied
--> $DIR/specialization-trait-not-implemented.rs:14:1
|
LL | default impl<T> Foo for T {
| ^^^^^^^^^^^^^^^^---^^^^^-
| |
| unsatisfied trait bound introduced here
note: the trait `Foo` must be implemented
--> $DIR/specialization-trait-not-implemented.rs:7:1
|
LL | trait Foo {
| ^^^^^^^^^
= help: items from traits can only be used if the trait is implemented and in scope
note: `Foo` defines an item `foo_one`, perhaps you need to implement it
--> $DIR/specialization-trait-not-implemented.rs:7:1
Expand Down
1 change: 1 addition & 0 deletions tests/ui/specialization/defaultimpl/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ struct Z;
default impl S {} //~ ERROR inherent impls cannot be `default`

default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
//~^ ERROR `S` cannot be sent between threads safely
default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
//~^ ERROR negative impls cannot be default impls

Expand Down
22 changes: 17 additions & 5 deletions tests/ui/specialization/defaultimpl/validation.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,38 @@ LL | default unsafe impl Send for S {}
| |
| default because of this

error[E0277]: `S` cannot be sent between threads safely
--> $DIR/validation.rs:9:1
|
LL | default unsafe impl Send for S {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `S` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `S`
= help: the trait `Send` is implemented for `S`
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable

error: impls of auto traits cannot be default
--> $DIR/validation.rs:10:15
--> $DIR/validation.rs:11:15
|
LL | default impl !Send for Z {}
| ------- ^^^^ auto trait
| |
| default because of this

error[E0750]: negative impls cannot be default impls
--> $DIR/validation.rs:10:1
--> $DIR/validation.rs:11:1
|
LL | default impl !Send for Z {}
| ^^^^^^^ ^

error[E0750]: negative impls cannot be default impls
--> $DIR/validation.rs:14:1
--> $DIR/validation.rs:15:1
|
LL | default impl !Tr for S {}
| ^^^^^^^ ^

error: aborting due to 5 previous errors; 1 warning emitted
error: aborting due to 6 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0750`.
Some errors have detailed explanations: E0277, E0750.
For more information about an error, try `rustc --explain E0277`.
16 changes: 7 additions & 9 deletions tests/ui/specialization/issue-45814.current.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
note: required for `T` to implement `Trait<_>`
--> $DIR/issue-45814.rs:9:20
error[E0119]: conflicting implementations of trait `Trait<_>`
--> $DIR/issue-45814.rs:10:1
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
= note: 128 redundant requirements hidden
= note: required for `T` to implement `Trait<_>`
| --------------------------------- first implementation here
LL |
LL | impl<T> Trait<<T as Iterator>::Item> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
For more information about this error, try `rustc --explain E0119`.
16 changes: 7 additions & 9 deletions tests/ui/specialization/issue-45814.negative.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
note: required for `T` to implement `Trait<_>`
--> $DIR/issue-45814.rs:9:20
error[E0119]: conflicting implementations of trait `Trait<_>`
--> $DIR/issue-45814.rs:10:1
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
= note: 128 redundant requirements hidden
= note: required for `T` to implement `Trait<_>`
| --------------------------------- first implementation here
LL |
LL | impl<T> Trait<<T as Iterator>::Item> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
For more information about this error, try `rustc --explain E0119`.
2 changes: 1 addition & 1 deletion tests/ui/specialization/issue-45814.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//~ ERROR overflow evaluating the requirement `T: Trait<_>`
// revisions: current negative
#![feature(specialization)]
#![cfg_attr(negative, feature(with_negative_coherence))]
Expand All @@ -9,5 +8,6 @@ pub trait Trait<T> {}
default impl<T, U> Trait<T> for U {}

impl<T> Trait<<T as Iterator>::Item> for T {}
//~^ ERROR conflicting implementations of trait `Trait<_>`

fn main() {}
Loading