Skip to content

Mismatched lifetime on trait impl shows a misleading error #80701

Open

Description

@Earlz

The rust compiler gives a very poor error message when there is a lifetime expectation mismatch on trait usage.

I used this code: (playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=581fa159f8ff99f2df447308fccd4bbc )

use std::cell::*;

#[derive(Default)]
struct Test {
    pub foo: u32,
}

trait FooSetter {
    fn set_foo(&mut self, value: u32);
}

impl FooSetter for Test {
    fn set_foo(&mut self, value: u32) {
        self.foo = value;
    }
}

trait BaseSetter{
    fn set(&mut self, value: u32);
}
impl BaseSetter for dyn FooSetter{
    fn set(&mut self, value: u32){
        self.set_foo(value);
    }
}

struct TestHolder<'a> {
    pub holder: Option<RefCell<&'a mut dyn FooSetter>>,
}

impl <'a>TestHolder<'a>{
    pub fn test_foo(&self){
       self.holder.as_ref().unwrap().borrow_mut().set(20); 
    }
}



fn main() {
    let mut test = Test::default();
    test.foo = 10;
    {
        let holder = TestHolder { holder: Some(RefCell::from(&mut test))};
        
        holder.test_foo();
    }
    test.foo = 30;
}

I expected to see a useful error message, such as "expected trait BaseSetter<'a>, found trait: BaseSetter<'static>"

Instead, I was greeted with this almost useless error message: "expected trait BaseSetter, found trait BaseSetter"

The same error occurs on stable and nightly compilers

Activity

  1. Earlz commented on Jan 4, 2021

    @Earlz
    Author

    For reference, this error message is resolved by changing

    impl BaseSetter for dyn FooSetter

    To this explicit lifetime scoped version:

    impl <'a>BaseSetter for (dyn FooSetter + 'a)
  2. ThePuzzlemaker commented on Jan 7, 2021

    @ThePuzzlemaker
    Contributor

    @rustbot modify labels: A-diagnostics A-traits C-bug D-confusing D-papercut T-compiler A-lifetimes

  3. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    A-lifetimesArea: Lifetimes / regions
    D-confusingDiagnostics: Confusing error or lint that should be reworked.
    D-papercutDiagnostics: An error or lint that needs small tweaks.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jan 7, 2021
  4. Dylan-DPC commented on Apr 18, 2023

    @Dylan-DPC
    Member

    Current error:

    error[[E0521]](https://doc.rust-lang.org/stable/error_codes/E0521.html): borrowed data escapes outside of associated function
      --> src/main.rs:33:8
       |
    31 | impl <'a>TestHolder<'a>{
       |       -- lifetime `'a` defined here
    32 |     pub fn test_foo(&self){
       |                     ----- `self` is a reference that is only valid in the associated function body
    33 |        self.holder.as_ref().unwrap().borrow_mut().set(20); 
       |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |        |
       |        `self` escapes the associated function body here
       |        argument requires that `'a` must outlive `'static`
       |
       = note: requirement occurs because of a mutable reference to `dyn FooSetter`
       = note: mutable references are invariant over their type parameter
       = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
    
  5. added
    A-dyn-traitArea: trait objects, vtable layout
    D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.
    and removed
    C-bugCategory: This is a bug.
    on Oct 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-dyn-traitArea: trait objects, vtable layoutA-lifetimesArea: Lifetimes / regionsA-trait-systemArea: Trait systemD-confusingDiagnostics: Confusing error or lint that should be reworked.D-papercutDiagnostics: An error or lint that needs small tweaks.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions