migrate: rest of builtin.rs
without builtin_asm_labels
This commit is contained in:
parent
587d49766b
commit
758140e196
@ -370,6 +370,8 @@ lint_builtin_anonymous_params = anonymous parameters are deprecated and will be
|
||||
.suggestion = try naming the parameter or explicitly ignoring it
|
||||
|
||||
lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
|
||||
.msg_suggestion = {$msg}
|
||||
.default_suggestion = remove this attribute
|
||||
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
|
||||
lint_builtin_deprecated_attr_default_suggestion = remove this attribute
|
||||
|
||||
@ -430,10 +432,16 @@ lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may n
|
||||
.note = see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information
|
||||
.help = consider using `min_{$name}` instead, which is more stable and complete
|
||||
|
||||
lint_builtin_clashing_extern_same_name = `{$this_fi}` redeclared with a different signature
|
||||
lint_builtin_unpermitted_type_init_zeroed = the type `{$ty}` does not permit zero-initialization
|
||||
lint_builtin_unpermitted_type_init_unint = the type `{$ty}` does not permit being left uninitialized
|
||||
|
||||
lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed
|
||||
lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
||||
|
||||
lint_builtin_clashing_extern_same_name = `{$this}` redeclared with a different signature
|
||||
.previous_decl_label = `{$orig}` previously declared here
|
||||
.mismatch_label = this signature doesn't match the previous declaration
|
||||
lint_builtin_clashing_extern_diff_name = `{$this_fi}` redeclares `{$orig}` with a different signature
|
||||
lint_builtin_clashing_extern_diff_name = `{$this}` redeclares `{$orig}` with a different signature
|
||||
.previous_decl_label = `{$orig}` previously declared here
|
||||
.mismatch_label = this signature doesn't match the previous declaration
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
// #![deny(rustc::untranslatable_diagnostic)]
|
||||
// #![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! Lints in the Rust compiler.
|
||||
//!
|
||||
//! This contains lints which can feasibly be implemented as their own
|
||||
@ -23,16 +25,21 @@
|
||||
use crate::{
|
||||
errors::BuiltinEllpisisInclusiveRangePatterns,
|
||||
lints::{
|
||||
BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinConstNoMangle,
|
||||
BuiltinDeprecatedAttrUsed, BuiltinDerefNullptr, BuiltinEllipsisInclusiveRangePatternsLint,
|
||||
BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinIncompleteFeatures,
|
||||
BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinClashingExtern,
|
||||
BuiltinClashingExternSub, BuiltinConstNoMangle, BuiltinDeprecatedAttrLink,
|
||||
BuiltinDeprecatedAttrLinkSuggestion, BuiltinDeprecatedAttrUsed, BuiltinDerefNullptr,
|
||||
BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives,
|
||||
BuiltinExplicitOutlivesSuggestion, BuiltinIncompleteFeatures,
|
||||
BuiltinIncompleteFeaturesHelp, BuiltinIncompleteFeaturesNote, BuiltinKeywordIdents,
|
||||
BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
|
||||
BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
|
||||
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinUnexpectedCliConfigName,
|
||||
BuiltinUnexpectedCliConfigValue, BuiltinUnnameableTestItems, BuiltinUnreachablePub,
|
||||
BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment,
|
||||
BuiltinUnusedDocCommentSub, BuiltinWhileTrue,
|
||||
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds,
|
||||
BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
|
||||
BuiltinUnexpectedCliConfigName, BuiltinUnexpectedCliConfigValue,
|
||||
BuiltinUngatedAsyncFnTrackCaller, BuiltinUnnameableTestItems, BuiltinUnpermittedTypeInit,
|
||||
BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
|
||||
BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
|
||||
BuiltinWhileTrue, SuggestChangingAssocTypes,
|
||||
},
|
||||
types::{transparent_newtype_field, CItemKind},
|
||||
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
|
||||
@ -45,9 +52,7 @@
|
||||
use rustc_ast_pretty::pprust::{self, expr_to_string};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::{
|
||||
fluent, Applicability, DecorateLint, DelayDm, Diagnostic, DiagnosticStyledString, MultiSpan,
|
||||
};
|
||||
use rustc_errors::{fluent, Applicability, DecorateLint, MultiSpan};
|
||||
use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
@ -923,24 +928,18 @@ fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
|
||||
_,
|
||||
) = gate
|
||||
{
|
||||
// FIXME(davidtwco) translatable deprecated attr
|
||||
cx.struct_span_lint(
|
||||
let suggestion = match suggestion {
|
||||
Some(msg) => {
|
||||
BuiltinDeprecatedAttrLinkSuggestion::Msg { suggestion: attr.span, msg }
|
||||
}
|
||||
None => {
|
||||
BuiltinDeprecatedAttrLinkSuggestion::Default { suggestion: attr.span }
|
||||
}
|
||||
};
|
||||
cx.emit_spanned_lint(
|
||||
DEPRECATED,
|
||||
attr.span,
|
||||
fluent::lint_builtin_deprecated_attr_link,
|
||||
|lint| {
|
||||
lint.set_arg("name", name)
|
||||
.set_arg("reason", reason)
|
||||
.set_arg("link", link)
|
||||
.span_suggestion_short(
|
||||
attr.span,
|
||||
suggestion.map(|s| s.into()).unwrap_or(
|
||||
fluent::lint_builtin_deprecated_attr_default_suggestion,
|
||||
),
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
},
|
||||
BuiltinDeprecatedAttrLink { name, reason, link, suggestion },
|
||||
);
|
||||
}
|
||||
return;
|
||||
@ -1305,20 +1304,10 @@ fn check_fn(
|
||||
// Now, check if the function has the `#[track_caller]` attribute
|
||||
&& let Some(attr) = attrs.iter().find(|attr| attr.has_name(sym::track_caller))
|
||||
{
|
||||
cx.struct_span_lint(
|
||||
UNGATED_ASYNC_FN_TRACK_CALLER,
|
||||
attr.span,
|
||||
fluent::lint_ungated_async_fn_track_caller,
|
||||
|lint| {
|
||||
lint.span_label(span, fluent::label);
|
||||
rustc_session::parse::add_feature_diagnostics(
|
||||
lint,
|
||||
&cx.tcx.sess.parse_sess,
|
||||
sym::closure_track_caller,
|
||||
);
|
||||
lint
|
||||
},
|
||||
);
|
||||
cx.emit_spanned_lint(UNGATED_ASYNC_FN_TRACK_CALLER, attr.span, BuiltinUngatedAsyncFnTrackCaller {
|
||||
label: span,
|
||||
parse_sess: &cx.tcx.sess.parse_sess,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1447,7 +1436,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_
|
||||
);
|
||||
|
||||
impl TypeAliasBounds {
|
||||
fn is_type_variable_assoc(qpath: &hir::QPath<'_>) -> bool {
|
||||
pub(crate) fn is_type_variable_assoc(qpath: &hir::QPath<'_>) -> bool {
|
||||
match *qpath {
|
||||
hir::QPath::TypeRelative(ref ty, _) => {
|
||||
// If this is a type variable, we found a `T::Assoc`.
|
||||
@ -1461,29 +1450,6 @@ fn is_type_variable_assoc(qpath: &hir::QPath<'_>) -> bool {
|
||||
hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_changing_assoc_types(ty: &hir::Ty<'_>, err: &mut Diagnostic) {
|
||||
// Access to associates types should use `<T as Bound>::Assoc`, which does not need a
|
||||
// bound. Let's see if this type does that.
|
||||
|
||||
// We use a HIR visitor to walk the type.
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
struct WalkAssocTypes<'a> {
|
||||
err: &'a mut Diagnostic,
|
||||
}
|
||||
impl Visitor<'_> for WalkAssocTypes<'_> {
|
||||
fn visit_qpath(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) {
|
||||
if TypeAliasBounds::is_type_variable_assoc(qpath) {
|
||||
self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help);
|
||||
}
|
||||
intravisit::walk_qpath(self, qpath, id)
|
||||
}
|
||||
}
|
||||
|
||||
// Let's go for a walk!
|
||||
let mut visitor = WalkAssocTypes { err };
|
||||
visitor.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
|
||||
@ -1517,35 +1483,31 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
|
||||
|
||||
let mut suggested_changing_assoc_types = false;
|
||||
if !where_spans.is_empty() {
|
||||
cx.lint(TYPE_ALIAS_BOUNDS, fluent::lint_builtin_type_alias_where_clause, |lint| {
|
||||
lint.set_span(where_spans);
|
||||
lint.span_suggestion(
|
||||
type_alias_generics.where_clause_span,
|
||||
fluent::suggestion,
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
if !suggested_changing_assoc_types {
|
||||
TypeAliasBounds::suggest_changing_assoc_types(ty, lint);
|
||||
suggested_changing_assoc_types = true;
|
||||
}
|
||||
lint
|
||||
let sub = (!suggested_changing_assoc_types).then(|| {
|
||||
suggested_changing_assoc_types = true;
|
||||
SuggestChangingAssocTypes { ty }
|
||||
});
|
||||
cx.emit_spanned_lint(
|
||||
TYPE_ALIAS_BOUNDS,
|
||||
where_spans,
|
||||
BuiltinTypeAliasWhereClause {
|
||||
suggestion: type_alias_generics.where_clause_span,
|
||||
sub,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if !inline_spans.is_empty() {
|
||||
cx.lint(TYPE_ALIAS_BOUNDS, fluent::lint_builtin_type_alias_generic_bounds, |lint| {
|
||||
lint.set_span(inline_spans);
|
||||
lint.multipart_suggestion(
|
||||
fluent::suggestion,
|
||||
inline_sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
if !suggested_changing_assoc_types {
|
||||
TypeAliasBounds::suggest_changing_assoc_types(ty, lint);
|
||||
}
|
||||
lint
|
||||
let suggestion = BuiltinTypeAliasGenericBoundsSuggestion { suggestions: inline_sugg };
|
||||
let sub = (!suggested_changing_assoc_types).then(|| {
|
||||
suggested_changing_assoc_types = true;
|
||||
SuggestChangingAssocTypes { ty }
|
||||
});
|
||||
cx.emit_spanned_lint(
|
||||
TYPE_ALIAS_BOUNDS,
|
||||
inline_spans,
|
||||
BuiltinTypeAliasGenericBounds { suggestion, sub },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2376,6 +2338,36 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
|
||||
|
||||
declare_lint_pass!(InvalidValue => [INVALID_VALUE]);
|
||||
|
||||
/// Information about why a type cannot be initialized this way.
|
||||
pub struct InitError {
|
||||
pub(crate) message: String,
|
||||
/// Spans from struct fields and similar that can be obtained from just the type.
|
||||
pub(crate) span: Option<Span>,
|
||||
/// Used to report a trace through adts.
|
||||
pub(crate) nested: Option<Box<InitError>>,
|
||||
}
|
||||
impl InitError {
|
||||
fn spanned(self, span: Span) -> InitError {
|
||||
Self { span: Some(span), ..self }
|
||||
}
|
||||
|
||||
fn nested(self, nested: impl Into<Option<InitError>>) -> InitError {
|
||||
assert!(self.nested.is_none());
|
||||
Self { nested: nested.into().map(Box::new), ..self }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for InitError {
|
||||
fn from(s: &'a str) -> Self {
|
||||
s.to_owned().into()
|
||||
}
|
||||
}
|
||||
impl From<String> for InitError {
|
||||
fn from(message: String) -> Self {
|
||||
Self { message, span: None, nested: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) {
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
@ -2384,36 +2376,6 @@ enum InitKind {
|
||||
Uninit,
|
||||
}
|
||||
|
||||
/// Information about why a type cannot be initialized this way.
|
||||
struct InitError {
|
||||
message: String,
|
||||
/// Spans from struct fields and similar that can be obtained from just the type.
|
||||
span: Option<Span>,
|
||||
/// Used to report a trace through adts.
|
||||
nested: Option<Box<InitError>>,
|
||||
}
|
||||
impl InitError {
|
||||
fn spanned(self, span: Span) -> InitError {
|
||||
Self { span: Some(span), ..self }
|
||||
}
|
||||
|
||||
fn nested(self, nested: impl Into<Option<InitError>>) -> InitError {
|
||||
assert!(self.nested.is_none());
|
||||
Self { nested: nested.into().map(Box::new), ..self }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for InitError {
|
||||
fn from(s: &'a str) -> Self {
|
||||
s.to_owned().into()
|
||||
}
|
||||
}
|
||||
impl From<String> for InitError {
|
||||
fn from(message: String) -> Self {
|
||||
Self { message, span: None, nested: None }
|
||||
}
|
||||
}
|
||||
|
||||
/// Test if this constant is all-0.
|
||||
fn is_zero(expr: &hir::Expr<'_>) -> bool {
|
||||
use hir::ExprKind::*;
|
||||
@ -2637,46 +2599,16 @@ fn ty_find_init_error<'tcx>(
|
||||
// using zeroed or uninitialized memory.
|
||||
// We are extremely conservative with what we warn about.
|
||||
let conjured_ty = cx.typeck_results().expr_ty(expr);
|
||||
if let Some(mut err) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init))
|
||||
{
|
||||
// FIXME(davidtwco): make translatable
|
||||
cx.struct_span_lint(
|
||||
if let Some(err) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init)) {
|
||||
let msg = match init {
|
||||
InitKind::Zeroed => fluent::lint_builtin_unpermitted_type_init_zeroed,
|
||||
InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_unint,
|
||||
};
|
||||
let sub = BuiltinUnpermittedTypeInitSub { err };
|
||||
cx.emit_spanned_lint(
|
||||
INVALID_VALUE,
|
||||
expr.span,
|
||||
DelayDm(|| {
|
||||
format!(
|
||||
"the type `{}` does not permit {}",
|
||||
conjured_ty,
|
||||
match init {
|
||||
InitKind::Zeroed => "zero-initialization",
|
||||
InitKind::Uninit => "being left uninitialized",
|
||||
},
|
||||
)
|
||||
}),
|
||||
|lint| {
|
||||
lint.span_label(
|
||||
expr.span,
|
||||
"this code causes undefined behavior when executed",
|
||||
);
|
||||
lint.span_label(
|
||||
expr.span,
|
||||
"help: use `MaybeUninit<T>` instead, \
|
||||
and only call `assume_init` after initialization is done",
|
||||
);
|
||||
loop {
|
||||
if let Some(span) = err.span {
|
||||
lint.span_note(span, &err.message);
|
||||
} else {
|
||||
lint.note(&err.message);
|
||||
}
|
||||
if let Some(e) = err.nested {
|
||||
err = *e;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lint
|
||||
},
|
||||
BuiltinUnpermittedTypeInit { msg, ty: conjured_ty, label: expr.span, sub },
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -3022,31 +2954,44 @@ fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, this_fi: &hir::ForeignI
|
||||
SymbolName::Normal(_) => fi.span,
|
||||
SymbolName::Link(_, annot_span) => fi.span.to(annot_span),
|
||||
};
|
||||
// Finally, emit the diagnostic.
|
||||
|
||||
let msg = if orig.get_name() == this_fi.ident.name {
|
||||
fluent::lint_builtin_clashing_extern_same_name
|
||||
} else {
|
||||
fluent::lint_builtin_clashing_extern_diff_name
|
||||
// Finally, emit the diagnostic.
|
||||
let mut expected_str = DiagnosticStyledString::new();
|
||||
expected_str.push(existing_decl_ty.fn_sig(tcx).to_string(), false);
|
||||
let mut found_str = DiagnosticStyledString::new();
|
||||
found_str.push(this_decl_ty.fn_sig(tcx).to_string(), true);
|
||||
|
||||
let this = this_fi.ident.name;
|
||||
let orig = orig.get_name();
|
||||
let previous_decl_label = get_relevant_span(orig_fi);
|
||||
let mismatch_label = get_relevant_span(this_fi);
|
||||
let sub = BuiltinClashingExternSub {
|
||||
tcx,
|
||||
expected: existing_decl_ty,
|
||||
found: this_decl_ty,
|
||||
};
|
||||
tcx.struct_span_lint_hir(
|
||||
let decorator = if orig == this {
|
||||
BuiltinClashingExtern::SameName {
|
||||
this,
|
||||
orig,
|
||||
previous_decl_label,
|
||||
mismatch_label,
|
||||
sub,
|
||||
}
|
||||
} else {
|
||||
BuiltinClashingExtern::DiffName {
|
||||
this,
|
||||
orig,
|
||||
previous_decl_label,
|
||||
mismatch_label,
|
||||
sub,
|
||||
}
|
||||
};
|
||||
tcx.emit_spanned_lint(
|
||||
CLASHING_EXTERN_DECLARATIONS,
|
||||
this_fi.hir_id(),
|
||||
get_relevant_span(this_fi),
|
||||
msg,
|
||||
|lint| {
|
||||
let mut expected_str = DiagnosticStyledString::new();
|
||||
expected_str.push(existing_decl_ty.fn_sig(tcx).to_string(), false);
|
||||
let mut found_str = DiagnosticStyledString::new();
|
||||
found_str.push(this_decl_ty.fn_sig(tcx).to_string(), true);
|
||||
|
||||
lint.set_arg("this_fi", this_fi.ident.name)
|
||||
.set_arg("orig", orig.get_name())
|
||||
.span_label(get_relevant_span(orig_fi), fluent::previous_decl_label)
|
||||
.span_label(get_relevant_span(this_fi), fluent::mismatch_label)
|
||||
// FIXME(davidtwco): translatable expected/found
|
||||
.note_expected_found(&"", expected_str, &"", found_str)
|
||||
},
|
||||
decorator,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use rustc_errors::{
|
||||
fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, SuggestionStyle,
|
||||
fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage,
|
||||
DiagnosticStyledString, SuggestionStyle,
|
||||
};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::{Predicate, Ty, TyCtxt};
|
||||
use rustc_span::{edition::Edition, symbol::Ident, Span, Symbol};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
|
||||
|
||||
use crate::{errors::OverruledAttributeSub, LateContext};
|
||||
use crate::{
|
||||
builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext,
|
||||
};
|
||||
|
||||
// array_into_iter.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
@ -142,7 +146,31 @@ pub struct BuiltinAnonymousParams<'a> {
|
||||
pub ty_snip: &'a str,
|
||||
}
|
||||
|
||||
// FIXME: add lint::builtin_deprecated_attr_link
|
||||
// FIXME(davidtwco) translatable deprecated attr
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_builtin_deprecated_attr_link)]
|
||||
pub struct BuiltinDeprecatedAttrLink<'a> {
|
||||
pub name: Symbol,
|
||||
pub reason: &'a str,
|
||||
pub link: &'a str,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: BuiltinDeprecatedAttrLinkSuggestion<'a>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
|
||||
#[suggestion(msg_suggestion, code = "", applicability = "machine-applicable")]
|
||||
Msg {
|
||||
#[primary_span]
|
||||
suggestion: Span,
|
||||
msg: &'a str,
|
||||
},
|
||||
#[suggestion(default_suggestion, code = "", applicability = "machine-applicable")]
|
||||
Default {
|
||||
#[primary_span]
|
||||
suggestion: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_builtin_deprecated_attr_used)]
|
||||
@ -199,6 +227,31 @@ pub struct BuiltinConstNoMangle {
|
||||
#[diag(lint_builtin_unstable_features)]
|
||||
pub struct BuiltinUnstableFeatures;
|
||||
|
||||
// lint_ungated_async_fn_track_caller
|
||||
pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
|
||||
pub label: Span,
|
||||
pub parse_sess: &'a ParseSess,
|
||||
}
|
||||
|
||||
impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
|
||||
fn decorate_lint<'b>(
|
||||
self,
|
||||
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
|
||||
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
|
||||
diag.span_label(self.label, fluent::label);
|
||||
rustc_session::parse::add_feature_diagnostics(
|
||||
diag,
|
||||
&self.parse_sess,
|
||||
sym::closure_track_caller,
|
||||
);
|
||||
diag
|
||||
}
|
||||
|
||||
fn msg(&self) -> DiagnosticMessage {
|
||||
fluent::lint_ungated_async_fn_track_caller
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_builtin_unreachable_pub)]
|
||||
pub struct BuiltinUnreachablePub<'a> {
|
||||
@ -209,9 +262,83 @@ pub struct BuiltinUnreachablePub<'a> {
|
||||
pub help: Option<()>,
|
||||
}
|
||||
|
||||
// FIXME: migrate builtin_type_alias_where_clause
|
||||
pub struct SuggestChangingAssocTypes<'a, 'b> {
|
||||
pub ty: &'a rustc_hir::Ty<'b>,
|
||||
}
|
||||
|
||||
// FIXME: migrate builtin_type_alias_generic_bounds
|
||||
impl AddToDiagnostic for SuggestChangingAssocTypes<'_, '_> {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(
|
||||
&mut rustc_errors::Diagnostic,
|
||||
rustc_errors::SubdiagnosticMessage,
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
{
|
||||
// Access to associates types should use `<T as Bound>::Assoc`, which does not need a
|
||||
// bound. Let's see if this type does that.
|
||||
|
||||
// We use a HIR visitor to walk the type.
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
struct WalkAssocTypes<'a> {
|
||||
err: &'a mut rustc_errors::Diagnostic,
|
||||
}
|
||||
impl Visitor<'_> for WalkAssocTypes<'_> {
|
||||
fn visit_qpath(
|
||||
&mut self,
|
||||
qpath: &rustc_hir::QPath<'_>,
|
||||
id: rustc_hir::HirId,
|
||||
span: Span,
|
||||
) {
|
||||
if TypeAliasBounds::is_type_variable_assoc(qpath) {
|
||||
self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help);
|
||||
}
|
||||
intravisit::walk_qpath(self, qpath, id)
|
||||
}
|
||||
}
|
||||
|
||||
// Let's go for a walk!
|
||||
let mut visitor = WalkAssocTypes { err: diag };
|
||||
visitor.visit_ty(self.ty);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_builtin_type_alias_where_clause)]
|
||||
pub struct BuiltinTypeAliasWhereClause<'a, 'b> {
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub suggestion: Span,
|
||||
#[subdiagnostic]
|
||||
pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_builtin_type_alias_generic_bounds)]
|
||||
pub struct BuiltinTypeAliasGenericBounds<'a, 'b> {
|
||||
#[subdiagnostic]
|
||||
pub suggestion: BuiltinTypeAliasGenericBoundsSuggestion,
|
||||
#[subdiagnostic]
|
||||
pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
|
||||
}
|
||||
|
||||
pub struct BuiltinTypeAliasGenericBoundsSuggestion {
|
||||
pub suggestions: Vec<(Span, String)>,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(
|
||||
&mut rustc_errors::Diagnostic,
|
||||
rustc_errors::SubdiagnosticMessage,
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
{
|
||||
diag.multipart_suggestion(
|
||||
fluent::suggestion,
|
||||
self.suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_builtin_trivial_bounds)]
|
||||
@ -285,9 +412,107 @@ pub struct BuiltinIncompleteFeaturesNote {
|
||||
pub n: NonZeroU32,
|
||||
}
|
||||
|
||||
// FIXME: migrate "the type `{}` does not permit {}"
|
||||
pub struct BuiltinUnpermittedTypeInit<'a> {
|
||||
pub msg: DiagnosticMessage,
|
||||
pub ty: Ty<'a>,
|
||||
pub label: Span,
|
||||
pub sub: BuiltinUnpermittedTypeInitSub,
|
||||
}
|
||||
|
||||
// FIXME: fluent::lint::builtin_clashing_extern_{same,diff}_name
|
||||
impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
|
||||
fn decorate_lint<'b>(
|
||||
self,
|
||||
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
|
||||
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
|
||||
diag.set_arg("ty", self.ty);
|
||||
diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
|
||||
diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label_suggestion);
|
||||
self.sub.add_to_diagnostic(diag);
|
||||
diag
|
||||
}
|
||||
|
||||
fn msg(&self) -> rustc_errors::DiagnosticMessage {
|
||||
self.msg.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(davidtwco): make translatable
|
||||
pub struct BuiltinUnpermittedTypeInitSub {
|
||||
pub err: InitError,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for BuiltinUnpermittedTypeInitSub {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(
|
||||
&mut rustc_errors::Diagnostic,
|
||||
rustc_errors::SubdiagnosticMessage,
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
{
|
||||
let mut err = self.err;
|
||||
loop {
|
||||
if let Some(span) = err.span {
|
||||
diag.span_note(span, err.message);
|
||||
} else {
|
||||
diag.note(err.message);
|
||||
}
|
||||
if let Some(e) = err.nested {
|
||||
err = *e;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
pub enum BuiltinClashingExtern<'a> {
|
||||
#[diag(lint_builtin_clashing_extern_same_name)]
|
||||
SameName {
|
||||
this: Symbol,
|
||||
orig: Symbol,
|
||||
#[label(previous_decl_label)]
|
||||
previous_decl_label: Span,
|
||||
#[label(mismatch_label)]
|
||||
mismatch_label: Span,
|
||||
#[subdiagnostic]
|
||||
sub: BuiltinClashingExternSub<'a>,
|
||||
},
|
||||
#[diag(lint_builtin_clashing_extern_diff_name)]
|
||||
DiffName {
|
||||
this: Symbol,
|
||||
orig: Symbol,
|
||||
#[label(previous_decl_label)]
|
||||
previous_decl_label: Span,
|
||||
#[label(mismatch_label)]
|
||||
mismatch_label: Span,
|
||||
#[subdiagnostic]
|
||||
sub: BuiltinClashingExternSub<'a>,
|
||||
},
|
||||
}
|
||||
|
||||
// FIXME(davidtwco): translatable expected/found
|
||||
pub struct BuiltinClashingExternSub<'a> {
|
||||
pub tcx: TyCtxt<'a>,
|
||||
pub expected: Ty<'a>,
|
||||
pub found: Ty<'a>,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for BuiltinClashingExternSub<'_> {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(
|
||||
&mut rustc_errors::Diagnostic,
|
||||
rustc_errors::SubdiagnosticMessage,
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
{
|
||||
let mut expected_str = DiagnosticStyledString::new();
|
||||
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
|
||||
let mut found_str = DiagnosticStyledString::new();
|
||||
found_str.push(self.found.fn_sig(self.tcx).to_string(), true);
|
||||
diag.note_expected_found(&"", expected_str, &"", found_str);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_builtin_deref_nullptr)]
|
||||
|
Loading…
Reference in New Issue
Block a user