diff --git a/Cargo.lock b/Cargo.lock index 9ea22911d5157..ada42bc1eeb0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4281,7 +4281,6 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index b497c6beeb984..cde8b8f9fe2e9 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -827,7 +827,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir_id, def_id: self.local_def_id(v.id), data: self.lower_variant_data(hir_id, item_kind, &v.data), - disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)), + disr_expr: v + .disr_expr + .as_ref() + .map(|e| self.lower_anon_const_to_anon_const(e, e.value.span)), ident: self.lower_ident(v.ident), span: self.lower_span(v.span), } @@ -917,7 +920,10 @@ impl<'hir> LoweringContext<'_, 'hir> { None => Ident::new(sym::integer(index), self.lower_span(f.span)), }, vis_span: self.lower_span(f.vis.span), - default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)), + default: f + .default + .as_ref() + .map(|v| self.lower_anon_const_to_anon_const(v, v.value.span)), ty, safety: self.lower_safety(f.safety, hir::Safety::Safe), } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e4698ce8d6db4..6dded9936fbac 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2425,15 +2425,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| { - let const_arg = if let ExprKind::ConstBlock(anon_const) = &arg.kind { - let def_id = self.local_def_id(anon_const.id); - let def_kind = self.tcx.def_kind(def_id); - assert_eq!(DefKind::AnonConst, def_kind); - self.lower_anon_const_to_const_arg(anon_const) - } else { - self.lower_expr_to_const_arg_direct(arg) - }; - + let const_arg = self.lower_expr_to_const_arg_direct(arg); &*self.arena.alloc(const_arg) })); @@ -2445,16 +2437,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } ExprKind::Tup(exprs) => { let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| { - let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind { - let def_id = self.local_def_id(anon_const.id); - let def_kind = self.tcx.def_kind(def_id); - assert_eq!(DefKind::AnonConst, def_kind); - - self.lower_anon_const_to_const_arg(anon_const) - } else { - self.lower_expr_to_const_arg_direct(&expr) - }; - + let expr = self.lower_expr_to_const_arg_direct(&expr); &*self.arena.alloc(expr) })); @@ -2494,16 +2477,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // then go unused as the `Target::ExprField` is not actually // corresponding to `Node::ExprField`. self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField); - - let expr = if let ExprKind::ConstBlock(anon_const) = &f.expr.kind { - let def_id = self.local_def_id(anon_const.id); - let def_kind = self.tcx.def_kind(def_id); - assert_eq!(DefKind::AnonConst, def_kind); - - self.lower_anon_const_to_const_arg(anon_const) - } else { - self.lower_expr_to_const_arg_direct(&f.expr) - }; + let expr = self.lower_expr_to_const_arg_direct(&f.expr); &*self.arena.alloc(hir::ConstArgExprField { hir_id, @@ -2521,13 +2495,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } ExprKind::Array(elements) => { let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| { - let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind { - let def_id = self.local_def_id(anon_const.id); - assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id)); - self.lower_anon_const_to_const_arg(anon_const) - } else { - self.lower_expr_to_const_arg_direct(element) - }; + let const_arg = self.lower_expr_to_const_arg_direct(element); &*self.arena.alloc(const_arg) })); let array_expr = self.arena.alloc(hir::ConstArgArrayExpr { @@ -2557,6 +2525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | ExprKind::Call(..) | ExprKind::Tup(..) | ExprKind::Array(..) + | ExprKind::ConstBlock(..) ) { return self.lower_expr_to_const_arg_direct(expr); @@ -2586,6 +2555,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span, } } + ExprKind::ConstBlock(anon_const) => { + let def_id = self.local_def_id(anon_const.id); + assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id)); + self.lower_anon_const_to_const_arg(anon_const, span) + } _ => overly_complex_const(self), } } @@ -2596,11 +2570,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, anon: &AnonConst, ) -> &'hir hir::ConstArg<'hir> { - self.arena.alloc(self.lower_anon_const_to_const_arg(anon)) + self.arena.alloc(self.lower_anon_const_to_const_arg(anon, anon.value.span)) } #[instrument(level = "debug", skip(self))] - fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> { + fn lower_anon_const_to_const_arg( + &mut self, + anon: &AnonConst, + span: Span, + ) -> hir::ConstArg<'hir> { let tcx = self.tcx; // We cannot change parsing depending on feature gates available, @@ -2611,7 +2589,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if tcx.features().min_generic_const_args() { return match anon.mgca_disambiguation { MgcaDisambiguation::AnonConst => { - let lowered_anon = self.lower_anon_const_to_anon_const(anon); + let lowered_anon = self.lower_anon_const_to_anon_const(anon, span); ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon), @@ -2657,7 +2635,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; } - let lowered_anon = self.lower_anon_const_to_anon_const(anon); + let lowered_anon = self.lower_anon_const_to_anon_const(anon, anon.value.span); ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon), @@ -2667,7 +2645,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// See [`hir::ConstArg`] for when to use this function vs /// [`Self::lower_anon_const_to_const_arg`]. - fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst { + fn lower_anon_const_to_anon_const( + &mut self, + c: &AnonConst, + span: Span, + ) -> &'hir hir::AnonConst { self.arena.alloc(self.with_new_scopes(c.value.span, |this| { let def_id = this.local_def_id(c.id); let hir_id = this.lower_node_id(c.id); @@ -2675,7 +2657,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { def_id, hir_id, body: this.lower_const_body(c.value.span, Some(&c.value)), - span: this.lower_span(c.value.span), + span: this.lower_span(span), } })) } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 4bbcf7373589c..11bd05cafa48c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -115,7 +115,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ // tidy-alphabetical-start rustc_const_eval::DEFAULT_LOCALE_RESOURCE, rustc_lint::DEFAULT_LOCALE_RESOURCE, - rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index f756f0a19ee9b..f05183d7c0681 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -12,7 +12,6 @@ rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl deleted file mode 100644 index 8b0c38dd3b536..0000000000000 --- a/compiler/rustc_mir_build/messages.ftl +++ /dev/null @@ -1,513 +0,0 @@ -mir_build_adt_defined_here = `{$ty}` defined here - -mir_build_already_borrowed = cannot borrow value as mutable because it is also borrowed as immutable - -mir_build_already_mut_borrowed = cannot borrow value as immutable because it is also borrowed as mutable - -mir_build_bindings_with_variant_name = - pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}` - .suggestion = to match on the variant, qualify the path - -mir_build_borrow = value is borrowed by `{$name}` here - -mir_build_borrow_of_layout_constrained_field_requires_unsafe = - borrow of layout constrained field with interior mutability is unsafe and requires unsafe block - .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - .label = borrow of layout constrained field with interior mutability - -mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block - .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - .label = borrow of layout constrained field with interior mutability - -mir_build_borrow_of_moved_value = borrow of moved value - .label = value moved into `{$name}` here - .occurs_because_label = move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait - .value_borrowed_label = value borrowed here after move - .suggestion = borrow this binding in the pattern to avoid moving the value - -mir_build_call_to_deprecated_safe_fn_requires_unsafe = - call to deprecated safe function `{$function}` is unsafe and requires unsafe block - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - .suggestion = you can wrap the call in an `unsafe` block if you can guarantee {$guarantee} - -mir_build_call_to_fn_with_requires_unsafe = - call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block - .help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> - [1] feature - *[count] features - }: {$missing_target_features} - .note = the {$build_target_features} target {$build_target_features_count -> - [1] feature - *[count] features - } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> - [1] it - *[count] them - } in `#[target_feature]` - .label = call to function with `#[target_feature]` - -mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe function or block - .help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> - [1] feature - *[count] features - }: {$missing_target_features} - .note = the {$build_target_features} target {$build_target_features_count -> - [1] feature - *[count] features - } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> - [1] it - *[count] them - } in `#[target_feature]` - .label = call to function with `#[target_feature]` - -mir_build_call_to_unsafe_fn_requires_unsafe = - call to unsafe function `{$function}` is unsafe and requires unsafe block - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - -mir_build_call_to_unsafe_fn_requires_unsafe_nameless = - call to unsafe function is unsafe and requires unsafe block - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - -mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed = - call to unsafe function is unsafe and requires unsafe function or block - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - -mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - call to unsafe function `{$function}` is unsafe and requires unsafe function or block - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - -mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable - -mir_build_const_continue_bad_const = could not determine the target branch for this `#[const_continue]` - .label = this value is too generic - -mir_build_const_continue_missing_label_or_value = a `#[const_continue]` must break to a label with a value - -mir_build_const_continue_not_const = could not determine the target branch for this `#[const_continue]` - .help = try extracting the expression into a `const` item - -mir_build_const_continue_not_const_const_block = `const` blocks may use generics, and are not evaluated early enough -mir_build_const_continue_not_const_const_other = this value must be a literal or a monomorphic const -mir_build_const_continue_not_const_constant_parameter = constant parameters may use generics, and are not evaluated early enough - -mir_build_const_continue_unknown_jump_target = the target of this `#[const_continue]` is not statically known - .label = this value must be a literal or a monomorphic const - -mir_build_const_defined_here = constant defined here - -mir_build_const_param_in_pattern = constant parameters cannot be referenced in patterns - .label = can't be used in patterns -mir_build_const_param_in_pattern_def = constant defined here - -mir_build_const_pattern_depends_on_generic_parameter = constant pattern cannot depend on generic parameters - .label = `const` depends on a generic parameter - -mir_build_could_not_eval_const_pattern = could not evaluate constant pattern - .label = could not evaluate constant - -mir_build_deref_raw_pointer_requires_unsafe = - dereference of raw pointer is unsafe and requires unsafe block - .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior - .label = dereference of raw pointer - -mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - dereference of raw pointer is unsafe and requires unsafe function or block - .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior - .label = dereference of raw pointer - -mir_build_extern_static_requires_unsafe = - use of extern static is unsafe and requires unsafe block - .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior - .label = use of extern static - -mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - use of extern static is unsafe and requires unsafe function or block - .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior - .label = use of extern static - -mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - -mir_build_initializing_type_with_requires_unsafe = - initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe block - .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior - .label = initializing type with `rustc_layout_scalar_valid_range` attr - -mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block - .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior - .label = initializing type with `rustc_layout_scalar_valid_range` attr - -mir_build_initializing_type_with_unsafe_field_requires_unsafe = - initializing type with an unsafe field is unsafe and requires unsafe block - .note = unsafe fields may carry library invariants - .label = initialization of struct with unsafe field - -mir_build_initializing_type_with_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - initializing type with an unsafe field is unsafe and requires unsafe block - .note = unsafe fields may carry library invariants - .label = initialization of struct with unsafe field - -mir_build_inline_assembly_requires_unsafe = - use of inline assembly is unsafe and requires unsafe block - .note = inline assembly is entirely unchecked and can cause undefined behavior - .label = use of inline assembly - -mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - use of inline assembly is unsafe and requires unsafe function or block - .note = inline assembly is entirely unchecked and can cause undefined behavior - .label = use of inline assembly - -mir_build_interpreted_as_const = introduce a variable instead - -mir_build_invalid_pattern = {$prefix} `{$non_sm_ty}` cannot be used in patterns - .label = {$prefix} can't be used in patterns - -mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count -> - [one] pattern - *[other] patterns - } - .note = {$count -> - [one] this pattern - *[other] these patterns - } will always match, so the `if let` is useless - .help = consider replacing the `if let` with a `let` - -mir_build_irrefutable_let_patterns_if_let_guard = irrefutable `if let` guard {$count -> - [one] pattern - *[other] patterns - } - .note = {$count -> - [one] this pattern - *[other] these patterns - } will always match, so the guard is useless - .help = consider removing the guard and adding a `let` inside the match arm - -mir_build_irrefutable_let_patterns_let_else = irrefutable `let...else` {$count -> - [one] pattern - *[other] patterns - } - .note = {$count -> - [one] this pattern - *[other] these patterns - } will always match, so the `else` clause is useless - .help = consider removing the `else` clause - -mir_build_irrefutable_let_patterns_while_let = irrefutable `while let` {$count -> - [one] pattern - *[other] patterns - } - .note = {$count -> - [one] this pattern - *[other] these patterns - } will always match, so the loop will never exit - .help = consider instead using a `loop {"{"} ... {"}"}` with a `let` inside it - -mir_build_leading_irrefutable_let_patterns = leading irrefutable {$count -> - [one] pattern - *[other] patterns - } in let chain - .note = {$count -> - [one] this pattern - *[other] these patterns - } will always match - .help = consider moving {$count -> - [one] it - *[other] them - } outside of the construct - -mir_build_literal_in_range_out_of_bounds = - literal out of range for `{$ty}` - .label = this value does not fit into the type `{$ty}` whose range is `{$min}..={$max}` - -mir_build_loop_match_arm_with_guard = - match arms that are part of a `#[loop_match]` cannot have guards - -mir_build_loop_match_bad_rhs = - this expression must be a single `match` wrapped in a labeled block - -mir_build_loop_match_bad_statements = - statements are not allowed in this position within a `#[loop_match]` - -mir_build_loop_match_invalid_match = - invalid match on `#[loop_match]` state - .note = a local variable must be the scrutinee within a `#[loop_match]` - -mir_build_loop_match_invalid_update = - invalid update of the `#[loop_match]` state - .label = the assignment must update this variable - -mir_build_loop_match_missing_assignment = - expected a single assignment expression - -mir_build_loop_match_unsupported_type = - this `#[loop_match]` state value has type `{$ty}`, which is not supported - .note = only integers, floats, bool, char, and enums without fields are supported - -mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper = - lower bound for range pattern must be less than or equal to upper bound - .label = lower bound larger than upper bound - .teach_note = When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range. - -mir_build_lower_range_bound_must_be_less_than_upper = lower bound for range pattern must be less than upper bound - -mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html - -mir_build_moved = value is moved into `{$name}` here - -mir_build_moved_while_borrowed = cannot move out of value because it is borrowed - -mir_build_multiple_mut_borrows = cannot borrow value as mutable more than once at a time - -mir_build_mutable_borrow = value is mutably borrowed by `{$name}` here - -mir_build_mutable_static_requires_unsafe = - use of mutable static is unsafe and requires unsafe block - .note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior - .label = use of mutable static - -mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - use of mutable static is unsafe and requires unsafe function or block - .note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior - .label = use of mutable static - -mir_build_mutation_of_layout_constrained_field_requires_unsafe = - mutation of layout constrained field is unsafe and requires unsafe block - .note = mutating layout constrained fields cannot statically be checked for valid values - .label = mutation of layout constrained field - -mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - mutation of layout constrained field is unsafe and requires unsafe function or block - .note = mutating layout constrained fields cannot statically be checked for valid values - .label = mutation of layout constrained field - -mir_build_nan_pattern = cannot use NaN in patterns - .label = evaluates to `NaN`, which is not allowed in patterns - .note = NaNs compare inequal to everything, even themselves, so this pattern would never match - .help = try using the `is_nan` method instead - -mir_build_non_const_path = runtime values cannot be referenced in patterns - .label = references a runtime value - -mir_build_non_empty_never_pattern = - mismatched types - .label = a never pattern must be used on an uninhabited type - .note = the matched value is of type `{$ty}` - -mir_build_non_exhaustive_match_all_arms_guarded = - match arms with guards don't count towards exhaustivity - -mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type `{$ty}` is non-empty - .def_note = `{$peeled_ty}` defined here - .type_note = the matched value is of type `{$ty}` - .non_exhaustive_type_note = the matched value is of type `{$ty}`, which is marked as non-exhaustive - .reference_note = references are always considered inhabited - .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern - -mir_build_non_partial_eq_match = constant of non-structural type `{$ty}` in a pattern - .label = constant of non-structural type - -mir_build_pattern_not_covered = refutable pattern in {$origin} - .pattern_ty = the matched value is of type `{$pattern_ty}` - -mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon - .label = can't be used in patterns - .note = see https://github.com/rust-lang/rust/issues/70861 for details - -mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future - -mir_build_static_in_pattern = statics cannot be referenced in patterns - .label = can't be used in patterns -mir_build_static_in_pattern_def = `static` defined here - -mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits - - -mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count -> - [one] variant that isn't - *[other] variants that aren't - } matched - -mir_build_suggest_let_else = you might want to use `let...else` to handle the {$count -> - [one] variant that isn't - *[other] variants that aren't - } matched - -mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count -> - [one] pattern - *[other] patterns - } in let chain - .note = {$count -> - [one] this pattern - *[other] these patterns - } will always match - .help = consider moving {$count -> - [one] it - *[other] them - } into the body - -mir_build_type_not_structural = constant of non-structural type `{$ty}` in a pattern - .label = constant of non-structural type -mir_build_type_not_structural_def = `{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns -mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -mir_build_type_not_structural_tip = - the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - -mir_build_union_field_requires_unsafe = - access to union field is unsafe and requires unsafe block - .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior - .label = access to union field - -mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - access to union field is unsafe and requires unsafe function or block - .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior - .label = access to union field - -mir_build_union_pattern = cannot use unions in constant patterns - .label = can't use a `union` here - -mir_build_unreachable_due_to_uninhabited = unreachable {$descr} - .label = unreachable {$descr} - .label_orig = any code following this expression is unreachable - .note = this expression has type `{$ty}`, which is uninhabited - -mir_build_unreachable_making_this_unreachable = collectively making this unreachable - -mir_build_unreachable_making_this_unreachable_n_more = ...and {$covered_by_many_n_more_count} other patterns collectively make this unreachable - -mir_build_unreachable_matches_same_values = matches some of the same values - -mir_build_unreachable_pattern = unreachable pattern - .label = no value can reach this - .unreachable_matches_no_values = matches no values because `{$matches_no_values_ty}` is uninhabited - .unreachable_uninhabited_note = to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - .unreachable_covered_by_catchall = matches any value - .unreachable_covered_by_one = matches all the relevant values - .unreachable_covered_by_many = multiple earlier patterns match some of the same values - .unreachable_pattern_const_reexport_accessible = there is a constant of the same name imported in another scope, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it needs to be imported in the pattern's scope - .unreachable_pattern_wanted_const = you might have meant to pattern match against the value of {$is_typo -> - [true] similarly named constant - *[false] constant - } `{$const_name}` instead of introducing a new catch-all binding - .unreachable_pattern_const_inaccessible = there is a constant of the same name, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it is not accessible from this scope - .unreachable_pattern_let_binding = there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings - .suggestion = remove the match arm - -mir_build_unsafe_binder_cast_requires_unsafe = - unsafe binder cast is unsafe and requires unsafe block - .label = unsafe binder cast - .note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime - information that may be required to uphold safety guarantees of a type - -mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - unsafe binder cast is unsafe and requires unsafe block or unsafe fn - .label = unsafe binder cast - .note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime - information that may be required to uphold safety guarantees of a type - -mir_build_unsafe_field_requires_unsafe = - use of unsafe field is unsafe and requires unsafe block - .note = unsafe fields may carry library invariants - .label = use of unsafe field - -mir_build_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = - use of unsafe field is unsafe and requires unsafe block - .note = unsafe fields may carry library invariants - .label = use of unsafe field - -mir_build_unsafe_fn_safe_body = an unsafe function restricts its caller, but its body is safe by default -mir_build_unsafe_not_inherited = items do not inherit unsafety from separate enclosing items - -mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe = - borrow of layout constrained field with interior mutability is unsafe and requires unsafe block - .note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values - .label = borrow of layout constrained field with interior mutability - -mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe = - call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block - .help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> - [1] feature - *[count] features - }: {$missing_target_features} - .note = the {$build_target_features} target {$build_target_features_count -> - [1] feature - *[count] features - } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> - [1] it - *[count] them - } in `#[target_feature]` - .label = call to function with `#[target_feature]` - -mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe = - call to unsafe function `{$function}` is unsafe and requires unsafe block - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - -mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless = - call to unsafe function is unsafe and requires unsafe block - .note = consult the function's documentation for information on how to avoid undefined behavior - .label = call to unsafe function - -mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe = - dereference of raw pointer is unsafe and requires unsafe block - .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior - .label = dereference of raw pointer - -mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe = - use of extern static is unsafe and requires unsafe block - .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior - .label = use of extern static - -mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe = - initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe block - .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior - .label = initializing type with `rustc_layout_scalar_valid_range` attr - -mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_unsafe_field_requires_unsafe = - initializing type with an unsafe field is unsafe and requires unsafe block - .note = unsafe fields may carry library invariants - .label = initialization of struct with unsafe field - -mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe = - use of inline assembly is unsafe and requires unsafe block - .note = inline assembly is entirely unchecked and can cause undefined behavior - .label = use of inline assembly - -mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe = - use of mutable static is unsafe and requires unsafe block - .note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior - .label = use of mutable static - -mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe = - mutation of layout constrained field is unsafe and requires unsafe block - .note = mutating layout constrained fields cannot statically be checked for valid values - .label = mutation of layout constrained field - -mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe = - access to union field is unsafe and requires unsafe block - .note = the field may not be properly initialized: using uninitialized data will cause undefined behavior - .label = access to union field - -mir_build_unsafe_op_in_unsafe_fn_unsafe_field_requires_unsafe = - use of unsafe field is unsafe and requires unsafe block - .note = unsafe fields may carry library invariants - .label = use of unsafe field - -mir_build_unsized_pattern = cannot use unsized non-slice type `{$non_sm_ty}` in constant patterns - -mir_build_unused_unsafe = unnecessary `unsafe` block - .label = unnecessary `unsafe` block - -mir_build_unused_unsafe_enclosing_block_label = because it's nested under this `unsafe` block - -mir_build_upper_range_bound_cannot_be_min = exclusive upper bound for a range bound cannot be the minimum - -mir_build_variant_defined_here = not covered - -mir_build_wrap_suggestion = consider wrapping the function body in an unsafe block diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 64e2bb3207c87..f51e130ea47a5 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,7 +1,7 @@ use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, - MultiSpan, Subdiagnostic, + MultiSpan, Subdiagnostic, inline_fluent, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; @@ -9,12 +9,10 @@ use rustc_pattern_analysis::errors::Uncovered; use rustc_pattern_analysis::rustc::RustcPatCtxt; use rustc_span::{Ident, Span, Symbol}; -use crate::fluent_generated as fluent; - #[derive(LintDiagnostic)] -#[diag(mir_build_call_to_deprecated_safe_fn_requires_unsafe)] +#[diag("call to deprecated safe function `{$function}` is unsafe and requires unsafe block")] pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { - #[label] + #[label("call to unsafe function")] pub(crate) span: Span, pub(crate) function: String, pub(crate) guarantee: String, @@ -23,7 +21,10 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { } #[derive(Subdiagnostic)] -#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "you can wrap the call in an `unsafe` block if you can guarantee that the environment access only happens in single-threaded code", + applicability = "machine-applicable" +)] pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { pub(crate) start_of_line_suggestion: String, #[suggestion_part(code = "{start_of_line_suggestion}")] @@ -35,10 +36,10 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe, code = E0133)] -#[note] +#[diag("call to unsafe function `{$function}` is unsafe and requires unsafe block", code = E0133)] +#[note("consult the function's documentation for information on how to avoid undefined behavior")] pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { - #[label] + #[label("call to unsafe function")] pub(crate) span: Span, pub(crate) function: String, #[subdiagnostic] @@ -46,90 +47,100 @@ pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] -#[note] +#[diag("call to unsafe function is unsafe and requires unsafe block", code = E0133)] +#[note("consult the function's documentation for information on how to avoid undefined behavior")] pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { - #[label] + #[label("call to unsafe function")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe, code = E0133)] -#[note] +#[diag("use of inline assembly is unsafe and requires unsafe block", code = E0133)] +#[note("inline assembly is entirely unchecked and can cause undefined behavior")] pub(crate) struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { - #[label] + #[label("use of inline assembly")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe, code = E0133)] -#[note] +#[diag("initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe block", code = E0133)] +#[note( + "initializing a layout restricted type's field with a value outside the valid range is undefined behavior" +)] pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { - #[label] + #[label("initializing type with `rustc_layout_scalar_valid_range` attr")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_unsafe_field_requires_unsafe, code = E0133)] -#[note] +#[diag("initializing type with an unsafe field is unsafe and requires unsafe block", code = E0133)] +#[note("unsafe fields may carry library invariants")] pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithUnsafeFieldRequiresUnsafe { - #[label] + #[label("initialization of struct with unsafe field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)] -#[note] +#[diag("use of mutable static is unsafe and requires unsafe block", code = E0133)] +#[note( + "mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior" +)] pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { - #[label] + #[label("use of mutable static")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe, code = E0133)] -#[note] +#[diag("use of extern static is unsafe and requires unsafe block", code = E0133)] +#[note( + "extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior" +)] pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { - #[label] + #[label("use of extern static")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_unsafe_field_requires_unsafe, code = E0133)] -#[note] +#[diag("use of unsafe field is unsafe and requires unsafe block", code = E0133)] +#[note("unsafe fields may carry library invariants")] pub(crate) struct UnsafeOpInUnsafeFnUseOfUnsafeFieldRequiresUnsafe { - #[label] + #[label("use of unsafe field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)] -#[note] +#[diag("dereference of raw pointer is unsafe and requires unsafe block", code = E0133)] +#[note( + "raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior" +)] pub(crate) struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { - #[label] + #[label("dereference of raw pointer")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe, code = E0133)] -#[note] +#[diag("access to union field is unsafe and requires unsafe block", code = E0133)] +#[note( + "the field may not be properly initialized: using uninitialized data will cause undefined behavior" +)] pub(crate) struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { - #[label] + #[label("access to union field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -137,12 +148,12 @@ pub(crate) struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { #[derive(LintDiagnostic)] #[diag( - mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe, + "mutation of layout constrained field is unsafe and requires unsafe block", code = E0133 )] -#[note] +#[note("mutating layout constrained fields cannot statically be checked for valid values")] pub(crate) struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { - #[label] + #[label("mutation of layout constrained field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -150,11 +161,11 @@ pub(crate) struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsa #[derive(LintDiagnostic)] #[diag( - mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe, + "borrow of layout constrained field with interior mutability is unsafe and requires unsafe block", code = E0133, )] pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { - #[label] + #[label("borrow of layout constrained field with interior mutability")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -162,26 +173,37 @@ pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe #[derive(LintDiagnostic)] #[diag( - mir_build_unsafe_binder_cast_requires_unsafe, + "unsafe binder cast is unsafe and requires unsafe block information that may be required to uphold safety guarantees of a type", code = E0133, )] pub(crate) struct UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe { - #[label] + #[label("unsafe binder cast")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] -#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)] -#[help] +#[diag("call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block", code = E0133)] +#[help( + "in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> + [1] feature + *[count] features + }: {$missing_target_features}" +)] pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { - #[label] + #[label("call to function with `#[target_feature]`")] pub(crate) span: Span, pub(crate) function: String, pub(crate) missing_target_features: DiagArgValue, pub(crate) missing_target_features_count: usize, - #[note] + #[note("the {$build_target_features} target {$build_target_features_count -> + [1] feature + *[count] features + } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> + [1] it +*[count] them +} in `#[target_feature]`")] pub(crate) note: bool, pub(crate) build_target_features: DiagArgValue, pub(crate) build_target_features_count: usize, @@ -190,11 +212,11 @@ pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { } #[derive(Diagnostic)] -#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)] -#[note] +#[diag("call to unsafe function `{$function}` is unsafe and requires unsafe block", code = E0133)] +#[note("consult the function's documentation for information on how to avoid undefined behavior")] pub(crate) struct CallToUnsafeFunctionRequiresUnsafe { #[primary_span] - #[label] + #[label("call to unsafe function")] pub(crate) span: Span, pub(crate) function: String, #[subdiagnostic] @@ -202,22 +224,22 @@ pub(crate) struct CallToUnsafeFunctionRequiresUnsafe { } #[derive(Diagnostic)] -#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] -#[note] +#[diag("call to unsafe function is unsafe and requires unsafe block", code = E0133)] +#[note("consult the function's documentation for information on how to avoid undefined behavior")] pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNameless { #[primary_span] - #[label] + #[label("call to unsafe function")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[note] +#[diag("call to unsafe function `{$function}` is unsafe and requires unsafe function or block", code = E0133)] +#[note("consult the function's documentation for information on how to avoid undefined behavior")] pub(crate) struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("call to unsafe function")] pub(crate) span: Span, pub(crate) function: String, #[subdiagnostic] @@ -226,57 +248,59 @@ pub(crate) struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[derive(Diagnostic)] #[diag( - mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed, + "call to unsafe function is unsafe and requires unsafe function or block", code = E0133 )] -#[note] +#[note("consult the function's documentation for information on how to avoid undefined behavior")] pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("call to unsafe function")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_inline_assembly_requires_unsafe, code = E0133)] -#[note] +#[diag("use of inline assembly is unsafe and requires unsafe block", code = E0133)] +#[note("inline assembly is entirely unchecked and can cause undefined behavior")] pub(crate) struct UseOfInlineAssemblyRequiresUnsafe { #[primary_span] - #[label] + #[label("use of inline assembly")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[note] +#[diag("use of inline assembly is unsafe and requires unsafe function or block", code = E0133)] +#[note("inline assembly is entirely unchecked and can cause undefined behavior")] pub(crate) struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("use of inline assembly")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_initializing_type_with_requires_unsafe, code = E0133)] -#[note] +#[diag("initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe block", code = E0133)] +#[note( + "initializing a layout restricted type's field with a value outside the valid range is undefined behavior" +)] pub(crate) struct InitializingTypeWithRequiresUnsafe { #[primary_span] - #[label] + #[label("initializing type with `rustc_layout_scalar_valid_range` attr")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_initializing_type_with_unsafe_field_requires_unsafe, code = E0133)] -#[note] +#[diag("initializing type with an unsafe field is unsafe and requires unsafe block", code = E0133)] +#[note("unsafe fields may carry library invariants")] pub(crate) struct InitializingTypeWithUnsafeFieldRequiresUnsafe { #[primary_span] - #[label] + #[label("initialization of struct with unsafe field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -284,13 +308,15 @@ pub(crate) struct InitializingTypeWithUnsafeFieldRequiresUnsafe { #[derive(Diagnostic)] #[diag( - mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + "initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block", code = E0133 )] -#[note] +#[note( + "initializing a layout restricted type's field with a value outside the valid range is undefined behavior" +)] pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("initializing type with `rustc_layout_scalar_valid_range` attr")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -298,134 +324,150 @@ pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[derive(Diagnostic)] #[diag( - mir_build_initializing_type_with_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + "initializing type with an unsafe field is unsafe and requires unsafe block", code = E0133 )] -#[note] +#[note("unsafe fields may carry library invariants")] pub(crate) struct InitializingTypeWithUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("initialization of struct with unsafe field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_mutable_static_requires_unsafe, code = E0133)] -#[note] +#[diag("use of mutable static is unsafe and requires unsafe block", code = E0133)] +#[note( + "mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior" +)] pub(crate) struct UseOfMutableStaticRequiresUnsafe { #[primary_span] - #[label] + #[label("use of mutable static")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[note] +#[diag("use of mutable static is unsafe and requires unsafe function or block", code = E0133)] +#[note( + "mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior" +)] pub(crate) struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("use of mutable static")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_extern_static_requires_unsafe, code = E0133)] -#[note] +#[diag("use of extern static is unsafe and requires unsafe block", code = E0133)] +#[note( + "extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior" +)] pub(crate) struct UseOfExternStaticRequiresUnsafe { #[primary_span] - #[label] + #[label("use of extern static")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[note] +#[diag("use of extern static is unsafe and requires unsafe function or block", code = E0133)] +#[note( + "extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior" +)] pub(crate) struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("use of extern static")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_unsafe_field_requires_unsafe, code = E0133)] -#[note] +#[diag("use of unsafe field is unsafe and requires unsafe block", code = E0133)] +#[note("unsafe fields may carry library invariants")] pub(crate) struct UseOfUnsafeFieldRequiresUnsafe { #[primary_span] - #[label] + #[label("use of unsafe field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_unsafe_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[note] +#[diag("use of unsafe field is unsafe and requires unsafe block", code = E0133)] +#[note("unsafe fields may carry library invariants")] pub(crate) struct UseOfUnsafeFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("use of unsafe field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)] -#[note] +#[diag("dereference of raw pointer is unsafe and requires unsafe block", code = E0133)] +#[note( + "raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior" +)] pub(crate) struct DerefOfRawPointerRequiresUnsafe { #[primary_span] - #[label] + #[label("dereference of raw pointer")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[note] +#[diag("dereference of raw pointer is unsafe and requires unsafe function or block", code = E0133)] +#[note( + "raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior" +)] pub(crate) struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("dereference of raw pointer")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_union_field_requires_unsafe, code = E0133)] -#[note] +#[diag("access to union field is unsafe and requires unsafe block", code = E0133)] +#[note( + "the field may not be properly initialized: using uninitialized data will cause undefined behavior" +)] pub(crate) struct AccessToUnionFieldRequiresUnsafe { #[primary_span] - #[label] + #[label("access to union field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[note] +#[diag("access to union field is unsafe and requires unsafe function or block", code = E0133)] +#[note( + "the field may not be properly initialized: using uninitialized data will cause undefined behavior" +)] pub(crate) struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("access to union field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = E0133)] -#[note] +#[diag("mutation of layout constrained field is unsafe and requires unsafe block", code = E0133)] +#[note("mutating layout constrained fields cannot statically be checked for valid values")] pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] - #[label] + #[label("mutation of layout constrained field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -433,24 +475,26 @@ pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafe { #[derive(Diagnostic)] #[diag( - mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + "mutation of layout constrained field is unsafe and requires unsafe function or block", code = E0133 )] -#[note] +#[note("mutating layout constrained fields cannot statically be checked for valid values")] pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("mutation of layout constrained field")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = E0133)] -#[note] +#[diag("borrow of layout constrained field with interior mutability is unsafe and requires unsafe block", code = E0133)] +#[note( + "references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values" +)] pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] - #[label] + #[label("borrow of layout constrained field with interior mutability")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -458,29 +502,42 @@ pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { #[derive(Diagnostic)] #[diag( - mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + "borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block", code = E0133 )] -#[note] +#[note( + "references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values" +)] pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("borrow of layout constrained field with interior mutability")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] -#[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)] -#[help] +#[diag("call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block", code = E0133)] +#[help( + "in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> + [1] feature + *[count] features +}: {$missing_target_features}" +)] pub(crate) struct CallToFunctionWithRequiresUnsafe { #[primary_span] - #[label] + #[label("call to function with `#[target_feature]`")] pub(crate) span: Span, pub(crate) function: String, pub(crate) missing_target_features: DiagArgValue, pub(crate) missing_target_features_count: usize, - #[note] + #[note("the {$build_target_features} target {$build_target_features_count -> + [1] feature + *[count] features +} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> + [1] it + *[count] them +} in `#[target_feature]`")] pub(crate) note: bool, pub(crate) build_target_features: DiagArgValue, pub(crate) build_target_features_count: usize, @@ -489,16 +546,30 @@ pub(crate) struct CallToFunctionWithRequiresUnsafe { } #[derive(Diagnostic)] -#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] -#[help] +#[diag( + "call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe function or block", + code = E0133, +)] +#[help( + "in order for the call to be safe, the context requires the following additional target {$missing_target_features_count -> + [1] feature + *[count] features +}: {$missing_target_features}" +)] pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("call to function with `#[target_feature]`")] pub(crate) span: Span, pub(crate) function: String, pub(crate) missing_target_features: DiagArgValue, pub(crate) missing_target_features_count: usize, - #[note] + #[note("the {$build_target_features} target {$build_target_features_count -> + [1] feature + *[count] features + } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> + [1] it + *[count] them + } in `#[target_feature]`")] pub(crate) note: bool, pub(crate) build_target_features: DiagArgValue, pub(crate) build_target_features_count: usize, @@ -508,12 +579,12 @@ pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[derive(Diagnostic)] #[diag( - mir_build_unsafe_binder_cast_requires_unsafe, + "unsafe binder cast is unsafe and requires unsafe block information that may be required to uphold safety guarantees of a type", code = E0133, )] pub(crate) struct UnsafeBinderCastRequiresUnsafe { #[primary_span] - #[label] + #[label("unsafe binder cast")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, @@ -521,19 +592,19 @@ pub(crate) struct UnsafeBinderCastRequiresUnsafe { #[derive(Diagnostic)] #[diag( - mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, + "unsafe binder cast is unsafe and requires unsafe block or unsafe fn information that may be required to uphold safety guarantees of a type", code = E0133, )] pub(crate) struct UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] - #[label] + #[label("unsafe binder cast")] pub(crate) span: Span, #[subdiagnostic] pub(crate) unsafe_not_inherited_note: Option, } #[derive(Subdiagnostic)] -#[label(mir_build_unsafe_not_inherited)] +#[label("items do not inherit unsafety from separate enclosing items")] pub(crate) struct UnsafeNotInheritedNote { #[primary_span] pub(crate) span: Span, @@ -546,11 +617,16 @@ pub(crate) struct UnsafeNotInheritedLintNote { impl Subdiagnostic for UnsafeNotInheritedLintNote { fn add_to_diag(self, diag: &mut Diag<'_, G>) { - diag.span_note(self.signature_span, fluent::mir_build_unsafe_fn_safe_body); + diag.span_note( + self.signature_span, + inline_fluent!( + "an unsafe function restricts its caller, but its body is safe by default" + ), + ); let body_start = self.body_span.shrink_to_lo(); let body_end = self.body_span.shrink_to_hi(); diag.tool_only_multipart_suggestion( - fluent::mir_build_wrap_suggestion, + inline_fluent!("consider wrapping the function body in an unsafe block"), vec![(body_start, "{ unsafe ".into()), (body_end, "}".into())], Applicability::MachineApplicable, ); @@ -558,9 +634,9 @@ impl Subdiagnostic for UnsafeNotInheritedLintNote { } #[derive(LintDiagnostic)] -#[diag(mir_build_unused_unsafe)] +#[diag("unnecessary `unsafe` block")] pub(crate) struct UnusedUnsafe { - #[label] + #[label("unnecessary `unsafe` block")] pub(crate) span: Span, #[subdiagnostic] pub(crate) enclosing: Option, @@ -568,7 +644,7 @@ pub(crate) struct UnusedUnsafe { #[derive(Subdiagnostic)] pub(crate) enum UnusedUnsafeEnclosing { - #[label(mir_build_unused_unsafe_enclosing_block_label)] + #[label("because it's nested under this `unsafe` block")] Block { #[primary_span] span: Span, @@ -584,8 +660,11 @@ pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> { impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let mut diag = - Diag::new(dcx, level, fluent::mir_build_non_exhaustive_patterns_type_not_empty); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("non-exhaustive patterns: type `{$ty}` is non-empty"), + ); diag.span(self.scrut_span); diag.code(E0004); let peeled_ty = self.ty.peel_refs(); @@ -605,20 +684,22 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo let mut span: MultiSpan = def_span.into(); span.push_span_label(def_span, ""); - diag.span_note(span, fluent::mir_build_def_note); + diag.span_note(span, inline_fluent!("`{$peeled_ty}` defined here")); } let is_non_exhaustive = matches!(self.ty.kind(), ty::Adt(def, _) if def.variant_list_has_applicable_non_exhaustive()); if is_non_exhaustive { - diag.note(fluent::mir_build_non_exhaustive_type_note); + diag.note(inline_fluent!( + "the matched value is of type `{$ty}`, which is marked as non-exhaustive" + )); } else { - diag.note(fluent::mir_build_type_note); + diag.note(inline_fluent!("the matched value is of type `{$ty}`")); } if let ty::Ref(_, sub_ty, _) = self.ty.kind() { if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env) { - diag.note(fluent::mir_build_reference_note); + diag.note(inline_fluent!("references are always considered inhabited")); } } @@ -633,12 +714,14 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo }; diag.span_suggestion_verbose( braces_span, - fluent::mir_build_suggestion, + inline_fluent!("ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown"), format!(" {{{indentation}{more}_ => todo!(),{indentation}}}"), Applicability::HasPlaceholders, ); } else { - diag.help(fluent::mir_build_help); + diag.help(inline_fluent!( + "ensure that all possible cases are being handled by adding a match arm with a wildcard pattern" + )); } diag @@ -646,69 +729,80 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo } #[derive(Subdiagnostic)] -#[note(mir_build_non_exhaustive_match_all_arms_guarded)] +#[note("match arms with guards don't count towards exhaustivity")] pub(crate) struct NonExhaustiveMatchAllArmsGuarded; #[derive(Diagnostic)] -#[diag(mir_build_static_in_pattern, code = E0158)] +#[diag("statics cannot be referenced in patterns", code = E0158)] pub(crate) struct StaticInPattern { #[primary_span] - #[label] + #[label("can't be used in patterns")] pub(crate) span: Span, - #[label(mir_build_static_in_pattern_def)] + #[label("`static` defined here")] pub(crate) static_span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_const_param_in_pattern, code = E0158)] +#[diag("constant parameters cannot be referenced in patterns", code = E0158)] pub(crate) struct ConstParamInPattern { #[primary_span] - #[label] + #[label("can't be used in patterns")] pub(crate) span: Span, - #[label(mir_build_const_param_in_pattern_def)] + #[label("constant defined here")] pub(crate) const_span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_non_const_path, code = E0080)] +#[diag("runtime values cannot be referenced in patterns", code = E0080)] pub(crate) struct NonConstPath { #[primary_span] - #[label] + #[label("references a runtime value")] pub(crate) span: Span, } #[derive(LintDiagnostic)] -#[diag(mir_build_unreachable_pattern)] +#[diag("unreachable pattern")] pub(crate) struct UnreachablePattern<'tcx> { - #[label] + #[label("no value can reach this")] pub(crate) span: Option, - #[label(mir_build_unreachable_matches_no_values)] + #[label("matches no values because `{$matches_no_values_ty}` is uninhabited")] pub(crate) matches_no_values: Option, pub(crate) matches_no_values_ty: Ty<'tcx>, - #[note(mir_build_unreachable_uninhabited_note)] + #[note( + "to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types" + )] pub(crate) uninhabited_note: Option<()>, - #[label(mir_build_unreachable_covered_by_catchall)] + #[label("matches any value")] pub(crate) covered_by_catchall: Option, #[subdiagnostic] pub(crate) wanted_constant: Option, - #[note(mir_build_unreachable_pattern_const_reexport_accessible)] + #[note( + "there is a constant of the same name imported in another scope, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it needs to be imported in the pattern's scope" + )] pub(crate) accessible_constant: Option, - #[note(mir_build_unreachable_pattern_const_inaccessible)] + #[note( + "there is a constant of the same name, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it is not accessible from this scope" + )] pub(crate) inaccessible_constant: Option, - #[note(mir_build_unreachable_pattern_let_binding)] + #[note( + "there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings" + )] pub(crate) pattern_let_binding: Option, - #[label(mir_build_unreachable_covered_by_one)] + #[label("matches all the relevant values")] pub(crate) covered_by_one: Option, - #[note(mir_build_unreachable_covered_by_many)] + #[note("multiple earlier patterns match some of the same values")] pub(crate) covered_by_many: Option, pub(crate) covered_by_many_n_more_count: usize, - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove the match arm", code = "", applicability = "machine-applicable")] pub(crate) suggest_remove: Option, } #[derive(Subdiagnostic)] #[suggestion( - mir_build_unreachable_pattern_wanted_const, + "you might have meant to pattern match against the value of {$is_typo -> + [true] similarly named constant + *[false] constant + } `{$const_name}` instead of introducing a new catch-all binding", code = "{const_path}", applicability = "machine-applicable" )] @@ -721,48 +815,50 @@ pub(crate) struct WantedConstant { } #[derive(LintDiagnostic)] -#[diag(mir_build_unreachable_due_to_uninhabited)] +#[diag("unreachable {$descr}")] pub(crate) struct UnreachableDueToUninhabited<'desc, 'tcx> { pub descr: &'desc str, - #[label] + #[label("unreachable {$descr}")] pub expr: Span, - #[label(mir_build_label_orig)] - #[note] + #[label("any code following this expression is unreachable")] + #[note("this expression has type `{$ty}`, which is uninhabited")] pub orig: Span, pub ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] +#[diag("constant pattern cannot depend on generic parameters", code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] - #[label] + #[label("`const` depends on a generic parameter")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_could_not_eval_const_pattern)] +#[diag("could not evaluate constant pattern")] pub(crate) struct CouldNotEvalConstPattern { #[primary_span] - #[label] + #[label("could not evaluate constant")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = E0030)] +#[diag("lower bound for range pattern must be less than or equal to upper bound", code = E0030)] pub(crate) struct LowerRangeBoundMustBeLessThanOrEqualToUpper { #[primary_span] - #[label] + #[label("lower bound larger than upper bound")] pub(crate) span: Span, - #[note(mir_build_teach_note)] + #[note( + "When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range." + )] pub(crate) teach: bool, } #[derive(Diagnostic)] -#[diag(mir_build_literal_in_range_out_of_bounds)] +#[diag("literal out of range for `{$ty}`")] pub(crate) struct LiteralOutOfRange<'tcx> { #[primary_span] - #[label] + #[label("this value does not fit into the type `{$ty}` whose range is `{$min}..={$max}`")] pub(crate) span: Span, pub(crate) ty: Ty<'tcx>, pub(crate) min: i128, @@ -770,93 +866,173 @@ pub(crate) struct LiteralOutOfRange<'tcx> { } #[derive(Diagnostic)] -#[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = E0579)] +#[diag("lower bound for range pattern must be less than upper bound", code = E0579)] pub(crate) struct LowerRangeBoundMustBeLessThanUpper { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_upper_range_bound_cannot_be_min, code = E0579)] +#[diag("exclusive upper bound for a range bound cannot be the minimum", code = E0579)] pub(crate) struct UpperRangeBoundCannotBeMin { #[primary_span] pub(crate) span: Span, } #[derive(LintDiagnostic)] -#[diag(mir_build_leading_irrefutable_let_patterns)] -#[note] -#[help] +#[diag( + "leading irrefutable {$count -> + [one] pattern + *[other] patterns +} in let chain" +)] +#[note( + "{$count -> + [one] this pattern + *[other] these patterns +} will always match" +)] +#[help( + "consider moving {$count -> + [one] it + *[other] them +} outside of the construct" +)] pub(crate) struct LeadingIrrefutableLetPatterns { pub(crate) count: usize, } #[derive(LintDiagnostic)] -#[diag(mir_build_trailing_irrefutable_let_patterns)] -#[note] -#[help] +#[diag( + "trailing irrefutable {$count -> + [one] pattern + *[other] patterns +} in let chain" +)] +#[note( + "{$count -> + [one] this pattern + *[other] these patterns +} will always match" +)] +#[help( + "consider moving {$count -> + [one] it + *[other] them +} into the body" +)] pub(crate) struct TrailingIrrefutableLetPatterns { pub(crate) count: usize, } #[derive(LintDiagnostic)] -#[diag(mir_build_bindings_with_variant_name, code = E0170)] +#[diag("pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}`", code = E0170)] pub(crate) struct BindingsWithVariantName { - #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")] + #[suggestion( + "to match on the variant, qualify the path", + code = "{ty_path}::{name}", + applicability = "machine-applicable" + )] pub(crate) suggestion: Option, pub(crate) ty_path: String, pub(crate) name: Ident, } #[derive(LintDiagnostic)] -#[diag(mir_build_irrefutable_let_patterns_if_let)] -#[note] -#[help] +#[diag( + "irrefutable `if let` {$count -> + [one] pattern + *[other] patterns +}" +)] +#[note( + "{$count -> + [one] this pattern + *[other] these patterns +} will always match, so the `if let` is useless" +)] +#[help("consider replacing the `if let` with a `let`")] pub(crate) struct IrrefutableLetPatternsIfLet { pub(crate) count: usize, } #[derive(LintDiagnostic)] -#[diag(mir_build_irrefutable_let_patterns_if_let_guard)] -#[note] -#[help] +#[diag( + "irrefutable `if let` guard {$count -> + [one] pattern + *[other] patterns +}" +)] +#[note( + "{$count -> + [one] this pattern + *[other] these patterns +} will always match, so the guard is useless" +)] +#[help("consider removing the guard and adding a `let` inside the match arm")] pub(crate) struct IrrefutableLetPatternsIfLetGuard { pub(crate) count: usize, } #[derive(LintDiagnostic)] -#[diag(mir_build_irrefutable_let_patterns_let_else)] -#[note] -#[help] +#[diag( + "irrefutable `let...else` {$count -> + [one] pattern + *[other] patterns +}" +)] +#[note( + "{$count -> + [one] this pattern + *[other] these patterns +} will always match, so the `else` clause is useless" +)] +#[help("consider removing the `else` clause")] pub(crate) struct IrrefutableLetPatternsLetElse { pub(crate) count: usize, } #[derive(LintDiagnostic)] -#[diag(mir_build_irrefutable_let_patterns_while_let)] -#[note] -#[help] +#[diag( + "irrefutable `while let` {$count -> + [one] pattern + *[other] patterns +}" +)] +#[note( + "{$count -> + [one] this pattern + *[other] these patterns +} will always match, so the loop will never exit" +)] +#[help("consider instead using a `loop {\"{\"} ... {\"}\"}` with a `let` inside it")] pub(crate) struct IrrefutableLetPatternsWhileLet { pub(crate) count: usize, } #[derive(Diagnostic)] -#[diag(mir_build_borrow_of_moved_value)] +#[diag("borrow of moved value")] pub(crate) struct BorrowOfMovedValue<'tcx> { #[primary_span] - #[label] - #[label(mir_build_occurs_because_label)] + #[label("value moved into `{$name}` here")] + #[label( + "move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait" + )] pub(crate) binding_span: Span, - #[label(mir_build_value_borrowed_label)] + #[label("value borrowed here after move")] pub(crate) conflicts_ref: Vec, pub(crate) name: Ident, pub(crate) ty: Ty<'tcx>, - #[suggestion(code = "ref ", applicability = "machine-applicable")] + #[suggestion( + "borrow this binding in the pattern to avoid moving the value", + code = "ref ", + applicability = "machine-applicable" + )] pub(crate) suggest_borrowing: Option, } #[derive(Diagnostic)] -#[diag(mir_build_multiple_mut_borrows)] +#[diag("cannot borrow value as mutable more than once at a time")] pub(crate) struct MultipleMutBorrows { #[primary_span] pub(crate) span: Span, @@ -865,7 +1041,7 @@ pub(crate) struct MultipleMutBorrows { } #[derive(Diagnostic)] -#[diag(mir_build_already_borrowed)] +#[diag("cannot borrow value as mutable because it is also borrowed as immutable")] pub(crate) struct AlreadyBorrowed { #[primary_span] pub(crate) span: Span, @@ -874,7 +1050,7 @@ pub(crate) struct AlreadyBorrowed { } #[derive(Diagnostic)] -#[diag(mir_build_already_mut_borrowed)] +#[diag("cannot borrow value as immutable because it is also borrowed as mutable")] pub(crate) struct AlreadyMutBorrowed { #[primary_span] pub(crate) span: Span, @@ -883,7 +1059,7 @@ pub(crate) struct AlreadyMutBorrowed { } #[derive(Diagnostic)] -#[diag(mir_build_moved_while_borrowed)] +#[diag("cannot move out of value because it is borrowed")] pub(crate) struct MovedWhileBorrowed { #[primary_span] pub(crate) span: Span, @@ -893,19 +1069,19 @@ pub(crate) struct MovedWhileBorrowed { #[derive(Subdiagnostic)] pub(crate) enum Conflict { - #[label(mir_build_mutable_borrow)] + #[label("value is mutably borrowed by `{$name}` here")] Mut { #[primary_span] span: Span, name: Symbol, }, - #[label(mir_build_borrow)] + #[label("value is borrowed by `{$name}` here")] Ref { #[primary_span] span: Span, name: Symbol, }, - #[label(mir_build_moved)] + #[label("value is moved into `{$name}` here")] Moved { #[primary_span] span: Span, @@ -914,50 +1090,56 @@ pub(crate) enum Conflict { } #[derive(Diagnostic)] -#[diag(mir_build_union_pattern)] +#[diag("cannot use unions in constant patterns")] pub(crate) struct UnionPattern { #[primary_span] - #[label] + #[label("can't use a `union` here")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_type_not_structural)] +#[diag("constant of non-structural type `{$ty}` in a pattern")] pub(crate) struct TypeNotStructural<'tcx> { #[primary_span] - #[label] + #[label("constant of non-structural type")] pub(crate) span: Span, - #[label(mir_build_type_not_structural_def)] + #[label("`{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns")] pub(crate) ty_def_span: Span, pub(crate) ty: Ty<'tcx>, - #[note(mir_build_type_not_structural_tip)] + #[note( + "the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" + )] pub(crate) manual_partialeq_impl_span: Option, - #[note(mir_build_type_not_structural_more_info)] + #[note( + "see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" + )] pub(crate) manual_partialeq_impl_note: bool, } #[derive(Diagnostic)] -#[diag(mir_build_non_partial_eq_match)] -#[note(mir_build_type_not_structural_more_info)] +#[diag("constant of non-structural type `{$ty}` in a pattern")] +#[note( + "see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details" +)] pub(crate) struct TypeNotPartialEq<'tcx> { #[primary_span] - #[label] + #[label("constant of non-structural type")] pub(crate) span: Span, pub(crate) ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(mir_build_invalid_pattern)] +#[diag("{$prefix} `{$non_sm_ty}` cannot be used in patterns")] pub(crate) struct InvalidPattern<'tcx> { #[primary_span] - #[label] + #[label("{$prefix} can't be used in patterns")] pub(crate) span: Span, pub(crate) non_sm_ty: Ty<'tcx>, pub(crate) prefix: String, } #[derive(Diagnostic)] -#[diag(mir_build_unsized_pattern)] +#[diag("cannot use unsized non-slice type `{$non_sm_ty}` in constant patterns")] pub(crate) struct UnsizedPattern<'tcx> { #[primary_span] pub(crate) span: Span, @@ -965,36 +1147,38 @@ pub(crate) struct UnsizedPattern<'tcx> { } #[derive(Diagnostic)] -#[diag(mir_build_nan_pattern)] -#[note] -#[help] +#[diag("cannot use NaN in patterns")] +#[note("NaNs compare inequal to everything, even themselves, so this pattern would never match")] +#[help("try using the `is_nan` method instead")] pub(crate) struct NaNPattern { #[primary_span] - #[label] + #[label("evaluates to `NaN`, which is not allowed in patterns")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_pointer_pattern)] -#[note] +#[diag( + "function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon" +)] +#[note("see https://github.com/rust-lang/rust/issues/70861 for details")] pub(crate) struct PointerPattern { #[primary_span] - #[label] + #[label("can't be used in patterns")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_non_empty_never_pattern)] -#[note] +#[diag("mismatched types")] +#[note("the matched value is of type `{$ty}`")] pub(crate) struct NonEmptyNeverPattern<'tcx> { #[primary_span] - #[label] + #[label("a never pattern must be used on an uninhabited type")] pub(crate) span: Span, pub(crate) ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(mir_build_pattern_not_covered, code = E0005)] +#[diag("refutable pattern in {$origin}", code = E0005)] pub(crate) struct PatternNotCovered<'s, 'tcx> { #[primary_span] pub(crate) span: Span, @@ -1009,10 +1193,12 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { pub(crate) interpreted_as_const_sugg: Option, #[subdiagnostic] pub(crate) adt_defined_here: Option>, - #[note(mir_build_privately_uninhabited)] + #[note( + "pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future" + )] pub(crate) witness_1_is_privately_uninhabited: bool, pub(crate) witness_1: String, - #[note(mir_build_pattern_ty)] + #[note("the matched value is of type `{$pattern_ty}`")] pub(crate) _p: (), pub(crate) pattern_ty: Ty<'tcx>, #[subdiagnostic] @@ -1022,12 +1208,16 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { } #[derive(Subdiagnostic)] -#[note(mir_build_inform_irrefutable)] -#[note(mir_build_more_information)] +#[note( + "`let` bindings require an \"irrefutable pattern\", like a `struct` or an `enum` with only one variant" +)] +#[note("for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html")] pub(crate) struct Inform; #[derive(Subdiagnostic)] -#[label(mir_build_confused)] +#[label( + "missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable" +)] pub(crate) struct InterpretedAsConst { #[primary_span] pub(crate) span: Span, @@ -1050,16 +1240,16 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> { let mut spans = MultiSpan::from(self.adt_def_span); for Variant { span } in self.variants { - spans.push_span_label(span, fluent::mir_build_variant_defined_here); + spans.push_span_label(span, inline_fluent!("not covered")); } - diag.span_note(spans, fluent::mir_build_adt_defined_here); + diag.span_note(spans, inline_fluent!("`{$ty}` defined here")); } } #[derive(Subdiagnostic)] #[suggestion( - mir_build_interpreted_as_const, + "introduce a variable instead", code = "{variable}_var", applicability = "maybe-incorrect", style = "verbose" @@ -1072,7 +1262,13 @@ pub(crate) struct InterpretedAsConstSugg { #[derive(Subdiagnostic)] pub(crate) enum SuggestLet { - #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")] + #[multipart_suggestion( + "you might want to use `if let` to ignore the {$count -> +[one] variant that isn't +*[other] variants that aren't +} matched", + applicability = "has-placeholders" + )] If { #[suggestion_part(code = "if ")] start_span: Span, @@ -1081,7 +1277,10 @@ pub(crate) enum SuggestLet { count: usize, }, #[suggestion( - mir_build_suggest_let_else, + "you might want to use `let...else` to handle the {$count -> +[one] variant that isn't +*[other] variants that aren't +} matched", code = " else {{ todo!() }}", applicability = "has-placeholders" )] @@ -1095,7 +1294,7 @@ pub(crate) enum SuggestLet { #[derive(Subdiagnostic)] pub(crate) enum MiscPatternSuggestion { #[suggestion( - mir_build_suggest_attempted_int_lit, + "alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits", code = "_", applicability = "maybe-incorrect" )] @@ -1106,25 +1305,25 @@ pub(crate) enum MiscPatternSuggestion { } #[derive(Diagnostic)] -#[diag(mir_build_loop_match_invalid_update)] +#[diag("invalid update of the `#[loop_match]` state")] pub(crate) struct LoopMatchInvalidUpdate { #[primary_span] pub lhs: Span, - #[label] + #[label("the assignment must update this variable")] pub scrutinee: Span, } #[derive(Diagnostic)] -#[diag(mir_build_loop_match_invalid_match)] -#[note] +#[diag("invalid match on `#[loop_match]` state")] +#[note("a local variable must be the scrutinee within a `#[loop_match]`")] pub(crate) struct LoopMatchInvalidMatch { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_loop_match_unsupported_type)] -#[note] +#[diag("this `#[loop_match]` state value has type `{$ty}`, which is not supported")] +#[note("only integers, floats, bool, char, and enums without fields are supported")] pub(crate) struct LoopMatchUnsupportedType<'tcx> { #[primary_span] pub span: Span, @@ -1132,36 +1331,36 @@ pub(crate) struct LoopMatchUnsupportedType<'tcx> { } #[derive(Diagnostic)] -#[diag(mir_build_loop_match_bad_statements)] +#[diag("statements are not allowed in this position within a `#[loop_match]`")] pub(crate) struct LoopMatchBadStatements { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_loop_match_bad_rhs)] +#[diag("this expression must be a single `match` wrapped in a labeled block")] pub(crate) struct LoopMatchBadRhs { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_loop_match_missing_assignment)] +#[diag("expected a single assignment expression")] pub(crate) struct LoopMatchMissingAssignment { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_loop_match_arm_with_guard)] +#[diag("match arms that are part of a `#[loop_match]` cannot have guards")] pub(crate) struct LoopMatchArmWithGuard { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_const_continue_not_const)] -#[help] +#[diag("could not determine the target branch for this `#[const_continue]`")] +#[help("try extracting the expression into a `const` item")] pub(crate) struct ConstContinueNotMonomorphicConst { #[primary_span] pub span: Span, @@ -1172,19 +1371,19 @@ pub(crate) struct ConstContinueNotMonomorphicConst { #[derive(Subdiagnostic)] pub(crate) enum ConstContinueNotMonomorphicConstReason { - #[label(mir_build_const_continue_not_const_constant_parameter)] + #[label("constant parameters may use generics, and are not evaluated early enough")] ConstantParameter { #[primary_span] span: Span, }, - #[label(mir_build_const_continue_not_const_const_block)] + #[label("`const` blocks may use generics, and are not evaluated early enough")] ConstBlock { #[primary_span] span: Span, }, - #[label(mir_build_const_continue_not_const_const_other)] + #[label("this value must be a literal or a monomorphic const")] Other { #[primary_span] span: Span, @@ -1192,22 +1391,22 @@ pub(crate) enum ConstContinueNotMonomorphicConstReason { } #[derive(Diagnostic)] -#[diag(mir_build_const_continue_bad_const)] +#[diag("could not determine the target branch for this `#[const_continue]`")] pub(crate) struct ConstContinueBadConst { #[primary_span] - #[label] + #[label("this value is too generic")] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_const_continue_missing_label_or_value)] +#[diag("a `#[const_continue]` must break to a label with a value")] pub(crate) struct ConstContinueMissingLabelOrValue { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_build_const_continue_unknown_jump_target)] +#[diag("the target of this `#[const_continue]` is not statically known")] pub(crate) struct ConstContinueUnknownJumpTarget { #[primary_span] pub span: Span, diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 5c5d979306bfa..cc8035e2b0acf 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -18,8 +18,6 @@ pub mod thir; use rustc_middle::util::Providers; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { providers.queries.check_match = thir::pattern::check_match; providers.queries.lit_to_const = thir::constant::lit_to_const; diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 290d4ab2bfbb0..4eb7b3671e9c4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -3,7 +3,9 @@ use rustc_ast::Mutability; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::codes::*; -use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, struct_span_code_err}; +use rustc_errors::{ + Applicability, ErrorGuaranteed, MultiSpan, inline_fluent, struct_span_code_err, +}; use rustc_hir::def::*; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, BindingMode, ByRef, HirId, MatchSource}; @@ -29,7 +31,6 @@ use rustc_trait_selection::infer::InferCtxtExt; use tracing::instrument; use crate::errors::*; -use crate::fluent_generated as fluent; pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let typeck_results = tcx.typeck(def_id); @@ -988,20 +989,20 @@ fn report_unreachable_pattern<'p, 'tcx>( for p in iter.by_ref().take(CAP_COVERED_BY_MANY) { multispan.push_span_label( p.data().span, - fluent::mir_build_unreachable_matches_same_values, + inline_fluent!("matches some of the same values"), ); } let remain = iter.count(); if remain == 0 { multispan.push_span_label( pat_span, - fluent::mir_build_unreachable_making_this_unreachable, + inline_fluent!("collectively making this unreachable"), ); } else { lint.covered_by_many_n_more_count = remain; multispan.push_span_label( pat_span, - fluent::mir_build_unreachable_making_this_unreachable_n_more, + inline_fluent!("...and {$covered_by_many_n_more_count} other patterns collectively make this unreachable"), ); } lint.covered_by_many = Some(multispan); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 0a0e0d06061eb..6f0f6478f2d74 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -3,7 +3,7 @@ use core::ops::ControlFlow; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_apfloat::Float; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::Diag; +use rustc_errors::{Diag, inline_fluent}; use rustc_hir as hir; use rustc_hir::attrs::AttributeKind; use rustc_hir::find_attr; @@ -82,10 +82,7 @@ impl<'tcx> ConstToPat<'tcx> { err.span_label(self.tcx.def_span(self.tcx.local_parent(def_id)), ""); } if let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = def_kind { - err.span_label( - self.tcx.def_span(uv.def), - crate::fluent_generated::mir_build_const_defined_here, - ); + err.span_label(self.tcx.def_span(uv.def), inline_fluent!("constant defined here")); } } Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()), extra: None }) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 84fe6770be583..11cde35fab17f 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1627,16 +1627,8 @@ impl<'a> Parser<'a> { let first_expr = self.parse_expr()?; if self.eat(exp!(Semi)) { // Repeating array syntax: `[ 0; 512 ]` - let count = if self.eat_keyword(exp!(Const)) { - // While we could just disambiguate `Direct` from `AnonConst` by - // treating all const block exprs as `AnonConst`, that would - // complicate the DefCollector and likely all other visitors. - // So we strip the const blockiness and just store it as a block - // in the AST with the extra disambiguator on the AnonConst - self.parse_mgca_const_block(false)? - } else { - self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))? - }; + let count = + self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?; self.expect(close)?; ExprKind::Repeat(first_expr, count) } else if self.eat(exp!(Comma)) { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 0ff0b66229366..a6b956b09bc16 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -33,9 +33,9 @@ use rustc_ast::tokenstream::{ }; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, AnonConst, AttrArgs, AttrId, BlockCheckMode, ByRef, Const, CoroutineKind, - DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, MgcaDisambiguation, - Mutability, Recovered, Safety, StrLit, Visibility, VisibilityKind, + self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID, + DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, MgcaDisambiguation, Mutability, + Recovered, Safety, StrLit, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::debug_assert_matches; @@ -1269,19 +1269,6 @@ impl<'a> Parser<'a> { } } - fn parse_mgca_const_block(&mut self, gate_syntax: bool) -> PResult<'a, AnonConst> { - let kw_span = self.prev_token.span; - let value = self.parse_expr_block(None, kw_span, BlockCheckMode::Default)?; - if gate_syntax { - self.psess.gated_spans.gate(sym::min_generic_const_args, kw_span.to(value.span)); - } - Ok(AnonConst { - id: ast::DUMMY_NODE_ID, - value, - mgca_disambiguation: MgcaDisambiguation::AnonConst, - }) - } - /// Parses inline const expressions. fn parse_const_block(&mut self, span: Span) -> PResult<'a, Box> { self.expect_keyword(exp!(Const))?; diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index dd190707c42b4..9196d8d156d8e 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -847,6 +847,7 @@ impl<'a> Parser<'a> { /// - A literal. /// - A numeric literal prefixed by `-`. /// - A single-segment path. + /// - A const block (under mGCA) pub(super) fn expr_is_valid_const_arg(&self, expr: &Box) -> bool { match &expr.kind { ast::ExprKind::Block(_, _) @@ -863,6 +864,10 @@ impl<'a> Parser<'a> { { true } + ast::ExprKind::ConstBlock(_) => { + self.psess.gated_spans.gate(sym::min_generic_const_args, expr.span); + true + } _ => false, } } @@ -874,14 +879,6 @@ impl<'a> Parser<'a> { let (value, mgca_disambiguation) = if self.token.kind == token::OpenBrace { let value = self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?; (value, MgcaDisambiguation::Direct) - } else if self.eat_keyword(exp!(Const)) { - // While we could just disambiguate `Direct` from `AnonConst` by - // treating all const block exprs as `AnonConst`, that would - // complicate the DefCollector and likely all other visitors. - // So we strip the const blockiness and just store it as a block - // in the AST with the extra disambiguator on the AnonConst - let value = self.parse_mgca_const_block(true)?; - (value.value, MgcaDisambiguation::AnonConst) } else { self.parse_unambiguous_unbraced_const_arg()? }; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 380b6a2148461..6ff165eb22b71 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -658,16 +658,8 @@ impl<'a> Parser<'a> { }; let ty = if self.eat(exp!(Semi)) { - let mut length = if self.eat_keyword(exp!(Const)) { - // While we could just disambiguate `Direct` from `AnonConst` by - // treating all const block exprs as `AnonConst`, that would - // complicate the DefCollector and likely all other visitors. - // So we strip the const blockiness and just store it as a block - // in the AST with the extra disambiguator on the AnonConst - self.parse_mgca_const_block(false)? - } else { - self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))? - }; + let mut length = + self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?; if let Err(e) = self.expect(exp!(CloseBracket)) { // Try to recover from `X` when `X::` works diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index a918ae929d2e0..325f54d78a505 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -953,6 +953,13 @@ impl Step for Rustc { cargo.rustdocflag("--extern-html-root-url"); cargo.rustdocflag("ena=https://docs.rs/ena/latest/"); + // Point std library crate links to local docs for offline usage. + for krate in STD_PUBLIC_CRATES { + cargo.rustdocflag("--extern-html-root-url"); + cargo.rustdocflag(&format!("{krate}=../")); + } + cargo.rustdocflag("--extern-html-root-takes-precedence"); + let mut to_open = None; let out_dir = builder.stage_out(build_compiler, Mode::Rustc).join(target).join("doc"); diff --git a/src/tools/rustfmt/tests/source/issue-6788.rs b/src/tools/rustfmt/tests/source/issue-6788.rs new file mode 100644 index 0000000000000..0e63ab53a1ac9 --- /dev/null +++ b/src/tools/rustfmt/tests/source/issue-6788.rs @@ -0,0 +1,7 @@ +fn foo() { + let a = [(); const { let x = 1; x }]; +} + +fn foo() { + let x = [(); const { 1 }]; +} diff --git a/src/tools/rustfmt/tests/target/issue-6788.rs b/src/tools/rustfmt/tests/target/issue-6788.rs new file mode 100644 index 0000000000000..c559438b2d52b --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue-6788.rs @@ -0,0 +1,10 @@ +fn foo() { + let a = [(); const { + let x = 1; + x + }]; +} + +fn foo() { + let x = [(); const { 1 }]; +}