about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2021-08-18 16:27:25 +0200
committerlcnr <rust@lcnr.de>2021-08-18 16:34:54 +0200
commit3329f67f173028bc41165894611ef54cab2c1438 (patch)
treeaeb9cae587ef8d8bc17cfd3b546ed27301265b38
parent896f058f13d6c8021f7637817953a44d3a78be32 (diff)
marker_traits: require `EvaluatedToOk`
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs13
-rw-r--r--src/test/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs9
-rw-r--r--src/test/ui/marker_trait_attr/region-overlap.rs8
-rw-r--r--src/test/ui/marker_trait_attr/region-overlap.stderr29
-rw-r--r--src/test/ui/marker_trait_attr/unsound-overlap.rs25
-rw-r--r--src/test/ui/marker_trait_attr/unsound-overlap.stderr12
6 files changed, 93 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 38dbacbf2ae..4eee31a8e81 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1566,12 +1566,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // See if we can toss out `victim` based on specialization.
                 // This requires us to know *for sure* that the `other` impl applies
                 // i.e., `EvaluatedToOk`.
+                //
+                // FIXME(@lcnr): Using `modulo_regions` here seems kind of scary
+                // to me but is required for `std` to compile, so I didn't change it
+                // for now.
+                let tcx = self.tcx();
                 if other.evaluation.must_apply_modulo_regions() {
-                    let tcx = self.tcx();
                     if tcx.specializes((other_def, victim_def)) {
                         return true;
                     }
-                    return match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
+                }
+
+                if other.evaluation.must_apply_considering_regions() {
+                    match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
                         Some(ty::ImplOverlapKind::Permitted { marker: true }) => {
                             // Subtle: If the predicate we are evaluating has inference
                             // variables, do *not* allow discarding candidates due to
@@ -1616,7 +1623,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         }
                         Some(_) => true,
                         None => false,
-                    };
+                    }
                 } else {
                     false
                 }
diff --git a/src/test/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs b/src/test/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs
new file mode 100644
index 00000000000..a8f3db5f5b2
--- /dev/null
+++ b/src/test/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs
@@ -0,0 +1,9 @@
+// check-pass
+#![feature(marker_trait_attr)]
+
+#[marker]
+pub trait F {}
+impl<T> F for T where T: Copy {}
+impl<T> F for T where T: 'static {}
+
+fn main() {}
diff --git a/src/test/ui/marker_trait_attr/region-overlap.rs b/src/test/ui/marker_trait_attr/region-overlap.rs
new file mode 100644
index 00000000000..b3c66710355
--- /dev/null
+++ b/src/test/ui/marker_trait_attr/region-overlap.rs
@@ -0,0 +1,8 @@
+#![feature(marker_trait_attr)]
+
+#[marker]
+trait A {}
+impl<'a> A for (&'static (), &'a ()) {} //~ ERROR type annotations needed
+impl<'a> A for (&'a (), &'static ()) {} //~ ERROR type annotations needed
+
+fn main() {}
diff --git a/src/test/ui/marker_trait_attr/region-overlap.stderr b/src/test/ui/marker_trait_attr/region-overlap.stderr
new file mode 100644
index 00000000000..e4a94d56f12
--- /dev/null
+++ b/src/test/ui/marker_trait_attr/region-overlap.stderr
@@ -0,0 +1,29 @@
+error[E0283]: type annotations needed
+  --> $DIR/region-overlap.rs:5:10
+   |
+LL | impl<'a> A for (&'static (), &'a ()) {}
+   |          ^ cannot infer type for tuple `(&'static (), &'a ())`
+   |
+   = note: cannot satisfy `(&'static (), &'a ()): A`
+note: required by a bound in `A`
+  --> $DIR/region-overlap.rs:4:1
+   |
+LL | trait A {}
+   | ^^^^^^^ required by this bound in `A`
+
+error[E0283]: type annotations needed
+  --> $DIR/region-overlap.rs:6:10
+   |
+LL | impl<'a> A for (&'a (), &'static ()) {}
+   |          ^ cannot infer type for tuple `(&'a (), &'static ())`
+   |
+   = note: cannot satisfy `(&'a (), &'static ()): A`
+note: required by a bound in `A`
+  --> $DIR/region-overlap.rs:4:1
+   |
+LL | trait A {}
+   | ^^^^^^^ required by this bound in `A`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/marker_trait_attr/unsound-overlap.rs b/src/test/ui/marker_trait_attr/unsound-overlap.rs
new file mode 100644
index 00000000000..2e5101b822c
--- /dev/null
+++ b/src/test/ui/marker_trait_attr/unsound-overlap.rs
@@ -0,0 +1,25 @@
+#![feature(marker_trait_attr)]
+
+#[marker]
+trait A {}
+
+trait B {}
+
+impl<T: A> B for T {}
+impl<T: B> A for T {}
+impl A for &str {}
+impl<T: A + B> A for (T,) {}
+trait TraitWithAssoc {
+    type Assoc;
+}
+
+impl<T: A> TraitWithAssoc for T {
+    type Assoc = T;
+}
+
+impl TraitWithAssoc for ((&str,),) {
+    //~^ ERROR conflicting implementations
+    type Assoc = ((&'static str,),);
+}
+
+fn main() {}
diff --git a/src/test/ui/marker_trait_attr/unsound-overlap.stderr b/src/test/ui/marker_trait_attr/unsound-overlap.stderr
new file mode 100644
index 00000000000..5ebac8270dd
--- /dev/null
+++ b/src/test/ui/marker_trait_attr/unsound-overlap.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `TraitWithAssoc` for type `((&str,),)`
+  --> $DIR/unsound-overlap.rs:20:1
+   |
+LL | impl<T: A> TraitWithAssoc for T {
+   | ------------------------------- first implementation here
+...
+LL | impl TraitWithAssoc for ((&str,),) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `((&str,),)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.