Skip to content

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

New issue

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

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

Already on GitHub? # to your account

Closed
steffahn opened this issue Jan 27, 2023 · 1 comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-coherence Area: Coherence A-trait-system 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-trait-system 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 (types, constants & functions) 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-coherence Area: Coherence A-trait-system 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