Skip to content

Breakage related to where Self: Sized bounds on trait associated types and methods #786

@obi1kenobi

Description

@obi1kenobi

Rust appears to allow trait items (so far, types and methods, in the future possibly also constants) to be excluded from trait objects by applying Self: Sized bounds like so:

pub trait Example {
    type Item where Self: Sized;
    
    fn method(&self) -> Self::Item where Self: Sized;
}

As far as I can tell, it is not required to repeat where Self: Sized on the items of trait implementations, so the breakage has to come from attempts to call or use the defined functionality, rather than being immediately caused by a definition lacking a where Self: Sized bound.

SemVer hazards:

  • Adding where Self: Sized is generally a major breaking change for trait methods.
  • Is removing where Self: Sized a major breaking change for trait methods? If so, how?
  • Is adding or removing where Self: Sized a major breaking change for trait associated types by itself, meaning without a simultaneous where Self: Sized bound change on a trait method as well? If so, how?

Adding where Self: Sized to a trait method is breaking

pub trait Example {
    // If you uncomment the bound below:
    fn method(&mut self) -> Option<i64> // where Self: Sized;
}

fn demo(value: &mut dyn Example) {
    // then you get the following error on the next line:
    value.method();
    // error: the `method` method cannot be invoked on a trait object
    //   --> src/lib.rs:20:11
    //    |
    // 2  |     fn method(&mut self) -> Option<i64> where Self: Sized;
    //    |                                                     ----- this has a `Sized` requirement
    // ...
    // 20 |     value.method();
    //    |           ^^^^^^
}

playground

Caveat: if the method is made non-callable from outside its own crate (i.e. the trait is partially-sealed as described in this post), then this is not a major breaking change since no external crate could have called the method and been broken by its signature change.

This is currently not expressible in a Trustfall query, so it cannot be linted without further work on the query schema.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: new or existing lint

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions