Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Associated types appear to cover or hide generic parameters in orphan rules checking #107377

Closed
steffahn opened this issue Jan 27, 2023 · 1 comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-coherence Area: Coherence A-traits Area: Trait system C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@steffahn
Copy link
Member

steffahn commented Jan 27, 2023

Here’s a soundness issue in the orphan rules checker. @rustbot label I-unsound, A-traits, A-associated-items, T-compiler.

One crate foo defines

pub trait Trait<Arg> {}

If a downstream crate uses foo and tries to implement

use foo::Trait;

pub struct Local<T>(T);

impl<T> Trait<Local<T>> for T {}

it fails as expected

error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local<T>`)
 --> dep1/src/lib.rs:5:6
  |
5 | impl<T> Trait<Local<T>> for T {}
  |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local<T>`)
  |
  = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
  = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last

and rightfully so, since other crates depending on foo might define an impl<T> Trait<T> for OtherLocal {} that overlaps.

But we can circumvent this error using a trait with an associated type, violating the orphan rules!

use foo::Trait;

pub struct Local<T>(T);

impl<T> Trait<Local<T>> for <T as WithAssoc>::Assoc {}

// implementing `<T as WithAssoc>::Assoc` to be `T`:

pub trait WithAssoc {
    type Assoc;
}

impl<T> WithAssoc for T {
    type Assoc = T;
}

(compiles fine)

I have only managed to turn this into an ICE during code generation so far, not UB at run-time, but I would be surprised if there wasn’t a way to actually exploit this bug, hence the label. I’ll look back into this in the next few days and either post a soundness exploit, or at least the way to achieve ICE.

@steffahn steffahn added the C-bug Category: This is a bug. label Jan 27, 2023
@rustbot rustbot added A-traits Area: Trait system I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jan 27, 2023
@Noratrieb Noratrieb added the A-coherence Area: Coherence label Jan 27, 2023
@rustbot rustbot added the A-associated-items Area: Associated items such as associated types and consts. label Jan 27, 2023
@steffahn
Copy link
Member Author

Nevermind, it’s a duplicate of #99554

@apiraino apiraino removed the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Jan 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-coherence Area: Coherence A-traits Area: Trait system C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants