Skip to content

Commit

Permalink
Auto merge of rust-lang#125410 - fmease:adj-lint-diag-api, r=<try>
Browse files Browse the repository at this point in the history
[perf] Delay construction of early lint diag structs

cc rust-lang#124417 (comment)
r? ghost
  • Loading branch information
bors committed May 22, 2024
2 parents 22f5bdc + 43ae057 commit 7ff5601
Show file tree
Hide file tree
Showing 47 changed files with 593 additions and 732 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
lint::builtin::INLINE_NO_SANITIZE,
hir_id,
no_sanitize_span,
"`no_sanitize` will have no effect after inlining",
|lint| {
lint.primary_message("`no_sanitize` will have no effect after inlining");
lint.span_note(inline_span, "inlining requested here");
},
)
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,6 @@ pub trait SubdiagMessageOp<G: EmissionGuarantee> =
pub trait LintDiagnostic<'a, G: EmissionGuarantee> {
/// Decorate and emit a lint.
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>);

fn msg(&self) -> DiagMessage;
}

#[derive(Clone, Debug, Encodable, Decodable)]
Expand Down
18 changes: 8 additions & 10 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,9 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
.emit();
}
None => {
tcx.node_span_lint(
UNSUPPORTED_CALLING_CONVENTIONS,
hir_id,
span,
"use of calling convention not supported on this target",
|_| {},
);
tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |diag| {
diag.primary_message("use of calling convention not supported on this target");
});
}
}

Expand Down Expand Up @@ -243,8 +239,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
UNINHABITED_STATIC,
tcx.local_def_id_to_hir_id(def_id),
span,
"static of uninhabited type",
|lint| {
lint.primary_message("static of uninhabited type");
lint
.note("uninhabited statics cannot be initialized, and any access would be an immediate error");
},
Expand Down Expand Up @@ -1315,9 +1311,11 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
tcx.local_def_id_to_hir_id(adt.did().expect_local()),
span,
"zero-sized fields in `repr(transparent)` cannot \
contain external non-exhaustive types",
|lint| {
lint.primary_message(
"zero-sized fields in `repr(transparent)` cannot \
contain external non-exhaustive types",
);
let note = if non_exhaustive {
"is marked with `#[non_exhaustive]`"
} else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
lint::builtin::ASM_SUB_REGISTER,
expr.hir_id,
spans,
"formatting may not be suitable for sub-register argument",
|lint| {
lint.primary_message("formatting may not be suitable for sub-register argument");
lint.span_label(expr.span, "for this argument");
lint.help(format!(
"use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)",
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_hir_analysis/src/check_unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
continue;
}
let (path, _) = item.expect_use();
let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
format!("unused import: `{snippet}`")
} else {
"unused import".to_owned()
};
tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, msg, |_| {});
tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
lint.primary_message(format!("unused import: `{snippet}`"));
} else {
lint.primary_message("unused import");
}
});
}
}
5 changes: 3 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
param.hir_id,
param.span,
TYPE_DEFAULT_NOT_ALLOWED,
|_| {},
|lint| {
lint.primary_message(TYPE_DEFAULT_NOT_ALLOWED);
},
);
}
Defaults::Deny => {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,9 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
LATE_BOUND_LIFETIME_ARGUMENTS,
args.args[0].hir_id(),
multispan,
msg,
|_| {},
|lint| {
lint.primary_message(msg);
},
);
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
} else {
let msg = "trait objects without an explicit `dyn` are deprecated";
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
lint.primary_message("trait objects without an explicit `dyn` are deprecated");
if self_ty.span.can_be_used_for_suggestions() {
lint.multipart_suggestion_verbose(
"if this is an object-safe trait, use `dyn`",
Expand Down
45 changes: 20 additions & 25 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,33 +1165,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound);

if let Some(variant_def_id) = variant_resolution {
tcx.node_span_lint(
AMBIGUOUS_ASSOCIATED_ITEMS,
hir_ref_id,
span,
"ambiguous associated item",
|lint| {
let mut could_refer_to = |kind: DefKind, def_id, also| {
let note_msg = format!(
"`{}` could{} refer to the {} defined here",
assoc_ident,
also,
tcx.def_kind_descr(kind, def_id)
);
lint.span_note(tcx.def_span(def_id), note_msg);
};
tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
lint.primary_message("ambiguous associated item");
let mut could_refer_to = |kind: DefKind, def_id, also| {
let note_msg = format!(
"`{}` could{} refer to the {} defined here",
assoc_ident,
also,
tcx.def_kind_descr(kind, def_id)
);
lint.span_note(tcx.def_span(def_id), note_msg);
};

could_refer_to(DefKind::Variant, variant_def_id, "");
could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");
could_refer_to(DefKind::Variant, variant_def_id, "");
could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");

lint.span_suggestion(
span,
"use fully-qualified syntax",
format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
Applicability::MachineApplicable,
);
},
);
lint.span_suggestion(
span,
"use fully-qualified syntax",
format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
Applicability::MachineApplicable,
);
});
}
Ok((ty, DefKind::AssocTy, assoc_ty_did))
}
Expand Down
20 changes: 7 additions & 13 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);

