Skip to content

Commit

Permalink
Auto merge of rust-lang#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 rust-lang#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 rust-lang#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.