about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-02-13 19:20:13 +0000
committerMichael Goulet <michael@errs.io>2024-02-13 19:20:13 +0000
commitb4eee2e8b3bad92465959679901fd5ecb4ada743 (patch)
treee87c129faaecea087b0c5000b13584249f887347
parentbc1b9e0e9a813d27a09708b293dc2d41c472f0d0 (diff)
downloadrust-b4eee2e8b3bad92465959679901fd5ecb4ada743.tar.gz
rust-b4eee2e8b3bad92465959679901fd5ecb4ada743.zip
Do not assemble candidates for default impls
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs8
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs2
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr18
-rw-r--r--tests/ui/specialization/defaultimpl/validation.rs1
-rw-r--r--tests/ui/specialization/defaultimpl/validation.stderr22
-rw-r--r--tests/ui/specialization/issue-45814.current.stderr16
-rw-r--r--tests/ui/specialization/issue-45814.negative.stderr16
-rw-r--r--tests/ui/specialization/issue-45814.rs2
9 files changed, 59 insertions, 40 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 6833d2ae330..4e78988a0da 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -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) => (),
@@ -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) => (),
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 31a0d6271fa..149dc4c75a7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -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,
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs
index 6834d573629..344dd7bb288 100644
--- a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs
@@ -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
 }
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
index e9b0845ccf7..74f81bb023e 100644
--- a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
@@ -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
diff --git a/tests/ui/specialization/defaultimpl/validation.rs b/tests/ui/specialization/defaultimpl/validation.rs
index 8558a1efb82..4049c4ea14c 100644
--- a/tests/ui/specialization/defaultimpl/validation.rs
+++ b/tests/ui/specialization/defaultimpl/validation.rs
@@ -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
 
diff --git a/tests/ui/specialization/defaultimpl/validation.stderr b/tests/ui/specialization/defaultimpl/validation.stderr
index eb6dc9355a3..5f62e8dce17 100644
--- a/tests/ui/specialization/defaultimpl/validation.stderr
+++ b/tests/ui/specialization/defaultimpl/validation.stderr
@@ -26,8 +26,19 @@ 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
@@ -35,17 +46,18 @@ LL | default impl !Send for Z {}
    | 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`.
diff --git a/tests/ui/specialization/issue-45814.current.stderr b/tests/ui/specialization/issue-45814.current.stderr
index da0dff78e26..b89d3073a8f 100644
--- a/tests/ui/specialization/issue-45814.current.stderr
+++ b/tests/ui/specialization/issue-45814.current.stderr
@@ -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`.
diff --git a/tests/ui/specialization/issue-45814.negative.stderr b/tests/ui/specialization/issue-45814.negative.stderr
index da0dff78e26..b89d3073a8f 100644
--- a/tests/ui/specialization/issue-45814.negative.stderr
+++ b/tests/ui/specialization/issue-45814.negative.stderr
@@ -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`.
diff --git a/tests/ui/specialization/issue-45814.rs b/tests/ui/specialization/issue-45814.rs
index fce236390c2..832d734d945 100644
--- a/tests/ui/specialization/issue-45814.rs
+++ b/tests/ui/specialization/issue-45814.rs
@@ -1,4 +1,3 @@
-//~ ERROR overflow evaluating the requirement `T: Trait<_>`
 // revisions: current negative
 #![feature(specialization)]
 #![cfg_attr(negative, feature(with_negative_coherence))]
@@ -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() {}