1
Fork 0

improve diagnostics and bless tests

This commit is contained in:
Boxy 2023-05-05 21:42:51 +01:00
parent 442617c046
commit 73b3ce26ec
65 changed files with 668 additions and 505 deletions

View file

@ -864,18 +864,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::ForwardDeclaredGenericParam => {
self.tcx.sess.create_err(errs::ForwardDeclaredGenericParam { span })
}
ResolutionError::ParamInTyOfConstParam(name) => {
self.tcx.sess.create_err(errs::ParamInTyOfConstParam { span, name })
}
ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self
.tcx
.sess
.create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }),
ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
self.tcx.sess.create_err(errs::ParamInNonTrivialAnonConst {
span,
name,
sub_is_type: if is_type {
errs::ParamInNonTrivialAnonConstIsType::AType
} else {
errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
},
param_kind: is_type,
help: self
.tcx
.sess
@ -883,6 +880,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.then_some(errs::ParamInNonTrivialAnonConstHelp),
})
}
ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
.tcx
.sess
.create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
ResolutionError::SelfInGenericParamDefault => {
self.tcx.sess.create_err(errs::SelfInGenericParamDefault { span })
}

View file

@ -326,6 +326,18 @@ pub(crate) struct ParamInTyOfConstParam {
#[label]
pub(crate) span: Span,
pub(crate) name: Symbol,
#[subdiagnostic]
pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
}
#[derive(Subdiagnostic)]
pub(crate) enum ParamKindInTyOfConstParam {
#[note(resolve_type_param_in_ty_of_const_param)]
Type,
#[note(resolve_const_param_in_ty_of_const_param)]
Const,
#[note(resolve_lifetime_param_in_ty_of_const_param)]
Lifetime,
}
#[derive(Diagnostic)]
@ -344,7 +356,7 @@ pub(crate) struct ParamInNonTrivialAnonConst {
pub(crate) span: Span,
pub(crate) name: Symbol,
#[subdiagnostic]
pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
pub(crate) param_kind: ParamKindInNonTrivialAnonConst,
#[subdiagnostic]
pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
}
@ -354,11 +366,13 @@ pub(crate) struct ParamInNonTrivialAnonConst {
pub(crate) struct ParamInNonTrivialAnonConstHelp;
#[derive(Subdiagnostic)]
pub(crate) enum ParamInNonTrivialAnonConstIsType {
#[note(resolve_param_in_non_trivial_anon_const_sub_type)]
AType,
#[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
NotAType { name: Symbol },
pub(crate) enum ParamKindInNonTrivialAnonConst {
#[note(resolve_type_param_in_non_trivial_anon_const)]
Type,
#[help(resolve_const_param_in_non_trivial_anon_const)]
Const { name: Symbol },
#[note(resolve_lifetime_param_in_non_trivial_anon_const)]
Lifetime,
}
#[derive(Diagnostic)]
@ -539,3 +553,24 @@ pub(crate) struct CfgAccessibleUnsure {
#[primary_span]
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(resolve_param_in_enum_discriminant)]
pub(crate) struct ParamInEnumDiscriminant {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) name: Symbol,
#[subdiagnostic]
pub(crate) param_kind: ParamKindInEnumDiscriminant,
}
#[derive(Subdiagnostic)]
pub(crate) enum ParamKindInEnumDiscriminant {
#[note(resolve_type_param_in_enum_discriminant)]
Type,
#[note(resolve_const_param_in_enum_discriminant)]
Const,
#[note(resolve_lifetime_param_in_enum_discriminant)]
Lifetime,
}

View file

@ -13,8 +13,10 @@ use rustc_span::{Span, DUMMY_SP};
use std::ptr;
use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use crate::late::{
ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
ConstantHasGenerics, ConstantItemKind, HasGenericParams, NoConstantGenericsReason, PathSource,
Rib, RibKind,
};
use crate::macros::{sub_namespace_match, MacroRulesScope};
use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
@ -1153,7 +1155,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
RibKind::ConstParamTy => {
if let Some(span) = finalize {
self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
self.report_error(
span,
ParamInTyOfConstParam {
name: rib_ident.name,
param_kind: None,
},
);
}
return Res::Err;
}
@ -1206,13 +1214,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
} else {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInNonTrivialAnonConst {
name: rib_ident.name,
is_type: true,
},
);
let error = match cause {
NoConstantGenericsReason::IsEnumDiscriminant => {
ResolutionError::ParamInEnumDiscriminant {
name: rib_ident.name,
param_kind: ParamKindInEnumDiscriminant::Type,
}
}
NoConstantGenericsReason::NonTrivialConstArg => {
ResolutionError::ParamInNonTrivialAnonConst {
name: rib_ident.name,
param_kind:
ParamKindInNonTrivialAnonConst::Type,
}
}
};
self.report_error(span, error);
self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
}
@ -1229,7 +1246,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam(rib_ident.name),
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
},
);
}
return Res::Err;
@ -1262,14 +1282,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
RibKind::ConstantItem(trivial, _) => {
if let ConstantHasGenerics::No(cause) = trivial {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInNonTrivialAnonConst {
name: rib_ident.name,
is_type: false,
},
);
self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
let error = match cause {
NoConstantGenericsReason::IsEnumDiscriminant => {
ResolutionError::ParamInEnumDiscriminant {
name: rib_ident.name,
param_kind: ParamKindInEnumDiscriminant::Const,
}
}
NoConstantGenericsReason::NonTrivialConstArg => {
ResolutionError::ParamInNonTrivialAnonConst {
name: rib_ident.name,
param_kind: ParamKindInNonTrivialAnonConst::Const {
name: rib_ident.name,
},
}
}
};
self.report_error(span, error);
}
return Res::Err;
@ -1283,7 +1312,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam(rib_ident.name),
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
},
);
}
return Res::Err;

