Auto merge of #110924 - matthiaskrgr:rollup-jvznpq2, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #110766 (More core::fmt::rt cleanup.) - #110873 (Migrate trivially translatable `rustc_parse` diagnostics) - #110904 (rustdoc: rebind bound vars to type-outlives predicates) - #110913 (Add some missing built-in lints) - #110918 (`remove_dir_all`: try deleting the directory even if `FILE_LIST_DIRECTORY` access is denied) - #110920 (Fix unavailable url) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2fce229086
@ -2976,7 +2976,7 @@ pub enum ItemKind {
|
||||
}
|
||||
|
||||
impl ItemKind {
|
||||
pub fn article(&self) -> &str {
|
||||
pub fn article(&self) -> &'static str {
|
||||
use ItemKind::*;
|
||||
match self {
|
||||
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
|
||||
@ -2985,7 +2985,7 @@ impl ItemKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn descr(&self) -> &str {
|
||||
pub fn descr(&self) -> &'static str {
|
||||
match self {
|
||||
ItemKind::ExternCrate(..) => "extern crate",
|
||||
ItemKind::Use(..) => "`use` import",
|
||||
|
@ -186,7 +186,7 @@ enum ArgumentType {
|
||||
/// Generates:
|
||||
///
|
||||
/// ```text
|
||||
/// <core::fmt::ArgumentV1>::new_…(arg)
|
||||
/// <core::fmt::Argument>::new_…(arg)
|
||||
/// ```
|
||||
fn make_argument<'hir>(
|
||||
ctx: &mut LoweringContext<'_, 'hir>,
|
||||
@ -327,7 +327,7 @@ fn make_format_spec<'hir>(
|
||||
None => sym::Unknown,
|
||||
},
|
||||
);
|
||||
// This needs to match `FlagV1` in library/core/src/fmt/mod.rs.
|
||||
// This needs to match `Flag` in library/core/src/fmt/rt.rs.
|
||||
let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
|
||||
| ((sign == Some(FormatSign::Minus)) as u32) << 1
|
||||
| (alternate as u32) << 2
|
||||
@ -438,7 +438,7 @@ fn expand_format_args<'hir>(
|
||||
// If the args array contains exactly all the original arguments once,
|
||||
// in order, we can use a simple array instead of a `match` construction.
|
||||
// However, if there's a yield point in any argument except the first one,
|
||||
// we don't do this, because an ArgumentV1 cannot be kept across yield points.
|
||||
// we don't do this, because an Argument cannot be kept across yield points.
|
||||
//
|
||||
// This is an optimization, speeding up compilation about 1-2% in some cases.
|
||||
// See https://github.com/rust-lang/rust/pull/106770#issuecomment-1380790609
|
||||
@ -449,9 +449,9 @@ fn expand_format_args<'hir>(
|
||||
let args = if use_simple_array {
|
||||
// Generate:
|
||||
// &[
|
||||
// <core::fmt::ArgumentV1>::new_display(&arg0),
|
||||
// <core::fmt::ArgumentV1>::new_lower_hex(&arg1),
|
||||
// <core::fmt::ArgumentV1>::new_debug(&arg2),
|
||||
// <core::fmt::Argument>::new_display(&arg0),
|
||||
// <core::fmt::Argument>::new_lower_hex(&arg1),
|
||||
// <core::fmt::Argument>::new_debug(&arg2),
|
||||
// …
|
||||
// ]
|
||||
let elements: Vec<_> = arguments
|
||||
@ -477,9 +477,9 @@ fn expand_format_args<'hir>(
|
||||
// Generate:
|
||||
// &match (&arg0, &arg1, &…) {
|
||||
// args => [
|
||||
// <core::fmt::ArgumentV1>::new_display(args.0),
|
||||
// <core::fmt::ArgumentV1>::new_lower_hex(args.1),
|
||||
// <core::fmt::ArgumentV1>::new_debug(args.0),
|
||||
// <core::fmt::Argument>::new_display(args.0),
|
||||
// <core::fmt::Argument>::new_lower_hex(args.1),
|
||||
// <core::fmt::Argument>::new_debug(args.0),
|
||||
// …
|
||||
// ]
|
||||
// }
|
||||
|
@ -296,7 +296,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
diag_trait(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, Some(span)));
|
||||
err
|
||||
}
|
||||
_ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => ccx
|
||||
_ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentMethods) => ccx
|
||||
.tcx
|
||||
.sess
|
||||
.create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind() }),
|
||||
|
@ -3273,110 +3273,115 @@ declare_lint_pass! {
|
||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||
/// that are used by other parts of the compiler.
|
||||
HardwiredLints => [
|
||||
FORBIDDEN_LINT_GROUPS,
|
||||
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
|
||||
// tidy-alphabetical-start
|
||||
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||
AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||
AMBIGUOUS_GLOB_REEXPORTS,
|
||||
ARITHMETIC_OVERFLOW,
|
||||
UNCONDITIONAL_PANIC,
|
||||
UNUSED_IMPORTS,
|
||||
UNUSED_EXTERN_CRATES,
|
||||
UNUSED_CRATE_DEPENDENCIES,
|
||||
UNUSED_QUALIFICATIONS,
|
||||
UNKNOWN_LINTS,
|
||||
UNFULFILLED_LINT_EXPECTATIONS,
|
||||
UNUSED_VARIABLES,
|
||||
UNUSED_ASSIGNMENTS,
|
||||
DEAD_CODE,
|
||||
UNREACHABLE_CODE,
|
||||
UNREACHABLE_PATTERNS,
|
||||
OVERLAPPING_RANGE_ENDPOINTS,
|
||||
ASM_SUB_REGISTER,
|
||||
BAD_ASM_STYLE,
|
||||
BARE_TRAIT_OBJECTS,
|
||||
BINDINGS_WITH_VARIANT_NAME,
|
||||
UNUSED_MACROS,
|
||||
UNUSED_MACRO_RULES,
|
||||
WARNINGS,
|
||||
UNUSED_FEATURES,
|
||||
BREAK_WITH_LABEL_AND_LOOP,
|
||||
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
CENUM_IMPL_DROP_CAST,
|
||||
COHERENCE_LEAK_CHECK,
|
||||
CONFLICTING_REPR_HINTS,
|
||||
CONST_EVALUATABLE_UNCHECKED,
|
||||
CONST_ITEM_MUTATION,
|
||||
DEAD_CODE,
|
||||
DEPRECATED,
|
||||
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
|
||||
DEPRECATED_IN_FUTURE,
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||
DUPLICATE_MACRO_ATTRIBUTES,
|
||||
ELIDED_LIFETIMES_IN_PATHS,
|
||||
EXPORTED_PRIVATE_DEPENDENCIES,
|
||||
FFI_UNWIND_CALLS,
|
||||
FORBIDDEN_LINT_GROUPS,
|
||||
FUNCTION_ITEM_REFERENCES,
|
||||
FUZZY_PROVENANCE_CASTS,
|
||||
ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
|
||||
IMPLIED_BOUNDS_ENTAILMENT,
|
||||
INCOMPLETE_INCLUDE,
|
||||
INDIRECT_STRUCTURAL_MATCH,
|
||||
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
|
||||
INLINE_NO_SANITIZE,
|
||||
INVALID_ALIGNMENT,
|
||||
INVALID_DOC_ATTRIBUTES,
|
||||
INVALID_MACRO_EXPORT_ARGUMENTS,
|
||||
INVALID_TYPE_PARAM_DEFAULT,
|
||||
IRREFUTABLE_LET_PATTERNS,
|
||||
LARGE_ASSIGNMENTS,
|
||||
LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
LEGACY_DERIVE_HELPERS,
|
||||
LOSSY_PROVENANCE_CASTS,
|
||||
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
||||
MACRO_USE_EXTERN_CRATE,
|
||||
META_VARIABLE_MISUSE,
|
||||
MISSING_ABI,
|
||||
MISSING_FRAGMENT_SPECIFIER,
|
||||
MUST_NOT_SUSPEND,
|
||||
NAMED_ARGUMENTS_USED_POSITIONALLY,
|
||||
NON_EXHAUSTIVE_OMITTED_PATTERNS,
|
||||
NONTRIVIAL_STRUCTURAL_MATCH,
|
||||
ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
OVERLAPPING_RANGE_ENDPOINTS,
|
||||
PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
POINTER_STRUCTURAL_MATCH,
|
||||
PRIVATE_IN_PUBLIC,
|
||||
PROC_MACRO_BACK_COMPAT,
|
||||
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
||||
RENAMED_AND_REMOVED_LINTS,
|
||||
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
|
||||
RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
|
||||
RUST_2021_INCOMPATIBLE_OR_PATTERNS,
|
||||
RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
|
||||
RUST_2021_PRELUDE_COLLISIONS,
|
||||
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
|
||||
SINGLE_USE_LIFETIMES,
|
||||
SOFT_UNSTABLE,
|
||||
STABLE_FEATURES,
|
||||
UNKNOWN_CRATE_TYPES,
|
||||
SUSPICIOUS_AUTO_TRAIT_IMPLS,
|
||||
TEST_UNSTABLE_LINT,
|
||||
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
|
||||
TRIVIAL_CASTS,
|
||||
TRIVIAL_NUMERIC_CASTS,
|
||||
PRIVATE_IN_PUBLIC,
|
||||
EXPORTED_PRIVATE_DEPENDENCIES,
|
||||
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
||||
INVALID_TYPE_PARAM_DEFAULT,
|
||||
RENAMED_AND_REMOVED_LINTS,
|
||||
CONST_ITEM_MUTATION,
|
||||
PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
MISSING_FRAGMENT_SPECIFIER,
|
||||
LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
COHERENCE_LEAK_CHECK,
|
||||
DEPRECATED,
|
||||
UNUSED_UNSAFE,
|
||||
UNUSED_MUT,
|
||||
UNCONDITIONAL_RECURSION,
|
||||
SINGLE_USE_LIFETIMES,
|
||||
UNUSED_LIFETIMES,
|
||||
UNUSED_LABELS,
|
||||
TYVAR_BEHIND_RAW_POINTER,
|
||||
ELIDED_LIFETIMES_IN_PATHS,
|
||||
BARE_TRAIT_OBJECTS,
|
||||
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||
UNSTABLE_NAME_COLLISIONS,
|
||||
IRREFUTABLE_LET_PATTERNS,
|
||||
WHERE_CLAUSES_OBJECT_SAFETY,
|
||||
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
MACRO_USE_EXTERN_CRATE,
|
||||
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
||||
ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
CONFLICTING_REPR_HINTS,
|
||||
META_VARIABLE_MISUSE,
|
||||
DEPRECATED_IN_FUTURE,
|
||||
AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||
INDIRECT_STRUCTURAL_MATCH,
|
||||
POINTER_STRUCTURAL_MATCH,
|
||||
NONTRIVIAL_STRUCTURAL_MATCH,
|
||||
SOFT_UNSTABLE,
|
||||
UNSTABLE_SYNTAX_PRE_EXPANSION,
|
||||
INLINE_NO_SANITIZE,
|
||||
BAD_ASM_STYLE,
|
||||
ASM_SUB_REGISTER,
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
INCOMPLETE_INCLUDE,
|
||||
CENUM_IMPL_DROP_CAST,
|
||||
FUZZY_PROVENANCE_CASTS,
|
||||
LOSSY_PROVENANCE_CASTS,
|
||||
CONST_EVALUATABLE_UNCHECKED,
|
||||
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
|
||||
MUST_NOT_SUSPEND,
|
||||
UNCONDITIONAL_PANIC,
|
||||
UNCONDITIONAL_RECURSION,
|
||||
UNDEFINED_NAKED_FUNCTION_ABI,
|
||||
UNFULFILLED_LINT_EXPECTATIONS,
|
||||
UNINHABITED_STATIC,
|
||||
FUNCTION_ITEM_REFERENCES,
|
||||
USELESS_DEPRECATED,
|
||||
MISSING_ABI,
|
||||
INVALID_DOC_ATTRIBUTES,
|
||||
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
|
||||
RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
|
||||
LEGACY_DERIVE_HELPERS,
|
||||
PROC_MACRO_BACK_COMPAT,
|
||||
RUST_2021_INCOMPATIBLE_OR_PATTERNS,
|
||||
LARGE_ASSIGNMENTS,
|
||||
RUST_2021_PRELUDE_COLLISIONS,
|
||||
RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
|
||||
UNKNOWN_CRATE_TYPES,
|
||||
UNKNOWN_LINTS,
|
||||
UNREACHABLE_CODE,
|
||||
UNREACHABLE_PATTERNS,
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
UNSTABLE_NAME_COLLISIONS,
|
||||
UNSTABLE_SYNTAX_PRE_EXPANSION,
|
||||
UNSUPPORTED_CALLING_CONVENTIONS,
|
||||
BREAK_WITH_LABEL_AND_LOOP,
|
||||
UNUSED_ASSIGNMENTS,
|
||||
UNUSED_ATTRIBUTES,
|
||||
UNUSED_CRATE_DEPENDENCIES,
|
||||
UNUSED_EXTERN_CRATES,
|
||||
UNUSED_FEATURES,
|
||||
UNUSED_IMPORTS,
|
||||
UNUSED_LABELS,
|
||||
UNUSED_LIFETIMES,
|
||||
UNUSED_MACRO_RULES,
|
||||
UNUSED_MACROS,
|
||||
UNUSED_MUT,
|
||||
UNUSED_QUALIFICATIONS,
|
||||
UNUSED_TUPLE_STRUCT_FIELDS,
|
||||
NON_EXHAUSTIVE_OMITTED_PATTERNS,
|
||||
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
|
||||
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
|
||||
DUPLICATE_MACRO_ATTRIBUTES,
|
||||
SUSPICIOUS_AUTO_TRAIT_IMPLS,
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||
TEST_UNSTABLE_LINT,
|
||||
FFI_UNWIND_CALLS,
|
||||
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
|
||||
NAMED_ARGUMENTS_USED_POSITIONALLY,
|
||||
IMPLIED_BOUNDS_ENTAILMENT,
|
||||
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
AMBIGUOUS_GLOB_REEXPORTS,
|
||||
UNUSED_UNSAFE,
|
||||
UNUSED_VARIABLES,
|
||||
USELESS_DEPRECATED,
|
||||
WARNINGS,
|
||||
WHERE_CLAUSES_OBJECT_SAFETY,
|
||||
// tidy-alphabetical-end
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -772,3 +772,75 @@ parse_const_bounds_missing_tilde = const bounds must start with `~`
|
||||
.suggestion = add `~`
|
||||
|
||||
parse_underscore_literal_suffix = underscore literal suffix is not allowed
|
||||
|
||||
parse_expect_label_found_ident = expected a label, found an identifier
|
||||
.suggestion = labels start with a tick
|
||||
|
||||
parse_inappropriate_default = {$article} {$descr} cannot be `default`
|
||||
.label = `default` because of this
|
||||
.note = only associated `fn`, `const`, and `type` items can be `default`
|
||||
|
||||
parse_recover_import_as_use = expected item, found {$token_name}
|
||||
.suggestion = items are imported using the `use` keyword
|
||||
|
||||
parse_single_colon_import_path = expected `::`, found `:`
|
||||
.suggestion = use double colon
|
||||
.note = import paths are delimited using `::`
|
||||
|
||||
parse_bad_item_kind = {$descr} is not supported in {$ctx}
|
||||
.help = consider moving the {$descr} out to a nearby module scope
|
||||
|
||||
parse_single_colon_struct_type = found single colon in a struct field type path
|
||||
.suggestion = write a path separator here
|
||||
|
||||
parse_equals_struct_default = default values on `struct` fields aren't supported
|
||||
.suggestion = remove this unsupported default value
|
||||
|
||||
parse_macro_rules_missing_bang = expected `!` after `macro_rules`
|
||||
.suggestion = add a `!`
|
||||
|
||||
parse_macro_name_remove_bang = macro names aren't followed by a `!`
|
||||
.suggestion = remove the `!`
|
||||
|
||||
parse_macro_rules_visibility = can't qualify macro_rules invocation with `{$vis}`
|
||||
.suggestion = try exporting the macro
|
||||
|
||||
parse_macro_invocation_visibility = can't qualify macro invocation with `pub`
|
||||
.suggestion = remove the visibility
|
||||
.help = try adjusting the macro to put `{$vis}` inside the invocation
|
||||
|
||||
parse_nested_adt = `{$kw_str}` definition cannot be nested inside `{$keyword}`
|
||||
.suggestion = consider creating a new `{$kw_str}` definition instead of nesting
|
||||
|
||||
parse_function_body_equals_expr = function body cannot be `= expression;`
|
||||
.suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`
|
||||
|
||||
parse_box_not_pat = expected pattern, found {$descr}
|
||||
.note = `box` is a reserved keyword
|
||||
.suggestion = escape `box` to use it as an identifier
|
||||
|
||||
parse_unmatched_angle = unmatched angle {$plural ->
|
||||
[true] brackets
|
||||
*[false] bracket
|
||||
}
|
||||
.suggestion = remove extra angle {$plural ->
|
||||
[true] brackets
|
||||
*[false] bracket
|
||||
}
|
||||
|
||||
parse_missing_plus_in_bounds = expected `+` between lifetime and {$sym}
|
||||
.suggestion = add `+`
|
||||
|
||||
parse_incorrect_braces_trait_bounds = incorrect braces around trait bounds
|
||||
.suggestion = remove the parentheses
|
||||
|
||||
parse_kw_bad_case = keyword `{$kw}` is written in the wrong case
|
||||
.suggestion = write it in the correct case
|
||||
|
||||
parse_meta_bad_delim = wrong meta list delimiters
|
||||
parse_cfg_attr_bad_delim = wrong `cfg_attr` delimiters
|
||||
parse_meta_bad_delim_suggestion = the delimiters should be `(` and `)`
|
||||
|
||||
parse_malformed_cfg_attr = malformed `cfg_attr` attribute input
|
||||
.suggestion = missing condition and attribute
|
||||
.note = for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
|
||||
|
@ -2421,3 +2421,227 @@ pub(crate) struct UnderscoreLiteralSuffix {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_expect_label_found_ident)]
|
||||
pub(crate) struct ExpectedLabelFoundIdent {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = "'", applicability = "machine-applicable", style = "short")]
|
||||
pub start: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_inappropriate_default)]
|
||||
#[note]
|
||||
pub(crate) struct InappropriateDefault {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub article: &'static str,
|
||||
pub descr: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_recover_import_as_use)]
|
||||
pub(crate) struct RecoverImportAsUse {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "use", applicability = "machine-applicable", style = "short")]
|
||||
pub span: Span,
|
||||
pub token_name: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_single_colon_import_path)]
|
||||
#[note]
|
||||
pub(crate) struct SingleColonImportPath {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "::", applicability = "machine-applicable", style = "short")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_bad_item_kind)]
|
||||
#[help]
|
||||
pub(crate) struct BadItemKind {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub descr: &'static str,
|
||||
pub ctx: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_single_colon_struct_type)]
|
||||
pub(crate) struct SingleColonStructType {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "::", applicability = "maybe-incorrect", style = "verbose")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_equals_struct_default)]
|
||||
pub(crate) struct EqualsStructDefault {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_macro_rules_missing_bang)]
|
||||
pub(crate) struct MacroRulesMissingBang {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = "!", applicability = "machine-applicable", style = "verbose")]
|
||||
pub hi: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_macro_name_remove_bang)]
|
||||
pub(crate) struct MacroNameRemoveBang {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_macro_rules_visibility)]
|
||||
pub(crate) struct MacroRulesVisibility<'a> {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "#[macro_export]", applicability = "maybe-incorrect")]
|
||||
pub span: Span,
|
||||
pub vis: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_macro_invocation_visibility)]
|
||||
#[help]
|
||||
pub(crate) struct MacroInvocationVisibility<'a> {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub span: Span,
|
||||
pub vis: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_nested_adt)]
|
||||
pub(crate) struct NestedAdt<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||
pub item: Span,
|
||||
pub keyword: &'a str,
|
||||
pub kw_str: Cow<'a, str>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_function_body_equals_expr)]
|
||||
pub(crate) struct FunctionBodyEqualsExpr {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: FunctionBodyEqualsExprSugg,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
|
||||
pub(crate) struct FunctionBodyEqualsExprSugg {
|
||||
#[suggestion_part(code = "{{")]
|
||||
pub eq: Span,
|
||||
#[suggestion_part(code = " }}")]
|
||||
pub semi: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_box_not_pat)]
|
||||
pub(crate) struct BoxNotPat {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[note]
|
||||
pub kw: Span,
|
||||
#[suggestion(code = "r#", applicability = "maybe-incorrect", style = "verbose")]
|
||||
pub lo: Span,
|
||||
pub descr: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_unmatched_angle)]
|
||||
pub(crate) struct UnmatchedAngle {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub span: Span,
|
||||
pub plural: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_missing_plus_in_bounds)]
|
||||
pub(crate) struct MissingPlusBounds {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " +", applicability = "maybe-incorrect", style = "verbose")]
|
||||
pub hi: Span,
|
||||
pub sym: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_incorrect_braces_trait_bounds)]
|
||||
pub(crate) struct IncorrectBracesTraitBounds {
|
||||
#[primary_span]
|
||||
pub span: Vec<Span>,
|
||||
#[subdiagnostic]
|
||||
pub sugg: IncorrectBracesTraitBoundsSugg,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
|
||||
pub(crate) struct IncorrectBracesTraitBoundsSugg {
|
||||
#[suggestion_part(code = " ")]
|
||||
pub l: Span,
|
||||
#[suggestion_part(code = "")]
|
||||
pub r: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_kw_bad_case)]
|
||||
pub(crate) struct KwBadCase<'a> {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "{kw}", applicability = "machine-applicable")]
|
||||
pub span: Span,
|
||||
pub kw: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_meta_bad_delim)]
|
||||
pub(crate) struct MetaBadDelim {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: MetaBadDelimSugg,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_cfg_attr_bad_delim)]
|
||||
pub(crate) struct CfgAttrBadDelim {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sugg: MetaBadDelimSugg,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(parse_meta_bad_delim_suggestion, applicability = "machine-applicable")]
|
||||
pub(crate) struct MetaBadDelimSugg {
|
||||
#[suggestion_part(code = "(")]
|
||||
pub open: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub close: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_malformed_cfg_attr)]
|
||||
#[note]
|
||||
pub(crate) struct MalformedCfgAttr {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "{sugg}")]
|
||||
pub span: Span,
|
||||
pub sugg: &'static str,
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::{AttrItem, Attribute, MetaItem};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult};
|
||||
use rustc_errors::{Diagnostic, FatalError, Level, PResult};
|
||||
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
|
||||
use rustc_fluent_macro::fluent_messages;
|
||||
use rustc_session::parse::ParseSess;
|
||||
@ -243,8 +243,7 @@ pub fn parse_cfg_attr(
|
||||
ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
|
||||
if !tokens.is_empty() =>
|
||||
{
|
||||
let msg = "wrong `cfg_attr` delimiters";
|
||||
crate::validate_attr::check_meta_bad_delim(parse_sess, dspan, delim, msg);
|
||||
crate::validate_attr::check_cfg_attr_bad_delim(parse_sess, dspan, delim);
|
||||
match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) {
|
||||
Ok(r) => return Some(r),
|
||||
Err(mut e) => {
|
||||
@ -265,15 +264,5 @@ const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
|
||||
#the-cfg_attr-attribute>";
|
||||
|
||||
fn error_malformed_cfg_attr_missing(span: Span, parse_sess: &ParseSess) {
|
||||
parse_sess
|
||||
.span_diagnostic
|
||||
.struct_span_err(span, "malformed `cfg_attr` attribute input")
|
||||
.span_suggestion(
|
||||
span,
|
||||
"missing condition and attribute",
|
||||
CFG_ATTR_GRAMMAR_HELP,
|
||||
Applicability::HasPlaceholders,
|
||||
)
|
||||
.note(CFG_ATTR_NOTE_REF)
|
||||
.emit();
|
||||
parse_sess.emit_err(errors::MalformedCfgAttr { span, sugg: CFG_ATTR_GRAMMAR_HELP });
|
||||
}
|
||||
|
@ -3151,14 +3151,10 @@ impl<'a> Parser<'a> {
|
||||
let label = format!("'{}", ident.name);
|
||||
let ident = Ident { name: Symbol::intern(&label), span: ident.span };
|
||||
|
||||
self.struct_span_err(ident.span, "expected a label, found an identifier")
|
||||
.span_suggestion(
|
||||
ident.span,
|
||||
"labels start with a tick",
|
||||
label,
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::ExpectedLabelFoundIdent {
|
||||
span: ident.span,
|
||||
start: ident.span.shrink_to_lo(),
|
||||
});
|
||||
|
||||
Label { ident }
|
||||
}
|
||||
|
@ -181,11 +181,11 @@ impl<'a> Parser<'a> {
|
||||
/// Error in-case `default` was parsed in an in-appropriate context.
|
||||
fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) {
|
||||
if let Defaultness::Default(span) = def {
|
||||
let msg = format!("{} {} cannot be `default`", kind.article(), kind.descr());
|
||||
self.struct_span_err(span, &msg)
|
||||
.span_label(span, "`default` because of this")
|
||||
.note("only associated `fn`, `const`, and `type` items can be `default`")
|
||||
.emit();
|
||||
self.sess.emit_err(errors::InappropriateDefault {
|
||||
span,
|
||||
article: kind.article(),
|
||||
descr: kind.descr(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,14 +310,7 @@ impl<'a> Parser<'a> {
|
||||
self.bump();
|
||||
match self.parse_use_item() {
|
||||
Ok(u) => {
|
||||
self.struct_span_err(span, format!("expected item, found {token_name}"))
|
||||
.span_suggestion_short(
|
||||
span,
|
||||
"items are imported using the `use` keyword",
|
||||
"use",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::RecoverImportAsUse { span, token_name });
|
||||
Ok(Some(u))
|
||||
}
|
||||
Err(e) => {
|
||||
@ -963,15 +956,8 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
// Recover from using a colon as path separator.
|
||||
while self.eat_noexpect(&token::Colon) {
|
||||
self.struct_span_err(self.prev_token.span, "expected `::`, found `:`")
|
||||
.span_suggestion_short(
|
||||
self.prev_token.span,
|
||||
"use double colon",
|
||||
"::",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.note_once("import paths are delimited using `::`")
|
||||
.emit();
|
||||
self.sess
|
||||
.emit_err(errors::SingleColonImportPath { span: self.prev_token.span });
|
||||
|
||||
// We parse the rest of the path and append it to the original prefix.
|
||||
self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
|
||||
@ -1134,13 +1120,11 @@ impl<'a> Parser<'a> {
|
||||
))
|
||||
}
|
||||
|
||||
fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &str) -> Option<T> {
|
||||
fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
|
||||
// FIXME(#100717): needs variant for each `ItemKind` (instead of using `ItemKind::descr()`)
|
||||
let span = self.sess.source_map().guess_head_span(span);
|
||||
let descr = kind.descr();
|
||||
self.struct_span_err(span, &format!("{descr} is not supported in {ctx}"))
|
||||
.help(&format!("consider moving the {descr} out to a nearby module scope"))
|
||||
.emit();
|
||||
self.sess.emit_err(errors::BadItemKind { span, descr, ctx });
|
||||
None
|
||||
}
|
||||
|
||||
@ -1713,27 +1697,13 @@ impl<'a> Parser<'a> {
|
||||
self.expect_field_ty_separator()?;
|
||||
let ty = self.parse_ty()?;
|
||||
if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
|
||||
self.struct_span_err(self.token.span, "found single colon in a struct field type path")
|
||||
.span_suggestion_verbose(
|
||||
self.token.span,
|
||||
"write a path separator here",
|
||||
"::",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::SingleColonStructType { span: self.token.span });
|
||||
}
|
||||
if self.token.kind == token::Eq {
|
||||
self.bump();
|
||||
let const_expr = self.parse_expr_anon_const()?;
|
||||
let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
|
||||
self.struct_span_err(sp, "default values on `struct` fields aren't supported")
|
||||
.span_suggestion(
|
||||
sp,
|
||||
"remove this unsupported default value",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::EqualsStructDefault { span: sp });
|
||||
}
|
||||
Ok(FieldDef {
|
||||
span: lo.to(self.prev_token.span),
|
||||
@ -1871,14 +1841,10 @@ impl<'a> Parser<'a> {
|
||||
return IsMacroRulesItem::Yes { has_bang: true };
|
||||
} else if self.look_ahead(1, |t| (t.is_ident())) {
|
||||
// macro_rules foo
|
||||
self.struct_span_err(macro_rules_span, "expected `!` after `macro_rules`")
|
||||
.span_suggestion(
|
||||
macro_rules_span,
|
||||
"add a `!`",
|
||||
"macro_rules!",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::MacroRulesMissingBang {
|
||||
span: macro_rules_span,
|
||||
hi: macro_rules_span.shrink_to_hi(),
|
||||
});
|
||||
|
||||
return IsMacroRulesItem::Yes { has_bang: false };
|
||||
}
|
||||
@ -1903,9 +1869,7 @@ impl<'a> Parser<'a> {
|
||||
if self.eat(&token::Not) {
|
||||
// Handle macro_rules! foo!
|
||||
let span = self.prev_token.span;
|
||||
self.struct_span_err(span, "macro names aren't followed by a `!`")
|
||||
.span_suggestion(span, "remove the `!`", "", Applicability::MachineApplicable)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::MacroNameRemoveBang { span });
|
||||
}
|
||||
|
||||
let body = self.parse_delim_args()?;
|
||||
@ -1925,25 +1889,9 @@ impl<'a> Parser<'a> {
|
||||
let vstr = pprust::vis_to_string(vis);
|
||||
let vstr = vstr.trim_end();
|
||||
if macro_rules {
|
||||
let msg = format!("can't qualify macro_rules invocation with `{vstr}`");
|
||||
self.struct_span_err(vis.span, &msg)
|
||||
.span_suggestion(
|
||||
vis.span,
|
||||
"try exporting the macro",
|
||||
"#[macro_export]",
|
||||
Applicability::MaybeIncorrect, // speculative
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
|
||||
} else {
|
||||
self.struct_span_err(vis.span, "can't qualify macro invocation with `pub`")
|
||||
.span_suggestion(
|
||||
vis.span,
|
||||
"remove the visibility",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.help(&format!("try adjusting the macro to put `{vstr}` inside the invocation"))
|
||||
.emit();
|
||||
self.sess.emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1989,18 +1937,12 @@ impl<'a> Parser<'a> {
|
||||
let kw_token = self.token.clone();
|
||||
let kw_str = pprust::token_to_string(&kw_token);
|
||||
let item = self.parse_item(ForceCollect::No)?;
|
||||
|
||||
self.struct_span_err(
|
||||
kw_token.span,
|
||||
&format!("`{kw_str}` definition cannot be nested inside `{keyword}`"),
|
||||
)
|
||||
.span_suggestion(
|
||||
item.unwrap().span,
|
||||
&format!("consider creating a new `{kw_str}` definition instead of nesting"),
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::NestedAdt {
|
||||
span: kw_token.span,
|
||||
item: item.unwrap().span,
|
||||
kw_str,
|
||||
keyword: keyword.as_str(),
|
||||
});
|
||||
// We successfully parsed the item but we must inform the caller about nested problem.
|
||||
return Ok(false);
|
||||
}
|
||||
@ -2139,13 +2081,10 @@ impl<'a> Parser<'a> {
|
||||
let _ = self.parse_expr()?;
|
||||
self.expect_semi()?; // `;`
|
||||
let span = eq_sp.to(self.prev_token.span);
|
||||
self.struct_span_err(span, "function body cannot be `= expression;`")
|
||||
.multipart_suggestion(
|
||||
"surround the expression with `{` and `}` instead of `=` and `;`",
|
||||
vec![(eq_sp, "{".to_string()), (self.prev_token.span, " }".to_string())],
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::FunctionBodyEqualsExpr {
|
||||
span,
|
||||
sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
|
||||
});
|
||||
(AttrVec::new(), Some(self.mk_block_err(span)))
|
||||
} else {
|
||||
let expected = if req_body {
|
||||
|
@ -43,7 +43,7 @@ use thin_vec::ThinVec;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::errors::{
|
||||
IncorrectVisibilityRestriction, MismatchedClosingDelimiter, NonStringAbiLiteral,
|
||||
self, IncorrectVisibilityRestriction, MismatchedClosingDelimiter, NonStringAbiLiteral,
|
||||
};
|
||||
|
||||
bitflags::bitflags! {
|
||||
@ -663,15 +663,10 @@ impl<'a> Parser<'a> {
|
||||
if case == Case::Insensitive
|
||||
&& let Some((ident, /* is_raw */ false)) = self.token.ident()
|
||||
&& ident.as_str().to_lowercase() == kw.as_str().to_lowercase() {
|
||||
self
|
||||
.struct_span_err(ident.span, format!("keyword `{kw}` is written in a wrong case"))
|
||||
.span_suggestion(
|
||||
ident.span,
|
||||
"write it in the correct case",
|
||||
kw,
|
||||
Applicability::MachineApplicable
|
||||
).emit();
|
||||
|
||||
self.sess.emit_err(errors::KwBadCase {
|
||||
span: ident.span,
|
||||
kw: kw.as_str()
|
||||
});
|
||||
self.bump();
|
||||
return true;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{ForceCollect, Parser, PathStyle, TrailingToken};
|
||||
use crate::errors::{
|
||||
AmbiguousRangePattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed,
|
||||
self, AmbiguousRangePattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed,
|
||||
DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt,
|
||||
ExpectedCommaAfterPatternField, InclusiveRangeExtraEquals, InclusiveRangeMatchArrow,
|
||||
InclusiveRangeNoEnd, InvalidMutInPattern, PatternOnWrongSideOfAt, RefMutOrderIncorrect,
|
||||
@ -908,18 +908,13 @@ impl<'a> Parser<'a> {
|
||||
let box_span = self.prev_token.span;
|
||||
|
||||
if self.isnt_pattern_start() {
|
||||
self.struct_span_err(
|
||||
self.token.span,
|
||||
format!("expected pattern, found {}", super::token_descr(&self.token)),
|
||||
)
|
||||
.span_note(box_span, "`box` is a reserved keyword")
|
||||
.span_suggestion_verbose(
|
||||
box_span.shrink_to_lo(),
|
||||
"escape `box` to use it as an identifier",
|
||||
"r#",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
let descr = super::token_descr(&self.token);
|
||||
self.sess.emit_err(errors::BoxNotPat {
|
||||
span: self.token.span,
|
||||
kw: box_span,
|
||||
lo: box_span.shrink_to_lo(),
|
||||
descr,
|
||||
});
|
||||
|
||||
// We cannot use `parse_pat_ident()` since it will complain `box`
|
||||
// is not an identifier.
|
||||
|
@ -8,7 +8,7 @@ use rustc_ast::{
|
||||
AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
|
||||
Path, PathSegment, QSelf,
|
||||
};
|
||||
use rustc_errors::{pluralize, Applicability, PResult};
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
use rustc_span::source_map::{BytePos, Span};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use std::mem;
|
||||
@ -464,23 +464,10 @@ impl<'a> Parser<'a> {
|
||||
// i.e. no multibyte characters, in this range.
|
||||
let span =
|
||||
lo.with_hi(lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count));
|
||||
self.struct_span_err(
|
||||
self.sess.emit_err(errors::UnmatchedAngle {
|
||||
span,
|
||||
&format!(
|
||||
"unmatched angle bracket{}",
|
||||
pluralize!(snapshot.unmatched_angle_bracket_count)
|
||||
),
|
||||
)
|
||||
.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"remove extra angle bracket{}",
|
||||
pluralize!(snapshot.unmatched_angle_bracket_count)
|
||||
),
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
plural: snapshot.unmatched_angle_bracket_count > 1,
|
||||
});
|
||||
|
||||
// Try again without unmatched angle bracket characters.
|
||||
self.parse_angle_args(ty_generics)
|
||||
|
@ -588,20 +588,14 @@ impl<'a> Parser<'a> {
|
||||
// Always parse bounds greedily for better error recovery.
|
||||
if self.token.is_lifetime() {
|
||||
self.look_ahead(1, |t| {
|
||||
if let token::Ident(symname, _) = t.kind {
|
||||
if let token::Ident(sym, _) = t.kind {
|
||||
// parse pattern with "'a Sized" we're supposed to give suggestion like
|
||||
// "'a + Sized"
|
||||
self.struct_span_err(
|
||||
self.token.span,
|
||||
&format!("expected `+` between lifetime and {}", symname),
|
||||
)
|
||||
.span_suggestion_verbose(
|
||||
self.token.span.shrink_to_hi(),
|
||||
"add `+`",
|
||||
" +",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::MissingPlusBounds {
|
||||
span: self.token.span,
|
||||
hi: self.token.span.shrink_to_hi(),
|
||||
sym,
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -926,14 +920,10 @@ impl<'a> Parser<'a> {
|
||||
self.parse_remaining_bounds(bounds, true)?;
|
||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||
let sp = vec![lo, self.prev_token.span];
|
||||
let sugg = vec![(lo, String::from(" ")), (self.prev_token.span, String::new())];
|
||||
self.struct_span_err(sp, "incorrect braces around trait bounds")
|
||||
.multipart_suggestion(
|
||||
"remove the parentheses",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::IncorrectBracesTraitBounds {
|
||||
span: sp,
|
||||
sugg: errors::IncorrectBracesTraitBoundsSugg { l: lo, r: self.prev_token.span },
|
||||
});
|
||||
} else {
|
||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Meta-syntax validation logic of attributes for post-expansion.
|
||||
|
||||
use crate::parse_in;
|
||||
use crate::{errors, parse_in};
|
||||
|
||||
use rustc_ast::tokenstream::DelimSpan;
|
||||
use rustc_ast::MetaItemKind;
|
||||
@ -45,7 +45,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
|
||||
kind: match &item.args {
|
||||
AttrArgs::Empty => MetaItemKind::Word,
|
||||
AttrArgs::Delimited(DelimArgs { dspan, delim, tokens }) => {
|
||||
check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters");
|
||||
check_meta_bad_delim(sess, *dspan, *delim);
|
||||
let nmis = parse_in(sess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?;
|
||||
MetaItemKind::List(nmis)
|
||||
}
|
||||
@ -84,19 +84,24 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
|
||||
})
|
||||
}
|
||||
|
||||
pub fn check_meta_bad_delim(sess: &ParseSess, span: DelimSpan, delim: MacDelimiter, msg: &str) {
|
||||
pub fn check_meta_bad_delim(sess: &ParseSess, span: DelimSpan, delim: MacDelimiter) {
|
||||
if let ast::MacDelimiter::Parenthesis = delim {
|
||||
return;
|
||||
}
|
||||
sess.emit_err(errors::MetaBadDelim {
|
||||
span: span.entire(),
|
||||
sugg: errors::MetaBadDelimSugg { open: span.open, close: span.close },
|
||||
});
|
||||
}
|
||||
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(span.entire(), msg)
|
||||
.multipart_suggestion(
|
||||
"the delimiters should be `(` and `)`",
|
||||
vec![(span.open, "(".to_string()), (span.close, ")".to_string())],
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
pub fn check_cfg_attr_bad_delim(sess: &ParseSess, span: DelimSpan, delim: MacDelimiter) {
|
||||
if let ast::MacDelimiter::Parenthesis = delim {
|
||||
return;
|
||||
}
|
||||
sess.emit_err(errors::CfgAttrBadDelim {
|
||||
span: span.entire(),
|
||||
sugg: errors::MetaBadDelimSugg { open: span.open, close: span.close },
|
||||
});
|
||||
}
|
||||
|
||||
/// Checks that the given meta-item is compatible with this `AttributeTemplate`.
|
||||
|
@ -129,8 +129,7 @@ symbols! {
|
||||
Any,
|
||||
Arc,
|
||||
Argument,
|
||||
ArgumentV1,
|
||||
ArgumentV1Methods,
|
||||
ArgumentMethods,
|
||||
Arguments,
|
||||
AsMut,
|
||||
AsRef,
|
||||
|
@ -251,223 +251,6 @@ impl<'a> Formatter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// NB. Argument is essentially an optimized partially applied formatting function,
|
||||
// equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`.
|
||||
|
||||
extern "C" {
|
||||
type Opaque;
|
||||
}
|
||||
|
||||
/// This struct represents the generic "argument" which is taken by the Xprintf
|
||||
/// family of functions. It contains a function to format the given value. At
|
||||
/// compile time it is ensured that the function and the value have the correct
|
||||
/// types, and then this struct is used to canonicalize arguments to one type.
|
||||
#[lang = "format_argument"]
|
||||
#[derive(Copy, Clone)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
pub struct ArgumentV1<'a> {
|
||||
value: &'a Opaque,
|
||||
formatter: fn(&Opaque, &mut Formatter<'_>) -> Result,
|
||||
}
|
||||
|
||||
/// This struct represents the unsafety of constructing an `Arguments`.
|
||||
/// It exists, rather than an unsafe function, in order to simplify the expansion
|
||||
/// of `format_args!(..)` and reduce the scope of the `unsafe` block.
|
||||
#[lang = "format_unsafe_arg"]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
pub struct UnsafeArg {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl UnsafeArg {
|
||||
/// See documentation where `UnsafeArg` is required to know when it is safe to
|
||||
/// create and use `UnsafeArg`.
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn new() -> Self {
|
||||
Self { _private: () }
|
||||
}
|
||||
}
|
||||
|
||||
// This guarantees a single stable value for the function pointer associated with
|
||||
// indices/counts in the formatting infrastructure.
|
||||
//
|
||||
// Note that a function defined as such would not be correct as functions are
|
||||
// always tagged unnamed_addr with the current lowering to LLVM IR, so their
|
||||
// address is not considered important to LLVM and as such the as_usize cast
|
||||
// could have been miscompiled. In practice, we never call as_usize on non-usize
|
||||
// containing data (as a matter of static generation of the formatting
|
||||
// arguments), so this is merely an additional check.
|
||||
//
|
||||
// We primarily want to ensure that the function pointer at `USIZE_MARKER` has
|
||||
// an address corresponding *only* to functions that also take `&usize` as their
|
||||
// first argument. The read_volatile here ensures that we can safely ready out a
|
||||
// usize from the passed reference and that this address does not point at a
|
||||
// non-usize taking function.
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
static USIZE_MARKER: fn(&usize, &mut Formatter<'_>) -> Result = |ptr, _| {
|
||||
// SAFETY: ptr is a reference
|
||||
let _v: usize = unsafe { crate::ptr::read_volatile(ptr) };
|
||||
loop {}
|
||||
};
|
||||
|
||||
macro_rules! arg_new {
|
||||
($f: ident, $t: ident) => {
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
#[inline]
|
||||
pub fn $f<'b, T: $t>(x: &'b T) -> ArgumentV1<'_> {
|
||||
Self::new(x, $t::fmt)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[rustc_diagnostic_item = "ArgumentV1Methods"]
|
||||
impl<'a> ArgumentV1<'a> {
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
#[inline]
|
||||
pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> ArgumentV1<'b> {
|
||||
// SAFETY: `mem::transmute(x)` is safe because
|
||||
// 1. `&'b T` keeps the lifetime it originated with `'b`
|
||||
// (so as to not have an unbounded lifetime)
|
||||
// 2. `&'b T` and `&'b Opaque` have the same memory layout
|
||||
// (when `T` is `Sized`, as it is here)
|
||||
// `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result`
|
||||
// and `fn(&Opaque, &mut Formatter<'_>) -> Result` have the same ABI
|
||||
// (as long as `T` is `Sized`)
|
||||
unsafe { ArgumentV1 { formatter: mem::transmute(f), value: mem::transmute(x) } }
|
||||
}
|
||||
|
||||
arg_new!(new_display, Display);
|
||||
arg_new!(new_debug, Debug);
|
||||
arg_new!(new_octal, Octal);
|
||||
arg_new!(new_lower_hex, LowerHex);
|
||||
arg_new!(new_upper_hex, UpperHex);
|
||||
arg_new!(new_pointer, Pointer);
|
||||
arg_new!(new_binary, Binary);
|
||||
arg_new!(new_lower_exp, LowerExp);
|
||||
arg_new!(new_upper_exp, UpperExp);
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
|
||||
ArgumentV1::new(x, USIZE_MARKER)
|
||||
}
|
||||
|
||||
fn as_usize(&self) -> Option<usize> {
|
||||
// We are type punning a bit here: USIZE_MARKER only takes an &usize but
|
||||
// formatter takes an &Opaque. Rust understandably doesn't think we should compare
|
||||
// the function pointers if they don't have the same signature, so we cast to
|
||||
// usizes to tell it that we just want to compare addresses.
|
||||
if self.formatter as usize == USIZE_MARKER as usize {
|
||||
// SAFETY: The `formatter` field is only set to USIZE_MARKER if
|
||||
// the value is a usize, so this is safe
|
||||
Some(unsafe { *(self.value as *const _ as *const usize) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flags available in the v1 format of format_args
|
||||
#[derive(Copy, Clone)]
|
||||
enum FlagV1 {
|
||||
SignPlus,
|
||||
SignMinus,
|
||||
Alternate,
|
||||
SignAwareZeroPad,
|
||||
DebugLowerHex,
|
||||
DebugUpperHex,
|
||||
}
|
||||
|
||||
impl<'a> Arguments<'a> {
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
|
||||
pub const fn new_const(pieces: &'a [&'static str]) -> Self {
|
||||
if pieces.len() > 1 {
|
||||
panic!("invalid args");
|
||||
}
|
||||
Arguments { pieces, fmt: None, args: &[] }
|
||||
}
|
||||
|
||||
/// When using the format_args!() macro, this function is used to generate the
|
||||
/// Arguments structure.
|
||||
#[cfg(not(bootstrap))]
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
pub fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
|
||||
if pieces.len() < args.len() || pieces.len() > args.len() + 1 {
|
||||
panic!("invalid args");
|
||||
}
|
||||
Arguments { pieces, fmt: None, args }
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
|
||||
pub const fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
|
||||
if pieces.len() < args.len() || pieces.len() > args.len() + 1 {
|
||||
panic!("invalid args");
|
||||
}
|
||||
Arguments { pieces, fmt: None, args }
|
||||
}
|
||||
|
||||
/// This function is used to specify nonstandard formatting parameters.
|
||||
///
|
||||
/// An `UnsafeArg` is required because the following invariants must be held
|
||||
/// in order for this function to be safe:
|
||||
/// 1. The `pieces` slice must be at least as long as `fmt`.
|
||||
/// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`.
|
||||
/// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`.
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
pub fn new_v1_formatted(
|
||||
pieces: &'a [&'static str],
|
||||
args: &'a [ArgumentV1<'a>],
|
||||
fmt: &'a [rt::Placeholder],
|
||||
_unsafe_arg: UnsafeArg,
|
||||
) -> Arguments<'a> {
|
||||
Arguments { pieces, fmt: Some(fmt), args }
|
||||
}
|
||||
|
||||
/// Estimates the length of the formatted text.
|
||||
///
|
||||
/// This is intended to be used for setting initial `String` capacity
|
||||
/// when using `format!`. Note: this is neither the lower nor upper bound.
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
|
||||
pub fn estimated_capacity(&self) -> usize {
|
||||
let pieces_length: usize = self.pieces.iter().map(|x| x.len()).sum();
|
||||
|
||||
if self.args.is_empty() {
|
||||
pieces_length
|
||||
} else if !self.pieces.is_empty() && self.pieces[0].is_empty() && pieces_length < 16 {
|
||||
// If the format string starts with an argument,
|
||||
// don't preallocate anything, unless length
|
||||
// of pieces is significant.
|
||||
0
|
||||
} else {
|
||||
// There are some arguments, so any additional push
|
||||
// will reallocate the string. To avoid that,
|
||||
// we're "pre-doubling" the capacity here.
|
||||
pieces_length.checked_mul(2).unwrap_or(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This structure represents a safely precompiled version of a format string
|
||||
/// and its arguments. This cannot be generated at runtime because it cannot
|
||||
/// safely be done, so no constructors are given and the fields are private
|
||||
@ -502,7 +285,82 @@ pub struct Arguments<'a> {
|
||||
|
||||
// Dynamic arguments for interpolation, to be interleaved with string
|
||||
// pieces. (Every argument is preceded by a string piece.)
|
||||
args: &'a [ArgumentV1<'a>],
|
||||
args: &'a [rt::Argument<'a>],
|
||||
}
|
||||
|
||||
/// Used by the format_args!() macro to create a fmt::Arguments object.
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "fmt_internals", issue = "none")]
|
||||
impl<'a> Arguments<'a> {
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
|
||||
pub const fn new_const(pieces: &'a [&'static str]) -> Self {
|
||||
if pieces.len() > 1 {
|
||||
panic!("invalid args");
|
||||
}
|
||||
Arguments { pieces, fmt: None, args: &[] }
|
||||
}
|
||||
|
||||
/// When using the format_args!() macro, this function is used to generate the
|
||||
/// Arguments structure.
|
||||
#[cfg(not(bootstrap))]
|
||||
#[inline]
|
||||
pub fn new_v1(pieces: &'a [&'static str], args: &'a [rt::Argument<'a>]) -> Arguments<'a> {
|
||||
if pieces.len() < args.len() || pieces.len() > args.len() + 1 {
|
||||
panic!("invalid args");
|
||||
}
|
||||
Arguments { pieces, fmt: None, args }
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
|
||||
pub const fn new_v1(pieces: &'a [&'static str], args: &'a [rt::Argument<'a>]) -> Arguments<'a> {
|
||||
if pieces.len() < args.len() || pieces.len() > args.len() + 1 {
|
||||
panic!("invalid args");
|
||||
}
|
||||
Arguments { pieces, fmt: None, args }
|
||||
}
|
||||
|
||||
/// This function is used to specify nonstandard formatting parameters.
|
||||
///
|
||||
/// An `rt::UnsafeArg` is required because the following invariants must be held
|
||||
/// in order for this function to be safe:
|
||||
/// 1. The `pieces` slice must be at least as long as `fmt`.
|
||||
/// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`.
|
||||
/// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`.
|
||||
#[inline]
|
||||
pub fn new_v1_formatted(
|
||||
pieces: &'a [&'static str],
|
||||
args: &'a [rt::Argument<'a>],
|
||||
fmt: &'a [rt::Placeholder],
|
||||
_unsafe_arg: rt::UnsafeArg,
|
||||
) -> Arguments<'a> {
|
||||
Arguments { pieces, fmt: Some(fmt), args }
|
||||
}
|
||||
|
||||
/// Estimates the length of the formatted text.
|
||||
///
|
||||
/// This is intended to be used for setting initial `String` capacity
|
||||
/// when using `format!`. Note: this is neither the lower nor upper bound.
|
||||
#[inline]
|
||||
pub fn estimated_capacity(&self) -> usize {
|
||||
let pieces_length: usize = self.pieces.iter().map(|x| x.len()).sum();
|
||||
|
||||
if self.args.is_empty() {
|
||||
pieces_length
|
||||
} else if !self.pieces.is_empty() && self.pieces[0].is_empty() && pieces_length < 16 {
|
||||
// If the format string starts with an argument,
|
||||
// don't preallocate anything, unless length
|
||||
// of pieces is significant.
|
||||
0
|
||||
} else {
|
||||
// There are some arguments, so any additional push
|
||||
// will reallocate the string. To avoid that,
|
||||
// we're "pre-doubling" the capacity here.
|
||||
pieces_length.checked_mul(2).unwrap_or(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Arguments<'a> {
|
||||
@ -1244,7 +1102,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
|
||||
if !piece.is_empty() {
|
||||
formatter.buf.write_str(*piece)?;
|
||||
}
|
||||
(arg.formatter)(arg.value, &mut formatter)?;
|
||||
arg.fmt(&mut formatter)?;
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
@ -1274,7 +1132,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[ArgumentV1<'_>]) -> Result {
|
||||
unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argument<'_>]) -> Result {
|
||||
fmt.fill = arg.fill;
|
||||
fmt.align = arg.align;
|
||||
fmt.flags = arg.flags;
|
||||
@ -1292,10 +1150,10 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[ArgumentV1
|
||||
let value = unsafe { args.get_unchecked(arg.position) };
|
||||
|
||||
// Then actually do some printing
|
||||
(value.formatter)(value.value, fmt)
|
||||
value.fmt(fmt)
|
||||
}
|
||||
|
||||
unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::Count) -> Option<usize> {
|
||||
unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<usize> {
|
||||
match *cnt {
|
||||
rt::Count::Is(n) => Some(n),
|
||||
rt::Count::Implied => None,
|
||||
@ -1878,7 +1736,7 @@ impl<'a> Formatter<'a> {
|
||||
#[must_use]
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn sign_plus(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::SignPlus as u32) != 0
|
||||
self.flags & (1 << rt::Flag::SignPlus as u32) != 0
|
||||
}
|
||||
|
||||
/// Determines if the `-` flag was specified.
|
||||
@ -1907,7 +1765,7 @@ impl<'a> Formatter<'a> {
|
||||
#[must_use]
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn sign_minus(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::SignMinus as u32) != 0
|
||||
self.flags & (1 << rt::Flag::SignMinus as u32) != 0
|
||||
}
|
||||
|
||||
/// Determines if the `#` flag was specified.
|
||||
@ -1935,7 +1793,7 @@ impl<'a> Formatter<'a> {
|
||||
#[must_use]
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn alternate(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::Alternate as u32) != 0
|
||||
self.flags & (1 << rt::Flag::Alternate as u32) != 0
|
||||
}
|
||||
|
||||
/// Determines if the `0` flag was specified.
|
||||
@ -1961,17 +1819,17 @@ impl<'a> Formatter<'a> {
|
||||
#[must_use]
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn sign_aware_zero_pad(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0
|
||||
self.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0
|
||||
}
|
||||
|
||||
// FIXME: Decide what public API we want for these two flags.
|
||||
// https://github.com/rust-lang/rust/issues/48584
|
||||
fn debug_lower_hex(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0
|
||||
self.flags & (1 << rt::Flag::DebugLowerHex as u32) != 0
|
||||
}
|
||||
|
||||
fn debug_upper_hex(&self) -> bool {
|
||||
self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0
|
||||
self.flags & (1 << rt::Flag::DebugUpperHex as u32) != 0
|
||||
}
|
||||
|
||||
/// Creates a [`DebugStruct`] builder designed to assist with creation of
|
||||
@ -2531,13 +2389,13 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul
|
||||
// or not to zero extend, and then unconditionally set it to get the
|
||||
// prefix.
|
||||
if f.alternate() {
|
||||
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
|
||||
f.flags |= 1 << (rt::Flag::SignAwareZeroPad as u32);
|
||||
|
||||
if f.width.is_none() {
|
||||
f.width = Some((usize::BITS / 4) as usize + 2);
|
||||
}
|
||||
}
|
||||
f.flags |= 1 << (FlagV1::Alternate as u32);
|
||||
f.flags |= 1 << (rt::Flag::Alternate as u32);
|
||||
|
||||
let ret = LowerHex::fmt(&ptr_addr, f);
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
//! These are the lang items used by format_args!().
|
||||
|
||||
use super::*;
|
||||
|
||||
#[lang = "format_placeholder"]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Placeholder {
|
||||
@ -28,21 +30,17 @@ impl Placeholder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Possible alignments that can be requested as part of a formatting directive.
|
||||
#[lang = "format_alignment"]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Alignment {
|
||||
/// Indication that contents should be left-aligned.
|
||||
Left,
|
||||
/// Indication that contents should be right-aligned.
|
||||
Right,
|
||||
/// Indication that contents should be center-aligned.
|
||||
Center,
|
||||
/// No alignment was requested.
|
||||
Unknown,
|
||||
}
|
||||
|
||||
/// Used by [width](https://doc.rust-lang.org/std/fmt/#width) and [precision](https://doc.rust-lang.org/std/fmt/#precision) specifiers.
|
||||
/// Used by [width](https://doc.rust-lang.org/std/fmt/#width)
|
||||
/// and [precision](https://doc.rust-lang.org/std/fmt/#precision) specifiers.
|
||||
#[lang = "format_count"]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Count {
|
||||
@ -53,3 +51,147 @@ pub enum Count {
|
||||
/// Not specified
|
||||
Implied,
|
||||
}
|
||||
|
||||
// This needs to match the order of flags in compiler/rustc_ast_lowering/src/format.rs.
|
||||
#[derive(Copy, Clone)]
|
||||
pub(super) enum Flag {
|
||||
SignPlus,
|
||||
SignMinus,
|
||||
Alternate,
|
||||
SignAwareZeroPad,
|
||||
DebugLowerHex,
|
||||
DebugUpperHex,
|
||||
}
|
||||
|
||||
/// This struct represents the generic "argument" which is taken by format_args!().
|
||||
/// It contains a function to format the given value. At compile time it is ensured that the
|
||||
/// function and the value have the correct types, and then this struct is used to canonicalize
|
||||
/// arguments to one type.
|
||||
///
|
||||
/// Argument is essentially an optimized partially applied formatting function,
|
||||
/// equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`.
|
||||
#[lang = "format_argument"]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Argument<'a> {
|
||||
value: &'a Opaque,
|
||||
formatter: fn(&Opaque, &mut Formatter<'_>) -> Result,
|
||||
}
|
||||
|
||||
#[rustc_diagnostic_item = "ArgumentMethods"]
|
||||
impl<'a> Argument<'a> {
|
||||
#[inline(always)]
|
||||
fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'b> {
|
||||
// SAFETY: `mem::transmute(x)` is safe because
|
||||
// 1. `&'b T` keeps the lifetime it originated with `'b`
|
||||
// (so as to not have an unbounded lifetime)
|
||||
// 2. `&'b T` and `&'b Opaque` have the same memory layout
|
||||
// (when `T` is `Sized`, as it is here)
|
||||
// `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result`
|
||||
// and `fn(&Opaque, &mut Formatter<'_>) -> Result` have the same ABI
|
||||
// (as long as `T` is `Sized`)
|
||||
unsafe { Argument { formatter: mem::transmute(f), value: mem::transmute(x) } }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn new_display<'b, T: Display>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, Display::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_debug<'b, T: Debug>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, Debug::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_octal<'b, T: Octal>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, Octal::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_lower_hex<'b, T: LowerHex>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, LowerHex::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_upper_hex<'b, T: UpperHex>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, UpperHex::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_pointer<'b, T: Pointer>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, Pointer::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_binary<'b, T: Binary>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, Binary::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_lower_exp<'b, T: LowerExp>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, LowerExp::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn new_upper_exp<'b, T: UpperExp>(x: &'b T) -> Argument<'_> {
|
||||
Self::new(x, UpperExp::fmt)
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn from_usize(x: &usize) -> Argument<'_> {
|
||||
Self::new(x, USIZE_MARKER)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
(self.formatter)(self.value, f)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn as_usize(&self) -> Option<usize> {
|
||||
// We are type punning a bit here: USIZE_MARKER only takes an &usize but
|
||||
// formatter takes an &Opaque. Rust understandably doesn't think we should compare
|
||||
// the function pointers if they don't have the same signature, so we cast to
|
||||
// usizes to tell it that we just want to compare addresses.
|
||||
if self.formatter as usize == USIZE_MARKER as usize {
|
||||
// SAFETY: The `formatter` field is only set to USIZE_MARKER if
|
||||
// the value is a usize, so this is safe
|
||||
Some(unsafe { *(self.value as *const _ as *const usize) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This struct represents the unsafety of constructing an `Arguments`.
|
||||
/// It exists, rather than an unsafe function, in order to simplify the expansion
|
||||
/// of `format_args!(..)` and reduce the scope of the `unsafe` block.
|
||||
#[lang = "format_unsafe_arg"]
|
||||
pub struct UnsafeArg {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl UnsafeArg {
|
||||
/// See documentation where `UnsafeArg` is required to know when it is safe to
|
||||
/// create and use `UnsafeArg`.
|
||||
#[inline(always)]
|
||||
pub unsafe fn new() -> Self {
|
||||
Self { _private: () }
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
type Opaque;
|
||||
}
|
||||
|
||||
// This guarantees a single stable value for the function pointer associated with
|
||||
// indices/counts in the formatting infrastructure.
|
||||
//
|
||||
// Note that a function defined as such would not be correct as functions are
|
||||
// always tagged unnamed_addr with the current lowering to LLVM IR, so their
|
||||
// address is not considered important to LLVM and as such the as_usize cast
|
||||
// could have been miscompiled. In practice, we never call as_usize on non-usize
|
||||
// containing data (as a matter of static generation of the formatting
|
||||
// arguments), so this is merely an additional check.
|
||||
//
|
||||
// We primarily want to ensure that the function pointer at `USIZE_MARKER` has
|
||||
// an address corresponding *only* to functions that also take `&usize` as their
|
||||
// first argument. The read_volatile here ensures that we can safely ready out a
|
||||
// usize from the passed reference and that this address does not point at a
|
||||
// non-usize taking function.
|
||||
static USIZE_MARKER: fn(&usize, &mut Formatter<'_>) -> Result = |ptr, _| {
|
||||
// SAFETY: ptr is a reference
|
||||
let _v: usize = unsafe { crate::ptr::read_volatile(ptr) };
|
||||
loop {}
|
||||
};
|
||||
|
@ -1132,27 +1132,30 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
|
||||
&dir,
|
||||
&name,
|
||||
c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
|
||||
)?;
|
||||
dirlist.push(child_dir);
|
||||
} else {
|
||||
for i in 1..=MAX_RETRIES {
|
||||
let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
|
||||
match result {
|
||||
Ok(f) => delete(&f)?,
|
||||
// Already deleted, so skip.
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => break,
|
||||
// Retry a few times if the file is locked or a delete is already in progress.
|
||||
Err(e)
|
||||
if i < MAX_RETRIES
|
||||
&& (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
||||
|| e.raw_os_error()
|
||||
== Some(c::ERROR_SHARING_VIOLATION as _)) => {}
|
||||
// Otherwise return the error.
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
thread::yield_now();
|
||||
);
|
||||
// On success, add the handle to the queue.
|
||||
// If opening the directory fails we treat it the same as a file
|
||||
if let Ok(child_dir) = child_dir {
|
||||
dirlist.push(child_dir);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for i in 1..=MAX_RETRIES {
|
||||
let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
|
||||
match result {
|
||||
Ok(f) => delete(&f)?,
|
||||
// Already deleted, so skip.
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => break,
|
||||
// Retry a few times if the file is locked or a delete is already in progress.
|
||||
Err(e)
|
||||
if i < MAX_RETRIES
|
||||
&& (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
||||
|| e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _)) => {}
|
||||
// Otherwise return the error.
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
thread::yield_now();
|
||||
}
|
||||
}
|
||||
// If there were no more files then delete the directory.
|
||||
if !more_data {
|
||||
|
@ -31,7 +31,7 @@ from lldb import SBValue, SBData, SBError, eBasicTypeLong, eBasicTypeUnsignedLon
|
||||
#
|
||||
# You can find more information and examples here:
|
||||
# 1. https://lldb.llvm.org/varformats.html
|
||||
# 2. https://lldb.llvm.org/python-reference.html
|
||||
# 2. https://lldb.llvm.org/use/python-reference.html
|
||||
# 3. https://lldb.llvm.org/python_reference/lldb.formatters.cpp.libcxx-pysrc.html
|
||||
# 4. https://github.com/llvm-mirror/lldb/tree/master/examples/summaries/cocoa
|
||||
####################################################################################################
|
||||
|
@ -304,7 +304,7 @@ pub(crate) fn clean_predicate<'tcx>(
|
||||
clean_region_outlives_predicate(pred)
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(pred)) => {
|
||||
clean_type_outlives_predicate(pred, cx)
|
||||
clean_type_outlives_predicate(bound_predicate.rebind(pred), cx)
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => {
|
||||
Some(clean_projection_predicate(bound_predicate.rebind(pred), cx))
|
||||
@ -345,7 +345,7 @@ fn clean_poly_trait_predicate<'tcx>(
|
||||
}
|
||||
|
||||
fn clean_region_outlives_predicate<'tcx>(
|
||||
pred: ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>,
|
||||
pred: ty::RegionOutlivesPredicate<'tcx>,
|
||||
) -> Option<WherePredicate> {
|
||||
let ty::OutlivesPredicate(a, b) = pred;
|
||||
|
||||
@ -358,13 +358,13 @@ fn clean_region_outlives_predicate<'tcx>(
|
||||
}
|
||||
|
||||
fn clean_type_outlives_predicate<'tcx>(
|
||||
pred: ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
|
||||
pred: ty::Binder<'tcx, ty::TypeOutlivesPredicate<'tcx>>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> Option<WherePredicate> {
|
||||
let ty::OutlivesPredicate(ty, lt) = pred;
|
||||
let ty::OutlivesPredicate(ty, lt) = pred.skip_binder();
|
||||
|
||||
Some(WherePredicate::BoundPredicate {
|
||||
ty: clean_middle_ty(ty::Binder::dummy(ty), cx, None),
|
||||
ty: clean_middle_ty(pred.rebind(ty), cx, None),
|
||||
bounds: vec![GenericBound::Outlives(
|
||||
clean_middle_region(lt).expect("failed to clean lifetimes"),
|
||||
)],
|
||||
|
@ -12,57 +12,59 @@ stack backtrace:
|
||||
at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
|
||||
4: <std::sys_common::backtrace::_print::DisplayBacktrace as std::fmt::Display>::fmt
|
||||
at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
|
||||
5: std::fmt::write
|
||||
5: core::fmt::rt::Argument::fmt
|
||||
at RUSTLIB/core/src/fmt/rt.rs:LL:CC
|
||||
6: std::fmt::write
|
||||
at RUSTLIB/core/src/fmt/mod.rs:LL:CC
|
||||
6: <std::sys::PLATFORM::stdio::Stderr as std::io::Write>::write_fmt
|
||||
7: <std::sys::PLATFORM::stdio::Stderr as std::io::Write>::write_fmt
|
||||
at RUSTLIB/std/src/io/mod.rs:LL:CC
|
||||
7: std::sys_common::backtrace::_print
|
||||
8: std::sys_common::backtrace::_print
|
||||
at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
|
||||
8: std::sys_common::backtrace::print
|
||||
9: std::sys_common::backtrace::print
|
||||
at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
|
||||
9: std::panicking::default_hook::{closure#1}
|
||||
10: std::panicking::default_hook::{closure#1}
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
10: std::panicking::default_hook
|
||||
11: std::panicking::default_hook
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
11: std::panicking::rust_panic_with_hook
|
||||
12: std::panicking::rust_panic_with_hook
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
12: std::rt::begin_panic::{closure#0}
|
||||
13: std::rt::begin_panic::{closure#0}
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
13: std::sys_common::backtrace::__rust_end_short_backtrace
|
||||
14: std::sys_common::backtrace::__rust_end_short_backtrace
|
||||
at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
|
||||
14: std::rt::begin_panic
|
||||
15: std::rt::begin_panic
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
15: <Foo as std::ops::Drop>::drop
|
||||
16: <Foo as std::ops::Drop>::drop
|
||||
at $DIR/double_panic.rs:LL:CC
|
||||
16: std::ptr::drop_in_place - shim(Some(Foo))
|
||||
17: std::ptr::drop_in_place - shim(Some(Foo))
|
||||
at RUSTLIB/core/src/ptr/mod.rs:LL:CC
|
||||
17: main
|
||||
18: main
|
||||
at $DIR/double_panic.rs:LL:CC
|
||||
18: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
|
||||
19: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
|
||||
at RUSTLIB/core/src/ops/function.rs:LL:CC
|
||||
19: std::sys_common::backtrace::__rust_begin_short_backtrace
|
||||
20: std::sys_common::backtrace::__rust_begin_short_backtrace
|
||||
at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
|
||||
20: std::rt::lang_start::{closure#0}
|
||||
21: std::rt::lang_start::{closure#0}
|
||||
at RUSTLIB/std/src/rt.rs:LL:CC
|
||||
21: std::ops::function::impls::call_once
|
||||
22: std::ops::function::impls::call_once
|
||||
at RUSTLIB/core/src/ops/function.rs:LL:CC
|
||||
22: std::panicking::r#try::do_call
|
||||
23: std::panicking::r#try::do_call
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
23: std::panicking::r#try
|
||||
24: std::panicking::r#try
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
24: std::panic::catch_unwind
|
||||
25: std::panic::catch_unwind
|
||||
at RUSTLIB/std/src/panic.rs:LL:CC
|
||||
25: std::rt::lang_start_internal::{closure#2}
|
||||
26: std::rt::lang_start_internal::{closure#2}
|
||||
at RUSTLIB/std/src/rt.rs:LL:CC
|
||||
26: std::panicking::r#try::do_call
|
||||
27: std::panicking::r#try::do_call
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
27: std::panicking::r#try
|
||||
28: std::panicking::r#try
|
||||
at RUSTLIB/std/src/panicking.rs:LL:CC
|
||||
28: std::panic::catch_unwind
|
||||
29: std::panic::catch_unwind
|
||||
at RUSTLIB/std/src/panic.rs:LL:CC
|
||||
29: std::rt::lang_start_internal
|
||||
30: std::rt::lang_start_internal
|
||||
at RUSTLIB/std/src/rt.rs:LL:CC
|
||||
30: std::rt::lang_start
|
||||
31: std::rt::lang_start
|
||||
at RUSTLIB/std/src/rt.rs:LL:CC
|
||||
thread panicked while panicking. aborting.
|
||||
error: abnormal termination: the program aborted execution
|
||||
|
@ -201,7 +201,7 @@ macro_rules! format_args {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
$crate::fmt::Arguments::new_v1(&[], &[$crate::fmt::ArgumentV1::new(&(arg1(a, b, c)), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(arg2), $crate::fmt::Display::fmt), ]);
|
||||
$crate::fmt::Arguments::new_v1(&[], &[$crate::fmt::Argument::new(&(arg1(a, b, c)), $crate::fmt::Display::fmt), $crate::fmt::Argument::new(&(arg2), $crate::fmt::Display::fmt), ]);
|
||||
}
|
||||
"#]],
|
||||
);
|
||||
@ -229,7 +229,7 @@ macro_rules! format_args {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
$crate::fmt::Arguments::new_v1(&[], &[$crate::fmt::ArgumentV1::new(&(a::<A, B>()), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(b), $crate::fmt::Display::fmt), ]);
|
||||
$crate::fmt::Arguments::new_v1(&[], &[$crate::fmt::Argument::new(&(a::<A, B>()), $crate::fmt::Display::fmt), $crate::fmt::Argument::new(&(b), $crate::fmt::Display::fmt), ]);
|
||||
}
|
||||
"#]],
|
||||
);
|
||||
@ -260,7 +260,7 @@ macro_rules! format_args {
|
||||
fn main() {
|
||||
let _ =
|
||||
/* parse error: expected field name or number */
|
||||
$crate::fmt::Arguments::new_v1(&[], &[$crate::fmt::ArgumentV1::new(&(a.), $crate::fmt::Display::fmt), ]);
|
||||
$crate::fmt::Arguments::new_v1(&[], &[$crate::fmt::Argument::new(&(a.), $crate::fmt::Display::fmt), ]);
|
||||
}
|
||||
"#]],
|
||||
);
|
||||
|
@ -241,8 +241,8 @@ fn format_args_expand(
|
||||
// We expand `format_args!("", a1, a2)` to
|
||||
// ```
|
||||
// $crate::fmt::Arguments::new_v1(&[], &[
|
||||
// $crate::fmt::ArgumentV1::new(&arg1,$crate::fmt::Display::fmt),
|
||||
// $crate::fmt::ArgumentV1::new(&arg2,$crate::fmt::Display::fmt),
|
||||
// $crate::fmt::Argument::new(&arg1,$crate::fmt::Display::fmt),
|
||||
// $crate::fmt::Argument::new(&arg2,$crate::fmt::Display::fmt),
|
||||
// ])
|
||||
// ```,
|
||||
// which is still not really correct, but close enough for now
|
||||
@ -267,7 +267,7 @@ fn format_args_expand(
|
||||
}
|
||||
let _format_string = args.remove(0);
|
||||
let arg_tts = args.into_iter().flat_map(|arg| {
|
||||
quote! { #DOLLAR_CRATE::fmt::ArgumentV1::new(&(#arg), #DOLLAR_CRATE::fmt::Display::fmt), }
|
||||
quote! { #DOLLAR_CRATE::fmt::Argument::new(&(#arg), #DOLLAR_CRATE::fmt::Display::fmt), }
|
||||
}.token_trees);
|
||||
let expanded = quote! {
|
||||
#DOLLAR_CRATE::fmt::Arguments::new_v1(&[], &[##arg_tts])
|
||||
|
@ -15,14 +15,14 @@
|
||||
let mut _13: &[&str; 3]; // in scope 0 at $DIR/lifetimes.rs:+10:19: +10:28
|
||||
let _14: &[&str; 3]; // in scope 0 at $DIR/lifetimes.rs:+10:19: +10:28
|
||||
let _15: [&str; 3]; // in scope 0 at $DIR/lifetimes.rs:+10:19: +10:28
|
||||
let mut _16: &[core::fmt::ArgumentV1<'_>]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let mut _17: &[core::fmt::ArgumentV1<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let _18: &[core::fmt::ArgumentV1<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let _19: [core::fmt::ArgumentV1<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let mut _20: core::fmt::ArgumentV1<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
let mut _16: &[core::fmt::rt::Argument<'_>]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let mut _17: &[core::fmt::rt::Argument<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let _18: &[core::fmt::rt::Argument<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let _19: [core::fmt::rt::Argument<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
let mut _20: core::fmt::rt::Argument<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
let mut _21: &std::boxed::Box<dyn std::fmt::Display>; // in scope 0 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
let _22: &std::boxed::Box<dyn std::fmt::Display>; // in scope 0 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
let mut _23: core::fmt::ArgumentV1<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
let mut _23: core::fmt::rt::Argument<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
let mut _24: &u32; // in scope 0 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
let _25: &u32; // in scope 0 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
let mut _27: bool; // in scope 0 at $DIR/lifetimes.rs:+12:1: +12:2
|
||||
@ -113,11 +113,11 @@
|
||||
StorageLive(_22); // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
_22 = &_8; // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
_21 = &(*_22); // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
_20 = core::fmt::ArgumentV1::<'_>::new_display::<Box<dyn std::fmt::Display>>(move _21) -> [return: bb3, unwind unreachable]; // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
_20 = core::fmt::rt::Argument::<'_>::new_display::<Box<dyn std::fmt::Display>>(move _21) -> [return: bb3, unwind unreachable]; // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23
|
||||
// mir::Constant
|
||||
// + span: $DIR/lifetimes.rs:27:20: 27:23
|
||||
// + user_ty: UserType(4)
|
||||
// + literal: Const { ty: for<'b> fn(&'b Box<dyn std::fmt::Display>) -> core::fmt::ArgumentV1<'b> {core::fmt::ArgumentV1::<'_>::new_display::<Box<dyn std::fmt::Display>>}, val: Value(<ZST>) }
|
||||
// + literal: Const { ty: for<'b> fn(&'b Box<dyn std::fmt::Display>) -> core::fmt::rt::Argument<'b> {core::fmt::rt::Argument::<'_>::new_display::<Box<dyn std::fmt::Display>>}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
bb3: {
|
||||
@ -127,11 +127,11 @@
|
||||
StorageLive(_25); // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
_25 = &_6; // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
_24 = &(*_25); // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
_23 = core::fmt::ArgumentV1::<'_>::new_display::<u32>(move _24) -> [return: bb4, unwind unreachable]; // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
_23 = core::fmt::rt::Argument::<'_>::new_display::<u32>(move _24) -> [return: bb4, unwind unreachable]; // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27
|
||||
// mir::Constant
|
||||
// + span: $DIR/lifetimes.rs:27:24: 27:27
|
||||
// + user_ty: UserType(5)
|
||||
// + literal: Const { ty: for<'b> fn(&'b u32) -> core::fmt::ArgumentV1<'b> {core::fmt::ArgumentV1::<'_>::new_display::<u32>}, val: Value(<ZST>) }
|
||||
// + literal: Const { ty: for<'b> fn(&'b u32) -> core::fmt::rt::Argument<'b> {core::fmt::rt::Argument::<'_>::new_display::<u32>}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
bb4: {
|
||||
@ -141,13 +141,13 @@
|
||||
StorageDead(_20); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
_18 = &_19; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
_17 = &(*_18); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
_16 = move _17 as &[core::fmt::ArgumentV1<'_>] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
_16 = move _17 as &[core::fmt::rt::Argument<'_>] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
StorageDead(_17); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
_11 = Arguments::<'_>::new_v1(move _12, move _16) -> [return: bb5, unwind unreachable]; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/std/src/macros.rs:LL:COL
|
||||
// + user_ty: UserType(3)
|
||||
// + literal: Const { ty: fn(&[&'static str], &[core::fmt::ArgumentV1<'_>]) -> Arguments<'_> {Arguments::<'_>::new_v1}, val: Value(<ZST>) }
|
||||
// + literal: Const { ty: fn(&[&'static str], &[core::fmt::rt::Argument<'_>]) -> Arguments<'_> {Arguments::<'_>::new_v1}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
bb5: {
|
||||
|
28
tests/rustdoc-ui/issue-110900.rs
Normal file
28
tests/rustdoc-ui/issue-110900.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// check-pass
|
||||
|
||||
#![crate_type="lib"]
|
||||
#![feature(associated_type_bounds)]
|
||||
|
||||
trait A<'a> {}
|
||||
trait B<'b> {}
|
||||
|
||||
trait C<'c>: for<'a> A<'a> + for<'b> B<'b> {
|
||||
type As;
|
||||
}
|
||||
|
||||
trait E<'e> {
|
||||
type As;
|
||||
}
|
||||
trait F<'f>: for<'a> A<'a> + for<'e> E<'e> {}
|
||||
struct G<T>
|
||||
where
|
||||
T: for<'l, 'i> H<'l, 'i, As: for<'a> A<'a> + 'i>
|
||||
{
|
||||
t: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
trait I<'a, 'b, 'c> {
|
||||
type As;
|
||||
}
|
||||
|
||||
trait H<'d, 'e>: for<'f> I<'d, 'f, 'e> + 'd {}
|
@ -0,0 +1,20 @@
|
||||
error: `#[macro_export]` can only take 1 or 0 arguments
|
||||
--> $DIR/invalid_macro_export_argument.rs:7:1
|
||||
|
|
||||
LL | #[macro_export(hello, world)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/invalid_macro_export_argument.rs:4:24
|
||||
|
|
||||
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `not_local_inner_macros` isn't a valid `#[macro_export]` argument
|
||||
--> $DIR/invalid_macro_export_argument.rs:13:16
|
||||
|
|
||||
LL | #[macro_export(not_local_inner_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,10 +1,17 @@
|
||||
// check-pass
|
||||
#[macro_export(hello, world)] //~ WARN `#[macro_export]` can only take 1 or 0 arguments
|
||||
// revisions: deny allow
|
||||
//[allow] check-pass
|
||||
|
||||
#![cfg_attr(deny, deny(invalid_macro_export_arguments))]
|
||||
#![cfg_attr(allow, allow(invalid_macro_export_arguments))]
|
||||
|
||||
#[macro_export(hello, world)]
|
||||
//[deny]~^ ERROR `#[macro_export]` can only take 1 or 0 arguments
|
||||
macro_rules! a {
|
||||
() => ()
|
||||
}
|
||||
|
||||
#[macro_export(not_local_inner_macros)] //~ WARN `not_local_inner_macros` isn't a valid `#[macro_export]` argument
|
||||
#[macro_export(not_local_inner_macros)]
|
||||
//[deny]~^ ERROR `not_local_inner_macros` isn't a valid `#[macro_export]` argument
|
||||
macro_rules! b {
|
||||
() => ()
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
warning: `#[macro_export]` can only take 1 or 0 arguments
|
||||
--> $DIR/invalid_macro_export_argument.rs:2:1
|
||||
|
|
||||
LL | #[macro_export(hello, world)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(invalid_macro_export_arguments)]` on by default
|
||||
|
||||
warning: `not_local_inner_macros` isn't a valid `#[macro_export]` argument
|
||||
--> $DIR/invalid_macro_export_argument.rs:7:16
|
||||
|
|
||||
LL | #[macro_export(not_local_inner_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
@ -307,7 +307,7 @@ LL | println!("{} {:.*} {}", 1, 3.2, 4);
|
||||
= note: expected reference `&usize`
|
||||
found reference `&{float}`
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -321,7 +321,7 @@ LL | println!("{} {:07$.*} {}", 1, 3.2, 4);
|
||||
= note: expected reference `&usize`
|
||||
found reference `&{float}`
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 38 previous errors
|
||||
|
@ -17,9 +17,9 @@ LL | format!("{:X}", "3");
|
||||
NonZeroIsize
|
||||
and 21 others
|
||||
= note: required for `&str` to implement `UpperHex`
|
||||
note: required by a bound in `core::fmt::ArgumentV1::<'a>::new_upper_hex`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `arg_new` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex`
|
||||
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
|
||||
error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
--> $DIR/send-sync.rs:8:10
|
||||
|
|
||||
LL | send(format_args!("{:?}", c));
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `[core::fmt::ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque`
|
||||
= note: required because it appears within the type `&core::fmt::Opaque`
|
||||
= note: required because it appears within the type `ArgumentV1<'_>`
|
||||
= note: required because it appears within the type `[ArgumentV1<'_>]`
|
||||
= note: required for `&[core::fmt::ArgumentV1<'_>]` to implement `Send`
|
||||
= help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`
|
||||
= note: required because it appears within the type `&core::fmt::rt::Opaque`
|
||||
= note: required because it appears within the type `Argument<'_>`
|
||||
= note: required because it appears within the type `[Argument<'_>]`
|
||||
= note: required for `&[core::fmt::rt::Argument<'_>]` to implement `Send`
|
||||
= note: required because it appears within the type `Arguments<'_>`
|
||||
note: required by a bound in `send`
|
||||
--> $DIR/send-sync.rs:1:12
|
||||
@ -18,19 +18,19 @@ note: required by a bound in `send`
|
||||
LL | fn send<T: Send>(_: T) {}
|
||||
| ^^^^ required by this bound in `send`
|
||||
|
||||
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
|
||||
error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
--> $DIR/send-sync.rs:9:10
|
||||
|
|
||||
LL | sync(format_args!("{:?}", c));
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
|
||||
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::Opaque`
|
||||
= note: required because it appears within the type `&core::fmt::Opaque`
|
||||
= note: required because it appears within the type `ArgumentV1<'_>`
|
||||
= note: required because it appears within the type `[ArgumentV1<'_>]`
|
||||
= note: required because it appears within the type `&[ArgumentV1<'_>]`
|
||||
= help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`
|
||||
= note: required because it appears within the type `&core::fmt::rt::Opaque`
|
||||
= note: required because it appears within the type `Argument<'_>`
|
||||
= note: required because it appears within the type `[Argument<'_>]`
|
||||
= note: required because it appears within the type `&[Argument<'_>]`
|
||||
= note: required because it appears within the type `Arguments<'_>`
|
||||
note: required by a bound in `sync`
|
||||
--> $DIR/send-sync.rs:2:12
|
||||
|
@ -2,13 +2,23 @@ error: expected `!` after `macro_rules`
|
||||
--> $DIR/missing-bang-in-decl.rs:5:1
|
||||
|
|
||||
LL | macro_rules foo {
|
||||
| ^^^^^^^^^^^ help: add a `!`: `macro_rules!`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
help: add a `!`
|
||||
|
|
||||
LL | macro_rules! foo {
|
||||
| +
|
||||
|
||||
error: expected `!` after `macro_rules`
|
||||
--> $DIR/missing-bang-in-decl.rs:10:1
|
||||
|
|
||||
LL | macro_rules bar! {
|
||||
| ^^^^^^^^^^^ help: add a `!`: `macro_rules!`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
help: add a `!`
|
||||
|
|
||||
LL | macro_rules! bar! {
|
||||
| +
|
||||
|
||||
error: macro names aren't followed by a `!`
|
||||
--> $DIR/missing-bang-in-decl.rs:10:16
|
||||
|
@ -4,31 +4,31 @@
|
||||
|
||||
fn main() {}
|
||||
|
||||
use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
|
||||
use std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
|
||||
use std::ptr::read; //~ ERROR keyword `use` is written in the wrong case
|
||||
use std::ptr::write; //~ ERROR keyword `use` is written in the wrong case
|
||||
|
||||
async fn _a() {}
|
||||
//~^ ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
fn _b() {}
|
||||
//~^ ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
async fn _c() {}
|
||||
//~^ ERROR keyword `async` is written in a wrong case
|
||||
//~| ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `async` is written in the wrong case
|
||||
//~| ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
async fn _d() {}
|
||||
//~^ ERROR keyword `async` is written in a wrong case
|
||||
//~^ ERROR keyword `async` is written in the wrong case
|
||||
|
||||
const unsafe fn _e() {}
|
||||
//~^ ERROR keyword `const` is written in a wrong case
|
||||
//~| ERROR keyword `unsafe` is written in a wrong case
|
||||
//~| ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `const` is written in the wrong case
|
||||
//~| ERROR keyword `unsafe` is written in the wrong case
|
||||
//~| ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
unsafe extern fn _f() {}
|
||||
//~^ ERROR keyword `unsafe` is written in a wrong case
|
||||
//~| ERROR keyword `extern` is written in a wrong case
|
||||
//~^ ERROR keyword `unsafe` is written in the wrong case
|
||||
//~| ERROR keyword `extern` is written in the wrong case
|
||||
|
||||
extern "C" fn _g() {}
|
||||
//~^ ERROR keyword `extern` is written in a wrong case
|
||||
//~| ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `extern` is written in the wrong case
|
||||
//~| ERROR keyword `fn` is written in the wrong case
|
||||
|
@ -4,31 +4,31 @@
|
||||
|
||||
fn main() {}
|
||||
|
||||
Use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
|
||||
USE std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
|
||||
Use std::ptr::read; //~ ERROR keyword `use` is written in the wrong case
|
||||
USE std::ptr::write; //~ ERROR keyword `use` is written in the wrong case
|
||||
|
||||
async Fn _a() {}
|
||||
//~^ ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
Fn _b() {}
|
||||
//~^ ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
aSYNC fN _c() {}
|
||||
//~^ ERROR keyword `async` is written in a wrong case
|
||||
//~| ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `async` is written in the wrong case
|
||||
//~| ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
Async fn _d() {}
|
||||
//~^ ERROR keyword `async` is written in a wrong case
|
||||
//~^ ERROR keyword `async` is written in the wrong case
|
||||
|
||||
CONST UNSAFE FN _e() {}
|
||||
//~^ ERROR keyword `const` is written in a wrong case
|
||||
//~| ERROR keyword `unsafe` is written in a wrong case
|
||||
//~| ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `const` is written in the wrong case
|
||||
//~| ERROR keyword `unsafe` is written in the wrong case
|
||||
//~| ERROR keyword `fn` is written in the wrong case
|
||||
|
||||
unSAFE EXTern fn _f() {}
|
||||
//~^ ERROR keyword `unsafe` is written in a wrong case
|
||||
//~| ERROR keyword `extern` is written in a wrong case
|
||||
//~^ ERROR keyword `unsafe` is written in the wrong case
|
||||
//~| ERROR keyword `extern` is written in the wrong case
|
||||
|
||||
EXTERN "C" FN _g() {}
|
||||
//~^ ERROR keyword `extern` is written in a wrong case
|
||||
//~| ERROR keyword `fn` is written in a wrong case
|
||||
//~^ ERROR keyword `extern` is written in the wrong case
|
||||
//~| ERROR keyword `fn` is written in the wrong case
|
||||
|
@ -1,82 +1,82 @@
|
||||
error: keyword `use` is written in a wrong case
|
||||
error: keyword `use` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:7:1
|
||||
|
|
||||
LL | Use std::ptr::read;
|
||||
| ^^^ help: write it in the correct case (notice the capitalization): `use`
|
||||
|
||||
error: keyword `use` is written in a wrong case
|
||||
error: keyword `use` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:8:1
|
||||
|
|
||||
LL | USE std::ptr::write;
|
||||
| ^^^ help: write it in the correct case: `use`
|
||||
|
||||
error: keyword `fn` is written in a wrong case
|
||||
error: keyword `fn` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:10:7
|
||||
|
|
||||
LL | async Fn _a() {}
|
||||
| ^^ help: write it in the correct case (notice the capitalization): `fn`
|
||||
|
||||
error: keyword `fn` is written in a wrong case
|
||||
error: keyword `fn` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:13:1
|
||||
|
|
||||
LL | Fn _b() {}
|
||||
| ^^ help: write it in the correct case (notice the capitalization): `fn`
|
||||
|
||||
error: keyword `async` is written in a wrong case
|
||||
error: keyword `async` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:16:1
|
||||
|
|
||||
LL | aSYNC fN _c() {}
|
||||
| ^^^^^ help: write it in the correct case: `async`
|
||||
|
||||
error: keyword `fn` is written in a wrong case
|
||||
error: keyword `fn` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:16:7
|
||||
|
|
||||
LL | aSYNC fN _c() {}
|
||||
| ^^ help: write it in the correct case: `fn`
|
||||
|
||||
error: keyword `async` is written in a wrong case
|
||||
error: keyword `async` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:20:1
|
||||
|
|
||||
LL | Async fn _d() {}
|
||||
| ^^^^^ help: write it in the correct case: `async`
|
||||
|
||||
error: keyword `const` is written in a wrong case
|
||||
error: keyword `const` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:23:1
|
||||
|
|
||||
LL | CONST UNSAFE FN _e() {}
|
||||
| ^^^^^ help: write it in the correct case: `const`
|
||||
|
||||
error: keyword `unsafe` is written in a wrong case
|
||||
error: keyword `unsafe` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:23:7
|
||||
|
|
||||
LL | CONST UNSAFE FN _e() {}
|
||||
| ^^^^^^ help: write it in the correct case: `unsafe`
|
||||
|
||||
error: keyword `fn` is written in a wrong case
|
||||
error: keyword `fn` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:23:14
|
||||
|
|
||||
LL | CONST UNSAFE FN _e() {}
|
||||
| ^^ help: write it in the correct case: `fn`
|
||||
|
||||
error: keyword `unsafe` is written in a wrong case
|
||||
error: keyword `unsafe` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:28:1
|
||||
|
|
||||
LL | unSAFE EXTern fn _f() {}
|
||||
| ^^^^^^ help: write it in the correct case: `unsafe`
|
||||
|
||||
error: keyword `extern` is written in a wrong case
|
||||
error: keyword `extern` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:28:8
|
||||
|
|
||||
LL | unSAFE EXTern fn _f() {}
|
||||
| ^^^^^^ help: write it in the correct case: `extern`
|
||||
|
||||
error: keyword `extern` is written in a wrong case
|
||||
error: keyword `extern` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:32:1
|
||||
|
|
||||
LL | EXTERN "C" FN _g() {}
|
||||
| ^^^^^^ help: write it in the correct case: `extern`
|
||||
|
||||
error: keyword `fn` is written in a wrong case
|
||||
error: keyword `fn` is written in the wrong case
|
||||
--> $DIR/item-kw-case-mismatch.rs:32:12
|
||||
|
|
||||
LL | EXTERN "C" FN _g() {}
|
||||
|
@ -2,13 +2,17 @@ error: expected a label, found an identifier
|
||||
--> $DIR/recover-unticked-labels.rs:5:26
|
||||
|
|
||||
LL | 'label: loop { break label 0 };
|
||||
| ^^^^^ help: labels start with a tick: `'label`
|
||||
| -^^^^
|
||||
| |
|
||||
| help: labels start with a tick
|
||||
|
||||
error: expected a label, found an identifier
|
||||
--> $DIR/recover-unticked-labels.rs:6:29
|
||||
|
|
||||
LL | 'label: loop { continue label };
|
||||
| ^^^^^ help: labels start with a tick: `'label`
|
||||
| -^^^^
|
||||
| |
|
||||
| help: labels start with a tick
|
||||
|
||||
error[E0425]: cannot find value `label` in this scope
|
||||
--> $DIR/recover-unticked-labels.rs:4:26
|
||||
|
@ -11,18 +11,24 @@ error: expected `::`, found `:`
|
||||
|
|
||||
LL | use std:fs::File;
|
||||
| ^ help: use double colon
|
||||
|
|
||||
= note: import paths are delimited using `::`
|
||||
|
||||
error: expected `::`, found `:`
|
||||
--> $DIR/use-colon-as-mod-sep.rs:7:8
|
||||
|
|
||||
LL | use std:collections:HashMap;
|
||||
| ^ help: use double colon
|
||||
|
|
||||
= note: import paths are delimited using `::`
|
||||
|
||||
error: expected `::`, found `:`
|
||||
--> $DIR/use-colon-as-mod-sep.rs:7:20
|
||||
|
|
||||
LL | use std:collections:HashMap;
|
||||
| ^ help: use double colon
|
||||
|
|
||||
= note: import paths are delimited using `::`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user