Skip to content

Prohibit implementations of outer traits and types in blocks (function bodies, etc) #1355

Closed
@petrochenkov

Description

@petrochenkov

Consider the next code:

struct S;
trait A {}
trait B {}
trait C {}

fn check<T: A + B + C>(_: T) {}

fn block1() {
    impl A for S {} 
}
const BLOCK2: u8 = { impl B for S {} 0 };

const BLOCK3: [u8; { impl C for S {} 0 }] = [];

fn main() {
    check(S);
}

We see here that some things internal to function bodies or other blocks can leak outside and affect compilation of remote pieces of code. This doesn't normally happen (with exception of consts and const functions, which leak their bodies through their results available at compile time, but this is by design).

In the example above to find out if check(S) compiles or not compiler or other tools have to traverse the whole AST looking into every function, expression or type, because blocks can live pretty much anywhere and blocks can contain impls. Without impls in blocks algorithms traversing AST can take major shortcuts and scan only the surface, ignoring internals of function bodies, types, fields, etc. which is especially important for tools (cc @nrc) or things like incremental compilation (cc @nikomatsakis), I suppose.

I've seen several visitors in the compiler that already take these shortcuts, leading to errors in corner cases. I propose to make it official and prohibit implementing traits and types not belonging to a block in this block. I wouldn't expect it to break anything in existing code, but to bring more speed to some visitors and more convenience to people writing them.

Detailed design:

  • impl T { ... } in a block is prohibited if T is defined outside of this block
  • impl Tr for T { ... } in a block is prohibited if Tr and T are defined outside of this block
  • impl Tr for .. { } in a block is prohibited if Tr is defined outside of this block

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions