What is the meaning of this syntax

Trait Any : 'static{}

What is static means it's a super trait or lifetime specifier..

Then if it is lifetime specifier is then why it could be write like this insted of this

Trait Any<'static>{}

That bound means that any type which implements Any must not contain references shorter than 'static. In this case, I assume you're talking about std::any::Any, which is intended to provide downcasting and upcasting through type erasure. Because we're erasing the type however, we can't store lifetime information, so we require all types that want to become a dyn Any don't carry any references.

Always a good read and it's related:

4 Likes

That raises an interesting question: what if we could store lifetime information independently from the type? That is, apply type erasure, sure, but don't apply lifetime erasure.
So the semantics from the perspective of rustc could be something like "I don't know which type this value is, but these are the lifetimes it must adhere to".

Sure, that'd be great, however we'd have to be able to generate a TypeId for a type with a lifetime or somehow be able to generate a 'static equivalent to a type. At least if we wanted to keep the current intrinsics.

I was thinking about this while writing that reply too, and wished we could have something like

struct Foo<'short, 'long: 'short> {
    a: &'short &'long u8,
}

let x = Foo { &&0 };

let y: &(dyn Any + 'short) = &x;
// Where 'short is actually 'static in this case

Just like how we handle casting any type into a trait object, if it has lifetimes: slap a lifetime bound onto it and call it a day.

I was helping someone the other day with doing something similar and they came up with about this solution for generating a TypeId for non-'static types:

#[inline(never)]
pub unsafe extern "C" fn type_id_unsafe<T: ?Sized>() -> usize {
    type_id_unsafe::<T> as usize
}

We both acknowledged this is unsound however, since there's no guarantee the compiler won't collapse them all into one function and completely break the idea.

Why is that? I mean, given an accepted RFC (which admittedly is future talk) that guarantee could be given by the compiler team, yes?

Which compiler team? The team responsible for the rustc front-end, or the non-Rust team responsible for the LLVM backend? IMO it's the LLVM backend that's most likely to collapse them.

I'm not that well-versed in the boundaries of LLVM's capabilities and so I could be wrong, but collapsing Rust code seemsto me (at least at first glance) like a job for the frontend / code analysis team.

I'd even go one step further: in practice, for types that only differ on their lifetimes, such function will always be collapsed :grimacing:

  • That is, nowadays, it's "collapsed at the frontend";

  • Even if it somehow wasn't collapsed there through some lifetime work (meaning lifetimes would be an actual part of the type information and not a separate borrowck pass, so that Any could then directly drop the `'static bound), then, indeed, the LLVM backend / optimizer may still go and collapse those functions.

1 Like