提交 54f79bab 编写于 作者: B bors

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
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 @@
// 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_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 @@ pub fn span_labels(
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(
......
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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
_ => 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,
);
......
此差异已折叠。
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();
});
}
......
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();
......
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 @@ fn lint_text_direction_codepoint(
.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 @@ fn lint_text_direction_codepoint(
// 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 @@ fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
_ => 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 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
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 @@ fn check_path(
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 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx>) {
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 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx>) {
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 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx>) {
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 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx Ty<'tcx>) {
}
_ => {}
}
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 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
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 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) {
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 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
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 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
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 @@ pub(crate) fn push(
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 @@ pub(crate) fn push(
} 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,
......
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();
});
}
}
......
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 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
}
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 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
.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 @@ enum ScriptSetUsage {
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(&note).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();
});
}
}
......
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,
);
......
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 @@ fn check_case(&self, cx: &EarlyContext<'_>, sort: &str, ident: &Ident) {
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 @@ fn is_snake_case(ident: &str) -> bool {
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 @@ fn is_snake_case(ident: &str) -> bool {
// 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 @@ fn is_snake_case(ident: &str) -> bool {
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 @@ fn check_upper_case(cx: &LateContext<'_>, sort: &str, ident: &Ident) {
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::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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
) {
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 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
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(&note).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();
});
}
}
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 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
}
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,
......
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();
});
}
}
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
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 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
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();
});
}
}
......
此差异已折叠。
......@@ -3,7 +3,7 @@
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 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
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 @@ fn check_must_use_ty<'tcx>(
},
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 @@ fn check_must_use_def(
) -> 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 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
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 @@ fn emit_unused_delims(
}
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 @@ fn check_use_tree(&self, cx: &EarlyContext<'_>, use_tree: &ast::UseTree, item: &
};
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 @@ fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) {
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 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 fn new(
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 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
}
}
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 @@ fn recur(
id,
span,
|lint| {
lint.build(&msg).emit();
lint.build(msg).emit();
},
);
}
......
......@@ -1163,7 +1163,7 @@ fn check_doc_attrs(
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(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
/// 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 fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *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 fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
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 fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
}
// 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 fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
/// `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 @@ pub fn set_tag(&mut self, data: usize) {
}
}
#[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
......
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")]
......
// 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:
......
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);
| +++++
......
Subproject commit b74e96f509baf0be70281c55f14cb18fefbc6b22
Subproject commit 75b22326dad1914c22484ab6672de5cae94f7457
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册