diff options
| author | bors <bors@rust-lang.org> | 2021-08-22 10:44:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-08-22 10:44:38 +0000 |
| commit | 1eb187c16ec4f26fdeaff527e3ba2b1e609cabd2 (patch) | |
| tree | 18f682ff9ed72b38d477b84cbbe7145a5a145ce5 | |
| parent | 80dad6477520553899049c994a6f534dce5a4951 (diff) | |
| parent | 3329f67f173028bc41165894611ef54cab2c1438 (diff) | |
| download | rust-1eb187c16ec4f26fdeaff527e3ba2b1e609cabd2.tar.gz rust-1eb187c16ec4f26fdeaff527e3ba2b1e609cabd2.zip | |
Auto merge of #88139 - lcnr:marker-trait-attr, r=nikomatsakis
marker_traits: require `EvaluatedToOk` during winnowing closes #84955, while it doesn't really fix it in a way that makes me happy it should prevent the issue for now and this test can't be reproduced anyways, so it doesn't make much sense to keep it open. fixes #84917 as only one of the impls depends on regions, so we now drop the ambiguous one instead of the correct one. cc https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/winnowing.20soundly/near/247899832 r? `@nikomatsakis`
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 14d8aa494be..f95e7b8b6c3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1586,12 +1586,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 @@ -1636,7 +1643,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`. |
