about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-05-30 19:45:27 -0400
committerMichael Goulet <michael@errs.io>2024-05-30 19:45:59 -0400
commite485b193d07a77495dcdcb3f52f5976c9c9ca1f4 (patch)
treee38739b95556b6ac3a69a4b480fc7bbdf9b7fdcc
parent6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4 (diff)
downloadrust-e485b193d07a77495dcdcb3f52f5976c9c9ca1f4.tar.gz
rust-e485b193d07a77495dcdcb3f52f5976c9c9ca1f4.zip
Don't drop Upcast candidate in intercrate mode
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs6
-rw-r--r--tests/ui/specialization/dont-drop-upcast-candidate.rs13
-rw-r--r--tests/ui/specialization/dont-drop-upcast-candidate.stderr11
3 files changed, 30 insertions, 0 deletions
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 fd7c47ad6fb..f0ecbd83341 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -921,6 +921,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         cause: &ObligationCause<'tcx>,
     ) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
+        // Don't drop any candidates in intercrate mode, as it's incomplete.
+        // (Not that it matters, since `Unsize` is not a stable trait.)
+        if self.infcx.intercrate {
+            return None;
+        }
+
         let tcx = self.tcx();
         if tcx.features().trait_upcasting {
             return None;
diff --git a/tests/ui/specialization/dont-drop-upcast-candidate.rs b/tests/ui/specialization/dont-drop-upcast-candidate.rs
new file mode 100644
index 00000000000..98d8cad7c1f
--- /dev/null
+++ b/tests/ui/specialization/dont-drop-upcast-candidate.rs
@@ -0,0 +1,13 @@
+#![feature(unsize)]
+
+use std::marker::Unsize;
+use std::ops::Deref;
+
+trait Foo: Bar {}
+trait Bar {}
+
+impl<T> Bar for T where dyn Foo: Unsize<dyn Bar> {}
+impl Bar for () {}
+//~^ ERROR conflicting implementations of trait `Bar` for type `()`
+
+fn main() {}
diff --git a/tests/ui/specialization/dont-drop-upcast-candidate.stderr b/tests/ui/specialization/dont-drop-upcast-candidate.stderr
new file mode 100644
index 00000000000..dc0c54f9aa8
--- /dev/null
+++ b/tests/ui/specialization/dont-drop-upcast-candidate.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `Bar` for type `()`
+  --> $DIR/dont-drop-upcast-candidate.rs:10:1
+   |
+LL | impl<T> Bar for T where dyn Foo: Unsize<dyn Bar> {}
+   | ------------------------------------------------ first implementation here
+LL | impl Bar for () {}
+   | ^^^^^^^^^^^^^^^ conflicting implementation for `()`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.