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 247899832
r? `@nikomatsakis`
This commit is contained in:
commit
1eb187c16e
6 changed files with 93 additions and 3 deletions
|
@ -1586,12 +1586,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// See if we can toss out `victim` based on specialization.
|
// See if we can toss out `victim` based on specialization.
|
||||||
// This requires us to know *for sure* that the `other` impl applies
|
// This requires us to know *for sure* that the `other` impl applies
|
||||||
// i.e., `EvaluatedToOk`.
|
// 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() {
|
if other.evaluation.must_apply_modulo_regions() {
|
||||||
let tcx = self.tcx();
|
|
||||||
if tcx.specializes((other_def, victim_def)) {
|
if tcx.specializes((other_def, victim_def)) {
|
||||||
return true;
|
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 }) => {
|
Some(ty::ImplOverlapKind::Permitted { marker: true }) => {
|
||||||
// Subtle: If the predicate we are evaluating has inference
|
// Subtle: If the predicate we are evaluating has inference
|
||||||
// variables, do *not* allow discarding candidates due to
|
// variables, do *not* allow discarding candidates due to
|
||||||
|
@ -1636,7 +1643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
Some(_) => true,
|
Some(_) => true,
|
||||||
None => false,
|
None => false,
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {}
|
8
src/test/ui/marker_trait_attr/region-overlap.rs
Normal file
8
src/test/ui/marker_trait_attr/region-overlap.rs
Normal file
|
@ -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() {}
|
29
src/test/ui/marker_trait_attr/region-overlap.stderr
Normal file
29
src/test/ui/marker_trait_attr/region-overlap.stderr
Normal file
|
@ -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`.
|
25
src/test/ui/marker_trait_attr/unsound-overlap.rs
Normal file
25
src/test/ui/marker_trait_attr/unsound-overlap.rs
Normal file
|
@ -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() {}
|
12
src/test/ui/marker_trait_attr/unsound-overlap.stderr
Normal file
12
src/test/ui/marker_trait_attr/unsound-overlap.stderr
Normal file
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue