In item contexts, const trait bounds behind trait aliases aren't rejected in trait object types, considered dyn compatible & constness isn't checked
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
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)?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in HIR type lowering, around expand_trait_aliases and HirTyLowerer::dyn_compatibility_violations. Compare the item-signature and function-body handling using the two issue snippets, then determine whether HostEffect clauses should participate in minimal dyn-compatibility checks or whether const modifiers behind trait aliases need a direct rejection. Done means the invalid trait object is rejected consistently with the expected compiler diagnostics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100