Rollup merge of #139124 - xtexx:gh-139082, r=compiler-errors

compiler: report error when trait object type param reference self

Fixes #139082.

Emits an error when `Self` is found in the projection bounds of a trait
object. In type aliases, `Self` has no meaning, so `type A = &'static
dyn B` where `trait B = Fn() -> Self` will expands to `type A = &'static
Fn() -> Self` which is illegal, causing the region solver to bail out
when hitting the uninferred Self.

r? ````@compiler-errors```` ````@fee1-dead````
This commit is contained in:
Stuart Cook 2025-04-08 20:55:04 +10:00 committed by GitHub
commit 5913c5248b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 46 additions and 0 deletions

View file

@ -486,6 +486,9 @@ hir_analysis_self_in_impl_self =
`Self` is not valid in the self type of an impl block
.note = replace `Self` with a different type
hir_analysis_self_in_type_alias = `Self` is not allowed in type aliases
.label = `Self` is only available in impls, traits, and concrete type definitions
hir_analysis_self_ty_not_captured = `impl Trait` must mention the `Self` type of the trait in `use<...>`
.label = `Self` type parameter is implicitly captured by this `impl Trait`
.note = currently, all type parameters are required to be mentioned in the precise captures list

View file

@ -1707,3 +1707,11 @@ pub(crate) enum SupertraitItemShadowee {
traits: DiagSymbolList,
},
}
#[derive(Diagnostic)]
#[diag(hir_analysis_self_in_type_alias, code = E0411)]
pub(crate) struct SelfInTypeAlias {
#[primary_span]
#[label]
pub span: Span,
}

View file

@ -16,6 +16,7 @@ use smallvec::{SmallVec, smallvec};
use tracing::{debug, instrument};
use super::HirTyLowerer;
use crate::errors::SelfInTypeAlias;
use crate::hir_ty_lowering::{
GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason,
};
@ -125,6 +126,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// ```
let mut projection_bounds = FxIndexMap::default();
for (proj, proj_span) in elaborated_projection_bounds {
let proj = proj.map_bound(|mut b| {
if let Some(term_ty) = &b.term.as_type() {
let references_self = term_ty.walk().any(|arg| arg == dummy_self.into());
if references_self {
// With trait alias and type alias combined, type resolver
// may not be able to catch all illegal `Self` usages (issue 139082)
let guar = tcx.dcx().emit_err(SelfInTypeAlias { span });
b.term = replace_dummy_self_with_error(tcx, b.term, guar);
}
}
b
});
let key = (
proj.skip_binder().projection_term.def_id,
tcx.anonymize_bound_vars(

View file

@ -0,0 +1,12 @@
#![feature(trait_alias)]
trait B = Fn() -> Self;
type D = &'static dyn B;
//~^ ERROR E0411
fn a() -> D {
unreachable!();
}
fn main() {
_ = a();
}

View file

@ -0,0 +1,9 @@
error[E0411]: `Self` is not allowed in type aliases
--> $DIR/trait-alias-self-projection.rs:3:19
|
LL | type D = &'static dyn B;
| ^^^^^ `Self` is only available in impls, traits, and concrete type definitions
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0411`.