Auto merge of #101986 - WaffleLapkin:move_lint_note_to_the_bottom, r=estebank
Move lint level source explanation to the bottom So, uhhhhh r? `@estebank` ## User-facing change "note: `#[warn(...)]` on by default" and such are moved to the bottom of the diagnostic: ```diff - = note: `#[warn(unsupported_calling_conventions)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678> + = note: `#[warn(unsupported_calling_conventions)]` on by default ``` Why warning is enabled is the least important thing, so it shouldn't be the first note the user reads, IMO. ## Developer-facing change `struct_span_lint` and similar methods have a different signature. Before: `..., impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>)` After: `..., impl Into<DiagnosticMessage>, impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>) -> &'b mut DiagnosticBuilder<'a, ()>` The reason for this is that `struct_span_lint` needs to edit the diagnostic _after_ `decorate` closure is called. This also makes lint code a little bit nicer in my opinion. Another option is to use `impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) -> DiagnosticBuilder<'a, ()>` altough I don't _really_ see reasons to do `let lint = lint.build(message)` everywhere. ## Subtle problem By moving the message outside of the closure (that may not be called if the lint is disabled) `format!(...)` is executed earlier, possibly formatting `Ty` which may call a query that trims paths that crashes the compiler if there were no warnings... I don't think it's that big of a deal, considering that we move from `format!(...)` to `fluent` (which is lazy by-default) anyway, however this required adding a workaround which is unfortunate. ## P.S. I'm sorry, I do not how to make this PR smaller/easier to review. Changes to the lint API affect SO MUCH 😢
This commit is contained in:
@@ -48,9 +48,13 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
|
||||
.emit();
|
||||
}
|
||||
None => {
|
||||
tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
|
||||
lint.build("use of calling convention not supported on this target").emit();
|
||||
});
|
||||
tcx.struct_span_lint_hir(
|
||||
UNSUPPORTED_CALLING_CONVENTIONS,
|
||||
hir_id,
|
||||
span,
|
||||
"use of calling convention not supported on this target",
|
||||
|lint| lint,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,10 +514,10 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
|
||||
UNINHABITED_STATIC,
|
||||
tcx.hir().local_def_id_to_hir_id(def_id),
|
||||
span,
|
||||
"static of uninhabited type",
|
||||
|lint| {
|
||||
lint.build("static of uninhabited type")
|
||||
lint
|
||||
.note("uninhabited statics cannot be initialized, and any access would be an immediate error")
|
||||
.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -1437,6 +1441,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD
|
||||
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
|
||||
tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
|
||||
span,
|
||||
"zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types",
|
||||
|lint| {
|
||||
let note = if non_exhaustive {
|
||||
"is marked with `#[non_exhaustive]`"
|
||||
@@ -1444,10 +1449,9 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD
|
||||
"contains private fields"
|
||||
};
|
||||
let field_ty = tcx.def_path_str_with_substs(def_id, substs);
|
||||
lint.build("zero-sized fields in repr(transparent) cannot contain external non-exhaustive types")
|
||||
lint
|
||||
.note(format!("this {descr} contains `{field_ty}`, which {note}, \
|
||||
and makes it not a breaking change to become non-zero-sized in the future."))
|
||||
.emit();
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user