diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 38dbacbf2ae6c..4eee31a8e816c 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 0000000000000..a8f3db5f5b25b --- /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 F for T where T: Copy {} +impl 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 0000000000000..b3c667103555a --- /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 0000000000000..e4a94d56f12b0 --- /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 0000000000000..2e5101b822c0c --- /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 B for T {} +impl A for T {} +impl A for &str {} +impl A for (T,) {} +trait TraitWithAssoc { + type Assoc; +} + +impl 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 0000000000000..5ebac8270ddff --- /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 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`.