Skip to content

Commit 0580faa

Browse files
committed
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. Bug: #139082 Signed-off-by: xtex <xtexchooser@duck.com>
1 parent 8989165 commit 0580faa

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

compiler/rustc_hir_analysis/messages.ftl

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

compiler/rustc_hir_analysis/src/errors.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1707,3 +1707,11 @@ pub(crate) enum SupertraitItemShadowee {
17071707
traits: DiagSymbolList,
17081708
},
17091709
}
1710+
1711+
#[derive(Diagnostic)]
1712+
#[diag(hir_analysis_self_in_type_alias, code = E0411)]
1713+
pub(crate) struct SelfInTypeAlias {
1714+
#[primary_span]
1715+
#[label]
1716+
pub span: Span,
1717+
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

+11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use smallvec::{SmallVec, smallvec};
1616
use tracing::{debug, instrument};
1717

1818
use super::HirTyLowerer;
19+
use crate::errors::SelfInTypeAlias;
1920
use crate::hir_ty_lowering::{
2021
GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason,
2122
};
@@ -352,6 +353,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
352353
b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar);
353354
}
354355

356+
if let Some(term_ty) = &b.term.as_type() {
357+
let references_self = term_ty.walk().any(|arg| arg == dummy_self.into());
358+
if references_self {
359+
// With trait alias and type alias combined, type resolver
360+
// may not be able to catch all illegal `Self` usages (issue 139082)
361+
let guar = tcx.dcx().emit_err(SelfInTypeAlias { span });
362+
b.term = replace_dummy_self_with_error(tcx, b.term, guar);
363+
}
364+
}
365+
355366
ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(
356367
tcx, b,
357368
))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(trait_alias)]
2+
trait B = Fn() -> Self;
3+
type D = &'static dyn B;
4+
//~^ ERROR E0411
5+
6+
fn a() -> D {
7+
unreachable!();
8+
}
9+
10+
fn main() {
11+
_ = a();
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0411]: `Self` is not allowed in type aliases
2+
--> $DIR/trait-alias-self-projection.rs:3:19
3+
|
4+
LL | type D = &'static dyn B;
5+
| ^^^^^ `Self` is only available in impls, traits, and concrete type definitions
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0411`.

0 commit comments

Comments
 (0)