Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
White-Green opened this issue Oct 10, 2022 · 0 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) A-lifetimes Area: Lifetimes / regions D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@White-Green
Copy link

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
@White-Green White-Green added the C-bug Category: This is a bug. label Oct 10, 2022
@fmease fmease added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-types Relevant to the types team, which will review and decide on the PR/issue. A-lifetimes Area: Lifetimes / regions and removed C-bug Category: This is a bug. needs-triage-legacy labels Jan 25, 2024
@fmease fmease added the A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) label Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) A-lifetimes Area: Lifetimes / regions D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants