Skip to content

confusing error message around trait object bound #54779

Closed
@nikomatsakis

Description

@nikomatsakis

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.

Metadata

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsA-trait-systemArea: 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