View file

@ -1529,7 +1529,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
match rib.kind {
LifetimeRibKind::Item => break,
LifetimeRibKind::ConstParamTy => {
self.emit_non_static_lt_in_const_generic_error(lifetime);
self.emit_non_static_lt_in_const_param_ty_error(lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,
@ -1538,7 +1538,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
return;
}
LifetimeRibKind::ConcreteAnonConst(cause) => {
self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
self.record_lifetime_res(
lifetime.id,
LifetimeRes::Error,

View file

@ -1,7 +1,7 @@
use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
use crate::path_names_to_string;
use crate::{errors, path_names_to_string};
use crate::{Module, ModuleKind, ModuleOrUniformRoot};
use crate::{PathResult, PathSource, Segment};
@ -22,7 +22,6 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::PrimTy;
use rustc_session::lint;
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
@ -35,6 +34,8 @@ use std::ops::Deref;
use thin_vec::ThinVec;
use super::NoConstantGenericsReason;
type Res = def::Res<ast::NodeId>;
/// A field or associated item from self type suggested in case of resolution failure.
@ -2316,37 +2317,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
}
pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
struct_span_err!(
self.r.tcx.sess,
lifetime_ref.ident.span,
E0771,
"use of non-static lifetime `{}` in const generic",
lifetime_ref.ident
)
.note(
"for more information, see issue #74052 \
<https://github.com/rust-lang/rust/issues/74052>",
)
.emit();
pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) {
self.r
.tcx
.sess
.create_err(errors::ParamInTyOfConstParam {
span: lifetime_ref.ident.span,
name: lifetime_ref.ident.name,
param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
})
.emit();
}
/// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
/// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
/// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
pub(crate) fn emit_forbidden_non_static_lifetime_error(
&self,
cause: NoConstantGenericsReason,
lifetime_ref: &ast::Lifetime,
) {
let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs;
if !feature_active {
feature_err(
&self.r.tcx.sess.parse_sess,
sym::generic_const_exprs,
lifetime_ref.ident.span,
"a non-static lifetime is not allowed in a `const`",
)
.emit();
match cause {
NoConstantGenericsReason::IsEnumDiscriminant => {
self.r
.tcx
.sess
.create_err(errors::ParamInEnumDiscriminant {
span: lifetime_ref.ident.span,
name: lifetime_ref.ident.name,
param_kind: errors::ParamKindInEnumDiscriminant::Lifetime,
})
.emit();
}
NoConstantGenericsReason::NonTrivialConstArg => {
assert!(!self.r.tcx.features().generic_const_exprs);
self.r
.tcx
.sess
.create_err(errors::ParamInNonTrivialAnonConst {
span: lifetime_ref.ident.span,
name: lifetime_ref.ident.name,
param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime,
help: self
.r
.tcx
.sess
.is_nightly_build()
.then_some(errors::ParamInNonTrivialAnonConstHelp),
})
.emit();
}
}
}

View file

@ -21,6 +21,9 @@
#[macro_use]
extern crate tracing;
use errors::{
ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
};
use rustc_arena::{DroplessArena, TypedArena};
use rustc_ast::node_id::NodeMap;
use rustc_ast::{self as ast, attr, NodeId, CRATE_NODE_ID};
@ -223,11 +226,15 @@ enum ResolutionError<'a> {
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredGenericParam,
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
ParamInTyOfConstParam(Symbol),
ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> },
/// generic parameters must not be used inside const evaluations.
///
/// This error is only emitted when using `min_const_generics`.
ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst },
/// generic parameters must not be used inside enum discriminants.
///
/// This error is emitted even with `generic_const_exprs`.
ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
/// Error E0735: generic parameters with a default cannot use `Self`
SelfInGenericParamDefault,
/// Error E0767: use of unreachable label