diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 194f2cd04e4..2f7c3cb3c7d 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -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 diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index f2560f22874..e6090a128b1 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -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, +} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index aeebe45f881..e64cd8ec302 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -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( diff --git a/tests/ui/dyn-compatibility/trait-alias-self-projection.rs b/tests/ui/dyn-compatibility/trait-alias-self-projection.rs new file mode 100644 index 00000000000..0badb738809 --- /dev/null +++ b/tests/ui/dyn-compatibility/trait-alias-self-projection.rs @@ -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(); +} diff --git a/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr b/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr new file mode 100644 index 00000000000..dccee02e9cd --- /dev/null +++ b/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr @@ -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`.