Skip to content

Occurs higher-ranked lifetime error by dyn-trait, associated types, and Send constraints. #102870

Open
@White-Green

Description

@White-Green

A program using dyn-trait and associae types fails to infer a Send constraint and gives a higher-ranked lifetime error.
I think this is either a bug in rustc or the error message needs to be improved.
Here is the (probably near-minimal) code that produces this error.

use std::any::Any;
use std::future::Future;

// OK0
// struct ResultType(Box<dyn Any + Send>);
// impl From<Box<dyn Any + Send>> for ResultType {
//     fn from(value: Box<dyn Any + Send>) -> Self {
//         ResultType(value)
//     }
// }

// NG0
type ResultType = Box<dyn Any + Send>;

fn f() -> impl Future<Output=ResultType> + Send {
    async move {
        // OK1
        // let result = vec![ATNewType::<Option<ResultType>>(f2().await)];

        // NG1
        let mut result = Vec::<ATNewType<Option<ResultType>>>::new();
        result.push(ATNewType::<Option<ResultType>>(f2().await));

        // OK2
        // let result = Some(ATNewType::<Option<ResultType>>(f2().await));

        // NG2
        // let mut result = None::<ATNewType<Option<ResultType>>>;
        // result = Some(ATNewType::<Option<ResultType>>(f2().await));

        (Box::new(()) as Box<dyn Any + Send>).into()
    }
}

async fn f2() { unimplemented!() }

trait Trait {
    type AT;
}

struct ATNewType<T: Trait>(T::AT);

impl<T: 'static> Trait for Option<T> {
    type AT = ();
}

When compiling this program, rustc outputs the following error.

error: higher-ranked lifetime error
  --> src/main.rs:16:5
   |
16 | /     async move {
17 | |         // OK1
18 | |         // let result = vec![ATNewType::<Option<ResultType>>(f2().await)];
19 | |
...  |
31 | |         (Box::new(()) as Box<dyn Any + Send>).into()
32 | |     }
   | |_____^

I tried some changes to the program to see if this error would go away. The results are described below.

  • comment-out NG1 and uncomment either OK1 or OK2 -> succeed to compilation.
  • comment-out NG1 and uncomment both OK1 and OK2 -> failed to compilation.
  • comment-out NG1 and uncomment NG2 -> failed to compilation.
  • comment-out NG0 and uncomment OK0 -> succeed to compilation regardless of the contents of function f.
  • remove Send constraints from the return type of function f -> succeed to compilation regardless of the contents of function f.
  • change ResultType to a non-dyn-trait type like Box<()> (and make the program consistent) -> succeed to compilation regardless of the contents of function f.
  • change Trait to be implemented only for Option<ResultType> -> receive a different error message below
error: implementation of `Trait` is not general enough
  --> src\main.rs:16:5
   |
16 | /     async move {
17 | |         // OK1
18 | |         // let result = vec![ATNewType::<Option<ResultType>>(f2().await)];
19 | |
...  |
31 | |         (Box::new(()) as Box<dyn Any + Send>).into()
32 | |     }
   | |_____^ implementation of `Trait` is not general enough
   |
   = note: `Option<Box<(dyn Any + Send + '0)>>` must implement `Trait`, for any lifetime `'0`...
   = note: ...but `Trait` is actually implemented for the type `Option<Box<(dyn Any + Send + 'static)>>`

I am not familiar with the internals of rustc, but I hope this investigation helps.

Meta

I have seen this error in several rustc below.

rustc 1.64.0 (a55dd71d5 2022-09-19)
binary: rustc
commit-hash: a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52
commit-date: 2022-09-19
host: x86_64-pc-windows-msvc
release: 1.64.0
LLVM version: 14.0.6
rustc 1.66.0-nightly (81f391930 2022-10-09)
binary: rustc
commit-hash: 81f391930301afbc121b7c468138069daa354bf8
commit-date: 2022-10-09
host: x86_64-pc-windows-msvc
release: 1.66.0-nightly
LLVM version: 15.0.2
rustc 1.64.0 (a55dd71d5 2022-09-19)
binary: rustc
commit-hash: a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52
commit-date: 2022-09-19
host: x86_64-unknown-linux-gnu
release: 1.64.0
LLVM version: 14.0.6
rustc 1.66.0-nightly (81f391930 2022-10-09)
binary: rustc
commit-hash: 81f391930301afbc121b7c468138069daa354bf8
commit-date: 2022-10-09
host: x86_64-unknown-linux-gnu
release: 1.66.0-nightly
LLVM version: 15.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsD-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.T-typesRelevant to the types 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