Skip to content

Commit

Permalink
Auto merge of #88139 - lcnr:marker-trait-attr, r=nikomatsakis
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Aug 22, 2021
2 parents 80dad64 + 3329f67 commit 1eb187c
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 3 deletions.
13 changes: 10 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1636,7 +1643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
Some(_) => true,
None => false,
};
}
} else {
false
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions src/test/ui/marker_trait_attr/region-overlap.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 29 additions & 0 deletions src/test/ui/marker_trait_attr/region-overlap.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions src/test/ui/marker_trait_attr/unsound-overlap.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions src/test/ui/marker_trait_attr/unsound-overlap.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 1eb187c

Please sign in to comment.