Skip to content

confusing error message around trait object bound #54779

Closed

Description

This example:

#![feature(in_band_lifetimes)]
#![feature(nll)]

trait DebugWith<Cx: ?Sized> {
    fn debug_with(&'me self, cx: &'me Cx) -> DebugCxPair<'me, Self, Cx> {
        DebugCxPair { value: self, cx }
    }
    
    fn fmt_with(&self, cx: &Cx, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
}

struct DebugCxPair<'me, Value: ?Sized, Cx: ?Sized>
where
    Value: DebugWith<Cx>,
{
    value: &'me Value,
    cx: &'me Cx,
}

trait DebugContext { }

struct Foo {
    bar: Bar
}

impl DebugWith<dyn DebugContext> for Foo {
    fn fmt_with(&self, cx: &dyn DebugContext, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let Foo { bar } = self;
        bar.debug_with(cx);
        Ok(())
    }
}

struct Bar { }

impl DebugWith<dyn DebugContext> for Bar {
    fn fmt_with(&self, cx: &dyn DebugContext, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        Ok(())
    }
}

fn main() { }

gives this error:

error: unsatisfied lifetime constraints
  --> src/main.rs:29:9
   |
27 |     fn fmt_with(&self, cx: &dyn DebugContext, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
   |                 -          - let's call the lifetime of this reference `'1`
   |                 |
   |                 let's call the lifetime of this reference `'2`
28 |         let Foo { bar } = self;
29 |         bar.debug_with(cx);
   |         ^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`

It took me some time to puzzle out what was happening here:

  • cx: &dyn DebugContext expands to &'a dyn (DebugContext + 'a)
  • the default from the impl however is dyn (DebugContext + 'static)
  • the impl method is accepted because it is more general than the trait definition
  • but it fails to recursively invoke

The error message without NLL, of course, is also not very illuminating.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsA-traitsArea: Trait systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.NLL-diagnosticsWorking towards the "diagnostic parity" goalP-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions