-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Description
The following snippet successfully compiles while it should not!
//@ check-pass
#![feature(trait_alias, const_trait_impl)]
trait ConstTrait = const Trait;
const trait Trait {}
impl Trait for () {} // non-const!
fn make() -> Box<dyn ConstTrait> {
Box::new(())
}
fn main() {
//let _value = make(); // also ok
}(): const Trait isn't satisfied (only (): Trait is), therefore it should be impossible to construct a value of type dyn ConstTrait. Better yet, we should reject dyn ConstTrait outright to be consistent with us (semantically) rejecting types like dyn const Trait.
When lowering trait object types in HIR ty lowering we expand trait aliases using expand_trait_aliases which obviously doesn't return any HostEffect clauses. Rephrased, we're effectively dropping the const modifier inside trait object types.
Note that in fn contexts (i.e., bodies) we reject such trait object types on grounds of being dyn incompatible (presumably since PR #145627). However in the example above, the dyn ConstTrait is located in an item ctxt (i.e., item signature, non-body) in which we only perform minimal dyn compatibility checks (see HirTyLowerer::dyn_compatibility_violations). I presume that that function just doesn't consider HostEffect clauses. Consider this example:
#![feature(trait_alias, const_trait_impl)]
trait ConstTrait = const Trait;
const trait Trait {}
fn main() {
let _: dyn ConstTrait; //~ ERROR the trait alias `ConstTrait` is not dyn compatible
}I'm not sure which solution we want to pick for the first snippet: Do we want to reject it on account of being dyn incompatible (meaning: look for & reject HostEffect clauses when performing the minimal dyn compatibility checks in item ctxts) or do we want to more directly reject const trait bound modifiers behind trait aliases inside trait object types (somehow)?