summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ast_passes/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /compiler/rustc_ast_passes/src
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_ast_passes/src')
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs219
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs30
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs38
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs11
-rw-r--r--compiler/rustc_ast_passes/src/show_span.rs12
5 files changed, 178 insertions, 132 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 3d0513c89..887cb434a 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -8,9 +8,9 @@
use itertools::{Either, Itertools};
use rustc_ast::ptr::P;
-use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
+use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
+use rustc_ast::walk_list;
use rustc_ast::*;
-use rustc_ast::{walk_list, StaticItem};
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxIndexMap;
use rustc_feature::Features;
@@ -40,6 +40,10 @@ enum SelfSemantic {
enum DisallowTildeConstContext<'a> {
TraitObject,
Fn(FnKind<'a>),
+ Trait(Span),
+ TraitImpl(Span),
+ Impl(Span),
+ Item,
}
struct AstValidator<'a> {
@@ -110,18 +114,6 @@ impl<'a> AstValidator<'a> {
self.disallow_tilde_const = old;
}
- fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
- self.with_tilde_const(None, f)
- }
-
- fn with_banned_tilde_const(
- &mut self,
- ctx: DisallowTildeConstContext<'a>,
- f: impl FnOnce(&mut Self),
- ) {
- self.with_tilde_const(Some(ctx), f)
- }
-
fn check_type_alias_where_clause_location(
&mut self,
ty_alias: &TyAlias,
@@ -173,7 +165,7 @@ impl<'a> AstValidator<'a> {
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
}
TyKind::TraitObject(..) => self
- .with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
+ .with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| {
visit::walk_ty(this, t)
}),
TyKind::Path(qself, path) => {
@@ -229,8 +221,8 @@ impl<'a> AstValidator<'a> {
}
}
- fn err_handler(&self) -> &rustc_errors::Handler {
- &self.session.diagnostic()
+ fn dcx(&self) -> &rustc_errors::DiagCtxt {
+ self.session.dcx()
}
fn check_lifetime(&self, ident: Ident) {
@@ -278,7 +270,7 @@ impl<'a> AstValidator<'a> {
) {
return;
}
- self.err_handler().emit_err(errors::InvalidUnnamedFieldTy { span, ty_span: ty.span });
+ self.dcx().emit_err(errors::InvalidUnnamedFieldTy { span, ty_span: ty.span });
}
fn deny_anon_struct_or_union(&self, ty: &Ty) {
@@ -287,15 +279,14 @@ impl<'a> AstValidator<'a> {
TyKind::AnonUnion(..) => "union",
_ => return,
};
- self.err_handler()
- .emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
+ self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
}
fn deny_unnamed_field(&self, field: &FieldDef) {
if let Some(ident) = field.ident
&& ident.name == kw::Underscore
{
- self.err_handler()
+ self.dcx()
.emit_err(errors::InvalidUnnamedField { span: field.span, ident_span: ident.span });
}
}
@@ -401,7 +392,7 @@ impl<'a> AstValidator<'a> {
[b0] => b0.span(),
[b0, .., bl] => b0.span().to(bl.span()),
};
- self.err_handler().emit_err(errors::BoundInContext { span, ctx });
+ self.dcx().emit_err(errors::BoundInContext { span, ctx });
}
fn check_foreign_ty_genericless(
@@ -411,7 +402,7 @@ impl<'a> AstValidator<'a> {
after_where_clause: &TyAliasWhereClause,
) {
let cannot_have = |span, descr, remove_descr| {
- self.err_handler().emit_err(errors::ExternTypesCannotHave {
+ self.dcx().emit_err(errors::ExternTypesCannotHave {
span,
descr,
remove_descr,
@@ -437,7 +428,7 @@ impl<'a> AstValidator<'a> {
let Some(body) = body else {
return;
};
- self.err_handler().emit_err(errors::BodyInExtern {
+ self.dcx().emit_err(errors::BodyInExtern {
span: ident.span,
body,
block: self.current_extern_span(),
@@ -450,7 +441,7 @@ impl<'a> AstValidator<'a> {
let Some(body) = body else {
return;
};
- self.err_handler().emit_err(errors::FnBodyInExtern {
+ self.dcx().emit_err(errors::FnBodyInExtern {
span: ident.span,
body: body.span,
block: self.current_extern_span(),
@@ -464,7 +455,7 @@ impl<'a> AstValidator<'a> {
/// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) {
if header.has_qualifiers() {
- self.err_handler().emit_err(errors::FnQualifierInExtern {
+ self.dcx().emit_err(errors::FnQualifierInExtern {
span: ident.span,
block: self.current_extern_span(),
sugg_span: span.until(ident.span.shrink_to_lo()),
@@ -475,7 +466,7 @@ impl<'a> AstValidator<'a> {
/// An item in `extern { ... }` cannot use non-ascii identifier.
fn check_foreign_item_ascii_only(&self, ident: Ident) {
if !ident.as_str().is_ascii() {
- self.err_handler().emit_err(errors::ExternItemAscii {
+ self.dcx().emit_err(errors::ExternItemAscii {
span: ident.span,
block: self.current_extern_span(),
});
@@ -504,7 +495,7 @@ impl<'a> AstValidator<'a> {
if let Const::Yes(const_span) = header.constness {
let mut spans = variadic_spans.clone();
spans.push(const_span);
- self.err_handler().emit_err(errors::ConstAndCVariadic {
+ self.dcx().emit_err(errors::ConstAndCVariadic {
spans,
const_span,
variadic_spans: variadic_spans.clone(),
@@ -526,14 +517,14 @@ impl<'a> AstValidator<'a> {
_ => {}
};
- self.err_handler().emit_err(errors::BadCVariadic { span: variadic_spans });
+ self.dcx().emit_err(errors::BadCVariadic { span: variadic_spans });
}
fn check_item_named(&self, ident: Ident, kind: &str) {
if ident.name != kw::Underscore {
return;
}
- self.err_handler().emit_err(errors::ItemUnderscore { span: ident.span, kind });
+ self.dcx().emit_err(errors::ItemUnderscore { span: ident.span, kind });
}
fn check_nomangle_item_asciionly(&self, ident: Ident, item_span: Span) {
@@ -624,14 +615,14 @@ impl<'a> AstValidator<'a> {
let args_len = arg_spans.len();
let constraint_len = constraint_spans.len();
// ...and then error:
- self.err_handler().emit_err(errors::ArgsBeforeConstraint {
+ self.dcx().emit_err(errors::ArgsBeforeConstraint {
arg_spans: arg_spans.clone(),
constraints: constraint_spans[0],
args: *arg_spans.iter().last().unwrap(),
data: data.span,
constraint_spans: errors::EmptyLabelManySpans(constraint_spans),
arg_spans2: errors::EmptyLabelManySpans(arg_spans),
- suggestion: self.correct_generic_order_suggestion(&data),
+ suggestion: self.correct_generic_order_suggestion(data),
constraint_len,
args_len,
});
@@ -676,7 +667,7 @@ impl<'a> AstValidator<'a> {
}
if !bounds.iter().any(|b| matches!(b, GenericBound::Trait(..))) {
- self.err_handler().emit_err(errors::AtLeastOneTrait { span: ty.span });
+ self.dcx().emit_err(errors::AtLeastOneTrait { span: ty.span });
}
}
_ => {}
@@ -706,7 +697,7 @@ impl<'a> AstValidator<'a> {
/// Checks that generic parameters are in the correct order,
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
fn validate_generic_param_order(
- handler: &rustc_errors::Handler,
+ dcx: &rustc_errors::DiagCtxt,
generics: &[GenericParam],
span: Span,
) {
@@ -747,7 +738,7 @@ fn validate_generic_param_order(
if !bounds.is_empty() {
ordered_params += ": ";
- ordered_params += &pprust::bounds_to_string(&bounds);
+ ordered_params += &pprust::bounds_to_string(bounds);
}
match kind {
@@ -769,7 +760,7 @@ fn validate_generic_param_order(
ordered_params += ">";
for (param_ord, (max_param, spans)) in &out_of_order {
- handler.emit_err(errors::OutOfOrderParams {
+ dcx.emit_err(errors::OutOfOrderParams {
spans: spans.clone(),
sugg_span: span,
param_ord,
@@ -832,7 +823,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
errors::VisibilityNotPermittedNote::TraitImpl,
);
if let TyKind::Err = self_ty.kind {
- this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span });
+ this.dcx().emit_err(errors::ObsoleteAuto { span: item.span });
}
if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity)
{
@@ -845,11 +836,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
this.visit_vis(&item.vis);
this.visit_ident(item.ident);
- if let Const::Yes(_) = constness {
- this.with_tilde_const_allowed(|this| this.visit_generics(generics));
- } else {
- this.visit_generics(generics);
- }
+ let disallowed = matches!(constness, Const::No)
+ .then(|| DisallowTildeConstContext::TraitImpl(item.span));
+ this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
this.visit_trait_ref(t);
this.visit_ty(self_ty);
@@ -863,10 +852,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
polarity,
defaultness,
constness,
- generics: _,
+ generics,
of_trait: None,
self_ty,
- items: _,
+ items,
}) => {
let error =
|annotation_span, annotation, only_trait: bool| errors::InherentImplCannot {
@@ -882,7 +871,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
errors::VisibilityNotPermittedNote::IndividualImplItems,
);
if let &Unsafe::Yes(span) = unsafety {
- self.err_handler().emit_err(errors::InherentImplCannotUnsafe {
+ self.dcx().emit_err(errors::InherentImplCannotUnsafe {
span: self_ty.span,
annotation_span: span,
annotation: "unsafe",
@@ -890,14 +879,24 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
}
if let &ImplPolarity::Negative(span) = polarity {
- self.err_handler().emit_err(error(span, "negative", false));
+ self.dcx().emit_err(error(span, "negative", false));
}
if let &Defaultness::Default(def_span) = defaultness {
- self.err_handler().emit_err(error(def_span, "`default`", true));
+ self.dcx().emit_err(error(def_span, "`default`", true));
}
if let &Const::Yes(span) = constness {
- self.err_handler().emit_err(error(span, "`const`", true));
+ self.dcx().emit_err(error(span, "`const`", true));
}
+
+ self.visit_vis(&item.vis);
+ self.visit_ident(item.ident);
+ self.with_tilde_const(Some(DisallowTildeConstContext::Impl(item.span)), |this| {
+ this.visit_generics(generics)
+ });
+ self.visit_ty(self_ty);
+ walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl);
+ walk_list!(self, visit_attribute, &item.attrs);
+ return; // Avoid visiting again.
}
ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
self.check_defaultness(item.span, *defaultness);
@@ -940,7 +939,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
errors::VisibilityNotPermittedNote::IndividualForeignItems,
);
if let &Unsafe::Yes(span) = unsafety {
- self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" });
+ self.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" });
}
if abi.is_none() {
self.maybe_lint_missing_abi(item.span, item.id);
@@ -978,8 +977,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
// context for the supertraits.
this.visit_vis(&item.vis);
this.visit_ident(item.ident);
- this.visit_generics(generics);
- this.with_tilde_const_allowed(|this| {
+ let disallowed =
+ (!is_const_trait).then(|| DisallowTildeConstContext::Trait(item.span));
+ this.with_tilde_const(disallowed, |this| {
+ this.visit_generics(generics);
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
});
walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait);
@@ -989,7 +990,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::Mod(unsafety, mod_kind) => {
if let &Unsafe::Yes(span) = unsafety {
- self.err_handler().emit_err(errors::UnsafeItem { span, kind: "module" });
+ self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
}
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
@@ -999,16 +1000,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
ItemKind::Struct(vdata, generics) => match vdata {
- // Duplicating the `Visitor` logic allows catching all cases
- // of `Anonymous(Struct, Union)` outside of a field struct or union.
- //
- // Inside `visit_ty` the validator catches every `Anonymous(Struct, Union)` it
- // encounters, and only on `ItemKind::Struct` and `ItemKind::Union`
- // it uses `visit_ty_common`, which doesn't contain that specific check.
- VariantData::Struct(fields, ..) => {
+ VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis);
self.visit_ident(item.ident);
self.visit_generics(generics);
+ // Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields);
walk_list!(self, visit_attribute, &item.attrs);
return;
@@ -1017,13 +1013,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
},
ItemKind::Union(vdata, generics) => {
if vdata.fields().is_empty() {
- self.err_handler().emit_err(errors::FieldlessUnion { span: item.span });
+ self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
}
match vdata {
- VariantData::Struct(fields, ..) => {
+ VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis);
self.visit_ident(item.ident);
self.visit_generics(generics);
+ // Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields);
walk_list!(self, visit_attribute, &item.attrs);
return;
@@ -1031,12 +1028,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
_ => {}
}
}
- ItemKind::Const(box ConstItem { defaultness, expr: None, .. }) => {
+ ItemKind::Const(box ConstItem { defaultness, expr, .. }) => {
self.check_defaultness(item.span, *defaultness);
- self.session.emit_err(errors::ConstWithoutBody {
- span: item.span,
- replace_span: self.ending_semi_or_hi(item.span),
- });
+ if expr.is_none() {
+ self.session.emit_err(errors::ConstWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
+ }
}
ItemKind::Static(box StaticItem { expr: None, .. }) => {
self.session.emit_err(errors::StaticWithoutBody {
@@ -1058,10 +1057,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if self.features.lazy_type_alias {
if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) {
- self.err_handler().emit_err(err);
+ self.dcx().emit_err(err);
}
} else if where_clauses.1.0 {
- self.err_handler().emit_err(errors::WhereClauseAfterTypeAlias {
+ self.dcx().emit_err(errors::WhereClauseAfterTypeAlias {
span: where_clauses.1.1,
help: self.session.is_nightly_build().then_some(()),
});
@@ -1146,14 +1145,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
if let Some(span) = prev_param_default {
- self.err_handler().emit_err(errors::GenericDefaultTrailing { span });
+ self.dcx().emit_err(errors::GenericDefaultTrailing { span });
break;
}
}
}
}
- validate_generic_param_order(self.err_handler(), &generics.params, generics.span);
+ validate_generic_param_order(self.dcx(), &generics.params, generics.span);
for predicate in &generics.where_clause.predicates {
if let WherePredicate::EqPredicate(predicate) = predicate {
@@ -1174,7 +1173,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
match bound {
GenericBound::Trait(t, _) => {
if !t.bound_generic_params.is_empty() {
- self.err_handler()
+ self.dcx()
.emit_err(errors::NestedLifetimes { span: t.span });
}
}
@@ -1200,39 +1199,50 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let GenericBound::Trait(poly, modify) = bound {
match (ctxt, modify) {
(BoundKind::SuperTraits, TraitBoundModifier::Maybe) => {
- self.err_handler().emit_err(errors::OptionalTraitSupertrait {
+ self.dcx().emit_err(errors::OptionalTraitSupertrait {
span: poly.span,
path_str: pprust::path_to_string(&poly.trait_ref.path),
});
}
(BoundKind::TraitObject, TraitBoundModifier::Maybe) => {
- self.err_handler().emit_err(errors::OptionalTraitObject { span: poly.span });
+ self.dcx().emit_err(errors::OptionalTraitObject { span: poly.span });
}
- (_, TraitBoundModifier::MaybeConst)
+ (_, &TraitBoundModifier::MaybeConst(span))
if let Some(reason) = &self.disallow_tilde_const =>
{
let reason = match reason {
- DisallowTildeConstContext::TraitObject => {
- errors::TildeConstReason::TraitObject
- }
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => {
errors::TildeConstReason::Closure
}
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
errors::TildeConstReason::Function { ident: ident.span }
}
+ &DisallowTildeConstContext::Trait(span) => {
+ errors::TildeConstReason::Trait { span }
+ }
+ &DisallowTildeConstContext::TraitImpl(span) => {
+ errors::TildeConstReason::TraitImpl { span }
+ }
+ &DisallowTildeConstContext::Impl(span) => {
+ // FIXME(effects): Consider providing a help message or even a structured
+ // suggestion for moving such bounds to the assoc const fns if available.
+ errors::TildeConstReason::Impl { span }
+ }
+ DisallowTildeConstContext::TraitObject => {
+ errors::TildeConstReason::TraitObject
+ }
+ DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
};
- self.err_handler()
- .emit_err(errors::TildeConstDisallowed { span: bound.span(), reason });
+ self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
}
(_, TraitBoundModifier::MaybeConstMaybe) => {
- self.err_handler().emit_err(errors::OptionalConstExclusive {
+ self.dcx().emit_err(errors::OptionalConstExclusive {
span: bound.span(),
modifier: "?",
});
}
(_, TraitBoundModifier::MaybeConstNegative) => {
- self.err_handler().emit_err(errors::OptionalConstExclusive {
+ self.dcx().emit_err(errors::OptionalConstExclusive {
span: bound.span(),
modifier: "!",
});
@@ -1248,7 +1258,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
{
for arg in &args.args {
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
- self.err_handler()
+ self.dcx()
.emit_err(errors::ConstraintOnNegativeBound { span: constraint.span });
}
}
@@ -1267,14 +1277,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_c_variadic_type(fk);
- // Functions cannot both be `const async`
+ // Functions cannot both be `const async` or `const gen`
if let Some(&FnHeader {
constness: Const::Yes(cspan),
- asyncness: Async::Yes { span: aspan, .. },
+ coroutine_kind: Some(coroutine_kind),
..
}) = fk.header()
{
- self.err_handler().emit_err(errors::ConstAndAsync {
+ let aspan = match coroutine_kind {
+ CoroutineKind::Async { span: aspan, .. }
+ | CoroutineKind::Gen { span: aspan, .. }
+ | CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
+ };
+ // FIXME(gen_blocks): Report a different error for `const gen`
+ self.dcx().emit_err(errors::ConstAndAsync {
spans: vec![cspan, aspan],
cspan,
aspan,
@@ -1314,10 +1330,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
} else {
match ctxt {
- FnCtxt::Foreign => {
- self.err_handler().emit_err(errors::PatternInForeign { span })
- }
- _ => self.err_handler().emit_err(errors::PatternInBodiless { span }),
+ FnCtxt::Foreign => self.dcx().emit_err(errors::PatternInForeign { span }),
+ _ => self.dcx().emit_err(errors::PatternInBodiless { span }),
};
}
});
@@ -1328,7 +1342,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)) if self.in_const_trait_or_impl);
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
-
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
}
@@ -1397,18 +1410,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
match &item.kind {
- AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. })
- if ctxt == AssocCtxt::Trait =>
- {
- self.visit_vis(&item.vis);
- self.visit_ident(item.ident);
- walk_list!(self, visit_attribute, &item.attrs);
- self.with_tilde_const_allowed(|this| {
- this.visit_generics(generics);
- walk_list!(this, visit_param_bound, bounds, BoundKind::Bound);
- });
- walk_list!(self, visit_ty, ty);
- }
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
if self.in_const_trait_or_impl
|| ctxt == AssocCtxt::Trait
@@ -1461,9 +1462,7 @@ fn deny_equality_constraints(
id: rustc_ast::node_id::DUMMY_NODE_ID,
ident: *ident,
gen_args,
- kind: AssocConstraintKind::Equality {
- term: predicate.rhs_ty.clone().into(),
- },
+ kind: AssocConstraintKind::Equality { term: predicate.rhs_ty.clone().into() },
span: ident.span,
});
// Add `<Bar = RhsTy>` to `Foo`.
@@ -1476,11 +1475,7 @@ fn deny_equality_constraints(
},
empty_args => {
*empty_args = Some(
- AngleBracketedArgs {
- span: ident.span,
- args: thin_vec![arg],
- }
- .into(),
+ AngleBracketedArgs { span: ident.span, args: thin_vec![arg] }.into(),
);
}
}
@@ -1535,7 +1530,7 @@ fn deny_equality_constraints(
}
}
}
- this.err_handler().emit_err(err);
+ this.dcx().emit_err(err);
}
pub fn check_crate(
@@ -1552,7 +1547,7 @@ pub fn check_crate(
in_const_trait_or_impl: false,
has_proc_macro_decls: false,
outer_impl_trait: None,
- disallow_tilde_const: None,
+ disallow_tilde_const: Some(DisallowTildeConstContext::Item),
is_impl_trait_banned: false,
lint_buffer: lints,
};
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index d14b62d6b..4283fc7c0 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -551,8 +551,6 @@ pub struct TildeConstDisallowed {
#[derive(Subdiagnostic)]
pub enum TildeConstReason {
- #[note(ast_passes_trait)]
- TraitObject,
#[note(ast_passes_closure)]
Closure,
#[note(ast_passes_function)]
@@ -560,6 +558,25 @@ pub enum TildeConstReason {
#[primary_span]
ident: Span,
},
+ #[note(ast_passes_trait)]
+ Trait {
+ #[primary_span]
+ span: Span,
+ },
+ #[note(ast_passes_trait_impl)]
+ TraitImpl {
+ #[primary_span]
+ span: Span,
+ },
+ #[note(ast_passes_impl)]
+ Impl {
+ #[primary_span]
+ span: Span,
+ },
+ #[note(ast_passes_object)]
+ TraitObject,
+ #[note(ast_passes_item)]
+ Item,
}
#[derive(Diagnostic)]
@@ -746,3 +763,12 @@ pub struct AnonStructOrUnionNotAllowed {
pub span: Span,
pub struct_or_union: &'static str,
}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_match_arm_with_no_body)]
+pub struct MatchArmWithNoBody {
+ #[primary_span]
+ pub span: Span,
+ #[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
+ pub suggestion: Span,
+}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index e1cf0a258..6900d3392 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -88,7 +88,7 @@ impl<'a> PostExpansionVisitor<'a> {
}
}
- match abi::is_enabled(&self.features, span, symbol_unescaped.as_str()) {
+ match abi::is_enabled(self.features, span, symbol_unescaped.as_str()) {
Ok(()) => (),
Err(abi::AbiDisabled::Unstable { feature, explain }) => {
feature_err_issue(
@@ -102,7 +102,7 @@ impl<'a> PostExpansionVisitor<'a> {
}
Err(abi::AbiDisabled::Unrecognized) => {
if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
- self.sess.parse_sess.span_diagnostic.delay_span_bug(
+ self.sess.dcx().span_delayed_bug(
span,
format!(
"unrecognized ABI not caught in lowering: {}",
@@ -182,7 +182,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
..
}) = attr_info
{
- gate_alt!(self, has_feature(&self.features), *name, attr.span, *descr);
+ gate_alt!(self, has_feature(self.features), *name, attr.span, *descr);
}
// Check unstable flavors of the `#[doc]` attribute.
if attr.has_name(sym::doc) {
@@ -300,7 +300,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => {
- self.check_impl_trait(&ty, false)
+ self.check_impl_trait(ty, false)
}
_ => {}
@@ -556,6 +556,34 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(generic_const_items, "generic const items are experimental");
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
+ if !visitor.features.never_patterns {
+ if let Some(spans) = spans.get(&sym::never_patterns) {
+ for &span in spans {
+ if span.allows_unstable(sym::never_patterns) {
+ continue;
+ }
+ let sm = sess.source_map();
+ // We gate two types of spans: the span of a `!` pattern, and the span of a
+ // match arm without a body. For the latter we want to give the user a normal
+ // error.
+ if let Ok(snippet) = sm.span_to_snippet(span)
+ && snippet == "!"
+ {
+ feature_err(
+ &sess.parse_sess,
+ sym::never_patterns,
+ span,
+ "`!` patterns are experimental",
+ )
+ .emit();
+ } else {
+ let suggestion = span.shrink_to_hi();
+ sess.emit_err(errors::MatchArmWithNoBody { span, suggestion });
+ }
+ }
+ }
+ }
+
if !visitor.features.negative_bounds {
for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
sess.emit_err(errors::NegativeBoundUnsupported { span });
@@ -627,7 +655,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
if all_stable {
err.sugg = Some(attr.span);
}
- sess.parse_sess.span_diagnostic.emit_err(err);
+ sess.dcx().emit_err(err);
}
}
}
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index 5147e672f..ba0918337 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -4,9 +4,9 @@
//!
//! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`.
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
+#![allow(internal_features)]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
@@ -15,13 +15,10 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
-use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
-use rustc_fluent_macro::fluent_messages;
-
pub mod ast_validation;
mod errors;
pub mod feature_gate;
pub mod node_count;
pub mod show_span;
-fluent_messages! { "../messages.ftl" }
+rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_ast_passes/src/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs
index 280cf3284..9882f1d23 100644
--- a/compiler/rustc_ast_passes/src/show_span.rs
+++ b/compiler/rustc_ast_passes/src/show_span.rs
@@ -31,37 +31,37 @@ impl FromStr for Mode {
}
struct ShowSpanVisitor<'a> {
- span_diagnostic: &'a rustc_errors::Handler,
+ dcx: &'a rustc_errors::DiagCtxt,
mode: Mode,
}
impl<'a> Visitor<'a> for ShowSpanVisitor<'a> {
fn visit_expr(&mut self, e: &'a ast::Expr) {
if let Mode::Expression = self.mode {
- self.span_diagnostic.emit_warning(errors::ShowSpan { span: e.span, msg: "expression" });
+ self.dcx.emit_warning(errors::ShowSpan { span: e.span, msg: "expression" });
}
visit::walk_expr(self, e);
}
fn visit_pat(&mut self, p: &'a ast::Pat) {
if let Mode::Pattern = self.mode {
- self.span_diagnostic.emit_warning(errors::ShowSpan { span: p.span, msg: "pattern" });
+ self.dcx.emit_warning(errors::ShowSpan { span: p.span, msg: "pattern" });
}
visit::walk_pat(self, p);
}
fn visit_ty(&mut self, t: &'a ast::Ty) {
if let Mode::Type = self.mode {
- self.span_diagnostic.emit_warning(errors::ShowSpan { span: t.span, msg: "type" });
+ self.dcx.emit_warning(errors::ShowSpan { span: t.span, msg: "type" });
}
visit::walk_ty(self, t);
}
}
-pub fn run(span_diagnostic: &rustc_errors::Handler, mode: &str, krate: &ast::Crate) {
+pub fn run(dcx: &rustc_errors::DiagCtxt, mode: &str, krate: &ast::Crate) {
let Ok(mode) = mode.parse() else {
return;
};
- let mut v = ShowSpanVisitor { span_diagnostic, mode };
+ let mut v = ShowSpanVisitor { dcx, mode };
visit::walk_crate(&mut v, krate);
}