Skip to content

Generic trait with constraint on Any does not compile anymore #100266

Closed as not planned
@CLOVIS-AI

Description

@CLOVIS-AI

Code

I tried this code:

use std::any::Any;

// Generic trait used to store multiple different kinds of objects dynamically
trait Foo<T> : Any {
    fn as_any(&self) -> &dyn Any;
}

// Example (empty) implementation of the Foo trait
// The error is not related to this structure, it is only needed to have a meaningful example in the main function
#[derive(Copy, Clone, Debug)]
struct FooImpl;

impl Foo<usize> for FooImpl {
    fn as_any(&self) -> &dyn Any {
        self
    }
}

// Finds all instances of type F in the array of Foo trait objects
fn find<T, F : Foo<T> + Clone>(vec: &Vec<Box<dyn Foo<T>>>) -> Vec<F> {
    vec.iter()
        .filter_map(|foo| foo.as_ref().as_any().downcast_ref::<F>())
        .cloned()
        .collect()
}

fn main() {
    let mut vec: Vec<Box<dyn Foo<usize>>> = Default::default();
    vec.push(Box::new(FooImpl));

    // "find all instances of FooImpl in vec"
    let result = find::<usize, FooImpl>(&vec);
    println!("Results: {:?}", result);
}

I expected to see this happen: code compiles

Instead, this happened: code doesn't compile (see error below)

Version it worked on

It most recently worked on toolchain 1.60-x86_64-unknown-linux-gnu

rustup run 1.60-x86_64-unknown-linux-gnu rustc --version --verbose:

rustc 1.60.0 (7737e0b5c 2022-04-04)
binary: rustc
commit-hash: 7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c
commit-date: 2022-04-04
host: x86_64-unknown-linux-gnu
release: 1.60.0
LLVM version: 14.0.0

Version with regression

rustc --version --verbose:

rustc 1.62.1 (e092d0b6b 2022-07-16)
binary: rustc
commit-hash: e092d0b6b43f2de967af0887873151bb1c0b18d3
commit-date: 2022-07-16
host: x86_64-unknown-linux-gnu
release: 1.62.1
LLVM version: 14.0.5

Backtrace

Compilation error on stable

$ cargo build                                     
   Compiling test-annotation v0.1.0 ([REDACTED]/test-annotation)
error[E0310]: the parameter type `T` may not live long enough
  --> src/main.rs:18:40
   |
18 |         .filter_map(|foo| foo.as_ref().as_any().downcast_ref::<F>())
   |                                        ^^^^^^ ...so that the type `dyn Foo<T>` will meet its required lifetime bounds...
   |
note: ...that is required by this bound
  --> src/main.rs:3:16
   |
3  | trait Foo<T> : Any {
   |                ^^^
help: consider adding an explicit lifetime bound...
   |
16 | fn find<T: 'static, F : Foo<T> + Clone>(vec: &Vec<Box<dyn Foo<T>>>) -> Vec<F> {
   |          +++++++++

For more information about this error, try `rustc --explain E0310`.
error: could not compile `test-annotation` due to previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.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