let msg = format!("unreachable {kind}");
self.tcx().node_span_lint(
lint::builtin::UNREACHABLE_CODE,
id,
span,
msg.clone(),
|lint| {
lint.span_label(span, msg).span_label(
orig_span,
custom_note
.unwrap_or("any code following this expression is unreachable"),
);
},
)
self.tcx().node_span_lint(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
lint.primary_message(msg.clone());
lint.span_label(span, msg).span_label(
orig_span,
custom_note.unwrap_or("any code following this expression is unreachable"),
);
})
}
}
}
Expand Down
130 changes: 63 additions & 67 deletions compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
prelude_or_array_lint,
self_expr.hir_id,
self_expr.span,
format!(
"trait method `{}` will become ambiguous in Rust {edition}",
segment.ident.name
),
|lint| {
lint.primary_message(format!(
"trait method `{}` will become ambiguous in Rust {edition}",
segment.ident.name
));

let sp = self_expr.span;

let derefs = "*".repeat(pick.autoderefs);
Expand Down Expand Up @@ -144,11 +145,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
prelude_or_array_lint,
call_expr.hir_id,
call_expr.span,
format!(
"trait method `{}` will become ambiguous in Rust {edition}",
segment.ident.name
),
|lint| {
lint.primary_message(format!(
"trait method `{}` will become ambiguous in Rust {edition}",
segment.ident.name
));

let sp = call_expr.span;
let trait_name = self.trait_path_or_bare_name(
span,
Expand Down Expand Up @@ -251,73 +253,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
}

self.tcx.node_span_lint(
RUST_2021_PRELUDE_COLLISIONS,
expr_id,
span,
format!(
self.tcx.node_span_lint(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
lint.primary_message(format!(
"trait-associated function `{}` will become ambiguous in Rust 2021",
method_name.name
),
|lint| {
// "type" refers to either a type or, more likely, a trait from which
// the associated function or method is from.
let container_id = pick.item.container_id(self.tcx);
let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
let trait_generics = self.tcx.generics_of(container_id);

let trait_name =
if trait_generics.own_params.len() <= trait_generics.has_self as usize {
trait_path
} else {
let counts = trait_generics.own_counts();
format!(
"{}<{}>",
trait_path,
));

// "type" refers to either a type or, more likely, a trait from which
// the associated function or method is from.
let container_id = pick.item.container_id(self.tcx);
let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
let trait_generics = self.tcx.generics_of(container_id);

let trait_name =
if trait_generics.own_params.len() <= trait_generics.has_self as usize {
trait_path
} else {
let counts = trait_generics.own_counts();
format!(
"{}<{}>",
trait_path,
std::iter::repeat("'_")
.take(counts.lifetimes)
.chain(std::iter::repeat("_").take(
counts.types + counts.consts - trait_generics.has_self as usize
))
.collect::<Vec<_>>()
.join(", ")
)
};

let mut self_ty_name = self_ty_span
.find_ancestor_inside(span)
.and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
.unwrap_or_else(|| self_ty.to_string());

// Get the number of generics the self type has (if an Adt) unless we can determine that
// the user has written the self type with generics already which we (naively) do by looking
// for a "<" in `self_ty_name`.
if !self_ty_name.contains('<') {
if let ty::Adt(def, _) = self_ty.kind() {
let generics = self.tcx.generics_of(def.did());
if !generics.is_own_empty() {
let counts = generics.own_counts();
self_ty_name += &format!(
"<{}>",
std::iter::repeat("'_")
.take(counts.lifetimes)
.chain(std::iter::repeat("_").take(
counts.types + counts.consts - trait_generics.has_self as usize
))
.chain(std::iter::repeat("_").take(counts.types + counts.consts))
.collect::<Vec<_>>()
.join(", ")
)
};

let mut self_ty_name = self_ty_span
.find_ancestor_inside(span)
.and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
.unwrap_or_else(|| self_ty.to_string());

// Get the number of generics the self type has (if an Adt) unless we can determine that
// the user has written the self type with generics already which we (naively) do by looking
// for a "<" in `self_ty_name`.
if !self_ty_name.contains('<') {
if let ty::Adt(def, _) = self_ty.kind() {
let generics = self.tcx.generics_of(def.did());
if !generics.is_own_empty() {
let counts = generics.own_counts();
self_ty_name += &format!(
"<{}>",
std::iter::repeat("'_")
.take(counts.lifetimes)
.chain(
std::iter::repeat("_").take(counts.types + counts.consts)
)
.collect::<Vec<_>>()
.join(", ")
);
}
);
}
}
lint.span_suggestion(
span,
"disambiguate the associated function",
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
Applicability::MachineApplicable,
);
},
);
}
lint.span_suggestion(
span,
"disambiguate the associated function",
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
Applicability::MachineApplicable,
);
});
}

fn trait_path_or_bare_name(
Expand Down
Loading

0 comments on commit 7ff5601

Please sign in to comment.