Auto merge of #98925 - Dylan-DPC:rollup-9185c9y, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #97712 (ptr::copy and ptr::swap are doing untyped copies) - #98624 (lints: mostly translatable diagnostics) - #98776 (rustdoc: improve click behavior of the source code mobile full-screen "sidebar") - #98856 (Remove FIXME from rustdoc intra-doc test) - #98913 (⬆️ rust-analyzer) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
54f79babae
39 changed files with 1223 additions and 737 deletions
400
compiler/rustc_error_messages/locales/en-US/lint.ftl
Normal file
400
compiler/rustc_error_messages/locales/en-US/lint.ftl
Normal file
|
@ -0,0 +1,400 @@
|
|||
lint-array-into-iter =
|
||||
this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <{$target} as IntoIterator>::into_iter in Rust 2021
|
||||
.use-iter-suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
||||
.remove-into-iter-suggestion = or remove `.into_iter()` to iterate by value
|
||||
.use-explicit-into-iter-suggestion =
|
||||
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
|
||||
|
||||
lint-enum-intrinsics-mem-discriminant =
|
||||
the return value of `mem::discriminant` is unspecified when called with a non-enum type
|
||||
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum.
|
||||
|
||||
lint-enum-intrinsics-mem-variant =
|
||||
the return value of `mem::variant_count` is unspecified when called with a non-enum type
|
||||
.note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum.
|
||||
|
||||
lint-expectation = this lint expectation is unfulfilled
|
||||
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
|
||||
|
||||
lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of text present in {$label}
|
||||
.label = this {$label} contains {$count ->
|
||||
[one] an invisible
|
||||
*[other] invisible
|
||||
} unicode text flow control {$count ->
|
||||
[one] codepoint
|
||||
*[other] codepoints
|
||||
}
|
||||
.note = these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
|
||||
.suggestion-remove = if their presence wasn't intentional, you can remove them
|
||||
.suggestion-escape = if you want to keep them but make them visible in your source code, you can escape them
|
||||
.no-suggestion-note-escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
|
||||
|
||||
lint-default-hash-types = prefer `{$preferred}` over `{$used}`, it has better performance
|
||||
.note = a `use rustc_data_structures::fx::{$preferred}` may be necessary
|
||||
|
||||
lint-query-instability = using `{$query}` can result in unstable query results
|
||||
.note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
|
||||
|
||||
lint-tykind-kind = usage of `ty::TyKind::<kind>`
|
||||
.suggestion = try using `ty::<kind>` directly
|
||||
|
||||
lint-tykind = usage of `ty::TyKind`
|
||||
.help = try using `Ty` instead
|
||||
|
||||
lint-ty-qualified = usage of qualified `ty::{$ty}`
|
||||
.suggestion = try importing it and using it unqualified
|
||||
|
||||
lint-lintpass-by-hand = implementing `LintPass` by hand
|
||||
.help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
|
||||
|
||||
lint-non-existant-doc-keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
|
||||
.help = only existing keywords are allowed in core/std
|
||||
|
||||
lint-diag-out-of-impl =
|
||||
diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
|
||||
|
||||
lint-untranslatable-diag = diagnostics should be created using translatable messages
|
||||
|
||||
lint-cstring-ptr = getting the inner pointer of a temporary `CString`
|
||||
.as-ptr-label = this pointer will be invalid
|
||||
.unwrap-label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
||||
.note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
||||
.help = for more information, see https://doc.rust-lang.org/reference/destructors.html
|
||||
|
||||
lint-identifier-non-ascii-char = identifier contains non-ASCII characters
|
||||
|
||||
lint-identifier-uncommon-codepoints = identifier contains uncommon Unicode codepoints
|
||||
|
||||
lint-confusable-identifier-pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
|
||||
.label = this is where the previous identifier occurred
|
||||
|
||||
lint-mixed-script-confusables =
|
||||
the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables
|
||||
.includes-note = the usage includes {$includes}
|
||||
.note = please recheck to make sure their usages are indeed what you want
|
||||
|
||||
lint-non-fmt-panic = panic message is not a string literal
|
||||
.note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021
|
||||
.more-info-note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
.supports-fmt-note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
|
||||
.supports-fmt-suggestion = remove the `format!(..)` macro call
|
||||
.display-suggestion = add a "{"{"}{"}"}" format string to `Display` the message
|
||||
.debug-suggestion =
|
||||
add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}`
|
||||
.panic-suggestion = {$already_suggested ->
|
||||
[true] or use
|
||||
*[false] use
|
||||
} std::panic::panic_any instead
|
||||
|
||||
lint-non-fmt-panic-unused =
|
||||
panic message contains {$count ->
|
||||
[one] an unused
|
||||
*[other] unused
|
||||
} formatting {$count ->
|
||||
[one] placeholder
|
||||
*[other] placeholders
|
||||
}
|
||||
.note = this message is not used as a format string when given without arguments, but will be in Rust 2021
|
||||
.add-args-suggestion = add the missing {$count ->
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}
|
||||
.add-fmt-suggestion = or add a "{"{"}{"}"}" format string to use the message literally
|
||||
|
||||
lint-non-fmt-panic-braces =
|
||||
panic message contains {$count ->
|
||||
[one] a brace
|
||||
*[other] braces
|
||||
}
|
||||
.note = this message is not used as a format string, but will be in Rust 2021
|
||||
.suggestion = add a "{"{"}{"}"}" format string to use the message literally
|
||||
|
||||
lint-non-camel-case-type = {$sort} `{$name}` should have an upper camel case name
|
||||
.suggestion = convert the identifier to upper camel case
|
||||
.label = should have an UpperCamelCase name
|
||||
|
||||
lint-non-snake-case = {$sort} `{$name}` should have a snake case name
|
||||
.rename-or-convert-suggestion = rename the identifier or convert it to a snake case raw identifier
|
||||
.cannot-convert-note = `{$sc}` cannot be used as a raw identifier
|
||||
.rename-suggestion = rename the identifier
|
||||
.convert-suggestion = convert the identifier to snake case
|
||||
.help = convert the identifier to snake case: `{$sc}`
|
||||
.label = should have a snake_case name
|
||||
|
||||
lint-non-upper_case-global = {$sort} `{$name}` should have an upper case name
|
||||
.suggestion = convert the identifier to upper case
|
||||
.label = should have an UPPER_CASE name
|
||||
|
||||
lint-noop-method-call = call to `.{$method}()` on a reference in this situation does nothing
|
||||
.label = unnecessary method call
|
||||
.note = the type `{$receiver_ty}` which `{$method}` is being called on is the same as the type returned from `{$method}`, so the method call does not do anything and can be removed
|
||||
|
||||
lint-pass-by-value = passing `{$ty}` by reference
|
||||
.suggestion = try passing by value
|
||||
|
||||
lint-redundant-semicolons =
|
||||
unnecessary trailing {$multiple ->
|
||||
[true] semicolons
|
||||
*[false] semicolon
|
||||
}
|
||||
.suggestion = remove {$multiple ->
|
||||
[true] these semicolons
|
||||
*[false] this semicolon
|
||||
}
|
||||
|
||||
lint-drop-trait-constraints =
|
||||
bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped
|
||||
|
||||
lint-drop-glue =
|
||||
types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped
|
||||
|
||||
lint-range-endpoint-out-of-range = range endpoint is out of range for `{$ty}`
|
||||
.suggestion = use an inclusive range instead
|
||||
|
||||
lint-overflowing-bin-hex = literal out of range for `{$ty}`
|
||||
.negative-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
|
||||
.negative-becomes-note = and the value `-{$lit}` will become `{$actually}{$ty}`
|
||||
.positive-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
|
||||
.suggestion = consider using the type `{$suggestion_ty}` instead
|
||||
.help = consider using the type `{$suggestion_ty}` instead
|
||||
|
||||
lint-overflowing-int = literal out of range for `{$ty}`
|
||||
.note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
|
||||
.help = consider using the type `{$suggestion_ty}` instead
|
||||
|
||||
lint-only-cast-u8-to-char = only `u8` can be cast into `char`
|
||||
.suggestion = use a `char` literal instead
|
||||
|
||||
lint-overflowing-uint = literal out of range for `{$ty}`
|
||||
.note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
|
||||
|
||||
lint-overflowing-literal = literal out of range for `{$ty}`
|
||||
.note = the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY`
|
||||
|
||||
lint-unused-comparisons = comparison is useless due to type limits
|
||||
|
||||
lint-improper-ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
|
||||
.label = not FFI-safe
|
||||
.note = the type is defined here
|
||||
|
||||
lint-improper-ctypes-opaque = opaque types have no C equivalent
|
||||
|
||||
lint-improper-ctypes-fnptr-reason = this function pointer has Rust-specific calling convention
|
||||
lint-improper-ctypes-fnptr-help = consider using an `extern fn(...) -> ...` function pointer instead
|
||||
|
||||
lint-improper-ctypes-tuple-reason = tuples have unspecified layout
|
||||
lint-improper-ctypes-tuple-help = consider using a struct instead
|
||||
|
||||
lint-improper-ctypes-str-reason = string slices have no C equivalent
|
||||
lint-improper-ctypes-str-help = consider using `*const u8` and a length instead
|
||||
|
||||
lint-improper-ctypes-dyn = trait objects have no C equivalent
|
||||
|
||||
lint-improper-ctypes-slice-reason = slices have no C equivalent
|
||||
lint-improper-ctypes-slice-help = consider using a raw pointer instead
|
||||
|
||||
lint-improper-ctypes-128bit = 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
lint-improper-ctypes-char-reason = the `char` type has no C equivalent
|
||||
lint-improper-ctypes-char-help = consider using `u32` or `libc::wchar_t` instead
|
||||
|
||||
lint-improper-ctypes-non-exhaustive = this enum is non-exhaustive
|
||||
lint-improper-ctypes-non-exhaustive-variant = this enum has non-exhaustive variants
|
||||
|
||||
lint-improper-ctypes-enum-repr-reason = enum has no representation hint
|
||||
lint-improper-ctypes-enum-repr-help =
|
||||
consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
|
||||
lint-improper-ctypes-struct-fieldless-reason = this struct has no fields
|
||||
lint-improper-ctypes-struct-fieldless-help = consider adding a member to this struct
|
||||
|
||||
lint-improper-ctypes-union-fieldless-reason = this union has no fields
|
||||
lint-improper-ctypes-union-fieldless-help = consider adding a member to this union
|
||||
|
||||
lint-improper-ctypes-struct-non-exhaustive = this struct is non-exhaustive
|
||||
lint-improper-ctypes-union-non-exhaustive = this union is non-exhaustive
|
||||
|
||||
lint-improper-ctypes-struct-layout-reason = this struct has unspecified layout
|
||||
lint-improper-ctypes-struct-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
|
||||
lint-improper-ctypes-union-layout-reason = this union has unspecified layout
|
||||
lint-improper-ctypes-union-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
|
||||
|
||||
lint-improper-ctypes-box = box cannot be represented as a single pointer
|
||||
|
||||
lint-improper-ctypes-enum-phantomdata = this enum contains a PhantomData field
|
||||
|
||||
lint-improper-ctypes-struct-zst = this struct contains only zero-sized fields
|
||||
|
||||
lint-improper-ctypes-array-reason = passing raw arrays by value is not FFI-safe
|
||||
lint-improper-ctypes-array-help = consider passing a pointer to the array
|
||||
|
||||
lint-improper-ctypes-only-phantomdata = composed only of `PhantomData`
|
||||
|
||||
lint-variant-size-differences =
|
||||
enum variant is more than three times larger ({$largest} bytes) than the next largest
|
||||
|
||||
lint-atomic-ordering-load = atomic loads cannot have `Release` or `AcqRel` ordering
|
||||
.help = consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
|
||||
|
||||
lint-atomic-ordering-store = atomic stores cannot have `Acquire` or `AcqRel` ordering
|
||||
.help = consider using ordering modes `Release`, `SeqCst` or `Relaxed`
|
||||
|
||||
lint-atomic-ordering-fence = memory fences cannot have `Relaxed` ordering
|
||||
.help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
|
||||
|
||||
lint-atomic-ordering-invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
|
||||
.label = invalid failure ordering
|
||||
.help = consider using `Acquire` or `Relaxed` failure ordering instead
|
||||
|
||||
lint-atomic-ordering-invalid-fail-success = `{$method}`'s success ordering must be at least as strong as its failure ordering
|
||||
.fail-label = `{$fail_ordering}` failure ordering
|
||||
.success-label = `{$success_ordering}` success ordering
|
||||
.suggestion = consider using `{$success_suggestion}` success ordering instead
|
||||
|
||||
lint-unused-op = unused {$op} that must be used
|
||||
.label = the {$op} produces a value
|
||||
.suggestion = use `let _ = ...` to ignore the resulting value
|
||||
|
||||
lint-unused-result = unused result of type `{$ty}`
|
||||
|
||||
lint-unused-closure =
|
||||
unused {$pre}{$count ->
|
||||
[one] closure
|
||||
*[other] closures
|
||||
}{$post} that must be used
|
||||
.note = closures are lazy and do nothing unless called
|
||||
|
||||
lint-unused-generator =
|
||||
unused {$pre}{$count ->
|
||||
[one] generator
|
||||
*[other] generator
|
||||
}{$post} that must be used
|
||||
.note = generators are lazy and do nothing unless resumed
|
||||
|
||||
lint-unused-def = unused {$pre}`{$def}`{$post} that must be used
|
||||
|
||||
lint-path-statement-drop = path statement drops value
|
||||
.suggestion = use `drop` to clarify the intent
|
||||
|
||||
lint-path-statement-no-effect = path statement with no effect
|
||||
|
||||
lint-unused-delim = unnecessary {$delim} around {$item}
|
||||
.suggestion = remove these {$delim}
|
||||
|
||||
lint-unused-import-braces = braces around {$node} is unnecessary
|
||||
|
||||
lint-unused-allocation = unnecessary allocation, use `&` instead
|
||||
lint-unused-allocation-mut = unnecessary allocation, use `&mut` instead
|
||||
|
||||
lint-builtin-while-true = denote infinite loops with `loop {"{"} ... {"}"}`
|
||||
.suggestion = use `loop`
|
||||
|
||||
lint-builtin-box-pointers = type uses owned (Box type) pointers: {$ty}
|
||||
|
||||
lint-builtin-non-shorthand-field-patterns = the `{$ident}:` in this pattern is redundant
|
||||
.suggestion = use shorthand field pattern
|
||||
|
||||
lint-builtin-overridden-symbol-name =
|
||||
the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
|
||||
|
||||
lint-builtin-overridden-symbol-section =
|
||||
the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
|
||||
|
||||
lint-builtin-allow-internal-unsafe =
|
||||
`allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
|
||||
|
||||
lint-builtin-unsafe-block = usage of an `unsafe` block
|
||||
|
||||
lint-builtin-unsafe-trait = declaration of an `unsafe` trait
|
||||
|
||||
lint-builtin-unsafe-impl = implementation of an `unsafe` trait
|
||||
|
||||
lint-builtin-no-mangle-fn = declaration of a `no_mangle` function
|
||||
lint-builtin-export-name-fn = declaration of a function with `export_name`
|
||||
lint-builtin-link-section-fn = declaration of a function with `link_section`
|
||||
|
||||
lint-builtin-no-mangle-static = declaration of a `no_mangle` static
|
||||
lint-builtin-export-name-static = declaration of a static with `export_name`
|
||||
lint-builtin-link-section-static = declaration of a static with `link_section`
|
||||
|
||||
lint-builtin-no-mangle-method = declaration of a `no_mangle` method
|
||||
lint-builtin-export-name-method = declaration of a method with `export_name`
|
||||
|
||||
lint-builtin-decl-unsafe-fn = declaration of an `unsafe` function
|
||||
lint-builtin-decl-unsafe-method = declaration of an `unsafe` method
|
||||
lint-builtin-impl-unsafe-method = implementation of an `unsafe` method
|
||||
|
||||
lint-builtin-missing-doc = missing documentation for {$article} {$desc}
|
||||
|
||||
lint-builtin-missing-copy-impl = type could implement `Copy`; consider adding `impl Copy`
|
||||
|
||||
lint-builtin-missing-debug-impl =
|
||||
type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation
|
||||
|
||||
lint-builtin-anonymous-params = anonymous parameters are deprecated and will be removed in the next edition
|
||||
.suggestion = try naming the parameter or explicitly ignoring it
|
||||
|
||||
lint-builtin-deprecated-attr-link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
|
||||
lint-builtin-deprecated-attr-used = use of deprecated attribute `{$name}`: no longer used.
|
||||
lint-builtin-deprecated-attr-default-suggestion = remove this attribute
|
||||
|
||||
lint-builtin-unused-doc-comment = unused doc comment
|
||||
.label = rustdoc does not generate documentation for {$kind}
|
||||
.plain-help = use `//` for a plain comment
|
||||
.block-help = use `/* */` for a plain comment
|
||||
|
||||
lint-builtin-no-mangle-generic = functions generic over types or consts must be mangled
|
||||
.suggestion = remove this attribute
|
||||
|
||||
lint-builtin-const-no-mangle = const items should never be `#[no_mangle]`
|
||||
.suggestion = try a static value
|
||||
|
||||
lint-builtin-mutable-transmutes =
|
||||
transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
|
||||
|
||||
lint-builtin-unstable-features = unstable feature
|
||||
|
||||
lint-builtin-unreachable-pub = unreachable `pub` {$what}
|
||||
.suggestion = consider restricting its visibility
|
||||
.help = or consider exporting it for use by other crates
|
||||
|
||||
lint-builtin-type-alias-bounds-help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
|
||||
|
||||
lint-builtin-type-alias-where-clause = where clauses are not enforced in type aliases
|
||||
.suggestion = the clause will not be checked when the type alias is used, and should be removed
|
||||
|
||||
lint-builtin-type-alias-generic-bounds = bounds on generic parameters are not enforced in type aliases
|
||||
.suggestion = the bound will not be checked when the type alias is used, and should be removed
|
||||
|
||||
lint-builtin-trivial-bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
|
||||
|
||||
lint-builtin-ellipsis-inclusive-range-patterns = `...` range patterns are deprecated
|
||||
.suggestion = use `..=` for an inclusive range
|
||||
|
||||
lint-builtin-unnameable-test-items = cannot test inner items
|
||||
|
||||
lint-builtin-keyword-idents = `{$kw}` is a keyword in the {$next} edition
|
||||
.suggestion = you can use a raw identifier to stay compatible
|
||||
|
||||
lint-builtin-explicit-outlives = outlives requirements can be inferred
|
||||
.suggestion = remove {$count ->
|
||||
[one] this bound
|
||||
*[other] these bounds
|
||||
}
|
||||
|
||||
lint-builtin-incomplete-features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
.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
|
||||
.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
|
||||
.previous-decl-label = `{$orig}` previously declared here
|
||||
.mismatch-label = this signature doesn't match the previous declaration
|
||||
|
||||
lint-builtin-deref-nullptr = dereferencing a null pointer
|
||||
.label = this code causes undefined behavior when executed
|
||||
|
||||
lint-builtin-asm-labels = avoid using named labels in inline assembly
|
|
@ -31,11 +31,12 @@ pub use unic_langid::{langid, LanguageIdentifier};
|
|||
|
||||
// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
|
||||
fluent_messages! {
|
||||
borrowck => "../locales/en-US/borrowck.ftl",
|
||||
builtin_macros => "../locales/en-US/builtin_macros.ftl",
|
||||
lint => "../locales/en-US/lint.ftl",
|
||||
parser => "../locales/en-US/parser.ftl",
|
||||
privacy => "../locales/en-US/privacy.ftl",
|
||||
typeck => "../locales/en-US/typeck.ftl",
|
||||
builtin_macros => "../locales/en-US/builtin_macros.ftl",
|
||||
borrowck => "../locales/en-US/borrowck.ftl",
|
||||
}
|
||||
|
||||
pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};
|
||||
|
|
|
@ -8,7 +8,7 @@ use rustc_error_messages::FluentValue;
|
|||
use rustc_lint_defs::{Applicability, LintExpectationId};
|
||||
use rustc_span::edition::LATEST_STABLE_EDITION;
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_span::{edition::Edition, Span, DUMMY_SP};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
@ -39,12 +39,94 @@ pub trait IntoDiagnosticArg {
|
|||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>;
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for bool {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
if self {
|
||||
DiagnosticArgValue::Str(Cow::Borrowed("true"))
|
||||
} else {
|
||||
DiagnosticArgValue::Str(Cow::Borrowed("false"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for i8 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for u8 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for i16 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for u16 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for i32 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for u32 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for i64 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for u64 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for i128 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for u128 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for String {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for std::num::NonZeroU32 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for Edition {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for Symbol {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
self.to_ident_string().into_diagnostic_arg()
|
||||
|
|
|
@ -529,7 +529,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
|||
applicability: Applicability,
|
||||
) -> &mut Self);
|
||||
|
||||
forward!(pub fn set_primary_message(&mut self, msg: impl Into<String>) -> &mut Self);
|
||||
forward!(pub fn set_primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self);
|
||||
forward!(pub fn set_span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self);
|
||||
forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
|
||||
forward!(pub fn set_arg(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{fluent, Applicability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
||||
|
@ -120,31 +120,30 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
|
|||
_ => bug!("array type coerced to something other than array or slice"),
|
||||
};
|
||||
cx.struct_span_lint(ARRAY_INTO_ITER, call.ident.span, |lint| {
|
||||
let mut diag = lint.build(&format!(
|
||||
"this method call resolves to `<&{} as IntoIterator>::into_iter` \
|
||||
(due to backwards compatibility), \
|
||||
but will resolve to <{} as IntoIterator>::into_iter in Rust 2021",
|
||||
target, target,
|
||||
));
|
||||
let mut diag = lint.build(fluent::lint::array_into_iter);
|
||||
diag.set_arg("target", target);
|
||||
diag.span_suggestion(
|
||||
call.ident.span,
|
||||
"use `.iter()` instead of `.into_iter()` to avoid ambiguity",
|
||||
fluent::lint::use_iter_suggestion,
|
||||
"iter",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
if self.for_expr_span == expr.span {
|
||||
diag.span_suggestion(
|
||||
receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
|
||||
"or remove `.into_iter()` to iterate by value",
|
||||
fluent::lint::remove_into_iter_suggestion,
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if receiver_ty.is_array() {
|
||||
diag.multipart_suggestion(
|
||||
"or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value",
|
||||
fluent::lint::use_explicit_into_iter_suggestion,
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), "IntoIterator::into_iter(".into()),
|
||||
(receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), ")".into()),
|
||||
(
|
||||
receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
|
||||
")".into(),
|
||||
),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
|
|
@ -31,7 +31,9 @@ use rustc_ast::{self as ast, *};
|
|||
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::{Applicability, Diagnostic, DiagnosticStyledString, MultiSpan};
|
||||
use rustc_errors::{
|
||||
fluent, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString, MultiSpan,
|
||||
};
|
||||
use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
@ -99,13 +101,12 @@ impl EarlyLintPass for WhileTrue {
|
|||
if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind {
|
||||
if let ast::LitKind::Bool(true) = lit.kind {
|
||||
if !lit.span.from_expansion() {
|
||||
let msg = "denote infinite loops with `loop { ... }`";
|
||||
let condition_span = e.span.with_hi(cond.span.hi());
|
||||
cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| {
|
||||
lint.build(msg)
|
||||
lint.build(fluent::lint::builtin_while_true)
|
||||
.span_suggestion_short(
|
||||
condition_span,
|
||||
"use `loop`",
|
||||
fluent::lint::suggestion,
|
||||
format!(
|
||||
"{}loop",
|
||||
label.map_or_else(String::new, |label| format!(
|
||||
|
@ -156,7 +157,7 @@ impl BoxPointers {
|
|||
if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
|
||||
if leaf_ty.is_box() {
|
||||
cx.struct_span_lint(BOX_POINTERS, span, |lint| {
|
||||
lint.build(&format!("type uses owned (Box type) pointers: {}", ty)).emit();
|
||||
lint.build(fluent::lint::builtin_box_pointers).set_arg("ty", ty).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -257,26 +258,26 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
|
|||
== Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results()))
|
||||
{
|
||||
cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, |lint| {
|
||||
let mut err = lint
|
||||
.build(&format!("the `{}:` in this pattern is redundant", ident));
|
||||
let binding = match binding_annot {
|
||||
hir::BindingAnnotation::Unannotated => None,
|
||||
hir::BindingAnnotation::Mutable => Some("mut"),
|
||||
hir::BindingAnnotation::Ref => Some("ref"),
|
||||
hir::BindingAnnotation::RefMut => Some("ref mut"),
|
||||
};
|
||||
let ident = if let Some(binding) = binding {
|
||||
let suggested_ident = if let Some(binding) = binding {
|
||||
format!("{} {}", binding, ident)
|
||||
} else {
|
||||
ident.to_string()
|
||||
};
|
||||
err.span_suggestion(
|
||||
fieldpat.span,
|
||||
"use shorthand field pattern",
|
||||
ident,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
lint.build(fluent::lint::builtin_non_shorthand_field_patterns)
|
||||
.set_arg("ident", ident.clone())
|
||||
.span_suggestion(
|
||||
fieldpat.span,
|
||||
fluent::lint::suggestion,
|
||||
suggested_ident,
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -327,26 +328,25 @@ impl UnsafeCode {
|
|||
cx.struct_span_lint(UNSAFE_CODE, span, decorate);
|
||||
}
|
||||
|
||||
fn report_overridden_symbol_name(&self, cx: &EarlyContext<'_>, span: Span, msg: &str) {
|
||||
fn report_overridden_symbol_name(
|
||||
&self,
|
||||
cx: &EarlyContext<'_>,
|
||||
span: Span,
|
||||
msg: DiagnosticMessage,
|
||||
) {
|
||||
self.report_unsafe(cx, span, |lint| {
|
||||
lint.build(msg)
|
||||
.note(
|
||||
"the linker's behavior with multiple libraries exporting duplicate symbol \
|
||||
names is undefined and Rust cannot provide guarantees when you manually \
|
||||
override them",
|
||||
)
|
||||
.emit();
|
||||
lint.build(msg).note(fluent::lint::builtin_overridden_symbol_name).emit();
|
||||
})
|
||||
}
|
||||
|
||||
fn report_overridden_symbol_section(&self, cx: &EarlyContext<'_>, span: Span, msg: &str) {
|
||||
fn report_overridden_symbol_section(
|
||||
&self,
|
||||
cx: &EarlyContext<'_>,
|
||||
span: Span,
|
||||
msg: DiagnosticMessage,
|
||||
) {
|
||||
self.report_unsafe(cx, span, |lint| {
|
||||
lint.build(msg)
|
||||
.note(
|
||||
"the program's behavior with overridden link sections on items is unpredictable \
|
||||
and Rust cannot provide guarantees when you manually override them",
|
||||
)
|
||||
.emit();
|
||||
lint.build(msg).note(fluent::lint::builtin_overridden_symbol_section).emit();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -355,12 +355,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
|
||||
if attr.has_name(sym::allow_internal_unsafe) {
|
||||
self.report_unsafe(cx, attr.span, |lint| {
|
||||
lint.build(
|
||||
"`allow_internal_unsafe` allows defining \
|
||||
macros using unsafe without triggering \
|
||||
the `unsafe_code` lint at their call site",
|
||||
)
|
||||
.emit();
|
||||
lint.build(fluent::lint::builtin_allow_internal_unsafe).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +365,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
// Don't warn about generated blocks; that'll just pollute the output.
|
||||
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
|
||||
self.report_unsafe(cx, blk.span, |lint| {
|
||||
lint.build("usage of an `unsafe` block").emit();
|
||||
lint.build(fluent::lint::builtin_unsafe_block).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -380,12 +375,12 @@ impl EarlyLintPass for UnsafeCode {
|
|||
match it.kind {
|
||||
ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => self
|
||||
.report_unsafe(cx, it.span, |lint| {
|
||||
lint.build("declaration of an `unsafe` trait").emit();
|
||||
lint.build(fluent::lint::builtin_unsafe_trait).emit();
|
||||
}),
|
||||
|
||||
ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => self
|
||||
.report_unsafe(cx, it.span, |lint| {
|
||||
lint.build("implementation of an `unsafe` trait").emit();
|
||||
lint.build(fluent::lint::builtin_unsafe_impl).emit();
|
||||
}),
|
||||
|
||||
ast::ItemKind::Fn(..) => {
|
||||
|
@ -393,7 +388,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
self.report_overridden_symbol_name(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a `no_mangle` function",
|
||||
fluent::lint::builtin_no_mangle_fn,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -401,7 +396,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
self.report_overridden_symbol_name(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a function with `export_name`",
|
||||
fluent::lint::builtin_export_name_fn,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -409,7 +404,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
self.report_overridden_symbol_section(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a function with `link_section`",
|
||||
fluent::lint::builtin_link_section_fn,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +414,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
self.report_overridden_symbol_name(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a `no_mangle` static",
|
||||
fluent::lint::builtin_no_mangle_static,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -427,7 +422,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
self.report_overridden_symbol_name(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a static with `export_name`",
|
||||
fluent::lint::builtin_export_name_static,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -435,7 +430,7 @@ impl EarlyLintPass for UnsafeCode {
|
|||
self.report_overridden_symbol_section(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a static with `link_section`",
|
||||
fluent::lint::builtin_link_section_static,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -450,14 +445,14 @@ impl EarlyLintPass for UnsafeCode {
|
|||
self.report_overridden_symbol_name(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a `no_mangle` method",
|
||||
fluent::lint::builtin_no_mangle_method,
|
||||
);
|
||||
}
|
||||
if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) {
|
||||
self.report_overridden_symbol_name(
|
||||
cx,
|
||||
attr.span,
|
||||
"declaration of a method with `export_name`",
|
||||
fluent::lint::builtin_export_name_method,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -475,9 +470,9 @@ impl EarlyLintPass for UnsafeCode {
|
|||
{
|
||||
let msg = match ctxt {
|
||||
FnCtxt::Foreign => return,
|
||||
FnCtxt::Free => "declaration of an `unsafe` function",
|
||||
FnCtxt::Assoc(_) if body.is_none() => "declaration of an `unsafe` method",
|
||||
FnCtxt::Assoc(_) => "implementation of an `unsafe` method",
|
||||
FnCtxt::Free => fluent::lint::builtin_decl_unsafe_fn,
|
||||
FnCtxt::Assoc(_) if body.is_none() => fluent::lint::builtin_decl_unsafe_method,
|
||||
FnCtxt::Assoc(_) => fluent::lint::builtin_impl_unsafe_method,
|
||||
};
|
||||
self.report_unsafe(cx, span, |lint| {
|
||||
lint.build(msg).emit();
|
||||
|
@ -587,7 +582,10 @@ impl MissingDoc {
|
|||
MISSING_DOCS,
|
||||
cx.tcx.sess.source_map().guess_head_span(sp),
|
||||
|lint| {
|
||||
lint.build(&format!("missing documentation for {} {}", article, desc)).emit();
|
||||
lint.build(fluent::lint::builtin_missing_doc)
|
||||
.set_arg("article", article)
|
||||
.set_arg("desc", desc)
|
||||
.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -783,11 +781,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
|||
.is_ok()
|
||||
{
|
||||
cx.struct_span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, |lint| {
|
||||
lint.build(
|
||||
"type could implement `Copy`; consider adding `impl \
|
||||
Copy`",
|
||||
)
|
||||
.emit();
|
||||
lint.build(fluent::lint::builtin_missing_copy_impl).emit();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -863,12 +857,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
|
|||
|
||||
if !self.impling_types.as_ref().unwrap().contains(&item.def_id) {
|
||||
cx.struct_span_lint(MISSING_DEBUG_IMPLEMENTATIONS, item.span, |lint| {
|
||||
lint.build(&format!(
|
||||
"type does not implement `{}`; consider adding `#[derive(Debug)]` \
|
||||
or a manual implementation",
|
||||
cx.tcx.def_path_str(debug)
|
||||
))
|
||||
.emit();
|
||||
lint.build(fluent::lint::builtin_missing_debug_impl)
|
||||
.set_arg("debug", cx.tcx.def_path_str(debug))
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -946,18 +937,14 @@ impl EarlyLintPass for AnonymousParameters {
|
|||
("<type>", Applicability::HasPlaceholders)
|
||||
};
|
||||
|
||||
lint.build(
|
||||
"anonymous parameters are deprecated and will be \
|
||||
removed in the next edition",
|
||||
)
|
||||
.span_suggestion(
|
||||
arg.pat.span,
|
||||
"try naming the parameter or explicitly \
|
||||
ignoring it",
|
||||
format!("_: {}", ty_snip),
|
||||
appl,
|
||||
)
|
||||
.emit();
|
||||
lint.build(fluent::lint::builtin_anonymous_params)
|
||||
.span_suggestion(
|
||||
arg.pat.span,
|
||||
fluent::lint::suggestion,
|
||||
format!("_: {}", ty_snip),
|
||||
appl,
|
||||
)
|
||||
.emit();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -982,24 +969,6 @@ impl DeprecatedAttr {
|
|||
}
|
||||
}
|
||||
|
||||
fn lint_deprecated_attr(
|
||||
cx: &EarlyContext<'_>,
|
||||
attr: &ast::Attribute,
|
||||
msg: &str,
|
||||
suggestion: Option<&str>,
|
||||
) {
|
||||
cx.struct_span_lint(DEPRECATED, attr.span, |lint| {
|
||||
lint.build(msg)
|
||||
.span_suggestion_short(
|
||||
attr.span,
|
||||
suggestion.unwrap_or("remove this attribute"),
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
})
|
||||
}
|
||||
|
||||
impl EarlyLintPass for DeprecatedAttr {
|
||||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
|
||||
for BuiltinAttribute { name, gate, .. } in &self.depr_attrs {
|
||||
|
@ -1011,17 +980,38 @@ impl EarlyLintPass for DeprecatedAttr {
|
|||
_,
|
||||
) = gate
|
||||
{
|
||||
let msg =
|
||||
format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link);
|
||||
lint_deprecated_attr(cx, attr, &msg, suggestion);
|
||||
cx.struct_span_lint(DEPRECATED, attr.span, |lint| {
|
||||
// FIXME(davidtwco) translatable deprecated attr
|
||||
lint.build(fluent::lint::builtin_deprecated_attr_link)
|
||||
.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,
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if attr.has_name(sym::no_start) || attr.has_name(sym::crate_id) {
|
||||
let path_str = pprust::path_to_string(&attr.get_normal_item().path);
|
||||
let msg = format!("use of deprecated attribute `{}`: no longer used.", path_str);
|
||||
lint_deprecated_attr(cx, attr, &msg, None);
|
||||
cx.struct_span_lint(DEPRECATED, attr.span, |lint| {
|
||||
lint.build(fluent::lint::builtin_deprecated_attr_used)
|
||||
.set_arg("name", pprust::path_to_string(&attr.get_normal_item().path))
|
||||
.span_suggestion_short(
|
||||
attr.span,
|
||||
fluent::lint::builtin_deprecated_attr_default_suggestion,
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1049,17 +1039,15 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
|
|||
|
||||
if is_doc_comment || attr.has_name(sym::doc) {
|
||||
cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| {
|
||||
let mut err = lint.build("unused doc comment");
|
||||
err.span_label(
|
||||
node_span,
|
||||
format!("rustdoc does not generate documentation for {}", node_kind),
|
||||
);
|
||||
let mut err = lint.build(fluent::lint::builtin_unused_doc_comment);
|
||||
err.set_arg("kind", node_kind);
|
||||
err.span_label(node_span, fluent::lint::label);
|
||||
match attr.kind {
|
||||
AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => {
|
||||
err.help("use `//` for a plain comment");
|
||||
err.help(fluent::lint::plain_help);
|
||||
}
|
||||
AttrKind::DocComment(CommentKind::Block, _) => {
|
||||
err.help("use `/* */` for a plain comment");
|
||||
err.help(fluent::lint::block_help);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
|
@ -1178,10 +1166,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
|
|||
GenericParamKind::Lifetime { .. } => {}
|
||||
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
|
||||
cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS, span, |lint| {
|
||||
lint.build("functions generic over types or consts must be mangled")
|
||||
lint.build(fluent::lint::builtin_no_mangle_generic)
|
||||
.span_suggestion_short(
|
||||
no_mangle_attr.span,
|
||||
"remove this attribute",
|
||||
fluent::lint::suggestion,
|
||||
"",
|
||||
// Use of `#[no_mangle]` suggests FFI intent; correct
|
||||
// fix may be to monomorphize source by hand
|
||||
|
@ -1205,8 +1193,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
|
|||
// Const items do not refer to a particular location in memory, and therefore
|
||||
// don't have anything to attach a symbol to
|
||||
cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, |lint| {
|
||||
let msg = "const items should never be `#[no_mangle]`";
|
||||
let mut err = lint.build(msg);
|
||||
let mut err = lint.build(fluent::lint::builtin_const_no_mangle);
|
||||
|
||||
// account for "pub const" (#45562)
|
||||
let start = cx
|
||||
|
@ -1220,7 +1207,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
|
|||
let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
|
||||
err.span_suggestion(
|
||||
const_span,
|
||||
"try a static value",
|
||||
fluent::lint::suggestion,
|
||||
"pub static",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -1285,10 +1272,8 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
|
|||
get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (ty1.kind(), ty2.kind()))
|
||||
{
|
||||
if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not {
|
||||
let msg = "transmuting &T to &mut T is undefined behavior, \
|
||||
even if the reference is unused, consider instead using an UnsafeCell";
|
||||
cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| {
|
||||
lint.build(msg).emit();
|
||||
lint.build(fluent::lint::builtin_mutable_transmutes).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1338,7 +1323,7 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
|
|||
if let Some(items) = attr.meta_item_list() {
|
||||
for item in items {
|
||||
cx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| {
|
||||
lint.build("unstable feature").emit();
|
||||
lint.build(fluent::lint::builtin_unstable_features).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1400,16 +1385,17 @@ impl UnreachablePub {
|
|||
}
|
||||
let def_span = cx.tcx.sess.source_map().guess_head_span(span);
|
||||
cx.struct_span_lint(UNREACHABLE_PUB, def_span, |lint| {
|
||||
let mut err = lint.build(&format!("unreachable `pub` {}", what));
|
||||
let mut err = lint.build(fluent::lint::builtin_unreachable_pub);
|
||||
err.set_arg("what", what);
|
||||
|
||||
err.span_suggestion(
|
||||
vis_span,
|
||||
"consider restricting its visibility",
|
||||
fluent::lint::suggestion,
|
||||
"pub(crate)",
|
||||
applicability,
|
||||
);
|
||||
if exportable {
|
||||
err.help("or consider exporting it for use by other crates");
|
||||
err.help(fluent::lint::help);
|
||||
}
|
||||
err.emit();
|
||||
});
|
||||
|
@ -1513,11 +1499,7 @@ impl TypeAliasBounds {
|
|||
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,
|
||||
"use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to \
|
||||
associated types in type aliases",
|
||||
);
|
||||
self.err.span_help(span, fluent::lint::builtin_type_alias_bounds_help);
|
||||
}
|
||||
intravisit::walk_qpath(self, qpath, id, span)
|
||||
}
|
||||
|
@ -1561,11 +1543,11 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
|
|||
let mut suggested_changing_assoc_types = false;
|
||||
if !where_spans.is_empty() {
|
||||
cx.lint(TYPE_ALIAS_BOUNDS, |lint| {
|
||||
let mut err = lint.build("where clauses are not enforced in type aliases");
|
||||
let mut err = lint.build(fluent::lint::builtin_type_alias_where_clause);
|
||||
err.set_span(where_spans);
|
||||
err.span_suggestion(
|
||||
type_alias_generics.where_clause_span,
|
||||
"the clause will not be checked when the type alias is used, and should be removed",
|
||||
fluent::lint::suggestion,
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -1579,11 +1561,10 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
|
|||
|
||||
if !inline_spans.is_empty() {
|
||||
cx.lint(TYPE_ALIAS_BOUNDS, |lint| {
|
||||
let mut err =
|
||||
lint.build("bounds on generic parameters are not enforced in type aliases");
|
||||
let mut err = lint.build(fluent::lint::builtin_type_alias_generic_bounds);
|
||||
err.set_span(inline_spans);
|
||||
err.multipart_suggestion(
|
||||
"the bound will not be checked when the type alias is used, and should be removed",
|
||||
fluent::lint::suggestion,
|
||||
inline_sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -1690,12 +1671,10 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
|||
};
|
||||
if predicate.is_global() {
|
||||
cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| {
|
||||
lint.build(&format!(
|
||||
"{} bound {} does not depend on any type \
|
||||
or lifetime parameters",
|
||||
predicate_kind_name, predicate
|
||||
))
|
||||
.emit();
|
||||
lint.build(fluent::lint::builtin_trivial_bounds)
|
||||
.set_arg("predicate_kind_name", predicate_kind_name)
|
||||
.set_arg("predicate", predicate)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1796,8 +1775,8 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
|
|||
};
|
||||
|
||||
if let Some((start, end, join)) = endpoints {
|
||||
let msg = "`...` range patterns are deprecated";
|
||||
let suggestion = "use `..=` for an inclusive range";
|
||||
let msg = fluent::lint::builtin_ellipsis_inclusive_range_patterns;
|
||||
let suggestion = fluent::lint::suggestion;
|
||||
if parenthesise {
|
||||
self.node_id = Some(pat.id);
|
||||
let end = expr_to_string(&end);
|
||||
|
@ -1806,8 +1785,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
|
|||
None => format!("&(..={})", end),
|
||||
};
|
||||
if join.edition() >= Edition::Edition2021 {
|
||||
let mut err =
|
||||
rustc_errors::struct_span_err!(cx.sess(), pat.span, E0783, "{}", msg,);
|
||||
let mut err = cx.sess().struct_span_err_with_code(
|
||||
pat.span,
|
||||
msg,
|
||||
rustc_errors::error_code!(E0783),
|
||||
);
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
suggestion,
|
||||
|
@ -1830,8 +1812,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
|
|||
} else {
|
||||
let replace = "..=";
|
||||
if join.edition() >= Edition::Edition2021 {
|
||||
let mut err =
|
||||
rustc_errors::struct_span_err!(cx.sess(), pat.span, E0783, "{}", msg,);
|
||||
let mut err = cx.sess().struct_span_err_with_code(
|
||||
pat.span,
|
||||
msg,
|
||||
rustc_errors::error_code!(E0783),
|
||||
);
|
||||
err.span_suggestion_short(
|
||||
join,
|
||||
suggestion,
|
||||
|
@ -1930,7 +1915,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
|
|||
let attrs = cx.tcx.hir().attrs(it.hir_id());
|
||||
if let Some(attr) = cx.sess().find_by_name(attrs, sym::rustc_test_marker) {
|
||||
cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| {
|
||||
lint.build("cannot test inner items").emit();
|
||||
lint.build(fluent::lint::builtin_unnameable_test_items).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2048,10 +2033,12 @@ impl KeywordIdents {
|
|||
}
|
||||
|
||||
cx.struct_span_lint(KEYWORD_IDENTS, ident.span, |lint| {
|
||||
lint.build(&format!("`{}` is a keyword in the {} edition", ident, next_edition))
|
||||
lint.build(fluent::lint::builtin_keyword_idents)
|
||||
.set_arg("kw", ident.clone())
|
||||
.set_arg("next", next_edition)
|
||||
.span_suggestion(
|
||||
ident.span,
|
||||
"you can use a raw identifier to stay compatible",
|
||||
fluent::lint::suggestion,
|
||||
format!("r#{}", ident),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
|
@ -2301,13 +2288,10 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
|
||||
if !lint_spans.is_empty() {
|
||||
cx.struct_span_lint(EXPLICIT_OUTLIVES_REQUIREMENTS, lint_spans.clone(), |lint| {
|
||||
lint.build("outlives requirements can be inferred")
|
||||
lint.build(fluent::lint::builtin_explicit_outlives)
|
||||
.set_arg("count", bound_count)
|
||||
.multipart_suggestion(
|
||||
if bound_count == 1 {
|
||||
"remove this bound"
|
||||
} else {
|
||||
"remove these bounds"
|
||||
},
|
||||
fluent::lint::suggestion,
|
||||
lint_spans
|
||||
.into_iter()
|
||||
.map(|span| (span, String::new()))
|
||||
|
@ -2363,23 +2347,14 @@ impl EarlyLintPass for IncompleteFeatures {
|
|||
.filter(|(&name, _)| features.incomplete(name))
|
||||
.for_each(|(&name, &span)| {
|
||||
cx.struct_span_lint(INCOMPLETE_FEATURES, span, |lint| {
|
||||
let mut builder = lint.build(&format!(
|
||||
"the feature `{}` is incomplete and may not be safe to use \
|
||||
and/or cause compiler crashes",
|
||||
name,
|
||||
));
|
||||
let mut builder = lint.build(fluent::lint::builtin_incomplete_features);
|
||||
builder.set_arg("name", name);
|
||||
if let Some(n) = rustc_feature::find_feature_issue(name, GateIssue::Language) {
|
||||
builder.note(&format!(
|
||||
"see issue #{} <https://github.com/rust-lang/rust/issues/{}> \
|
||||
for more information",
|
||||
n, n,
|
||||
));
|
||||
builder.set_arg("n", n);
|
||||
builder.note(fluent::lint::note);
|
||||
}
|
||||
if HAS_MIN_FEATURES.contains(&name) {
|
||||
builder.help(&format!(
|
||||
"consider using `min_{}` instead, which is more stable and complete",
|
||||
name,
|
||||
));
|
||||
builder.help(fluent::lint::help);
|
||||
}
|
||||
builder.emit();
|
||||
})
|
||||
|
@ -2620,6 +2595,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
|||
if let Some((msg, span)) =
|
||||
with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init))
|
||||
{
|
||||
// FIXME(davidtwco): make translatable
|
||||
cx.struct_span_lint(INVALID_VALUE, expr.span, |lint| {
|
||||
let mut err = lint.build(&format!(
|
||||
"the type `{}` does not permit {}",
|
||||
|
@ -2996,23 +2972,19 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations {
|
|||
let mut found_str = DiagnosticStyledString::new();
|
||||
found_str.push(this_decl_ty.fn_sig(tcx).to_string(), true);
|
||||
|
||||
lint.build(&format!(
|
||||
"`{}` redeclare{} with a different signature",
|
||||
this_fi.ident.name,
|
||||
if orig.get_name() == this_fi.ident.name {
|
||||
"d".to_string()
|
||||
} else {
|
||||
format!("s `{}`", orig.get_name())
|
||||
}
|
||||
))
|
||||
lint.build(if orig.get_name() == this_fi.ident.name {
|
||||
fluent::lint::builtin_clashing_extern_same_name
|
||||
} else {
|
||||
fluent::lint::builtin_clashing_extern_diff_name
|
||||
})
|
||||
.set_arg("this_fi", this_fi.ident.name)
|
||||
.set_arg("orig", orig.get_name())
|
||||
.span_label(
|
||||
get_relevant_span(orig_fi),
|
||||
&format!("`{}` previously declared here", orig.get_name()),
|
||||
)
|
||||
.span_label(
|
||||
get_relevant_span(this_fi),
|
||||
"this signature doesn't match the previous declaration",
|
||||
fluent::lint::previous_decl_label,
|
||||
)
|
||||
.span_label(get_relevant_span(this_fi), fluent::lint::mismatch_label)
|
||||
// FIXME(davidtwco): translatable expected/found
|
||||
.note_expected_found(&"", expected_str, &"", found_str)
|
||||
.emit();
|
||||
},
|
||||
|
@ -3096,8 +3068,8 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
|
|||
if let rustc_hir::ExprKind::Unary(rustc_hir::UnOp::Deref, expr_deref) = expr.kind {
|
||||
if is_null_ptr(cx, expr_deref) {
|
||||
cx.struct_span_lint(DEREF_NULLPTR, expr.span, |lint| {
|
||||
let mut err = lint.build("dereferencing a null pointer");
|
||||
err.span_label(expr.span, "this code causes undefined behavior when executed");
|
||||
let mut err = lint.build(fluent::lint::builtin_deref_nullptr);
|
||||
err.span_label(expr.span, fluent::lint::label);
|
||||
err.emit();
|
||||
});
|
||||
}
|
||||
|
@ -3210,9 +3182,7 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
|
|||
NAMED_ASM_LABELS,
|
||||
Some(target_spans),
|
||||
|diag| {
|
||||
let mut err =
|
||||
diag.build("avoid using named labels in inline assembly");
|
||||
err.emit();
|
||||
diag.build(fluent::lint::builtin_asm_labels).emit();
|
||||
},
|
||||
BuiltinLintDiagnostics::NamedAsmLabel(
|
||||
"only local labels of the form `<number>:` should be used in inline asm"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{context::LintContext, LateContext, LateLintPass};
|
||||
use rustc_errors::fluent;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::{fold::TypeFoldable, Ty};
|
||||
use rustc_span::{symbol::sym, Span};
|
||||
|
@ -51,19 +52,9 @@ fn enforce_mem_discriminant(
|
|||
if is_non_enum(ty_param) {
|
||||
cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, expr_span, |builder| {
|
||||
builder
|
||||
.build(
|
||||
"the return value of `mem::discriminant` is \
|
||||
unspecified when called with a non-enum type",
|
||||
)
|
||||
.span_note(
|
||||
args_span,
|
||||
&format!(
|
||||
"the argument to `discriminant` should be a \
|
||||
reference to an enum, but it was passed \
|
||||
a reference to a `{}`, which is not an enum.",
|
||||
ty_param,
|
||||
),
|
||||
)
|
||||
.build(fluent::lint::enum_intrinsics_mem_discriminant)
|
||||
.set_arg("ty_param", ty_param)
|
||||
.span_note(args_span, fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
@ -74,16 +65,9 @@ fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, sp
|
|||
if is_non_enum(ty_param) {
|
||||
cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, span, |builder| {
|
||||
builder
|
||||
.build(
|
||||
"the return value of `mem::variant_count` is \
|
||||
unspecified when called with a non-enum type",
|
||||
)
|
||||
.note(&format!(
|
||||
"the type parameter of `variant_count` should \
|
||||
be an enum, but it was instantiated with \
|
||||
the type `{}`, which is not an enum.",
|
||||
ty_param,
|
||||
))
|
||||
.build(fluent::lint::enum_intrinsics_mem_variant)
|
||||
.set_arg("ty_param", ty_param)
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::builtin;
|
||||
use rustc_errors::fluent;
|
||||
use rustc_hir::HirId;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::{lint::LintExpectation, ty::TyCtxt};
|
||||
|
@ -43,13 +44,13 @@ fn emit_unfulfilled_expectation_lint(
|
|||
hir_id,
|
||||
expectation.emission_span,
|
||||
|diag| {
|
||||
let mut diag = diag.build("this lint expectation is unfulfilled");
|
||||
let mut diag = diag.build(fluent::lint::expectation);
|
||||
if let Some(rationale) = expectation.reason {
|
||||
diag.note(rationale.as_str());
|
||||
}
|
||||
|
||||
if expectation.is_unfulfilled_lint_expectations {
|
||||
diag.note("the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message");
|
||||
diag.note(fluent::lint::note);
|
||||
}
|
||||
|
||||
diag.emit();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use ast::util::unicode::{contains_text_flow_control_chars, TEXT_FLOW_CONTROL_CHARS};
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::{Applicability, SuggestionStyle};
|
||||
use rustc_errors::{fluent, Applicability, SuggestionStyle};
|
||||
use rustc_span::{BytePos, Span, Symbol};
|
||||
|
||||
declare_lint! {
|
||||
|
@ -61,41 +61,25 @@ impl HiddenUnicodeCodepoints {
|
|||
.collect();
|
||||
|
||||
cx.struct_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, |lint| {
|
||||
let mut err = lint.build(&format!(
|
||||
"unicode codepoint changing visible direction of text present in {}",
|
||||
label
|
||||
));
|
||||
let (an, s) = match spans.len() {
|
||||
1 => ("an ", ""),
|
||||
_ => ("", "s"),
|
||||
};
|
||||
err.span_label(
|
||||
span,
|
||||
&format!(
|
||||
"this {} contains {}invisible unicode text flow control codepoint{}",
|
||||
label, an, s,
|
||||
),
|
||||
);
|
||||
let mut err = lint.build(fluent::lint::hidden_unicode_codepoints);
|
||||
err.set_arg("label", label);
|
||||
err.set_arg("count", spans.len());
|
||||
err.span_label(span, fluent::lint::label);
|
||||
err.note(fluent::lint::note);
|
||||
if point_at_inner_spans {
|
||||
for (c, span) in &spans {
|
||||
err.span_label(*span, format!("{:?}", c));
|
||||
}
|
||||
}
|
||||
err.note(
|
||||
"these kind of unicode codepoints change the way text flows on applications that \
|
||||
support them, but can cause confusion because they change the order of \
|
||||
characters on the screen",
|
||||
);
|
||||
if point_at_inner_spans && !spans.is_empty() {
|
||||
err.multipart_suggestion_with_style(
|
||||
"if their presence wasn't intentional, you can remove them",
|
||||
fluent::lint::suggestion_remove,
|
||||
spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
|
||||
Applicability::MachineApplicable,
|
||||
SuggestionStyle::HideCodeAlways,
|
||||
);
|
||||
err.multipart_suggestion(
|
||||
"if you want to keep them but make them visible in your source code, you can \
|
||||
escape them",
|
||||
fluent::lint::suggestion_escape,
|
||||
spans
|
||||
.into_iter()
|
||||
.map(|(c, span)| {
|
||||
|
@ -109,16 +93,16 @@ impl HiddenUnicodeCodepoints {
|
|||
// FIXME: in other suggestions we've reversed the inner spans of doc comments. We
|
||||
// should do the same here to provide the same good suggestions as we do for
|
||||
// literals above.
|
||||
err.note("if their presence wasn't intentional, you can remove them");
|
||||
err.note(&format!(
|
||||
"if you want to keep them but make them visible in your source code, you can \
|
||||
escape them: {}",
|
||||
err.set_arg(
|
||||
"escaped",
|
||||
spans
|
||||
.into_iter()
|
||||
.map(|(c, _)| { format!("{:?}", c) })
|
||||
.map(|(c, _)| format!("{:?}", c))
|
||||
.collect::<Vec<String>>()
|
||||
.join(", "),
|
||||
));
|
||||
);
|
||||
err.note(fluent::lint::suggestion_remove);
|
||||
err.note(fluent::lint::no_suggestion_note_escape);
|
||||
}
|
||||
err.emit();
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{fluent, Applicability};
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath};
|
||||
use rustc_hir::{HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind};
|
||||
|
@ -36,13 +36,10 @@ impl LateLintPass<'_> for DefaultHashTypes {
|
|||
_ => return,
|
||||
};
|
||||
cx.struct_span_lint(DEFAULT_HASH_TYPES, path.span, |lint| {
|
||||
let msg = format!(
|
||||
"prefer `{}` over `{}`, it has better performance",
|
||||
replace,
|
||||
cx.tcx.item_name(def_id)
|
||||
);
|
||||
lint.build(&msg)
|
||||
.note(&format!("a `use rustc_data_structures::fx::{}` may be necessary", replace))
|
||||
lint.build(fluent::lint::default_hash_types)
|
||||
.set_arg("preferred", replace)
|
||||
.set_arg("used", cx.tcx.item_name(def_id))
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
@ -99,12 +96,9 @@ impl LateLintPass<'_> for QueryStability {
|
|||
let def_id = instance.def_id();
|
||||
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
|
||||
cx.struct_span_lint(POTENTIAL_QUERY_INSTABILITY, span, |lint| {
|
||||
let msg = format!(
|
||||
"using `{}` can result in unstable query results",
|
||||
cx.tcx.item_name(def_id)
|
||||
);
|
||||
lint.build(&msg)
|
||||
.note("if you believe this case to be fine, allow this lint and add a comment explaining your rationale")
|
||||
lint.build(fluent::lint::query_instability)
|
||||
.set_arg("query", cx.tcx.item_name(def_id))
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
})
|
||||
}
|
||||
|
@ -146,10 +140,10 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
|
|||
segment.args.map_or(segment.ident.span, |a| a.span_ext).hi()
|
||||
);
|
||||
cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, |lint| {
|
||||
lint.build("usage of `ty::TyKind::<kind>`")
|
||||
lint.build(fluent::lint::tykind_kind)
|
||||
.span_suggestion(
|
||||
span,
|
||||
"try using `ty::<kind>` directly",
|
||||
fluent::lint::suggestion,
|
||||
"ty",
|
||||
Applicability::MaybeIncorrect, // ty maybe needs an import
|
||||
)
|
||||
|
@ -175,10 +169,10 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
|
|||
if let QPath::TypeRelative(qpath_ty, ..) = qpath
|
||||
&& qpath_ty.hir_id == ty.hir_id
|
||||
{
|
||||
lint.build("usage of `ty::TyKind::<kind>`")
|
||||
lint.build(fluent::lint::tykind_kind)
|
||||
.span_suggestion(
|
||||
path.span,
|
||||
"try using `ty::<kind>` directly",
|
||||
fluent::lint::suggestion,
|
||||
"ty",
|
||||
Applicability::MaybeIncorrect, // ty maybe needs an import
|
||||
)
|
||||
|
@ -193,10 +187,10 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
|
|||
if let QPath::TypeRelative(qpath_ty, ..) = qpath
|
||||
&& qpath_ty.hir_id == ty.hir_id
|
||||
{
|
||||
lint.build("usage of `ty::TyKind::<kind>`")
|
||||
lint.build(fluent::lint::tykind_kind)
|
||||
.span_suggestion(
|
||||
path.span,
|
||||
"try using `ty::<kind>` directly",
|
||||
fluent::lint::suggestion,
|
||||
"ty",
|
||||
Applicability::MaybeIncorrect, // ty maybe needs an import
|
||||
)
|
||||
|
@ -213,10 +207,10 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
|
|||
if let QPath::TypeRelative(qpath_ty, ..) = qpath
|
||||
&& qpath_ty.hir_id == ty.hir_id
|
||||
{
|
||||
lint.build("usage of `ty::TyKind::<kind>`")
|
||||
lint.build(fluent::lint::tykind_kind)
|
||||
.span_suggestion(
|
||||
path.span,
|
||||
"try using `ty::<kind>` directly",
|
||||
fluent::lint::suggestion,
|
||||
"ty",
|
||||
Applicability::MaybeIncorrect, // ty maybe needs an import
|
||||
)
|
||||
|
@ -226,15 +220,16 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
lint.build("usage of `ty::TyKind`").help("try using `Ty` instead").emit();
|
||||
lint.build(fluent::lint::tykind).help(fluent::lint::help).emit();
|
||||
})
|
||||
} else if !ty.span.from_expansion() && let Some(t) = is_ty_or_ty_ctxt(cx, &path) {
|
||||
if path.segments.len() > 1 {
|
||||
cx.struct_span_lint(USAGE_OF_QUALIFIED_TY, path.span, |lint| {
|
||||
lint.build(&format!("usage of qualified `ty::{}`", t))
|
||||
lint.build(fluent::lint::ty_qualified)
|
||||
.set_arg("ty", t.clone())
|
||||
.span_suggestion(
|
||||
path.span,
|
||||
"try importing it and using it unqualified",
|
||||
fluent::lint::suggestion,
|
||||
t,
|
||||
// The import probably needs to be changed
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -330,8 +325,8 @@ impl EarlyLintPass for LintPassImpl {
|
|||
LINT_PASS_IMPL_WITHOUT_MACRO,
|
||||
lint_pass.path.span,
|
||||
|lint| {
|
||||
lint.build("implementing `LintPass` by hand")
|
||||
.help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
|
||||
lint.build(fluent::lint::lintpass_by_hand)
|
||||
.help(fluent::lint::help)
|
||||
.emit();
|
||||
},
|
||||
)
|
||||
|
@ -371,13 +366,10 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword {
|
|||
return;
|
||||
}
|
||||
cx.struct_span_lint(EXISTING_DOC_KEYWORD, attr.span, |lint| {
|
||||
lint.build(&format!(
|
||||
"Found non-existing keyword `{}` used in \
|
||||
`#[doc(keyword = \"...\")]`",
|
||||
v,
|
||||
))
|
||||
.help("only existing keywords are allowed in core/std")
|
||||
.emit();
|
||||
lint.build(fluent::lint::non_existant_doc_keyword)
|
||||
.set_arg("keyword", v)
|
||||
.help(fluent::lint::help)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -431,8 +423,7 @@ impl LateLintPass<'_> for Diagnostics {
|
|||
debug!(?found_impl);
|
||||
if !found_impl {
|
||||
cx.struct_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, |lint| {
|
||||
lint.build("diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls")
|
||||
.emit();
|
||||
lint.build(fluent::lint::diag_out_of_impl).emit();
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -450,7 +441,7 @@ impl LateLintPass<'_> for Diagnostics {
|
|||
debug!(?found_diagnostic_message);
|
||||
if !found_diagnostic_message {
|
||||
cx.struct_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, |lint| {
|
||||
lint.build("diagnostics should be created using translatable messages").emit();
|
||||
lint.build(fluent::lint::untranslatable_diag).emit();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -521,7 +521,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
|||
src,
|
||||
Some(sp.into()),
|
||||
|lint| {
|
||||
let mut err = lint.build(&msg);
|
||||
let mut err = lint.build(msg);
|
||||
if let Some(new_name) = &renamed {
|
||||
err.span_suggestion(
|
||||
sp,
|
||||
|
@ -548,7 +548,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
|||
} else {
|
||||
name.to_string()
|
||||
};
|
||||
let mut db = lint.build(&format!("unknown lint: `{}`", name));
|
||||
let mut db = lint.build(format!("unknown lint: `{}`", name));
|
||||
if let Some(suggestion) = suggestion {
|
||||
db.span_suggestion(
|
||||
sp,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::LateContext;
|
||||
use crate::LateLintPass;
|
||||
use crate::LintContext;
|
||||
use rustc_errors::fluent;
|
||||
use rustc_hir::{Expr, ExprKind, PathSegment};
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::{symbol::sym, ExpnKind, Span};
|
||||
|
@ -88,16 +89,12 @@ fn lint_cstring_as_ptr(
|
|||
if let ty::Adt(adt, _) = substs.type_at(0).kind() {
|
||||
if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) {
|
||||
cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| {
|
||||
let mut diag = diag
|
||||
.build("getting the inner pointer of a temporary `CString`");
|
||||
diag.span_label(as_ptr_span, "this pointer will be invalid");
|
||||
diag.span_label(
|
||||
unwrap.span,
|
||||
"this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime",
|
||||
);
|
||||
diag.note("pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned");
|
||||
diag.help("for more information, see https://doc.rust-lang.org/reference/destructors.html");
|
||||
diag.emit();
|
||||
diag.build(fluent::lint::cstring_ptr)
|
||||
.span_label(as_ptr_span, fluent::lint::as_ptr_label)
|
||||
.span_label(unwrap.span, fluent::lint::unwrap_label)
|
||||
.note(fluent::lint::note)
|
||||
.help(fluent::lint::help)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::fluent;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
declare_lint! {
|
||||
|
@ -180,13 +181,13 @@ impl EarlyLintPass for NonAsciiIdents {
|
|||
}
|
||||
has_non_ascii_idents = true;
|
||||
cx.struct_span_lint(NON_ASCII_IDENTS, sp, |lint| {
|
||||
lint.build("identifier contains non-ASCII characters").emit();
|
||||
lint.build(fluent::lint::identifier_non_ascii_char).emit();
|
||||
});
|
||||
if check_uncommon_codepoints
|
||||
&& !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed)
|
||||
{
|
||||
cx.struct_span_lint(UNCOMMON_CODEPOINTS, sp, |lint| {
|
||||
lint.build("identifier contains uncommon Unicode codepoints").emit();
|
||||
lint.build(fluent::lint::identifier_uncommon_codepoints).emit();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -216,15 +217,11 @@ impl EarlyLintPass for NonAsciiIdents {
|
|||
.and_modify(|(existing_symbol, existing_span, existing_is_ascii)| {
|
||||
if !*existing_is_ascii || !is_ascii {
|
||||
cx.struct_span_lint(CONFUSABLE_IDENTS, sp, |lint| {
|
||||
lint.build(&format!(
|
||||
"identifier pair considered confusable between `{}` and `{}`",
|
||||
existing_symbol, symbol
|
||||
))
|
||||
.span_label(
|
||||
*existing_span,
|
||||
"this is where the previous identifier occurred",
|
||||
)
|
||||
.emit();
|
||||
lint.build(fluent::lint::confusable_identifier_pair)
|
||||
.set_arg("existing_sym", *existing_symbol)
|
||||
.set_arg("sym", symbol)
|
||||
.span_label(*existing_span, fluent::lint::label)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
if *existing_is_ascii && !is_ascii {
|
||||
|
@ -326,18 +323,20 @@ impl EarlyLintPass for NonAsciiIdents {
|
|||
|
||||
for ((sp, ch_list), script_set) in lint_reports {
|
||||
cx.struct_span_lint(MIXED_SCRIPT_CONFUSABLES, sp, |lint| {
|
||||
let message = format!(
|
||||
"the usage of Script Group `{}` in this crate consists solely of mixed script confusables",
|
||||
script_set);
|
||||
let mut note = "the usage includes ".to_string();
|
||||
let mut includes = String::new();
|
||||
for (idx, ch) in ch_list.into_iter().enumerate() {
|
||||
if idx != 0 {
|
||||
note += ", ";
|
||||
includes += ", ";
|
||||
}
|
||||
let char_info = format!("'{}' (U+{:04X})", ch, ch as u32);
|
||||
note += &char_info;
|
||||
includes += &char_info;
|
||||
}
|
||||
lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit();
|
||||
lint.build(fluent::lint::mixed_script_confusables)
|
||||
.set_arg("set", script_set.to_string())
|
||||
.set_arg("includes", includes)
|
||||
.note(fluent::lint::includes_note)
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::{pluralize, Applicability};
|
||||
use rustc_errors::{fluent, Applicability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
@ -120,9 +120,10 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
}
|
||||
|
||||
cx.struct_span_lint(NON_FMT_PANICS, arg_span, |lint| {
|
||||
let mut l = lint.build("panic message is not a string literal");
|
||||
l.note(&format!("this usage of {}!() is deprecated; it will be a hard error in Rust 2021", symbol));
|
||||
l.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>");
|
||||
let mut l = lint.build(fluent::lint::non_fmt_panic);
|
||||
l.set_arg("name", symbol);
|
||||
l.note(fluent::lint::note);
|
||||
l.note(fluent::lint::more_info_note);
|
||||
if !is_arg_inside_call(arg_span, span) {
|
||||
// No clue where this argument is coming from.
|
||||
l.emit();
|
||||
|
@ -130,10 +131,10 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
}
|
||||
if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
|
||||
// A case of `panic!(format!(..))`.
|
||||
l.note(format!("the {}!() macro supports formatting, so there's no need for the format!() macro here", symbol).as_str());
|
||||
l.note(fluent::lint::supports_fmt_note);
|
||||
if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
|
||||
l.multipart_suggestion(
|
||||
"remove the `format!(..)` macro call",
|
||||
fluent::lint::supports_fmt_suggestion,
|
||||
vec![
|
||||
(arg_span.until(open.shrink_to_hi()), "".into()),
|
||||
(close.until(arg_span.shrink_to_hi()), "".into()),
|
||||
|
@ -153,12 +154,18 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
);
|
||||
|
||||
let (suggest_display, suggest_debug) = cx.tcx.infer_ctxt().enter(|infcx| {
|
||||
let display = is_str || cx.tcx.get_diagnostic_item(sym::Display).map(|t| {
|
||||
infcx.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env).may_apply()
|
||||
}) == Some(true);
|
||||
let debug = !display && cx.tcx.get_diagnostic_item(sym::Debug).map(|t| {
|
||||
infcx.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env).may_apply()
|
||||
}) == Some(true);
|
||||
let display = is_str
|
||||
|| cx.tcx.get_diagnostic_item(sym::Display).map(|t| {
|
||||
infcx
|
||||
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
|
||||
.may_apply()
|
||||
}) == Some(true);
|
||||
let debug = !display
|
||||
&& cx.tcx.get_diagnostic_item(sym::Debug).map(|t| {
|
||||
infcx
|
||||
.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env)
|
||||
.may_apply()
|
||||
}) == Some(true);
|
||||
(display, debug)
|
||||
});
|
||||
|
||||
|
@ -175,17 +182,15 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
if suggest_display {
|
||||
l.span_suggestion_verbose(
|
||||
arg_span.shrink_to_lo(),
|
||||
"add a \"{}\" format string to Display the message",
|
||||
fluent::lint::display_suggestion,
|
||||
"\"{}\", ",
|
||||
fmt_applicability,
|
||||
);
|
||||
} else if suggest_debug {
|
||||
l.set_arg("ty", ty);
|
||||
l.span_suggestion_verbose(
|
||||
arg_span.shrink_to_lo(),
|
||||
&format!(
|
||||
"add a \"{{:?}}\" format string to use the Debug implementation of `{}`",
|
||||
ty,
|
||||
),
|
||||
fluent::lint::debug_suggestion,
|
||||
"\"{:?}\", ",
|
||||
fmt_applicability,
|
||||
);
|
||||
|
@ -193,15 +198,9 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
|
||||
if suggest_panic_any {
|
||||
if let Some((open, close, del)) = find_delimiters(cx, span) {
|
||||
l.set_arg("already_suggested", suggest_display || suggest_debug);
|
||||
l.multipart_suggestion(
|
||||
&format!(
|
||||
"{}use std::panic::panic_any instead",
|
||||
if suggest_display || suggest_debug {
|
||||
"or "
|
||||
} else {
|
||||
""
|
||||
},
|
||||
),
|
||||
fluent::lint::panic_suggestion,
|
||||
if del == '(' {
|
||||
vec![(span.until(open), "std::panic::panic_any".into())]
|
||||
} else {
|
||||
|
@ -260,21 +259,19 @@ fn check_panic_str<'tcx>(
|
|||
.collect(),
|
||||
};
|
||||
cx.struct_span_lint(NON_FMT_PANICS, arg_spans, |lint| {
|
||||
let mut l = lint.build(match n_arguments {
|
||||
1 => "panic message contains an unused formatting placeholder",
|
||||
_ => "panic message contains unused formatting placeholders",
|
||||
});
|
||||
l.note("this message is not used as a format string when given without arguments, but will be in Rust 2021");
|
||||
let mut l = lint.build(fluent::lint::non_fmt_panic_unused);
|
||||
l.set_arg("count", n_arguments);
|
||||
l.note(fluent::lint::note);
|
||||
if is_arg_inside_call(arg.span, span) {
|
||||
l.span_suggestion(
|
||||
arg.span.shrink_to_hi(),
|
||||
&format!("add the missing argument{}", pluralize!(n_arguments)),
|
||||
fluent::lint::add_args_suggestion,
|
||||
", ...",
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
l.span_suggestion(
|
||||
arg.span.shrink_to_lo(),
|
||||
"or add a \"{}\" format string to use the message literally",
|
||||
fluent::lint::add_fmt_suggestion,
|
||||
"\"{}\", ",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -289,17 +286,15 @@ fn check_panic_str<'tcx>(
|
|||
.map(|(i, _)| fmt_span.from_inner(InnerSpan { start: i, end: i + 1 }))
|
||||
.collect()
|
||||
});
|
||||
let msg = match &brace_spans {
|
||||
Some(v) if v.len() == 1 => "panic message contains a brace",
|
||||
_ => "panic message contains braces",
|
||||
};
|
||||
let count = brace_spans.as_ref().map(|v| v.len()).unwrap_or(/* any number >1 */ 2);
|
||||
cx.struct_span_lint(NON_FMT_PANICS, brace_spans.unwrap_or_else(|| vec![span]), |lint| {
|
||||
let mut l = lint.build(msg);
|
||||
l.note("this message is not used as a format string, but will be in Rust 2021");
|
||||
let mut l = lint.build(fluent::lint::non_fmt_panic_braces);
|
||||
l.set_arg("count", count);
|
||||
l.note(fluent::lint::note);
|
||||
if is_arg_inside_call(arg.span, span) {
|
||||
l.span_suggestion(
|
||||
arg.span.shrink_to_lo(),
|
||||
"add a \"{}\" format string to use the message literally",
|
||||
fluent::lint::suggestion,
|
||||
"\"{}\", ",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{fluent, Applicability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
|
@ -137,22 +137,23 @@ impl NonCamelCaseTypes {
|
|||
|
||||
if !is_camel_case(name) {
|
||||
cx.struct_span_lint(NON_CAMEL_CASE_TYPES, ident.span, |lint| {
|
||||
let msg = format!("{} `{}` should have an upper camel case name", sort, name);
|
||||
let mut err = lint.build(&msg);
|
||||
let mut err = lint.build(fluent::lint::non_camel_case_type);
|
||||
let cc = to_camel_case(name);
|
||||
// We cannot provide meaningful suggestions
|
||||
// if the characters are in the category of "Lowercase Letter".
|
||||
if *name != cc {
|
||||
err.span_suggestion(
|
||||
ident.span,
|
||||
"convert the identifier to upper camel case",
|
||||
fluent::lint::suggestion,
|
||||
to_camel_case(name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_label(ident.span, "should have an UpperCamelCase name");
|
||||
err.span_label(ident.span, fluent::lint::label);
|
||||
}
|
||||
|
||||
err.set_arg("sort", sort);
|
||||
err.set_arg("name", name);
|
||||
err.emit();
|
||||
})
|
||||
}
|
||||
|
@ -281,11 +282,10 @@ impl NonSnakeCase {
|
|||
if !is_snake_case(name) {
|
||||
cx.struct_span_lint(NON_SNAKE_CASE, ident.span, |lint| {
|
||||
let sc = NonSnakeCase::to_snake_case(name);
|
||||
let msg = format!("{} `{}` should have a snake case name", sort, name);
|
||||
let mut err = lint.build(&msg);
|
||||
let mut err = lint.build(fluent::lint::non_snake_case);
|
||||
// We cannot provide meaningful suggestions
|
||||
// if the characters are in the category of "Uppercase Letter".
|
||||
if *name != sc {
|
||||
if name != sc {
|
||||
// We have a valid span in almost all cases, but we don't have one when linting a crate
|
||||
// name provided via the command line.
|
||||
if !ident.span.is_dummy() {
|
||||
|
@ -295,13 +295,13 @@ impl NonSnakeCase {
|
|||
// Instead, recommend renaming the identifier entirely or, if permitted,
|
||||
// escaping it to create a raw identifier.
|
||||
if sc_ident.name.can_be_raw() {
|
||||
("rename the identifier or convert it to a snake case raw identifier", sc_ident.to_string())
|
||||
(fluent::lint::rename_or_convert_suggestion, sc_ident.to_string())
|
||||
} else {
|
||||
err.note(&format!("`{}` cannot be used as a raw identifier", sc));
|
||||
("rename the identifier", String::new())
|
||||
err.note(fluent::lint::cannot_convert_note);
|
||||
(fluent::lint::rename_suggestion, String::new())
|
||||
}
|
||||
} else {
|
||||
("convert the identifier to snake case", sc)
|
||||
(fluent::lint::convert_suggestion, sc.clone())
|
||||
};
|
||||
|
||||
err.span_suggestion(
|
||||
|
@ -311,12 +311,15 @@ impl NonSnakeCase {
|
|||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.help(&format!("convert the identifier to snake case: `{}`", sc));
|
||||
err.help(fluent::lint::help);
|
||||
}
|
||||
} else {
|
||||
err.span_label(ident.span, "should have a snake_case name");
|
||||
err.span_label(ident.span, fluent::lint::label);
|
||||
}
|
||||
|
||||
err.set_arg("sort", sort);
|
||||
err.set_arg("name", name);
|
||||
err.set_arg("sc", sc);
|
||||
err.emit();
|
||||
});
|
||||
}
|
||||
|
@ -488,21 +491,22 @@ impl NonUpperCaseGlobals {
|
|||
if name.chars().any(|c| c.is_lowercase()) {
|
||||
cx.struct_span_lint(NON_UPPER_CASE_GLOBALS, ident.span, |lint| {
|
||||
let uc = NonSnakeCase::to_snake_case(&name).to_uppercase();
|
||||
let mut err =
|
||||
lint.build(&format!("{} `{}` should have an upper case name", sort, name));
|
||||
let mut err = lint.build(fluent::lint::non_upper_case_global);
|
||||
// We cannot provide meaningful suggestions
|
||||
// if the characters are in the category of "Lowercase Letter".
|
||||
if *name != uc {
|
||||
err.span_suggestion(
|
||||
ident.span,
|
||||
"convert the identifier to upper case",
|
||||
fluent::lint::suggestion,
|
||||
uc,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_label(ident.span, "should have an UPPER_CASE name");
|
||||
err.span_label(ident.span, fluent::lint::label);
|
||||
}
|
||||
|
||||
err.set_arg("sort", sort);
|
||||
err.set_arg("name", name);
|
||||
err.emit();
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::context::LintContext;
|
|||
use crate::rustc_middle::ty::TypeFoldable;
|
||||
use crate::LateContext;
|
||||
use crate::LateLintPass;
|
||||
use rustc_errors::fluent;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_middle::ty;
|
||||
|
@ -80,7 +81,6 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||
) {
|
||||
return;
|
||||
}
|
||||
let method = &call.ident.name;
|
||||
let receiver = &elements[0];
|
||||
let receiver_ty = cx.typeck_results().expr_ty(receiver);
|
||||
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
|
||||
|
@ -90,19 +90,14 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||
return;
|
||||
}
|
||||
let expr_span = expr.span;
|
||||
let note = format!(
|
||||
"the type `{:?}` which `{}` is being called on is the same as \
|
||||
the type returned from `{}`, so the method call does not do \
|
||||
anything and can be removed",
|
||||
receiver_ty, method, method,
|
||||
);
|
||||
|
||||
let span = expr_span.with_lo(receiver.span.hi());
|
||||
cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
|
||||
let method = &call.ident.name;
|
||||
let message =
|
||||
format!("call to `.{}()` on a reference in this situation does nothing", &method,);
|
||||
lint.build(&message).span_label(span, "unnecessary method call").note(¬e).emit();
|
||||
lint.build(fluent::lint::noop_method_call)
|
||||
.set_arg("method", call.ident.name)
|
||||
.set_arg("receiver_ty", receiver_ty)
|
||||
.span_label(span, fluent::lint::label)
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{fluent, Applicability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{GenericArg, PathSegment, QPath, TyKind};
|
||||
|
@ -30,10 +30,11 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
|
|||
}
|
||||
if let Some(t) = path_for_pass_by_value(cx, &inner_ty) {
|
||||
cx.struct_span_lint(PASS_BY_VALUE, ty.span, |lint| {
|
||||
lint.build(&format!("passing `{}` by reference", t))
|
||||
lint.build(fluent::lint::pass_by_value)
|
||||
.set_arg("ty", t.clone())
|
||||
.span_suggestion(
|
||||
ty.span,
|
||||
"try passing by value",
|
||||
fluent::lint::suggestion,
|
||||
t,
|
||||
// Changing type of function argument
|
||||
Applicability::MaybeIncorrect,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_ast::{Block, StmtKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{fluent, Applicability};
|
||||
use rustc_span::Span;
|
||||
|
||||
declare_lint! {
|
||||
|
@ -49,12 +49,10 @@ fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, boo
|
|||
}
|
||||
|
||||
cx.struct_span_lint(REDUNDANT_SEMICOLONS, span, |lint| {
|
||||
let (msg, rem) = if multiple {
|
||||
("unnecessary trailing semicolons", "remove these semicolons")
|
||||
} else {
|
||||
("unnecessary trailing semicolon", "remove this semicolon")
|
||||
};
|
||||
lint.build(msg).span_suggestion(span, rem, "", Applicability::MaybeIncorrect).emit();
|
||||
lint.build(fluent::lint::redundant_semicolons)
|
||||
.set_arg("multiple", multiple)
|
||||
.span_suggestion(span, fluent::lint::suggestion, "", Applicability::MaybeIncorrect)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::LateContext;
|
||||
use crate::LateLintPass;
|
||||
use crate::LintContext;
|
||||
use rustc_errors::fluent;
|
||||
use rustc_hir as hir;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
|
@ -103,13 +104,10 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
|||
let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else {
|
||||
return
|
||||
};
|
||||
let msg = format!(
|
||||
"bounds on `{}` are most likely incorrect, consider instead \
|
||||
using `{}` to detect whether a type can be trivially dropped",
|
||||
predicate,
|
||||
cx.tcx.def_path_str(needs_drop)
|
||||
);
|
||||
lint.build(&msg).emit();
|
||||
lint.build(fluent::lint::drop_trait_constraints)
|
||||
.set_arg("predicate", predicate)
|
||||
.set_arg("needs_drop", cx.tcx.def_path_str(needs_drop))
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -126,12 +124,9 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
|||
let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else {
|
||||
return
|
||||
};
|
||||
let msg = format!(
|
||||
"types that do not implement `Drop` can still have drop glue, consider \
|
||||
instead using `{}` to detect whether a type is trivially dropped",
|
||||
cx.tcx.def_path_str(needs_drop)
|
||||
);
|
||||
lint.build(&msg).emit();
|
||||
lint.build(fluent::lint::drop_glue)
|
||||
.set_arg("needs_drop", cx.tcx.def_path_str(needs_drop))
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{LateContext, LateLintPass, LintContext};
|
|||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_errors::{fluent, Applicability, DiagnosticMessage};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
|
||||
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
|
||||
|
@ -139,7 +139,8 @@ fn lint_overflowing_range_endpoint<'tcx>(
|
|||
// overflowing and only by 1.
|
||||
if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
|
||||
cx.struct_span_lint(OVERFLOWING_LITERALS, parent_expr.span, |lint| {
|
||||
let mut err = lint.build(&format!("range endpoint is out of range for `{}`", ty));
|
||||
let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
|
||||
err.set_arg("ty", ty);
|
||||
if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
|
||||
use ast::{LitIntType, LitKind};
|
||||
// We need to preserve the literal's suffix,
|
||||
|
@ -153,7 +154,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
|
|||
let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
|
||||
err.span_suggestion(
|
||||
parent_expr.span,
|
||||
"use an inclusive range instead",
|
||||
fluent::lint::suggestion,
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -229,38 +230,35 @@ fn report_bin_hex_error(
|
|||
(t.name_str(), actually.to_string())
|
||||
}
|
||||
};
|
||||
let mut err = lint.build(&format!("literal out of range for `{}`", t));
|
||||
let mut err = lint.build(fluent::lint::overflowing_bin_hex);
|
||||
if negative {
|
||||
// If the value is negative,
|
||||
// emits a note about the value itself, apart from the literal.
|
||||
err.note(&format!(
|
||||
"the literal `{}` (decimal `{}`) does not fit into \
|
||||
the type `{}`",
|
||||
repr_str, val, t
|
||||
));
|
||||
err.note(&format!("and the value `-{}` will become `{}{}`", repr_str, actually, t));
|
||||
err.note(fluent::lint::negative_note);
|
||||
err.note(fluent::lint::negative_becomes_note);
|
||||
} else {
|
||||
err.note(&format!(
|
||||
"the literal `{}` (decimal `{}`) does not fit into \
|
||||
the type `{}` and will become `{}{}`",
|
||||
repr_str, val, t, actually, t
|
||||
));
|
||||
err.note(fluent::lint::positive_note);
|
||||
}
|
||||
if let Some(sugg_ty) =
|
||||
get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative)
|
||||
{
|
||||
err.set_arg("suggestion_ty", sugg_ty);
|
||||
if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
|
||||
let (sans_suffix, _) = repr_str.split_at(pos);
|
||||
err.span_suggestion(
|
||||
expr.span,
|
||||
&format!("consider using the type `{}` instead", sugg_ty),
|
||||
fluent::lint::suggestion,
|
||||
format!("{}{}", sans_suffix, sugg_ty),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.help(&format!("consider using the type `{}` instead", sugg_ty));
|
||||
err.help(fluent::lint::help);
|
||||
}
|
||||
}
|
||||
err.set_arg("ty", t);
|
||||
err.set_arg("lit", repr_str);
|
||||
err.set_arg("dec", val);
|
||||
err.set_arg("actually", actually);
|
||||
err.emit();
|
||||
});
|
||||
}
|
||||
|
@ -353,21 +351,23 @@ fn lint_int_literal<'tcx>(
|
|||
}
|
||||
|
||||
cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
|
||||
let mut err = lint.build(&format!("literal out of range for `{}`", t.name_str()));
|
||||
err.note(&format!(
|
||||
"the literal `{}` does not fit into the type `{}` whose range is `{}..={}`",
|
||||
let mut err = lint.build(fluent::lint::overflowing_int);
|
||||
err.set_arg("ty", t.name_str());
|
||||
err.set_arg(
|
||||
"lit",
|
||||
cx.sess()
|
||||
.source_map()
|
||||
.span_to_snippet(lit.span)
|
||||
.expect("must get snippet from literal"),
|
||||
t.name_str(),
|
||||
min,
|
||||
max,
|
||||
));
|
||||
);
|
||||
err.set_arg("min", min);
|
||||
err.set_arg("max", max);
|
||||
err.note(fluent::lint::note);
|
||||
if let Some(sugg_ty) =
|
||||
get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
|
||||
{
|
||||
err.help(&format!("consider using the type `{}` instead", sugg_ty));
|
||||
err.set_arg("suggestion_ty", sugg_ty);
|
||||
err.help(fluent::lint::help);
|
||||
}
|
||||
err.emit();
|
||||
});
|
||||
|
@ -395,10 +395,10 @@ fn lint_uint_literal<'tcx>(
|
|||
hir::ExprKind::Cast(..) => {
|
||||
if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
|
||||
cx.struct_span_lint(OVERFLOWING_LITERALS, par_e.span, |lint| {
|
||||
lint.build("only `u8` can be cast into `char`")
|
||||
lint.build(fluent::lint::only_cast_u8_to_char)
|
||||
.span_suggestion(
|
||||
par_e.span,
|
||||
"use a `char` literal instead",
|
||||
fluent::lint::suggestion,
|
||||
format!("'\\u{{{:X}}}'", lit_val),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
|
@ -429,17 +429,18 @@ fn lint_uint_literal<'tcx>(
|
|||
return;
|
||||
}
|
||||
cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
|
||||
lint.build(&format!("literal out of range for `{}`", t.name_str()))
|
||||
.note(&format!(
|
||||
"the literal `{}` does not fit into the type `{}` whose range is `{}..={}`",
|
||||
lint.build(fluent::lint::overflowing_uint)
|
||||
.set_arg("ty", t.name_str())
|
||||
.set_arg(
|
||||
"lit",
|
||||
cx.sess()
|
||||
.source_map()
|
||||
.span_to_snippet(lit.span)
|
||||
.expect("must get snippet from literal"),
|
||||
t.name_str(),
|
||||
min,
|
||||
max,
|
||||
))
|
||||
)
|
||||
.set_arg("min", min)
|
||||
.set_arg("max", max)
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
@ -471,16 +472,16 @@ fn lint_literal<'tcx>(
|
|||
};
|
||||
if is_infinite == Ok(true) {
|
||||
cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
|
||||
lint.build(&format!("literal out of range for `{}`", t.name_str()))
|
||||
.note(&format!(
|
||||
"the literal `{}` does not fit into the type `{}` and will be converted to `{}::INFINITY`",
|
||||
lint.build(fluent::lint::overflowing_literal)
|
||||
.set_arg("ty", t.name_str())
|
||||
.set_arg(
|
||||
"lit",
|
||||
cx.sess()
|
||||
.source_map()
|
||||
.span_to_snippet(lit.span)
|
||||
.expect("must get snippet from literal"),
|
||||
t.name_str(),
|
||||
t.name_str(),
|
||||
))
|
||||
)
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
@ -501,7 +502,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
|||
hir::ExprKind::Binary(binop, ref l, ref r) => {
|
||||
if is_comparison(binop) && !check_limits(cx, binop, &l, &r) {
|
||||
cx.struct_span_lint(UNUSED_COMPARISONS, e.span, |lint| {
|
||||
lint.build("comparison is useless due to type limits").emit();
|
||||
lint.build(fluent::lint::unused_comparisons).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -663,7 +664,7 @@ struct ImproperCTypesVisitor<'a, 'tcx> {
|
|||
enum FfiResult<'tcx> {
|
||||
FfiSafe,
|
||||
FfiPhantom(Ty<'tcx>),
|
||||
FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> },
|
||||
FfiUnsafe { ty: Ty<'tcx>, reason: DiagnosticMessage, help: Option<DiagnosticMessage> },
|
||||
}
|
||||
|
||||
pub(crate) fn nonnull_optimization_guaranteed<'tcx>(
|
||||
|
@ -823,8 +824,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
self.emit_ffi_unsafe_type_lint(
|
||||
ty,
|
||||
sp,
|
||||
"passing raw arrays by value is not FFI-safe",
|
||||
Some("consider passing a pointer to the array"),
|
||||
fluent::lint::improper_ctypes_array_reason,
|
||||
Some(fluent::lint::improper_ctypes_array_help),
|
||||
);
|
||||
true
|
||||
} else {
|
||||
|
@ -867,11 +868,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
} else {
|
||||
// All fields are ZSTs; this means that the type should behave
|
||||
// like (), which is FFI-unsafe
|
||||
FfiUnsafe {
|
||||
ty,
|
||||
reason: "this struct contains only zero-sized fields".into(),
|
||||
help: None,
|
||||
}
|
||||
FfiUnsafe { ty, reason: fluent::lint::improper_ctypes_struct_zst, help: None }
|
||||
}
|
||||
} else {
|
||||
// We can't completely trust repr(C) markings; make sure the fields are
|
||||
|
@ -885,7 +882,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
FfiPhantom(..) if def.is_enum() => {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "this enum contains a PhantomData field".into(),
|
||||
reason: fluent::lint::improper_ctypes_enum_phantomdata,
|
||||
help: None,
|
||||
};
|
||||
}
|
||||
|
@ -921,7 +918,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
} else {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "box cannot be represented as a single pointer".to_string(),
|
||||
reason: fluent::lint::improper_ctypes_box,
|
||||
help: None,
|
||||
};
|
||||
}
|
||||
|
@ -931,17 +928,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
}
|
||||
match def.adt_kind() {
|
||||
AdtKind::Struct | AdtKind::Union => {
|
||||
let kind = if def.is_struct() { "struct" } else { "union" };
|
||||
|
||||
if !def.repr().c() && !def.repr().transparent() {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: format!("this {} has unspecified layout", kind),
|
||||
help: Some(format!(
|
||||
"consider adding a `#[repr(C)]` or \
|
||||
`#[repr(transparent)]` attribute to this {}",
|
||||
kind
|
||||
)),
|
||||
reason: if def.is_struct() {
|
||||
fluent::lint::improper_ctypes_struct_layout_reason
|
||||
} else {
|
||||
fluent::lint::improper_ctypes_union_layout_reason
|
||||
},
|
||||
help: if def.is_struct() {
|
||||
Some(fluent::lint::improper_ctypes_struct_layout_help)
|
||||
} else {
|
||||
Some(fluent::lint::improper_ctypes_union_layout_help)
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -950,7 +949,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
if is_non_exhaustive && !def.did().is_local() {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: format!("this {} is non-exhaustive", kind),
|
||||
reason: if def.is_struct() {
|
||||
fluent::lint::improper_ctypes_struct_non_exhaustive
|
||||
} else {
|
||||
fluent::lint::improper_ctypes_union_non_exhaustive
|
||||
},
|
||||
help: None,
|
||||
};
|
||||
}
|
||||
|
@ -958,8 +961,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
if def.non_enum_variant().fields.is_empty() {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: format!("this {} has no fields", kind),
|
||||
help: Some(format!("consider adding a member to this {}", kind)),
|
||||
reason: if def.is_struct() {
|
||||
fluent::lint::improper_ctypes_struct_fieldless_reason
|
||||
} else {
|
||||
fluent::lint::improper_ctypes_union_fieldless_reason
|
||||
},
|
||||
help: if def.is_struct() {
|
||||
Some(fluent::lint::improper_ctypes_struct_fieldless_help)
|
||||
} else {
|
||||
Some(fluent::lint::improper_ctypes_union_fieldless_help)
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -979,13 +990,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
if repr_nullable_ptr(self.cx, ty, self.mode).is_none() {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "enum has no representation hint".into(),
|
||||
help: Some(
|
||||
"consider adding a `#[repr(C)]`, \
|
||||
`#[repr(transparent)]`, or integer `#[repr(...)]` \
|
||||
attribute to this enum"
|
||||
.into(),
|
||||
),
|
||||
reason: fluent::lint::improper_ctypes_enum_repr_reason,
|
||||
help: Some(fluent::lint::improper_ctypes_enum_repr_help),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -993,7 +999,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
if def.is_variant_list_non_exhaustive() && !def.did().is_local() {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "this enum is non-exhaustive".into(),
|
||||
reason: fluent::lint::improper_ctypes_non_exhaustive,
|
||||
help: None,
|
||||
};
|
||||
}
|
||||
|
@ -1004,7 +1010,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
if is_non_exhaustive && !variant.def_id.is_local() {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "this enum has non-exhaustive variants".into(),
|
||||
reason: fluent::lint::improper_ctypes_non_exhaustive_variant,
|
||||
help: None,
|
||||
};
|
||||
}
|
||||
|
@ -1022,39 +1028,37 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
|
||||
ty::Char => FfiUnsafe {
|
||||
ty,
|
||||
reason: "the `char` type has no C equivalent".into(),
|
||||
help: Some("consider using `u32` or `libc::wchar_t` instead".into()),
|
||||
reason: fluent::lint::improper_ctypes_char_reason,
|
||||
help: Some(fluent::lint::improper_ctypes_char_help),
|
||||
},
|
||||
|
||||
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => FfiUnsafe {
|
||||
ty,
|
||||
reason: "128-bit integers don't currently have a known stable ABI".into(),
|
||||
help: None,
|
||||
},
|
||||
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => {
|
||||
FfiUnsafe { ty, reason: fluent::lint::improper_ctypes_128bit, help: None }
|
||||
}
|
||||
|
||||
// Primitive types with a stable representation.
|
||||
ty::Bool | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Never => FfiSafe,
|
||||
|
||||
ty::Slice(_) => FfiUnsafe {
|
||||
ty,
|
||||
reason: "slices have no C equivalent".into(),
|
||||
help: Some("consider using a raw pointer instead".into()),
|
||||
reason: fluent::lint::improper_ctypes_slice_reason,
|
||||
help: Some(fluent::lint::improper_ctypes_slice_help),
|
||||
},
|
||||
|
||||
ty::Dynamic(..) => {
|
||||
FfiUnsafe { ty, reason: "trait objects have no C equivalent".into(), help: None }
|
||||
FfiUnsafe { ty, reason: fluent::lint::improper_ctypes_dyn, help: None }
|
||||
}
|
||||
|
||||
ty::Str => FfiUnsafe {
|
||||
ty,
|
||||
reason: "string slices have no C equivalent".into(),
|
||||
help: Some("consider using `*const u8` and a length instead".into()),
|
||||
reason: fluent::lint::improper_ctypes_str_reason,
|
||||
help: Some(fluent::lint::improper_ctypes_str_help),
|
||||
},
|
||||
|
||||
ty::Tuple(..) => FfiUnsafe {
|
||||
ty,
|
||||
reason: "tuples have unspecified layout".into(),
|
||||
help: Some("consider using a struct instead".into()),
|
||||
reason: fluent::lint::improper_ctypes_tuple_reason,
|
||||
help: Some(fluent::lint::improper_ctypes_tuple_help),
|
||||
},
|
||||
|
||||
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
|
||||
|
@ -1085,12 +1089,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
if self.is_internal_abi(sig.abi()) {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: "this function pointer has Rust-specific calling convention".into(),
|
||||
help: Some(
|
||||
"consider using an `extern fn(...) -> ...` \
|
||||
function pointer instead"
|
||||
.into(),
|
||||
),
|
||||
reason: fluent::lint::improper_ctypes_fnptr_reason,
|
||||
help: Some(fluent::lint::improper_ctypes_fnptr_help),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1121,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
// While opaque types are checked for earlier, if a projection in a struct field
|
||||
// normalizes to an opaque type, then it will reach this branch.
|
||||
ty::Opaque(..) => {
|
||||
FfiUnsafe { ty, reason: "opaque types have no C equivalent".into(), help: None }
|
||||
FfiUnsafe { ty, reason: fluent::lint::improper_ctypes_opaque, help: None }
|
||||
}
|
||||
|
||||
// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
|
||||
|
@ -1147,8 +1147,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
sp: Span,
|
||||
note: &str,
|
||||
help: Option<&str>,
|
||||
note: DiagnosticMessage,
|
||||
help: Option<DiagnosticMessage>,
|
||||
) {
|
||||
let lint = match self.mode {
|
||||
CItemKind::Declaration => IMPROPER_CTYPES,
|
||||
|
@ -1160,18 +1160,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
CItemKind::Declaration => "block",
|
||||
CItemKind::Definition => "fn",
|
||||
};
|
||||
let mut diag = lint.build(&format!(
|
||||
"`extern` {} uses type `{}`, which is not FFI-safe",
|
||||
item_description, ty
|
||||
));
|
||||
diag.span_label(sp, "not FFI-safe");
|
||||
let mut diag = lint.build(fluent::lint::improper_ctypes);
|
||||
diag.set_arg("ty", ty);
|
||||
diag.set_arg("desc", item_description);
|
||||
diag.span_label(sp, fluent::lint::label);
|
||||
if let Some(help) = help {
|
||||
diag.help(help);
|
||||
}
|
||||
diag.note(note);
|
||||
if let ty::Adt(def, _) = ty.kind() {
|
||||
if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did()) {
|
||||
diag.span_note(sp, "the type is defined here");
|
||||
diag.span_note(sp, fluent::lint::note);
|
||||
}
|
||||
}
|
||||
diag.emit();
|
||||
|
@ -1208,7 +1207,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
if let Some(ty) = ty.visit_with(&mut ProhibitOpaqueTypes { cx: self.cx }).break_value() {
|
||||
self.emit_ffi_unsafe_type_lint(ty, sp, "opaque types have no C equivalent", None);
|
||||
self.emit_ffi_unsafe_type_lint(ty, sp, fluent::lint::improper_ctypes_opaque, None);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -1250,13 +1249,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
|
||||
FfiResult::FfiSafe => {}
|
||||
FfiResult::FfiPhantom(ty) => {
|
||||
self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
|
||||
self.emit_ffi_unsafe_type_lint(
|
||||
ty,
|
||||
sp,
|
||||
fluent::lint::improper_ctypes_only_phantomdata,
|
||||
None,
|
||||
);
|
||||
}
|
||||
// If `ty` is a `repr(transparent)` newtype, and the non-zero-sized type is a generic
|
||||
// argument, which after substitution, is `()`, then this branch can be hit.
|
||||
FfiResult::FfiUnsafe { ty, .. } if is_return_type && ty.is_unit() => {}
|
||||
FfiResult::FfiUnsafe { ty, reason, help } => {
|
||||
self.emit_ffi_unsafe_type_lint(ty, sp, &reason, help.as_deref());
|
||||
self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1383,12 +1387,9 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
|
|||
VARIANT_SIZE_DIFFERENCES,
|
||||
enum_definition.variants[largest_index].span,
|
||||
|lint| {
|
||||
lint.build(&format!(
|
||||
"enum variant is more than three times \
|
||||
larger ({} bytes) than the next largest",
|
||||
largest
|
||||
))
|
||||
.emit();
|
||||
lint.build(fluent::lint::variant_size_differences)
|
||||
.set_arg("largest", largest)
|
||||
.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1511,13 +1512,13 @@ impl InvalidAtomicOrdering {
|
|||
{
|
||||
cx.struct_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, |diag| {
|
||||
if method == sym::load {
|
||||
diag.build("atomic loads cannot have `Release` or `AcqRel` ordering")
|
||||
.help("consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`")
|
||||
diag.build(fluent::lint::atomic_ordering_load)
|
||||
.help(fluent::lint::help)
|
||||
.emit()
|
||||
} else {
|
||||
debug_assert_eq!(method, sym::store);
|
||||
diag.build("atomic stores cannot have `Acquire` or `AcqRel` ordering")
|
||||
.help("consider using ordering modes `Release`, `SeqCst` or `Relaxed`")
|
||||
diag.build(fluent::lint::atomic_ordering_store)
|
||||
.help(fluent::lint::help)
|
||||
.emit();
|
||||
}
|
||||
});
|
||||
|
@ -1532,8 +1533,8 @@ impl InvalidAtomicOrdering {
|
|||
&& Self::match_ordering(cx, &args[0]) == Some(sym::Relaxed)
|
||||
{
|
||||
cx.struct_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, |diag| {
|
||||
diag.build("memory fences cannot have `Relaxed` ordering")
|
||||
.help("consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`")
|
||||
diag.build(fluent::lint::atomic_ordering_fence)
|
||||
.help(fluent::lint::help)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
@ -1553,13 +1554,11 @@ impl InvalidAtomicOrdering {
|
|||
|
||||
if matches!(fail_ordering, sym::Release | sym::AcqRel) {
|
||||
cx.struct_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg.span, |diag| {
|
||||
diag.build(&format!(
|
||||
"`{method}`'s failure ordering may not be `Release` or `AcqRel`, \
|
||||
since a failed `{method}` does not result in a write",
|
||||
))
|
||||
.span_label(fail_order_arg.span, "invalid failure ordering")
|
||||
.help("consider using `Acquire` or `Relaxed` failure ordering instead")
|
||||
.emit();
|
||||
diag.build(fluent::lint::atomic_ordering_invalid)
|
||||
.set_arg("method", method)
|
||||
.span_label(fail_order_arg.span, fluent::lint::label)
|
||||
.help(fluent::lint::help)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1577,18 +1576,20 @@ impl InvalidAtomicOrdering {
|
|||
fail_ordering
|
||||
};
|
||||
cx.struct_span_lint(INVALID_ATOMIC_ORDERING, success_order_arg.span, |diag| {
|
||||
diag.build(&format!(
|
||||
"`{method}`'s success ordering must be at least as strong as its failure ordering"
|
||||
))
|
||||
.span_label(fail_order_arg.span, format!("`{fail_ordering}` failure ordering"))
|
||||
.span_label(success_order_arg.span, format!("`{success_ordering}` success ordering"))
|
||||
.span_suggestion_short(
|
||||
success_order_arg.span,
|
||||
format!("consider using `{success_suggestion}` success ordering instead"),
|
||||
format!("std::sync::atomic::Ordering::{success_suggestion}"),
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
diag.build(fluent::lint::atomic_ordering_invalid_fail_success)
|
||||
.set_arg("method", method)
|
||||
.set_arg("fail_ordering", fail_ordering)
|
||||
.set_arg("success_ordering", success_ordering)
|
||||
.set_arg("success_suggestion", success_suggestion)
|
||||
.span_label(fail_order_arg.span, fluent::lint::fail_label)
|
||||
.span_label(success_order_arg.span, fluent::lint::success_label)
|
||||
.span_suggestion_short(
|
||||
success_order_arg.span,
|
||||
fluent::lint::suggestion,
|
||||
format!("std::sync::atomic::Ordering::{success_suggestion}"),
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}
|
|||
use rustc_ast as ast;
|
||||
use rustc_ast::util::{classify, parser};
|
||||
use rustc_ast::{ExprKind, StmtKind};
|
||||
use rustc_errors::{pluralize, Applicability, MultiSpan};
|
||||
use rustc_errors::{fluent, pluralize, Applicability, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
@ -155,22 +155,23 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
|
||||
if let Some(must_use_op) = must_use_op {
|
||||
cx.struct_span_lint(UNUSED_MUST_USE, expr.span, |lint| {
|
||||
let mut lint = lint.build(&format!("unused {} that must be used", must_use_op));
|
||||
lint.span_label(expr.span, &format!("the {} produces a value", must_use_op));
|
||||
lint.span_suggestion_verbose(
|
||||
expr.span.shrink_to_lo(),
|
||||
"use `let _ = ...` to ignore the resulting value",
|
||||
"let _ = ",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
lint.emit();
|
||||
lint.build(fluent::lint::unused_op)
|
||||
.set_arg("op", must_use_op)
|
||||
.span_label(expr.span, fluent::lint::label)
|
||||
.span_suggestion_verbose(
|
||||
expr.span.shrink_to_lo(),
|
||||
fluent::lint::suggestion,
|
||||
"let _ = ",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
op_warned = true;
|
||||
}
|
||||
|
||||
if !(type_permits_lack_of_use || fn_warned || op_warned) {
|
||||
cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| {
|
||||
lint.build(&format!("unused result of type `{}`", ty)).emit();
|
||||
lint.build(fluent::lint::unused_result).set_arg("ty", ty).emit();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -267,23 +268,27 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
},
|
||||
ty::Closure(..) => {
|
||||
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
|
||||
let mut err = lint.build(&format!(
|
||||
"unused {}closure{}{} that must be used",
|
||||
descr_pre, plural_suffix, descr_post,
|
||||
));
|
||||
err.note("closures are lazy and do nothing unless called");
|
||||
err.emit();
|
||||
// FIXME(davidtwco): this isn't properly translatable becauses of the
|
||||
// pre/post strings
|
||||
lint.build(fluent::lint::unused_closure)
|
||||
.set_arg("count", plural_len)
|
||||
.set_arg("pre", descr_pre)
|
||||
.set_arg("post", descr_post)
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
true
|
||||
}
|
||||
ty::Generator(..) => {
|
||||
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
|
||||
let mut err = lint.build(&format!(
|
||||
"unused {}generator{}{} that must be used",
|
||||
descr_pre, plural_suffix, descr_post,
|
||||
));
|
||||
err.note("generators are lazy and do nothing unless resumed");
|
||||
err.emit();
|
||||
// FIXME(davidtwco): this isn't properly translatable becauses of the
|
||||
// pre/post strings
|
||||
lint.build(fluent::lint::unused_generator)
|
||||
.set_arg("count", plural_len)
|
||||
.set_arg("pre", descr_pre)
|
||||
.set_arg("post", descr_post)
|
||||
.note(fluent::lint::note)
|
||||
.emit();
|
||||
});
|
||||
true
|
||||
}
|
||||
|
@ -305,13 +310,12 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
) -> bool {
|
||||
if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) {
|
||||
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
|
||||
let msg = format!(
|
||||
"unused {}`{}`{} that must be used",
|
||||
descr_pre_path,
|
||||
cx.tcx.def_path_str(def_id),
|
||||
descr_post_path
|
||||
);
|
||||
let mut err = lint.build(&msg);
|
||||
// FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
|
||||
// strings
|
||||
let mut err = lint.build(fluent::lint::unused_def);
|
||||
err.set_arg("pre", descr_pre_path);
|
||||
err.set_arg("post", descr_post_path);
|
||||
err.set_arg("def", cx.tcx.def_path_str(def_id));
|
||||
// check for #[must_use = "..."]
|
||||
if let Some(note) = attr.value_str() {
|
||||
err.note(note.as_str());
|
||||
|
@ -356,20 +360,20 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
|
|||
cx.struct_span_lint(PATH_STATEMENTS, s.span, |lint| {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if ty.needs_drop(cx.tcx, cx.param_env) {
|
||||
let mut lint = lint.build("path statement drops value");
|
||||
let mut lint = lint.build(fluent::lint::path_statement_drop);
|
||||
if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) {
|
||||
lint.span_suggestion(
|
||||
s.span,
|
||||
"use `drop` to clarify the intent",
|
||||
fluent::lint::suggestion,
|
||||
format!("drop({});", snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
lint.span_help(s.span, "use `drop` to clarify the intent");
|
||||
lint.span_help(s.span, fluent::lint::suggestion);
|
||||
}
|
||||
lint.emit();
|
||||
} else {
|
||||
lint.build("path statement with no effect").emit();
|
||||
lint.build(fluent::lint::path_statement_no_effect).emit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -540,15 +544,19 @@ trait UnusedDelimLint {
|
|||
}
|
||||
|
||||
cx.struct_span_lint(self.lint(), MultiSpan::from(vec![spans.0, spans.1]), |lint| {
|
||||
let span_msg = format!("unnecessary {} around {}", Self::DELIM_STR, msg);
|
||||
let mut err = lint.build(&span_msg);
|
||||
let replacement = vec![
|
||||
(spans.0, if keep_space.0 { " ".into() } else { "".into() }),
|
||||
(spans.1, if keep_space.1 { " ".into() } else { "".into() }),
|
||||
];
|
||||
let suggestion = format!("remove these {}", Self::DELIM_STR);
|
||||
err.multipart_suggestion(&suggestion, replacement, Applicability::MachineApplicable);
|
||||
err.emit();
|
||||
lint.build(fluent::lint::unused_delim)
|
||||
.set_arg("delim", Self::DELIM_STR)
|
||||
.set_arg("item", msg)
|
||||
.multipart_suggestion(
|
||||
fluent::lint::suggestion,
|
||||
replacement,
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1110,7 +1118,7 @@ impl UnusedImportBraces {
|
|||
};
|
||||
|
||||
cx.struct_span_lint(UNUSED_IMPORT_BRACES, item.span, |lint| {
|
||||
lint.build(&format!("braces around {} is unnecessary", node_name)).emit();
|
||||
lint.build(fluent::lint::unused_import_braces).set_arg("node", node_name).emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1161,15 +1169,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
|
|||
for adj in cx.typeck_results().expr_adjustments(e) {
|
||||
if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind {
|
||||
cx.struct_span_lint(UNUSED_ALLOCATION, e.span, |lint| {
|
||||
let msg = match m {
|
||||
adjustment::AutoBorrowMutability::Not => {
|
||||
"unnecessary allocation, use `&` instead"
|
||||
}
|
||||
lint.build(match m {
|
||||
adjustment::AutoBorrowMutability::Not => fluent::lint::unused_allocation,
|
||||
adjustment::AutoBorrowMutability::Mut { .. } => {
|
||||
"unnecessary allocation, use `&mut` instead"
|
||||
fluent::lint::unused_allocation_mut
|
||||
}
|
||||
};
|
||||
lint.build(msg).emit();
|
||||
})
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@ use std::cmp;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_errors::{
|
||||
Diagnostic, DiagnosticBuilder, DiagnosticId, EmissionGuarantee, ErrorGuaranteed, MultiSpan,
|
||||
Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee,
|
||||
ErrorGuaranteed, MultiSpan,
|
||||
};
|
||||
use rustc_hir::HirId;
|
||||
use rustc_index::vec::IndexVec;
|
||||
|
@ -231,7 +232,7 @@ pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a,
|
|||
|
||||
impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> {
|
||||
/// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`.
|
||||
pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, G> {
|
||||
pub fn build(mut self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'a, G> {
|
||||
self.0.set_primary_message(msg);
|
||||
self.0.set_is_lint();
|
||||
self.0
|
||||
|
|
|
@ -611,6 +611,12 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl rustc_errors::IntoDiagnosticArg for Predicate<'_> {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable)]
|
||||
pub enum PredicateKind<'tcx> {
|
||||
|
|
|
@ -550,7 +550,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
|||
id,
|
||||
span,
|
||||
|lint| {
|
||||
lint.build(&msg).emit();
|
||||
lint.build(msg).emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1163,7 +1163,7 @@ impl CheckAttrVisitor<'_> {
|
|||
hir_id,
|
||||
meta.span(),
|
||||
|lint| {
|
||||
lint.build(&"invalid `doc` attribute").emit();
|
||||
lint.build("invalid `doc` attribute").emit();
|
||||
},
|
||||
);
|
||||
is_valid = false;
|
||||
|
|
|
@ -2356,6 +2356,9 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
|
|||
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
|
||||
/// with the argument order swapped.
|
||||
///
|
||||
/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
|
||||
/// requirements of `T`. The initialization state is preserved exactly.
|
||||
///
|
||||
/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
|
||||
///
|
||||
/// # Safety
|
||||
|
@ -2461,6 +2464,9 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
|
|||
/// order swapped. Copying takes place as if the bytes were copied from `src`
|
||||
/// to a temporary array and then copied from the array to `dst`.
|
||||
///
|
||||
/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
|
||||
/// requirements of `T`. The initialization state is preserved exactly.
|
||||
///
|
||||
/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
|
||||
///
|
||||
/// # Safety
|
||||
|
|
|
@ -730,7 +730,7 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
|
|||
/// Swaps the values at two mutable locations of the same type, without
|
||||
/// deinitializing either.
|
||||
///
|
||||
/// But for the following two exceptions, this function is semantically
|
||||
/// But for the following exceptions, this function is semantically
|
||||
/// equivalent to [`mem::swap`]:
|
||||
///
|
||||
/// * It operates on raw pointers instead of references. When references are
|
||||
|
@ -740,6 +740,9 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
|
|||
/// overlapping region of memory from `x` will be used. This is demonstrated
|
||||
/// in the second example below.
|
||||
///
|
||||
/// * The operation is "untyped" in the sense that data may be uninitialized or otherwise violate
|
||||
/// the requirements of `T`. The initialization state is preserved exactly.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
|
@ -816,6 +819,9 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
|
|||
/// Swaps `count * size_of::<T>()` bytes between the two regions of memory
|
||||
/// beginning at `x` and `y`. The two regions must *not* overlap.
|
||||
///
|
||||
/// The operation is "untyped" in the sense that data may be uninitialized or otherwise violate the
|
||||
/// requirements of `T`. The initialization state is preserved exactly.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
|
@ -861,15 +867,15 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
|
|||
if mem::align_of::<T>() >= mem::align_of::<$ChunkTy>()
|
||||
&& mem::size_of::<T>() % mem::size_of::<$ChunkTy>() == 0
|
||||
{
|
||||
let x: *mut MaybeUninit<$ChunkTy> = x.cast();
|
||||
let y: *mut MaybeUninit<$ChunkTy> = y.cast();
|
||||
let x: *mut $ChunkTy = x.cast();
|
||||
let y: *mut $ChunkTy = y.cast();
|
||||
let count = count * (mem::size_of::<T>() / mem::size_of::<$ChunkTy>());
|
||||
// SAFETY: these are the same bytes that the caller promised were
|
||||
// ok, just typed as `MaybeUninit<ChunkTy>`s instead of as `T`s.
|
||||
// The `if` condition above ensures that we're not violating
|
||||
// alignment requirements, and that the division is exact so
|
||||
// that we don't lose any bytes off the end.
|
||||
return unsafe { swap_nonoverlapping_simple(x, y, count) };
|
||||
return unsafe { swap_nonoverlapping_simple_untyped(x, y, count) };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -902,7 +908,7 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
|
|||
}
|
||||
|
||||
// SAFETY: Same preconditions as this function
|
||||
unsafe { swap_nonoverlapping_simple(x, y, count) }
|
||||
unsafe { swap_nonoverlapping_simple_untyped(x, y, count) }
|
||||
}
|
||||
|
||||
/// Same behaviour and safety conditions as [`swap_nonoverlapping`]
|
||||
|
@ -911,17 +917,17 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
|
|||
/// `swap_nonoverlapping` tries to use) so no need to manually SIMD it.
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
|
||||
const unsafe fn swap_nonoverlapping_simple<T>(x: *mut T, y: *mut T, count: usize) {
|
||||
const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, count: usize) {
|
||||
let x = x.cast::<MaybeUninit<T>>();
|
||||
let y = y.cast::<MaybeUninit<T>>();
|
||||
let mut i = 0;
|
||||
while i < count {
|
||||
let x: &mut T =
|
||||
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
|
||||
unsafe { &mut *x.add(i) };
|
||||
let y: &mut T =
|
||||
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
|
||||
// and it's distinct from `x` since the ranges are non-overlapping
|
||||
unsafe { &mut *y.add(i) };
|
||||
mem::swap_simple(x, y);
|
||||
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
|
||||
let x = unsafe { &mut *x.add(i) };
|
||||
// SAFETY: By precondition, `i` is in-bounds because it's below `n`
|
||||
// and it's distinct from `x` since the ranges are non-overlapping
|
||||
let y = unsafe { &mut *y.add(i) };
|
||||
mem::swap_simple::<MaybeUninit<T>>(x, y);
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
|
|
@ -781,6 +781,31 @@ fn nonnull_tagged_pointer_with_provenance() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn swap_copy_untyped() {
|
||||
// We call `{swap,copy}{,_nonoverlapping}` at `bool` type on data that is not a valid bool.
|
||||
// These should all do untyped copies, so this should work fine.
|
||||
let mut x = 5u8;
|
||||
let mut y = 6u8;
|
||||
|
||||
let ptr1 = &mut x as *mut u8 as *mut bool;
|
||||
let ptr2 = &mut y as *mut u8 as *mut bool;
|
||||
|
||||
unsafe {
|
||||
ptr::swap(ptr1, ptr2);
|
||||
ptr::swap_nonoverlapping(ptr1, ptr2, 1);
|
||||
}
|
||||
assert_eq!(x, 5);
|
||||
assert_eq!(y, 6);
|
||||
|
||||
unsafe {
|
||||
ptr::copy(ptr1, ptr2, 1);
|
||||
ptr::copy_nonoverlapping(ptr1, ptr2, 1);
|
||||
}
|
||||
assert_eq!(x, 5);
|
||||
assert_eq!(y, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_const_copy() {
|
||||
const {
|
||||
|
|
|
@ -1739,6 +1739,11 @@ details.rustdoc-toggle[open] > summary.hideme::after {
|
|||
|
||||
/* Media Queries */
|
||||
|
||||
/*
|
||||
WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY;
|
||||
If you update this line, then you also need to update the line with the same warning
|
||||
in storage.js plus the media query with (max-width: 700px)
|
||||
*/
|
||||
@media (min-width: 701px) {
|
||||
/* In case there is no documentation before a code block, we need to add some margin at the top
|
||||
to prevent an overlay between the "collapse toggle" and the information tooltip.
|
||||
|
@ -1759,6 +1764,11 @@ details.rustdoc-toggle[open] > summary.hideme::after {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
|
||||
If you update this line, then you also need to update the line with the same warning
|
||||
in storage.js plus the media query with (min-width: 701px)
|
||||
*/
|
||||
@media (max-width: 700px) {
|
||||
/* When linking to an item with an `id` (for instance, by clicking a link in the sidebar,
|
||||
or visiting a URL with a fragment like `#method.new`, we don't want the item to be obscured
|
||||
|
|
|
@ -12,6 +12,12 @@
|
|||
const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value;
|
||||
let oldScrollPosition = 0;
|
||||
|
||||
function closeSidebarIfMobile() {
|
||||
if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
|
||||
updateLocalStorage("source-sidebar-show", "false");
|
||||
}
|
||||
}
|
||||
|
||||
function createDirEntry(elem, parent, fullPath, hasFoundFile) {
|
||||
const dirEntry = document.createElement("details");
|
||||
const summary = document.createElement("summary");
|
||||
|
@ -42,6 +48,7 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
|
|||
const file = document.createElement("a");
|
||||
file.innerText = file_text;
|
||||
file.href = rootPath + "src/" + fullPath + file_text + ".html";
|
||||
file.addEventListener("click", closeSidebarIfMobile);
|
||||
const w = window.location.href.split("#")[0];
|
||||
if (!hasFoundFile && w === file.href) {
|
||||
file.className = "selected";
|
||||
|
@ -59,7 +66,7 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
|
|||
function toggleSidebar() {
|
||||
const child = this.parentNode.children[0];
|
||||
if (child.innerText === ">") {
|
||||
if (window.innerWidth < 701) {
|
||||
if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
|
||||
// This is to keep the scroll position on mobile.
|
||||
oldScrollPosition = window.scrollY;
|
||||
document.body.style.position = "fixed";
|
||||
|
@ -69,7 +76,7 @@ function toggleSidebar() {
|
|||
child.innerText = "<";
|
||||
updateLocalStorage("source-sidebar-show", "true");
|
||||
} else {
|
||||
if (window.innerWidth < 701) {
|
||||
if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) {
|
||||
// This is to keep the scroll position on mobile.
|
||||
document.body.style.position = "";
|
||||
document.body.style.top = "";
|
||||
|
|
|
@ -9,6 +9,11 @@ const darkThemes = ["dark", "ayu"];
|
|||
window.currentTheme = document.getElementById("themeStyle");
|
||||
window.mainTheme = document.getElementById("mainThemeStyle");
|
||||
|
||||
// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
|
||||
// If you update this line, then you also need to update the two media queries with the same
|
||||
// warning in rustdoc.css
|
||||
window.RUSTDOC_MOBILE_BREAKPOINT = 701;
|
||||
|
||||
const settingsDataset = (function() {
|
||||
const settingsElement = document.getElementById("default-settings");
|
||||
if (settingsElement === null) {
|
||||
|
|
|
@ -18,6 +18,17 @@ click: "#sidebar-toggle"
|
|||
// Because of the transition CSS, we check by using `wait-for-css` instead of `assert-css`.
|
||||
wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
|
||||
|
||||
// We now check that opening the sidebar and clicking a link will leave it open.
|
||||
// The behavior here on desktop is different than the behavior on mobile,
|
||||
// but since the sidebar doesn't fill the entire screen here, it makes sense to have the
|
||||
// sidebar stay resident.
|
||||
wait-for-css: (".sidebar", {"width": "300px"})
|
||||
assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
|
||||
click: ".sidebar a.selected"
|
||||
goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
|
||||
wait-for-css: (".sidebar", {"width": "300px"})
|
||||
assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
|
||||
|
||||
// Now we check the display of the sidebar items.
|
||||
show-text: true
|
||||
|
||||
|
@ -221,3 +232,23 @@ click: "#sidebar-toggle"
|
|||
wait-for-css: (".sidebar", {"width": "0px"})
|
||||
// The "scrollTop" property should be the same.
|
||||
assert-window-property: {"pageYOffset": "2519"}
|
||||
|
||||
// We now check that opening the sidebar and clicking a link will close it.
|
||||
// The behavior here on mobile is different than the behavior on desktop,
|
||||
// but common sense dictates that if you have a list of files that fills the entire screen, and
|
||||
// you click one of them, you probably want to actually see the file's contents, and not just
|
||||
// make it the current selection.
|
||||
click: "#sidebar-toggle"
|
||||
wait-for-css: ("#source-sidebar", {"visibility": "visible"})
|
||||
assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
|
||||
click: ".sidebar a.selected"
|
||||
goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
|
||||
wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
|
||||
assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
|
||||
// Resize back to desktop size, to check that the sidebar doesn't spontaneously open.
|
||||
size: (1000, 1000)
|
||||
wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
|
||||
assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
|
||||
click: "#sidebar-toggle"
|
||||
wait-for-css: ("#source-sidebar", {"visibility": "visible"})
|
||||
assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
|
||||
|
|
|
@ -5,21 +5,11 @@
|
|||
extern crate inner;
|
||||
|
||||
/// [mod@std::env] [g]
|
||||
|
||||
// FIXME: This can't be tested because rustdoc doesn't show documentation on pub re-exports.
|
||||
// Until then, comment out the `htmldocck` test.
|
||||
// This test still does something; namely check that no incorrect errors are emitted when
|
||||
// documenting the re-export.
|
||||
|
||||
// @has outer/index.html
|
||||
// @ has - '//a[@href="{{channel}}/std/env/fn.var.html"]' "std::env"
|
||||
// @ has - '//a[@href="fn.f.html"]' "g"
|
||||
// @has - '//a[@href="{{channel}}/std/env/index.html"]' "std::env"
|
||||
// @has - '//a[@href="fn.f.html"]' "g"
|
||||
pub use f as g;
|
||||
|
||||
// FIXME: same as above
|
||||
/// [std::env]
|
||||
extern crate self as _;
|
||||
|
||||
// Make sure the documentation is actually correct by documenting an inlined re-export
|
||||
/// [mod@std::env]
|
||||
// @has outer/fn.f.html
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: Found non-existing keyword `tadam` used in `#[doc(keyword = "...")]`
|
||||
error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]`
|
||||
--> $DIR/existing_doc_keyword.rs:10:1
|
||||
|
|
||||
LL | #[doc(keyword = "tadam")]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// check-fail
|
||||
// Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
|
||||
|
||||
// normalize-stderr-test "the following other types implement trait `IntoDiagnosticArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr"
|
||||
|
||||
// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
|
||||
// changing the output of this test. Since SessionDiagnostic is strictly internal to the compiler
|
||||
// the test is just ignored on stable and beta:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: `#[derive(SessionDiagnostic)]` can only be used on structs
|
||||
--> $DIR/diagnostic-derive.rs:37:1
|
||||
--> $DIR/diagnostic-derive.rs:39:1
|
||||
|
|
||||
LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
LL | |
|
||||
|
@ -10,13 +10,13 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: `#[error = ...]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:46:1
|
||||
--> $DIR/diagnostic-derive.rs:48:1
|
||||
|
|
||||
LL | #[error = "E0123"]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[nonsense(...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:51:1
|
||||
--> $DIR/diagnostic-derive.rs:53:1
|
||||
|
|
||||
LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -24,7 +24,7 @@ LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
|||
= help: only `error`, `warning`, `help` and `note` are valid attributes
|
||||
|
||||
error: diagnostic kind not specified
|
||||
--> $DIR/diagnostic-derive.rs:51:1
|
||||
--> $DIR/diagnostic-derive.rs:53:1
|
||||
|
|
||||
LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
LL | |
|
||||
|
@ -36,7 +36,7 @@ LL | | struct InvalidStructAttr {}
|
|||
= help: use the `#[error(...)]` attribute to create an error
|
||||
|
||||
error: `#[error("...")]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:58:9
|
||||
--> $DIR/diagnostic-derive.rs:60:9
|
||||
|
|
||||
LL | #[error("E0123")]
|
||||
| ^^^^^^^
|
||||
|
@ -44,7 +44,7 @@ LL | #[error("E0123")]
|
|||
= help: first argument of the attribute should be the diagnostic slug
|
||||
|
||||
error: diagnostic slug not specified
|
||||
--> $DIR/diagnostic-derive.rs:58:1
|
||||
--> $DIR/diagnostic-derive.rs:60:1
|
||||
|
|
||||
LL | / #[error("E0123")]
|
||||
LL | |
|
||||
|
@ -55,7 +55,7 @@ LL | | struct InvalidLitNestedAttr {}
|
|||
= help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
|
||||
|
||||
error: `#[error(nonsense(...))]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:69:9
|
||||
--> $DIR/diagnostic-derive.rs:71:9
|
||||
|
|
||||
LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
@ -63,7 +63,7 @@ LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")]
|
|||
= help: first argument of the attribute should be the diagnostic slug
|
||||
|
||||
error: diagnostic slug not specified
|
||||
--> $DIR/diagnostic-derive.rs:69:1
|
||||
--> $DIR/diagnostic-derive.rs:71:1
|
||||
|
|
||||
LL | / #[error(nonsense("foo"), code = "E0123", slug = "foo")]
|
||||
LL | |
|
||||
|
@ -74,7 +74,7 @@ LL | | struct InvalidNestedStructAttr1 {}
|
|||
= help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
|
||||
|
||||
error: `#[error(nonsense = ...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:75:9
|
||||
--> $DIR/diagnostic-derive.rs:77:9
|
||||
|
|
||||
LL | #[error(nonsense = "...", code = "E0123", slug = "foo")]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
@ -82,7 +82,7 @@ LL | #[error(nonsense = "...", code = "E0123", slug = "foo")]
|
|||
= help: first argument of the attribute should be the diagnostic slug
|
||||
|
||||
error: diagnostic slug not specified
|
||||
--> $DIR/diagnostic-derive.rs:75:1
|
||||
--> $DIR/diagnostic-derive.rs:77:1
|
||||
|
|
||||
LL | / #[error(nonsense = "...", code = "E0123", slug = "foo")]
|
||||
LL | |
|
||||
|
@ -93,7 +93,7 @@ LL | | struct InvalidNestedStructAttr2 {}
|
|||
= help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
|
||||
|
||||
error: `#[error(nonsense = ...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:81:9
|
||||
--> $DIR/diagnostic-derive.rs:83:9
|
||||
|
|
||||
LL | #[error(nonsense = 4, code = "E0123", slug = "foo")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -101,7 +101,7 @@ LL | #[error(nonsense = 4, code = "E0123", slug = "foo")]
|
|||
= help: first argument of the attribute should be the diagnostic slug
|
||||
|
||||
error: diagnostic slug not specified
|
||||
--> $DIR/diagnostic-derive.rs:81:1
|
||||
--> $DIR/diagnostic-derive.rs:83:1
|
||||
|
|
||||
LL | / #[error(nonsense = 4, code = "E0123", slug = "foo")]
|
||||
LL | |
|
||||
|
@ -112,7 +112,7 @@ LL | | struct InvalidNestedStructAttr3 {}
|
|||
= help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
|
||||
|
||||
error: `#[error(slug = ...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:87:59
|
||||
--> $DIR/diagnostic-derive.rs:89:59
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -120,103 +120,103 @@ LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
|
|||
= help: only `code` is a valid nested attributes following the slug
|
||||
|
||||
error: `#[suggestion = ...]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:94:5
|
||||
--> $DIR/diagnostic-derive.rs:96:5
|
||||
|
|
||||
LL | #[suggestion = "bar"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:101:1
|
||||
--> $DIR/diagnostic-derive.rs:103:1
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:100:1
|
||||
--> $DIR/diagnostic-derive.rs:102:1
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:101:1
|
||||
--> $DIR/diagnostic-derive.rs:103:1
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:100:1
|
||||
--> $DIR/diagnostic-derive.rs:102:1
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:101:50
|
||||
--> $DIR/diagnostic-derive.rs:103:50
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:100:50
|
||||
--> $DIR/diagnostic-derive.rs:102:50
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:109:1
|
||||
--> $DIR/diagnostic-derive.rs:111:1
|
||||
|
|
||||
LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:108:1
|
||||
--> $DIR/diagnostic-derive.rs:110:1
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:109:1
|
||||
--> $DIR/diagnostic-derive.rs:111:1
|
||||
|
|
||||
LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:108:1
|
||||
--> $DIR/diagnostic-derive.rs:110:1
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:109:52
|
||||
--> $DIR/diagnostic-derive.rs:111:52
|
||||
|
|
||||
LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:108:50
|
||||
--> $DIR/diagnostic-derive.rs:110:50
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:116:66
|
||||
--> $DIR/diagnostic-derive.rs:118:66
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:116:50
|
||||
--> $DIR/diagnostic-derive.rs:118:50
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
|
||||
| ^^^^^^^
|
||||
|
||||
error: `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:121:43
|
||||
--> $DIR/diagnostic-derive.rs:123:43
|
||||
|
|
||||
LL | #[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: diagnostic kind not specified
|
||||
--> $DIR/diagnostic-derive.rs:126:1
|
||||
--> $DIR/diagnostic-derive.rs:128:1
|
||||
|
|
||||
LL | struct KindNotProvided {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -224,7 +224,7 @@ LL | struct KindNotProvided {}
|
|||
= help: use the `#[error(...)]` attribute to create an error
|
||||
|
||||
error: diagnostic slug not specified
|
||||
--> $DIR/diagnostic-derive.rs:129:1
|
||||
--> $DIR/diagnostic-derive.rs:131:1
|
||||
|
|
||||
LL | / #[error(code = "E0456")]
|
||||
LL | |
|
||||
|
@ -234,13 +234,13 @@ LL | | struct SlugNotProvided {}
|
|||
= help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
|
||||
|
||||
error: the `#[primary_span]` attribute can only be applied to fields of type `Span`
|
||||
--> $DIR/diagnostic-derive.rs:140:5
|
||||
--> $DIR/diagnostic-derive.rs:142:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[nonsense]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:148:5
|
||||
--> $DIR/diagnostic-derive.rs:150:5
|
||||
|
|
||||
LL | #[nonsense]
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -248,19 +248,19 @@ LL | #[nonsense]
|
|||
= help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes
|
||||
|
||||
error: the `#[label(...)]` attribute can only be applied to fields of type `Span`
|
||||
--> $DIR/diagnostic-derive.rs:165:5
|
||||
--> $DIR/diagnostic-derive.rs:167:5
|
||||
|
|
||||
LL | #[label(typeck::label)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `name` doesn't refer to a field on this type
|
||||
--> $DIR/diagnostic-derive.rs:173:45
|
||||
--> $DIR/diagnostic-derive.rs:175:45
|
||||
|
|
||||
LL | #[suggestion(typeck::suggestion, code = "{name}")]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: invalid format string: expected `'}'` but string was terminated
|
||||
--> $DIR/diagnostic-derive.rs:178:16
|
||||
--> $DIR/diagnostic-derive.rs:180:16
|
||||
|
|
||||
LL | #[derive(SessionDiagnostic)]
|
||||
| - ^ expected `'}'` in format string
|
||||
|
@ -271,7 +271,7 @@ LL | #[derive(SessionDiagnostic)]
|
|||
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: invalid format string: unmatched `}` found
|
||||
--> $DIR/diagnostic-derive.rs:188:15
|
||||
--> $DIR/diagnostic-derive.rs:190:15
|
||||
|
|
||||
LL | #[derive(SessionDiagnostic)]
|
||||
| ^ unmatched `}` in format string
|
||||
|
@ -280,13 +280,13 @@ LL | #[derive(SessionDiagnostic)]
|
|||
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: the `#[label(...)]` attribute can only be applied to fields of type `Span`
|
||||
--> $DIR/diagnostic-derive.rs:208:5
|
||||
--> $DIR/diagnostic-derive.rs:210:5
|
||||
|
|
||||
LL | #[label(typeck::label)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion(nonsense = ...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:233:18
|
||||
--> $DIR/diagnostic-derive.rs:235:18
|
||||
|
|
||||
LL | #[suggestion(nonsense = "bar")]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
@ -294,7 +294,7 @@ LL | #[suggestion(nonsense = "bar")]
|
|||
= help: only `message`, `code` and `applicability` are valid field attributes
|
||||
|
||||
error: `#[suggestion(msg = ...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:241:18
|
||||
--> $DIR/diagnostic-derive.rs:243:18
|
||||
|
|
||||
LL | #[suggestion(msg = "bar")]
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -302,7 +302,7 @@ LL | #[suggestion(msg = "bar")]
|
|||
= help: only `message`, `code` and `applicability` are valid field attributes
|
||||
|
||||
error: wrong field type for suggestion
|
||||
--> $DIR/diagnostic-derive.rs:263:5
|
||||
--> $DIR/diagnostic-derive.rs:265:5
|
||||
|
|
||||
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
|
||||
LL | |
|
||||
|
@ -312,7 +312,7 @@ LL | | suggestion: Applicability,
|
|||
= help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
|
||||
|
||||
error: type of field annotated with `#[suggestion(...)]` contains more than one `Span`
|
||||
--> $DIR/diagnostic-derive.rs:278:5
|
||||
--> $DIR/diagnostic-derive.rs:280:5
|
||||
|
|
||||
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
|
||||
LL | |
|
||||
|
@ -320,7 +320,7 @@ LL | | suggestion: (Span, Span, Applicability),
|
|||
| |___________________________________________^
|
||||
|
||||
error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
|
||||
--> $DIR/diagnostic-derive.rs:286:5
|
||||
--> $DIR/diagnostic-derive.rs:288:5
|
||||
|
|
||||
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
|
||||
LL | |
|
||||
|
@ -328,72 +328,66 @@ LL | | suggestion: (Applicability, Applicability, Span),
|
|||
| |____________________________________________________^
|
||||
|
||||
error: `#[label = ...]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:294:5
|
||||
--> $DIR/diagnostic-derive.rs:296:5
|
||||
|
|
||||
LL | #[label = "bar"]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: applicability cannot be set in both the field and attribute
|
||||
--> $DIR/diagnostic-derive.rs:445:52
|
||||
--> $DIR/diagnostic-derive.rs:447:52
|
||||
|
|
||||
LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid applicability
|
||||
--> $DIR/diagnostic-derive.rs:453:52
|
||||
--> $DIR/diagnostic-derive.rs:455:52
|
||||
|
|
||||
LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[label(...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:516:5
|
||||
--> $DIR/diagnostic-derive.rs:518:5
|
||||
|
|
||||
LL | #[label(typeck::label, foo)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[label(...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:524:5
|
||||
--> $DIR/diagnostic-derive.rs:526:5
|
||||
|
|
||||
LL | #[label(typeck::label, foo = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[label(...)]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:532:5
|
||||
--> $DIR/diagnostic-derive.rs:534:5
|
||||
|
|
||||
LL | #[label(typeck::label, foo("..."))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `nonsense` in this scope
|
||||
--> $DIR/diagnostic-derive.rs:51:3
|
||||
--> $DIR/diagnostic-derive.rs:53:3
|
||||
|
|
||||
LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: cannot find attribute `nonsense` in this scope
|
||||
--> $DIR/diagnostic-derive.rs:148:7
|
||||
--> $DIR/diagnostic-derive.rs:150:7
|
||||
|
|
||||
LL | #[nonsense]
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent`
|
||||
--> $DIR/diagnostic-derive.rs:64:9
|
||||
--> $DIR/diagnostic-derive.rs:66:9
|
||||
|
|
||||
LL | #[error(nonsense, code = "E0123")]
|
||||
| ^^^^^^^^ not found in `rustc_errors::fluent`
|
||||
|
||||
error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
|
||||
--> $DIR/diagnostic-derive.rs:338:10
|
||||
--> $DIR/diagnostic-derive.rs:340:10
|
||||
|
|
||||
LL | #[derive(SessionDiagnostic)]
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
|
||||
|
|
||||
= help: the following other types implement trait `IntoDiagnosticArg`:
|
||||
&'a str
|
||||
Ident
|
||||
String
|
||||
Symbol
|
||||
rustc_middle::ty::Ty<'tcx>
|
||||
usize
|
||||
= help: normalized in stderr
|
||||
note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:538:19
|
||||
|
|
||||
|
|
|
@ -5,9 +5,9 @@ LL | panic!({ "foo" });
|
|||
| ^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(non_fmt_panics)]` on by default
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!("{}", { "foo" });
|
||||
| +++++
|
||||
|
|
|
@ -73,9 +73,9 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, S);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | assert!(false, "{}", S);
|
||||
| +++++
|
||||
|
@ -86,9 +86,9 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, 123);
|
||||
| ^^^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | assert!(false, "{}", 123);
|
||||
| +++++
|
||||
|
@ -99,9 +99,9 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, Some(123));
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{:?}" format string to use the Debug implementation of `Option<i32>`
|
||||
help: add a "{:?}" format string to use the `Debug` implementation of `Option<i32>`
|
||||
|
|
||||
LL | assert!(false, "{:?}", Some(123));
|
||||
| +++++++
|
||||
|
@ -124,9 +124,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(C);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!("{}", C);
|
||||
| +++++
|
||||
|
@ -137,9 +137,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(S);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!("{}", S);
|
||||
| +++++
|
||||
|
@ -150,9 +150,9 @@ warning: panic message is not a string literal
|
|||
LL | unreachable!(S);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | unreachable!("{}", S);
|
||||
| +++++
|
||||
|
@ -163,9 +163,9 @@ warning: panic message is not a string literal
|
|||
LL | unreachable!(S);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | unreachable!("{}", S);
|
||||
| +++++
|
||||
|
@ -176,9 +176,9 @@ warning: panic message is not a string literal
|
|||
LL | std::panic!(123);
|
||||
| ^^^
|
||||
|
|
||||
= note: this usage of std::panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `std::panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | std::panic!("{}", 123);
|
||||
| +++++
|
||||
|
@ -193,9 +193,9 @@ warning: panic message is not a string literal
|
|||
LL | core::panic!(&*"abc");
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: this usage of core::panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `core::panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | core::panic!("{}", &*"abc");
|
||||
| +++++
|
||||
|
@ -206,9 +206,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(Some(123));
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{:?}" format string to use the Debug implementation of `Option<i32>`
|
||||
help: add a "{:?}" format string to use the `Debug` implementation of `Option<i32>`
|
||||
|
|
||||
LL | panic!("{:?}", Some(123));
|
||||
| +++++++
|
||||
|
@ -259,9 +259,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(a!());
|
||||
| ^^^^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!("{}", a!());
|
||||
| +++++
|
||||
|
@ -276,9 +276,9 @@ warning: panic message is not a string literal
|
|||
LL | unreachable!(a!());
|
||||
| ^^^^
|
||||
|
|
||||
= note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | unreachable!("{}", a!());
|
||||
| +++++
|
||||
|
@ -289,9 +289,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(format!("{}", 1));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: the panic!() macro supports formatting, so there's no need for the format!() macro here
|
||||
= note: the `panic!()` macro supports formatting, so there's no need for the `format!()` macro here
|
||||
help: remove the `format!(..)` macro call
|
||||
|
|
||||
LL - panic!(format!("{}", 1));
|
||||
|
@ -304,9 +304,9 @@ warning: panic message is not a string literal
|
|||
LL | unreachable!(format!("{}", 1));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: the unreachable!() macro supports formatting, so there's no need for the format!() macro here
|
||||
= note: the `unreachable!()` macro supports formatting, so there's no need for the `format!()` macro here
|
||||
help: remove the `format!(..)` macro call
|
||||
|
|
||||
LL - unreachable!(format!("{}", 1));
|
||||
|
@ -319,9 +319,9 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, format!("{}", 1));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: the assert!() macro supports formatting, so there's no need for the format!() macro here
|
||||
= note: the `assert!()` macro supports formatting, so there's no need for the `format!()` macro here
|
||||
help: remove the `format!(..)` macro call
|
||||
|
|
||||
LL - assert!(false, format!("{}", 1));
|
||||
|
@ -334,9 +334,9 @@ warning: panic message is not a string literal
|
|||
LL | debug_assert!(false, format!("{}", 1));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this usage of debug_assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `debug_assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
= note: the debug_assert!() macro supports formatting, so there's no need for the format!() macro here
|
||||
= note: the `debug_assert!()` macro supports formatting, so there's no need for the `format!()` macro here
|
||||
help: remove the `format!(..)` macro call
|
||||
|
|
||||
LL - debug_assert!(false, format!("{}", 1));
|
||||
|
@ -349,9 +349,9 @@ warning: panic message is not a string literal
|
|||
LL | panic![123];
|
||||
| ^^^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!["{}", 123];
|
||||
| +++++
|
||||
|
@ -366,9 +366,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!{123};
|
||||
| ^^^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!{"{}", 123};
|
||||
| +++++
|
||||
|
@ -385,7 +385,7 @@ LL | panic!(v);
|
|||
| |
|
||||
| help: use std::panic::panic_any instead: `std::panic::panic_any`
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
|
||||
warning: panic message is not a string literal
|
||||
|
@ -394,7 +394,7 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, v);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
|
||||
warning: panic message is not a string literal
|
||||
|
@ -403,9 +403,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(v);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{:?}" format string to use the Debug implementation of `T`
|
||||
help: add a "{:?}" format string to use the `Debug` implementation of `T`
|
||||
|
|
||||
LL | panic!("{:?}", v);
|
||||
| +++++++
|
||||
|
@ -420,9 +420,9 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, v);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{:?}" format string to use the Debug implementation of `T`
|
||||
help: add a "{:?}" format string to use the `Debug` implementation of `T`
|
||||
|
|
||||
LL | assert!(false, "{:?}", v);
|
||||
| +++++++
|
||||
|
@ -433,9 +433,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(v);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!("{}", v);
|
||||
| +++++
|
||||
|
@ -450,9 +450,9 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, v);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | assert!(false, "{}", v);
|
||||
| +++++
|
||||
|
@ -463,9 +463,9 @@ warning: panic message is not a string literal
|
|||
LL | panic!(v);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | panic!("{}", v);
|
||||
| +++++
|
||||
|
@ -480,9 +480,9 @@ warning: panic message is not a string literal
|
|||
LL | assert!(false, v);
|
||||
| ^
|
||||
|
|
||||
= note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021
|
||||
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
|
||||
help: add a "{}" format string to Display the message
|
||||
help: add a "{}" format string to `Display` the message
|
||||
|
|
||||
LL | assert!(false, "{}", v);
|
||||
| +++++
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b74e96f509baf0be70281c55f14cb18fefbc6b22
|
||||
Subproject commit 75b22326dad1914c22484ab6672de5cae94f7457
|
Loading…
Add table
Reference in a new issue