From 3af624272aeb25f0e7be4e1752631a86ce7c6358 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 4 May 2024 16:16:34 +0200 Subject: [PATCH 01/17] rustc_codegen_ssa: Remove unused ModuleConfig::inline_threshold --- compiler/rustc_codegen_ssa/src/back/write.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index dec87db0fc5cd..9115f130d499e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -120,7 +120,6 @@ pub struct ModuleConfig { pub vectorize_loop: bool, pub vectorize_slp: bool, pub merge_functions: bool, - pub inline_threshold: Option, pub emit_lifetime_markers: bool, pub llvm_plugins: Vec, } @@ -280,7 +279,6 @@ impl ModuleConfig { } }, - inline_threshold: sess.opts.cg.inline_threshold, emit_lifetime_markers: sess.emit_lifetime_markers(), llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]), } From 651ff643ae68438213bded335ef47cc9c50d3039 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 14 Jun 2024 19:48:40 +0200 Subject: [PATCH 02/17] Fix typo in `-Cno-stack-check` deprecation warning The flag `--no-stack-check` does not exist: $ rustc --no-stack-check error: Unrecognized option: 'no-stack-check'. Did you mean `-C no-stack-check`? --- compiler/rustc_driver_impl/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 9acff4a0a26ce..f7828b033bb80 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1133,7 +1133,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) -> } if cg_flags.iter().any(|x| *x == "no-stack-check") { - early_dcx.early_warn("the --no-stack-check flag is deprecated and does nothing"); + early_dcx.early_warn("the `-Cno-stack-check` flag is deprecated and does nothing"); } if cg_flags.iter().any(|x| *x == "passes=list") { From f5f067bf9d8de86f3a546a33d8a2e08dfa64cde1 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 4 May 2024 16:21:50 +0200 Subject: [PATCH 03/17] Deprecate no-op codegen option `-Cinline-threshold=...` This deprecates `-Cinline-threshold` since using it has no effect. This has been the case since the new LLVM pass manager started being used, more than 2 years ago. --- compiler/rustc_codegen_llvm/src/back/write.rs | 3 --- compiler/rustc_driver_impl/src/lib.rs | 4 ++++ compiler/rustc_session/src/options.rs | 3 ++- src/doc/rustc/src/codegen-options/index.md | 17 +++-------------- .../ui/codegen/issue-82833-slice-miscompile.rs | 2 +- .../deprecation/deprecated_inline_threshold.rs | 4 ++++ .../deprecated_inline_threshold.stderr | 2 ++ 7 files changed, 16 insertions(+), 19 deletions(-) create mode 100644 tests/ui/deprecation/deprecated_inline_threshold.rs create mode 100644 tests/ui/deprecation/deprecated_inline_threshold.stderr diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 02e3bb06dda3e..afacd0994b558 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -564,9 +564,6 @@ pub(crate) unsafe fn llvm_optimize( let llvm_plugins = config.llvm_plugins.join(","); - // FIXME: NewPM doesn't provide a facility to pass custom InlineParams. - // We would have to add upstream support for this first, before we can support - // config.inline_threshold and our more aggressive default thresholds. let result = llvm::LLVMRustOptimize( module.module_llvm.llmod(), &*module.module_llvm.tm, diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index f7828b033bb80..c51244a2c78fe 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1136,6 +1136,10 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) -> early_dcx.early_warn("the `-Cno-stack-check` flag is deprecated and does nothing"); } + if cg_flags.iter().any(|x| x.starts_with("inline-threshold")) { + early_dcx.early_warn("the `-Cinline-threshold` flag is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)"); + } + if cg_flags.iter().any(|x| *x == "passes=list") { let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index fd4a3a9e6cebd..2382412ee1a66 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1485,7 +1485,8 @@ options! { incremental: Option = (None, parse_opt_string, [UNTRACKED], "enable incremental compilation"), inline_threshold: Option = (None, parse_opt_number, [TRACKED], - "set the threshold for inlining a function"), + "this option is deprecated and does nothing \ + (consider using `-Cllvm-args=--inline-threshold=...`)"), #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")] instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED], "instrument the generated code to support LLVM source-based code coverage reports \ diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index babe2bc342bb0..cd10168bc1cf3 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -184,20 +184,9 @@ incremental files will be stored. ## inline-threshold -This option lets you set the default threshold for inlining a function. It -takes an unsigned integer as a value. Inlining is based on a cost model, where -a higher threshold will allow more inlining. - -The default depends on the [opt-level](#opt-level): - -| opt-level | Threshold | -|-----------|-----------| -| 0 | N/A, only inlines always-inline functions | -| 1 | N/A, only inlines always-inline functions and LLVM lifetime intrinsics | -| 2 | 225 | -| 3 | 275 | -| s | 75 | -| z | 25 | +This option is deprecated and does nothing. + +Consider using `-Cllvm-args=--inline-threshold=...`. ## instrument-coverage diff --git a/tests/ui/codegen/issue-82833-slice-miscompile.rs b/tests/ui/codegen/issue-82833-slice-miscompile.rs index 7723679dab19e..32eac923a6361 100644 --- a/tests/ui/codegen/issue-82833-slice-miscompile.rs +++ b/tests/ui/codegen/issue-82833-slice-miscompile.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ compile-flags: -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Copt-level=0 -Cdebuginfo=2 +//@ compile-flags: -Ccodegen-units=1 -Cllvm-args=--inline-threshold=0 -Clink-dead-code -Copt-level=0 -Cdebuginfo=2 // Make sure LLVM does not miscompile this. diff --git a/tests/ui/deprecation/deprecated_inline_threshold.rs b/tests/ui/deprecation/deprecated_inline_threshold.rs new file mode 100644 index 0000000000000..56e033b8cf547 --- /dev/null +++ b/tests/ui/deprecation/deprecated_inline_threshold.rs @@ -0,0 +1,4 @@ +//@ check-pass +//@ compile-flags: -Cinline-threshold=666 + +fn main() {} diff --git a/tests/ui/deprecation/deprecated_inline_threshold.stderr b/tests/ui/deprecation/deprecated_inline_threshold.stderr new file mode 100644 index 0000000000000..c4f8ff092b29a --- /dev/null +++ b/tests/ui/deprecation/deprecated_inline_threshold.stderr @@ -0,0 +1,2 @@ +warning: the `-Cinline-threshold` flag is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`) + From d630f5da7a24e225a9547301e6a7c634f67aad79 Mon Sep 17 00:00:00 2001 From: long-long-float Date: Sun, 28 Apr 2024 14:45:06 +0900 Subject: [PATCH 04/17] Show notice about "never used" for enum --- compiler/rustc_passes/src/dead.rs | 19 ++++++++++++++++ tests/ui/lint/dead-code/unused-variant.rs | 15 +++++++++++++ tests/ui/lint/dead-code/unused-variant.stderr | 22 ++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 6a74ddc5508a7..142cfc0559895 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -1011,6 +1011,22 @@ impl<'tcx> DeadVisitor<'tcx> { parent_item: Option, report_on: ReportOn, ) { + fn get_parent_if_enum_variant<'tcx>( + tcx: TyCtxt<'tcx>, + may_variant: LocalDefId, + ) -> LocalDefId { + if let Node::Variant(_) = tcx.hir_node_by_def_id(may_variant) + && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id()) + && let Some(enum_local_id) = enum_did.as_local() + && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id) + && let ItemKind::Enum(_, _) = item.kind + { + enum_local_id + } else { + may_variant + } + } + let Some(&first_item) = dead_codes.first() else { return; }; @@ -1054,6 +1070,9 @@ impl<'tcx> DeadVisitor<'tcx> { }; let encl_def_id = parent_item.unwrap_or(first_item.def_id); + // If parent of encl_def_id is an enum, use the parent ID intead. + let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id); + let ignored_derived_impls = if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { let trait_list = ign_traits diff --git a/tests/ui/lint/dead-code/unused-variant.rs b/tests/ui/lint/dead-code/unused-variant.rs index 82108fa9c13bf..7030681eb36d9 100644 --- a/tests/ui/lint/dead-code/unused-variant.rs +++ b/tests/ui/lint/dead-code/unused-variant.rs @@ -6,7 +6,22 @@ enum Enum { Variant2, } +#[derive(Debug)] +enum TupleVariant { + Variant1(i32), //~ ERROR: variant `Variant1` is never constructed + Variant2, +} + +#[derive(Debug)] +enum StructVariant { + Variant1 { id: i32 }, //~ ERROR: variant `Variant1` is never constructed + Variant2, +} + fn main() { let e = Enum::Variant2; e.clone(); + + let _ = TupleVariant::Variant2; + let _ = StructVariant::Variant2; } diff --git a/tests/ui/lint/dead-code/unused-variant.stderr b/tests/ui/lint/dead-code/unused-variant.stderr index 0ae15fde47b05..4bc8cf420da7b 100644 --- a/tests/ui/lint/dead-code/unused-variant.stderr +++ b/tests/ui/lint/dead-code/unused-variant.stderr @@ -13,5 +13,25 @@ note: the lint level is defined here LL | #![deny(dead_code)] | ^^^^^^^^^ -error: aborting due to 1 previous error +error: variant `Variant1` is never constructed + --> $DIR/unused-variant.rs:11:5 + | +LL | enum TupleVariant { + | ------------ variant in this enum +LL | Variant1(i32), + | ^^^^^^^^ + | + = note: `TupleVariant` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis + +error: variant `Variant1` is never constructed + --> $DIR/unused-variant.rs:17:5 + | +LL | enum StructVariant { + | ------------- variant in this enum +LL | Variant1 { id: i32 }, + | ^^^^^^^^ + | + = note: `StructVariant` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis + +error: aborting due to 3 previous errors From 3f2f8438b40e4f523353b341424b94ee1bf81741 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 13 Jun 2024 11:27:59 +0000 Subject: [PATCH 05/17] Ensure we don't accidentally succeed when we want to report an error --- compiler/rustc_hir_typeck/src/coercion.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 31f85e21d7133..0551b9bc1f0b4 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1245,11 +1245,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr, ); - return self + return Err(self .commit_if_ok(|_| { - self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty) + self.at(cause, self.param_env).lub(DefineOpaqueTypes::Yes, prev_ty, new_ty) }) - .map(|ok| self.register_infer_ok_obligations(ok)); + .unwrap_err()); } } @@ -1259,10 +1259,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(e) = first_error { Err(e) } else { - self.commit_if_ok(|_| { - self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty) - }) - .map(|ok| self.register_infer_ok_obligations(ok)) + Err(self + .commit_if_ok(|_| { + self.at(cause, self.param_env).lub( + DefineOpaqueTypes::Yes, + prev_ty, + new_ty, + ) + }) + .unwrap_err()) } } Ok(ok) => { From f1be59fa72b06c4a28acc59a0f0dff1484db0778 Mon Sep 17 00:00:00 2001 From: Xiangfei Ding Date: Sun, 26 May 2024 17:57:13 +0800 Subject: [PATCH 06/17] SmartPointer derive-macro Co-authored-by: Wedson Almeida Filho --- .../rustc_builtin_macros/src/deriving/mod.rs | 1 + .../src/deriving/smart_ptr.rs | 140 ++++++++++++++++++ compiler/rustc_builtin_macros/src/lib.rs | 1 + compiler/rustc_feature/src/builtin_attrs.rs | 6 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_span/src/symbol.rs | 8 + library/core/src/marker.rs | 9 ++ tests/ui/deriving/deriving-smart-pointer.rs | 55 +++++++ .../feature-gate-derive-smart-pointer.rs | 9 ++ .../feature-gate-derive-smart-pointer.stderr | 33 +++++ 10 files changed, 264 insertions(+) create mode 100644 compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs create mode 100644 tests/ui/deriving/deriving-smart-pointer.rs create mode 100644 tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs create mode 100644 tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index e3a93ae13e45f..32936ac183df9 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -27,6 +27,7 @@ pub(crate) mod decodable; pub(crate) mod default; pub(crate) mod encodable; pub(crate) mod hash; +pub(crate) mod smart_ptr; #[path = "cmp/eq.rs"] pub(crate) mod eq; diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs new file mode 100644 index 0000000000000..ea054a7e35526 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -0,0 +1,140 @@ +use std::mem::swap; + +use ast::HasAttrs; +use rustc_ast::{ + self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem, + TraitBoundModifiers, +}; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_span::symbol::{sym, Ident}; +use rustc_span::Span; +use smallvec::{smallvec, SmallVec}; +use thin_vec::{thin_vec, ThinVec}; + +macro_rules! path { + ($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] } +} + +pub fn expand_deriving_smart_ptr( + cx: &ExtCtxt<'_>, + span: Span, + _mitem: &MetaItem, + item: &Annotatable, + push: &mut dyn FnMut(Annotatable), + _is_const: bool, +) { + let (name_ident, generics) = if let Annotatable::Item(aitem) = item + && let ItemKind::Struct(_, g) = &aitem.kind + { + (aitem.ident, g) + } else { + cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit(); + return; + }; + + // Convert generic parameters (from the struct) into generic args. + let mut pointee_param = None; + let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![]; + let self_params = generics + .params + .iter() + .enumerate() + .map(|(idx, p)| match p.kind { + GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)), + GenericParamKind::Type { .. } => { + if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) { + if pointee_param.is_some() { + multiple_pointee_diag.push(cx.dcx().struct_span_err( + p.span(), + "`SmartPointer` can only admit one type as pointee", + )); + } else { + pointee_param = Some(idx); + } + } + GenericArg::Type(cx.ty_ident(p.span(), p.ident)) + } + GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)), + }) + .collect::>(); + let Some(pointee_param_idx) = pointee_param else { + cx.dcx().struct_span_err( + span, + "At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits", + ).emit(); + return; + }; + if !multiple_pointee_diag.is_empty() { + for diag in multiple_pointee_diag { + diag.emit(); + } + return; + } + + // Create the type of `self`. + let path = cx.path_all(span, false, vec![name_ident], self_params.clone()); + let self_type = cx.ty_path(path); + + // Declare helper function that adds implementation blocks. + // FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls + let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),]; + let mut add_impl_block = |generics, trait_symbol, trait_args| { + let mut parts = path!(span, core::ops); + parts.push(Ident::new(trait_symbol, span)); + let trait_path = cx.path_all(span, true, parts, trait_args); + let trait_ref = cx.trait_ref(trait_path); + let item = cx.item( + span, + Ident::empty(), + attrs.clone(), + ast::ItemKind::Impl(Box::new(ast::Impl { + safety: ast::Safety::Default, + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, + constness: ast::Const::No, + generics, + of_trait: Some(trait_ref), + self_ty: self_type.clone(), + items: ThinVec::new(), + })), + ); + push(Annotatable::Item(item)); + }; + + // Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For + // example, instead of `MyType<'a, T>`, it will be `MyType<'a, __S>`. + let s_ty = cx.ty_ident(span, Ident::new(sym::__S, span)); + let mut alt_self_params = self_params; + alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone()); + let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params)); + + // Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it. + let mut impl_generics = generics.clone(); + { + let p = &mut impl_generics.params[pointee_param_idx]; + let arg = GenericArg::Type(s_ty.clone()); + let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]); + p.bounds.push(cx.trait_bound(unsize, false)); + let mut attrs = thin_vec![]; + swap(&mut p.attrs, &mut attrs); + p.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect(); + } + + // Add the `__S: ?Sized` extra parameter to the impl block. + let sized = cx.path_global(span, path!(span, core::marker::Sized)); + let bound = GenericBound::Trait( + cx.poly_trait_ref(span, sized), + TraitBoundModifiers { + polarity: ast::BoundPolarity::Maybe(span), + constness: ast::BoundConstness::Never, + asyncness: ast::BoundAsyncness::Normal, + }, + ); + let extra_param = cx.typaram(span, Ident::new(sym::__S, span), vec![bound], None); + impl_generics.params.push(extra_param); + + // Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`. + let gen_args = vec![GenericArg::Type(alt_self_type.clone())]; + add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone()); + add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args.clone()); +} diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 35b0f43d8af77..8ac59605bc108 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -127,6 +127,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { PartialOrd: partial_ord::expand_deriving_partial_ord, RustcDecodable: decodable::expand_deriving_rustc_decodable, RustcEncodable: encodable::expand_deriving_rustc_encodable, + SmartPointer: smart_ptr::expand_deriving_smart_ptr, } let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 9e2756f07eded..25fec91c8177a 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -575,6 +575,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, coroutines, experimental!(coroutines) ), + // `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro + gated!( + pointee, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) + ), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index fbd67657e3b4c..4abeaf4bd4635 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -436,6 +436,8 @@ declare_features! ( (unstable, deprecated_suggestion, "1.61.0", Some(94785)), /// Allows deref patterns. (incomplete, deref_patterns, "1.79.0", Some(87121)), + /// Allows deriving `SmartPointer` traits + (unstable, derive_smart_pointer, "1.79.0", Some(123430)), /// Controls errors in trait implementations. (unstable, do_not_recommend, "1.67.0", Some(51992)), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8d8f4927e99cb..88229bdcc4209 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -174,6 +174,7 @@ symbols! { Center, Cleanup, Clone, + CoerceUnsized, Command, ConstParamTy, Context, @@ -189,6 +190,7 @@ symbols! { DiagMessage, Diagnostic, DirBuilder, + DispatchFromDyn, Display, DoubleEndedIterator, Duration, @@ -299,8 +301,10 @@ symbols! { Saturating, Send, SeqCst, + Sized, SliceIndex, SliceIter, + SmartPointer, Some, SpanCtxt, String, @@ -323,6 +327,7 @@ symbols! { TyCtxt, TyKind, Unknown, + Unsize, Upvars, Vec, VecDeque, @@ -707,6 +712,7 @@ symbols! { derive, derive_const, derive_default_enum, + derive_smart_pointer, destruct, destructuring_assignment, diagnostic, @@ -1315,6 +1321,7 @@ symbols! { on, on_unimplemented, opaque, + ops, opt_out_copy, optimize, optimize_attribute, @@ -1389,6 +1396,7 @@ symbols! { plugin, plugin_registrar, plugins, + pointee, pointee_trait, pointer, pointer_like, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 2e8be7bde4bc3..0fedb8835d1ae 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1018,3 +1018,12 @@ pub trait FnPtr: Copy + Clone { #[lang = "fn_ptr_addr"] fn addr(self) -> *const (); } + +/// Derive macro generating impls of traits related to smart pointers. +#[cfg(not(bootstrap))] +#[rustc_builtin_macro] +#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)] +#[unstable(feature = "derive_smart_pointer", issue = "123430")] +pub macro SmartPointer($item:item) { + /* compiler built-in */ +} diff --git a/tests/ui/deriving/deriving-smart-pointer.rs b/tests/ui/deriving/deriving-smart-pointer.rs new file mode 100644 index 0000000000000..cfc3369850bd6 --- /dev/null +++ b/tests/ui/deriving/deriving-smart-pointer.rs @@ -0,0 +1,55 @@ +//@ run-pass +#![feature(derive_smart_pointer, arbitrary_self_types)] + +use std::marker::SmartPointer; + +#[derive(SmartPointer)] +struct MyPointer<'a, #[pointee] T: ?Sized> { + ptr: &'a T, +} + +impl Copy for MyPointer<'_, T> {} +impl Clone for MyPointer<'_, T> { + fn clone(&self) -> Self { + Self { ptr: self.ptr } + } +} + +impl<'a, T: ?Sized> core::ops::Deref for MyPointer<'a, T> { + type Target = T; + fn deref(&self) -> &'a T { + self.ptr + } +} + +struct MyValue(u32); +impl MyValue { + fn through_pointer(self: MyPointer<'_, Self>) -> u32 { + self.ptr.0 + } +} + +trait MyTrait { + fn through_trait(&self) -> u32; + fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32; +} + +impl MyTrait for MyValue { + fn through_trait(&self) -> u32 { + self.0 + } + + fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32 { + self.ptr.0 + } +} + +pub fn main() { + let v = MyValue(10); + let ptr = MyPointer { ptr: &v }; + assert_eq!(v.0, ptr.through_pointer()); + assert_eq!(v.0, ptr.through_pointer()); + let dptr = ptr as MyPointer; + assert_eq!(v.0, dptr.through_trait()); + assert_eq!(v.0, dptr.through_trait_and_pointer()); +} diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs new file mode 100644 index 0000000000000..ae8005592cdb6 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs @@ -0,0 +1,9 @@ +use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive_smart_pointer' + +#[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer' +struct MyPointer<'a, #[pointee] T: ?Sized> { + //~^ ERROR the `#[pointee]` attribute is an experimental feature + ptr: &'a T, +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr new file mode 100644 index 0000000000000..0ffd82fb9e120 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr @@ -0,0 +1,33 @@ +error[E0658]: use of unstable library feature 'derive_smart_pointer' + --> $DIR/feature-gate-derive-smart-pointer.rs:3:10 + | +LL | #[derive(SmartPointer)] + | ^^^^^^^^^^^^ + | + = note: see issue #123430 for more information + = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[pointee]` attribute is an experimental feature + --> $DIR/feature-gate-derive-smart-pointer.rs:4:22 + | +LL | struct MyPointer<'a, #[pointee] T: ?Sized> { + | ^^^^^^^^^^ + | + = note: see issue #123430 for more information + = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature 'derive_smart_pointer' + --> $DIR/feature-gate-derive-smart-pointer.rs:1:5 + | +LL | use std::marker::SmartPointer; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #123430 for more information + = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. From b5dfeba0e14c00c5cc91c935bad5633fa2df8461 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 19 Jun 2024 17:02:19 +1000 Subject: [PATCH 07/17] coverage: Forbid multiple `#[coverage(..)]` attributes It might make sense to allow this in the future, if we add values that aren't mutually exclusive, but for now having multiple coverage attributes on one item is useless. --- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 5e83e0d27e198..7185240d24511 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -479,7 +479,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), gated!( coverage, Normal, template!(Word, List: "on|off"), - WarnFollowing, EncodeCrossCrate::No, + ErrorPreceding, EncodeCrossCrate::No, coverage_attribute, experimental!(coverage) ), From a000fa8b54c7502df36546d9344880062c622a3c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 20 Jun 2024 17:44:11 +1000 Subject: [PATCH 08/17] coverage: Tighten validation of `#[coverage(off)]` and `#[coverage(on)]` --- compiler/rustc_codegen_ssa/messages.ftl | 2 -- .../rustc_codegen_ssa/src/codegen_attrs.rs | 11 ++++----- compiler/rustc_codegen_ssa/src/errors.rs | 7 ------ compiler/rustc_feature/src/builtin_attrs.rs | 24 +++++++++++-------- compiler/rustc_parse/src/validate_attr.rs | 13 +++++++--- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 1a851ad04a1f0..000fe2e3ce0f5 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -27,8 +27,6 @@ codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error} -codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)` - codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 15955170e8736..fb71cdaa8ff2a 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -15,11 +15,7 @@ use rustc_span::{sym, Span}; use rustc_target::spec::{abi, SanitizerSet}; use crate::errors; -use crate::target_features::from_target_feature; -use crate::{ - errors::{ExpectedCoverageSymbol, ExpectedUsedSymbol}, - target_features::check_target_feature_trait_unsafe, -}; +use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature}; fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage { use rustc_middle::mir::mono::Linkage::*; @@ -139,7 +135,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // coverage on a smaller scope within an excluded larger scope. } Some(_) | None => { - tcx.dcx().emit_err(ExpectedCoverageSymbol { span: attr.span }); + tcx.dcx() + .span_delayed_bug(attr.span, "unexpected value of coverage attribute"); } } } @@ -174,7 +171,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; } Some(_) => { - tcx.dcx().emit_err(ExpectedUsedSymbol { span: attr.span }); + tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span }); } None => { // Unfortunately, unconditionally using `llvm.used` causes diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index e6ba31c516508..e9d31db92541b 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -564,13 +564,6 @@ pub struct UnknownArchiveKind<'a> { pub kind: &'a str, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_expected_coverage_symbol)] -pub struct ExpectedCoverageSymbol { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(codegen_ssa_expected_used_symbol)] pub struct ExpectedUsedSymbol { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 7185240d24511..4ce400fc49f6b 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -105,6 +105,9 @@ pub struct AttributeTemplate { pub word: bool, /// If `Some`, the attribute is allowed to take a list of items like `#[allow(..)]`. pub list: Option<&'static str>, + /// If non-empty, the attribute is allowed to take a list containing exactly + /// one of the listed words, like `#[coverage(off)]`. + pub one_of: &'static [Symbol], /// If `Some`, the attribute is allowed to be a name/value pair where the /// value is a string, like `#[must_use = "reason"]`. pub name_value_str: Option<&'static str>, @@ -165,19 +168,20 @@ pub enum AttributeDuplicates { /// E.g., `template!(Word, List: "description")` means that the attribute /// supports forms `#[attr]` and `#[attr(description)]`. macro_rules! template { - (Word) => { template!(@ true, None, None) }; - (List: $descr: expr) => { template!(@ false, Some($descr), None) }; - (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) }; - (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) }; - (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) }; + (Word) => { template!(@ true, None, &[], None) }; + (List: $descr: expr) => { template!(@ false, Some($descr), &[], None) }; + (OneOf: $one_of: expr) => { template!(@ false, None, $one_of, None) }; + (NameValueStr: $descr: expr) => { template!(@ false, None, &[], Some($descr)) }; + (Word, List: $descr: expr) => { template!(@ true, Some($descr), &[], None) }; + (Word, NameValueStr: $descr: expr) => { template!(@ true, None, &[], Some($descr)) }; (List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ false, Some($descr1), Some($descr2)) + template!(@ false, Some($descr1), &[], Some($descr2)) }; (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ true, Some($descr1), Some($descr2)) + template!(@ true, Some($descr1), &[], Some($descr2)) }; - (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate { - word: $word, list: $list, name_value_str: $name_value_str + (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr) => { AttributeTemplate { + word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str } }; } @@ -478,7 +482,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, experimental!(no_sanitize) ), gated!( - coverage, Normal, template!(Word, List: "on|off"), + coverage, Normal, template!(OneOf: &[sym::off, sym::on]), ErrorPreceding, EncodeCrossCrate::No, coverage_attribute, experimental!(coverage) ), diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index bcb1131cc1961..3d5e6371f4ce6 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -4,8 +4,10 @@ use crate::{errors, parse_in}; use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; -use rustc_ast::MetaItemKind; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety}; +use rustc_ast::{ + self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind, + NestedMetaItem, Safety, +}; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{ AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP, @@ -184,9 +186,13 @@ pub(super) fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim /// Checks that the given meta-item is compatible with this `AttributeTemplate`. fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool { + let is_one_allowed_subword = |items: &[NestedMetaItem]| match items { + [item] => item.is_word() && template.one_of.iter().any(|&word| item.has_name(word)), + _ => false, + }; match meta { MetaItemKind::Word => template.word, - MetaItemKind::List(..) => template.list.is_some(), + MetaItemKind::List(items) => template.list.is_some() || is_one_allowed_subword(items), MetaItemKind::NameValue(lit) if lit.kind.is_str() => template.name_value_str.is_some(), MetaItemKind::NameValue(..) => false, } @@ -230,6 +236,7 @@ fn emit_malformed_attribute( if let Some(descr) = template.list { suggestions.push(format!("#{inner}[{name}({descr})]")); } + suggestions.extend(template.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]"))); if let Some(descr) = template.name_value_str { suggestions.push(format!("#{inner}[{name} = \"{descr}\"]")); } From b7c057c9b2a00558594b854a3d01211d1767cfc6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 19 Jun 2024 17:11:27 +1000 Subject: [PATCH 09/17] coverage: Always error on `#[coverage(..)]` in unexpected places This upgrades some warnings to errors, and also catches cases where the attribute was silently ignored. --- compiler/rustc_passes/messages.ftl | 15 ++------- compiler/rustc_passes/src/check_attr.rs | 42 +++---------------------- compiler/rustc_passes/src/errors.rs | 16 ++-------- 3 files changed, 10 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 9a830b0f49bac..5a560325ab950 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -103,18 +103,9 @@ passes_continue_labeled_block = .label = labeled blocks cannot be `continue`'d .block_label = labeled block the `continue` points to -passes_coverage_fn_defn = - `#[coverage]` may only be applied to function definitions - -passes_coverage_ignored_function_prototype = - `#[coverage]` is ignored on function prototypes - -passes_coverage_not_coverable = - `#[coverage]` must be applied to coverable code - .label = not coverable code - -passes_coverage_propagate = - `#[coverage]` does not propagate into items and must be applied to the contained functions directly +passes_coverage_not_fn_or_closure = + attribute should be applied to a function definition or closure + .label = not a function or closure passes_dead_codes = { $multiple -> diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2ed5bba85c60b..d33f12a973fdc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -122,7 +122,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_unimplemented(attr.span, hir_id, target) } [sym::inline] => self.check_inline(hir_id, attr, span, target), - [sym::coverage] => self.check_coverage(hir_id, attr, span, target), + [sym::coverage] => self.check_coverage(attr, span, target), [sym::non_exhaustive] => self.check_non_exhaustive(hir_id, attr, span, target), [sym::marker] => self.check_marker(hir_id, attr, span, target), [sym::target_feature] => { @@ -369,47 +369,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if a `#[coverage]` is applied directly to a function - fn check_coverage(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks that `#[coverage(..)]` is applied to a function or closure. + fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool { match target { - // #[coverage] on function is fine + // #[coverage(..)] on function is fine Target::Fn | Target::Closure | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, - - // function prototypes can't be covered - Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoverageFnProto, - ); - true - } - - Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoveragePropagate, - ); - true - } - - Target::Expression | Target::Statement | Target::Arm => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoverageFnDefn, - ); - true - } - _ => { - self.dcx().emit_err(errors::IgnoredCoverageNotCoverable { + self.dcx().emit_err(errors::CoverageNotFnOrClosure { attr_span: attr.span, defn_span: span, }); diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f05965680920a..7734dba367046 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -60,21 +60,9 @@ pub struct InlineNotFnOrClosure { pub defn_span: Span, } -#[derive(LintDiagnostic)] -#[diag(passes_coverage_ignored_function_prototype)] -pub struct IgnoredCoverageFnProto; - -#[derive(LintDiagnostic)] -#[diag(passes_coverage_propagate)] -pub struct IgnoredCoveragePropagate; - -#[derive(LintDiagnostic)] -#[diag(passes_coverage_fn_defn)] -pub struct IgnoredCoverageFnDefn; - #[derive(Diagnostic)] -#[diag(passes_coverage_not_coverable, code = E0788)] -pub struct IgnoredCoverageNotCoverable { +#[diag(passes_coverage_not_fn_or_closure, code = E0788)] +pub struct CoverageNotFnOrClosure { #[primary_span] pub attr_span: Span, #[label] From 1852141219b39b2a6bb13ad273c96371d58a41e0 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 20 Jun 2024 18:13:48 +1000 Subject: [PATCH 10/17] coverage: Bless coverage attribute tests --- tests/ui/coverage-attr/bad-syntax.rs | 39 ++-- tests/ui/coverage-attr/bad-syntax.stderr | 137 ++++++++--- tests/ui/coverage-attr/name-value.rs | 51 ++-- tests/ui/coverage-attr/name-value.stderr | 194 ++++++++++------ tests/ui/coverage-attr/no-coverage.rs | 30 +-- tests/ui/coverage-attr/no-coverage.stderr | 103 +++++---- tests/ui/coverage-attr/subword.rs | 8 +- tests/ui/coverage-attr/subword.stderr | 36 ++- tests/ui/coverage-attr/word-only.rs | 45 ++-- tests/ui/coverage-attr/word-only.stderr | 270 ++++++++++++++++++++-- 10 files changed, 648 insertions(+), 265 deletions(-) diff --git a/tests/ui/coverage-attr/bad-syntax.rs b/tests/ui/coverage-attr/bad-syntax.rs index 127179877e55a..c8c92de8c380f 100644 --- a/tests/ui/coverage-attr/bad-syntax.rs +++ b/tests/ui/coverage-attr/bad-syntax.rs @@ -1,58 +1,45 @@ #![feature(coverage_attribute)] +//@ edition: 2021 // Tests the error messages produced (or not produced) by various unusual // uses of the `#[coverage(..)]` attribute. -// FIXME(#126658): Multiple coverage attributes with the same value are useless, -// and should probably produce a diagnostic. -#[coverage(off)] +#[coverage(off)] //~ ERROR multiple `coverage` attributes #[coverage(off)] fn multiple_consistent() {} -// FIXME(#126658): When there are multiple inconsistent coverage attributes, -// it's unclear which one will prevail. -#[coverage(off)] +#[coverage(off)] //~ ERROR multiple `coverage` attributes #[coverage(on)] fn multiple_inconsistent() {} -#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage] //~ ERROR malformed `coverage` attribute input fn bare_word() {} -// FIXME(#126658): This shows as multiple different errors, one of which suggests -// writing bare `#[coverage]`, which is not allowed. -#[coverage = true] -//~^ ERROR expected `coverage(off)` or `coverage(on)` -//~| ERROR malformed `coverage` attribute input -//~| HELP the following are the possible correct uses -//~| SUGGESTION #[coverage(on|off)] +#[coverage = true] //~ ERROR malformed `coverage` attribute input fn key_value() {} -#[coverage()] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage()] //~ ERROR malformed `coverage` attribute input fn list_empty() {} -#[coverage(off, off)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(off, off)] //~ ERROR malformed `coverage` attribute input fn list_consistent() {} -#[coverage(off, on)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(off, on)] //~ ERROR malformed `coverage` attribute input fn list_inconsistent() {} -#[coverage(bogus)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(bogus)] //~ ERROR malformed `coverage` attribute input fn bogus_word() {} -#[coverage(bogus, off)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(bogus, off)] //~ ERROR malformed `coverage` attribute input fn bogus_word_before() {} -#[coverage(off, bogus)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(off, bogus)] //~ ERROR malformed `coverage` attribute input fn bogus_word_after() {} -#[coverage(off,)] +#[coverage(off,)] // (OK!) fn comma_after() {} -// FIXME(#126658): This shows as multiple different errors. -#[coverage(,off)] -//~^ ERROR expected identifier, found `,` -//~| HELP remove this comma -//~| ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(,off)] //~ ERROR expected identifier, found `,` fn comma_before() {} fn main() {} diff --git a/tests/ui/coverage-attr/bad-syntax.stderr b/tests/ui/coverage-attr/bad-syntax.stderr index f6181d12a9466..a5868fcf19cff 100644 --- a/tests/ui/coverage-attr/bad-syntax.stderr +++ b/tests/ui/coverage-attr/bad-syntax.stderr @@ -1,78 +1,139 @@ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:23:1 - | -LL | #[coverage = true] - | ^^^^^^^^^^^^^^^^^^ - | -help: the following are the possible correct uses - | -LL | #[coverage(on|off)] + --> $DIR/bad-syntax.rs:15:1 | LL | #[coverage] + | ^^^^^^^^^^^ | - -error: expected identifier, found `,` - --> $DIR/bad-syntax.rs:52:12 +help: the following are the possible correct uses | -LL | #[coverage(,off)] - | ^ - | | - | expected identifier - | help: remove this comma +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:18:1 | -LL | #[coverage] - | ^^^^^^^^^^^ - -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:23:1 - | LL | #[coverage = true] | ^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:30:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:21:1 | LL | #[coverage()] | ^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:33:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:24:1 | LL | #[coverage(off, off)] | ^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:36:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:27:1 | LL | #[coverage(off, on)] | ^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:39:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:30:1 | LL | #[coverage(bogus)] | ^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:42:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:33:1 | LL | #[coverage(bogus, off)] | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:45:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:36:1 | LL | #[coverage(off, bogus)] | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:52:1 +error: expected identifier, found `,` + --> $DIR/bad-syntax.rs:42:12 | LL | #[coverage(,off)] - | ^^^^^^^^^^^^^^^^^ + | ^ + | | + | expected identifier + | help: remove this comma + +error: multiple `coverage` attributes + --> $DIR/bad-syntax.rs:7:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/bad-syntax.rs:8:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ + +error: multiple `coverage` attributes + --> $DIR/bad-syntax.rs:11:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/bad-syntax.rs:12:1 + | +LL | #[coverage(on)] + | ^^^^^^^^^^^^^^^ error: aborting due to 11 previous errors diff --git a/tests/ui/coverage-attr/name-value.rs b/tests/ui/coverage-attr/name-value.rs index 24c329780c59c..cfd78a03e438a 100644 --- a/tests/ui/coverage-attr/name-value.rs +++ b/tests/ui/coverage-attr/name-value.rs @@ -8,57 +8,62 @@ // and in places that cannot have a coverage attribute, to demonstrate the // interaction between multiple errors. -// FIXME(#126658): The error messages for using this syntax are inconsistent -// with the error message in other cases. They also sometimes appear together -// with other errors, and they suggest using the incorrect `#[coverage]` syntax. - -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure mod my_mod {} mod my_mod_inner { - #![coverage = "off"] //~ ERROR malformed `coverage` attribute input + #![coverage = "off"] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure } #[coverage = "off"] -//~^ ERROR `#[coverage]` must be applied to coverable code -//~| ERROR malformed `coverage` attribute input +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure struct MyStruct; -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyStruct { #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 7; } -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure trait MyTrait { #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32; #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T; } -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyTrait for MyStruct { #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 8; #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T = (); } #[coverage = "off"] -//~^ ERROR expected `coverage(off)` or `coverage(on)` -//~| ERROR malformed `coverage` attribute input +//~^ ERROR malformed `coverage` attribute input fn main() {} diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr index 90bc3a3b53b3e..caac687c94d01 100644 --- a/tests/ui/coverage-attr/name-value.stderr +++ b/tests/ui/coverage-attr/name-value.stderr @@ -1,28 +1,28 @@ error: malformed `coverage` attribute input - --> $DIR/name-value.rs:15:1 + --> $DIR/name-value.rs:11:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:19:5 + --> $DIR/name-value.rs:17:5 | LL | #![coverage = "off"] | ^^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #![coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~~ -LL | #![coverage] - | ~~~~~~~~~~~~ +LL | #![coverage(off)] + | +LL | #![coverage(on)] + | error: malformed `coverage` attribute input --> $DIR/name-value.rs:22:1 @@ -32,22 +32,22 @@ LL | #[coverage = "off"] | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:29:5 + --> $DIR/name-value.rs:31:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input @@ -58,162 +58,220 @@ LL | #[coverage = "off"] | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:37:5 + --> $DIR/name-value.rs:41:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:42:5 + --> $DIR/name-value.rs:46:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:35:1 + --> $DIR/name-value.rs:37:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:50:5 + --> $DIR/name-value.rs:56:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:55:5 + --> $DIR/name-value.rs:61:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:48:1 + --> $DIR/name-value.rs:52:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:61:1 + --> $DIR/name-value.rs:67:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] + | + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:11:1 | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | mod my_mod {} + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:17:5 + | +LL | / mod my_mod_inner { +LL | | #![coverage = "off"] + | | ^^^^^^^^^^^^^^^^^^^^ +LL | | +LL | | +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure --> $DIR/name-value.rs:22:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | struct MyStruct; - | ---------------- not coverable code + | ---------------- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:27:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | / impl MyStruct { +LL | | #[coverage = "off"] +LL | | +LL | | +LL | | const X: u32 = 7; +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:37:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | / trait MyTrait { +LL | | #[coverage = "off"] +LL | | +LL | | +... | +LL | | type T; +LL | | } + | |_- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:37:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:52:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | / impl MyTrait for MyStruct { +LL | | #[coverage = "off"] +LL | | +LL | | +... | +LL | | type T = (); +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:41:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | const X: u32; - | ------------- not coverable code + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:42:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:46:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | type T; - | ------- not coverable code + | ------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:29:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:31:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | const X: u32 = 7; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:50:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:56:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | const X: u32 = 8; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:55:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:61:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | type T = (); - | ------------ not coverable code - -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/name-value.rs:61:1 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ------------ not a function or closure -error: aborting due to 19 previous errors +error: aborting due to 23 previous errors For more information about this error, try `rustc --explain E0788`. diff --git a/tests/ui/coverage-attr/no-coverage.rs b/tests/ui/coverage-attr/no-coverage.rs index 907d25d333e20..5290fccca6100 100644 --- a/tests/ui/coverage-attr/no-coverage.rs +++ b/tests/ui/coverage-attr/no-coverage.rs @@ -2,54 +2,48 @@ #![feature(coverage_attribute)] #![feature(impl_trait_in_assoc_type)] #![warn(unused_attributes)] -#![coverage(off)] -//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +#![coverage(off)] //~ ERROR attribute should be applied to a function definition or closure -#[coverage(off)] -//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure trait Trait { - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure const X: u32; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type T; type U; } -#[coverage(off)] -//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure impl Trait for () { const X: u32 = 0; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type T = Self; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type U = impl Trait; //~ ERROR unconstrained opaque type } extern "C" { - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure static X: u32; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type T; } #[coverage(off)] fn main() { - #[coverage(off)] - //~^ WARN `#[coverage]` may only be applied to function definitions + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure let _ = (); match () { - #[coverage(off)] - //~^ WARN `#[coverage]` may only be applied to function definitions + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure () => (), } - #[coverage(off)] - //~^ WARN `#[coverage]` may only be applied to function definitions + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure return (); } diff --git a/tests/ui/coverage-attr/no-coverage.stderr b/tests/ui/coverage-attr/no-coverage.stderr index a87b0fb49f00e..c5e3b0922cb42 100644 --- a/tests/ui/coverage-attr/no-coverage.stderr +++ b/tests/ui/coverage-attr/no-coverage.stderr @@ -1,101 +1,116 @@ -warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly - --> $DIR/no-coverage.rs:8:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/no-coverage.rs:4:9 - | -LL | #![warn(unused_attributes)] - | ^^^^^^^^^^^^^^^^^ +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:7:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ +LL | / trait Trait { +LL | | #[coverage(off)] +LL | | const X: u32; +... | +LL | | type U; +LL | | } + | |_- not a function or closure -warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly - --> $DIR/no-coverage.rs:20:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:18:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ +LL | / impl Trait for () { +LL | | const X: u32 = 0; +LL | | +LL | | #[coverage(off)] +... | +LL | | type U = impl Trait; +LL | | } + | |_- not a function or closure -warning: `#[coverage]` may only be applied to function definitions - --> $DIR/no-coverage.rs:42:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:39:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ +LL | let _ = (); + | ----------- not a function or closure -warning: `#[coverage]` may only be applied to function definitions - --> $DIR/no-coverage.rs:47:9 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:43:9 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ +LL | () => (), + | -------- not a function or closure -warning: `#[coverage]` may only be applied to function definitions - --> $DIR/no-coverage.rs:52:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:47:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ +LL | return (); + | --------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:11:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:9:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | const X: u32; - | ------------- not coverable code + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:14:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:12:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type T; - | ------- not coverable code + | ------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:25:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:22:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type T = Self; - | -------------- not coverable code + | -------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:28:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:25:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type U = impl Trait; - | -------------------- not coverable code + | -------------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:33:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:30:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | static X: u32; - | -------------- not coverable code + | -------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:36:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:33:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type T; - | ------- not coverable code + | ------- not a function or closure -warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +error[E0788]: attribute should be applied to a function definition or closure --> $DIR/no-coverage.rs:5:1 | LL | #![coverage(off)] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ not a function or closure error: unconstrained opaque type - --> $DIR/no-coverage.rs:29:14 + --> $DIR/no-coverage.rs:26:14 | LL | type U = impl Trait; | ^^^^^^^^^^ | = note: `U` must be used in combination with a concrete type within the same impl -error: aborting due to 7 previous errors; 6 warnings emitted +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0788`. diff --git a/tests/ui/coverage-attr/subword.rs b/tests/ui/coverage-attr/subword.rs index 98b8c25113cbf..16582240b6908 100644 --- a/tests/ui/coverage-attr/subword.rs +++ b/tests/ui/coverage-attr/subword.rs @@ -4,16 +4,16 @@ // Check that yes/no in `#[coverage(yes)]` and `#[coverage(no)]` must be bare // words, not part of a more complicated substructure. -#[coverage(yes(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(yes(milord))] //~ ERROR malformed `coverage` attribute input fn yes_list() {} -#[coverage(no(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(no(milord))] //~ ERROR malformed `coverage` attribute input fn no_list() {} -#[coverage(yes = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(yes = "milord")] //~ ERROR malformed `coverage` attribute input fn yes_key() {} -#[coverage(no = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(no = "milord")] //~ ERROR malformed `coverage` attribute input fn no_key() {} fn main() {} diff --git a/tests/ui/coverage-attr/subword.stderr b/tests/ui/coverage-attr/subword.stderr index 561573b8ada64..3a106898f8b9c 100644 --- a/tests/ui/coverage-attr/subword.stderr +++ b/tests/ui/coverage-attr/subword.stderr @@ -1,26 +1,54 @@ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:7:1 | LL | #[coverage(yes(milord))] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:10:1 | LL | #[coverage(no(milord))] | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:13:1 | LL | #[coverage(yes = "milord")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:16:1 | LL | #[coverage(no = "milord")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ error: aborting due to 4 previous errors diff --git a/tests/ui/coverage-attr/word-only.rs b/tests/ui/coverage-attr/word-only.rs index 5c723b1b6b61e..0a61d1e709f51 100644 --- a/tests/ui/coverage-attr/word-only.rs +++ b/tests/ui/coverage-attr/word-only.rs @@ -8,47 +8,62 @@ // and in places that cannot have a coverage attribute, to demonstrate the // interaction between multiple errors. -// FIXME(#126658): The error messages for using this syntax give the impression -// that it is legal, even though it should never be legal. - -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure mod my_mod {} -// FIXME(#126658): This is silently allowed, but should not be. mod my_mod_inner { #![coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure } -#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code +#[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure struct MyStruct; -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyStruct { - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 7; } -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure trait MyTrait { - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32; - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T; } -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyTrait for MyStruct { - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 8; - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T = (); } -#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage] +//~^ ERROR malformed `coverage` attribute input fn main() {} diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr index bcafc23bc8d7d..18b5fed748476 100644 --- a/tests/ui/coverage-attr/word-only.stderr +++ b/tests/ui/coverage-attr/word-only.stderr @@ -1,57 +1,277 @@ -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:23:1 +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:11:1 | LL | #[coverage] | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:17:5 + | +LL | #![coverage] + | ^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #![coverage(off)] + | +LL | #![coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:22:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:31:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:27:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:41:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:46:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:37:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:56:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:61:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:52:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:67:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:11:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | mod my_mod {} + | ------------- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:17:5 + | +LL | / mod my_mod_inner { +LL | | #![coverage] + | | ^^^^^^^^^^^^ +LL | | +LL | | +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:22:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... LL | struct MyStruct; - | ---------------- not coverable code + | ---------------- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:27:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | / impl MyStruct { +LL | | #[coverage] +LL | | +LL | | +LL | | const X: u32 = 7; +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:37:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | / trait MyTrait { +LL | | #[coverage] +LL | | +LL | | +... | +LL | | type T; +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:52:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | / impl MyTrait for MyStruct { +LL | | #[coverage] +LL | | +LL | | +... | +LL | | type T = (); +LL | | } + | |_- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:36:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:41:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | const X: u32; - | ------------- not coverable code + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:39:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:46:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | type T; - | ------- not coverable code + | ------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:29:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:31:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | const X: u32 = 7; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:46:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:56:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | const X: u32 = 8; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:49:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:61:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | type T = (); - | ------------ not coverable code - -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/word-only.rs:53:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ + | ------------ not a function or closure -error: aborting due to 7 previous errors +error: aborting due to 23 previous errors For more information about this error, try `rustc --explain E0788`. From ba5ec1fc5c68dc727e5f68cd804829c4f9eb9b81 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 24 Jun 2024 15:30:24 +0300 Subject: [PATCH 11/17] Suggest inline const blocks for array initialization --- .../src/traits/error_reporting/suggestions.rs | 40 ++++--------------- .../const-blocks/fn-call-in-non-const.stderr | 8 ++-- .../ui/consts/const-blocks/trait-error.stderr | 11 ++--- tests/ui/consts/const-fn-in-vec.stderr | 33 ++++++--------- 4 files changed, 26 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index b2fa3489dda2b..f9cdca6360e91 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2915,38 +2915,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::RepeatElementCopy { is_constable, - elt_type, + elt_type: _, elt_span, - elt_stmt_span, + elt_stmt_span: _, } => { err.note( "the `Copy` trait is required because this value will be copied for each element of the array", ); - let value_kind = match is_constable { - IsConstable::Fn => Some("the result of the function call"), - IsConstable::Ctor => Some("the result of the constructor"), - _ => None, - }; let sm = tcx.sess.source_map(); - if let Some(value_kind) = value_kind + if matches!(is_constable, IsConstable::Fn | IsConstable::Ctor) && let Ok(snip) = sm.span_to_snippet(elt_span) { - let help_msg = format!( - "consider creating a new `const` item and initializing it with {value_kind} \ - to be used in the repeat position" - ); - let indentation = sm.indentation_before(elt_stmt_span).unwrap_or_default(); - err.multipart_suggestion( - help_msg, - vec![ - ( - elt_stmt_span.shrink_to_lo(), - format!( - "const ARRAY_REPEAT_VALUE: {elt_type} = {snip};\n{indentation}" - ), - ), - (elt_span, "ARRAY_REPEAT_VALUE".to_string()), - ], + err.span_suggestion( + elt_span, + "create an inline `const` block", + format!("const {{ {snip} }}"), Applicability::MachineApplicable, ); } else { @@ -2954,15 +2937,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help("consider using `core::array::from_fn` to initialize the array"); err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html for more information"); } - - if tcx.sess.is_nightly_build() - && matches!(is_constable, IsConstable::Fn | IsConstable::Ctor) - { - err.help( - "create an inline `const` block, see RFC #2920 \ - for more information", - ); - } } ObligationCauseCode::VariableType(hir_id) => { if let Some(typeck_results) = &self.typeck_results diff --git a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr index 14bce10f78744..9dce29732ac80 100644 --- a/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr +++ b/tests/ui/consts/const-blocks/fn-call-in-non-const.stderr @@ -6,17 +6,15 @@ LL | let _: [Option; 2] = [no_copy(); 2]; | = note: required for `Option` to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information help: consider annotating `Bar` with `#[derive(Copy)]` | LL + #[derive(Copy)] LL | struct Bar; | -help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: Option = no_copy(); -LL ~ let _: [Option; 2] = [ARRAY_REPEAT_VALUE; 2]; +help: create an inline `const` block | +LL | let _: [Option; 2] = [const { no_copy() }; 2]; + | ~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index b0b1378bb7de0..8f00f14dfb900 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -2,7 +2,10 @@ error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/trait-error.rs:5:6 | LL | [Foo(String::new()); 4]; - | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`, which is required by `Foo: Copy` + | ^^^^^^^^^^^^^^^^^^ + | | + | the trait `Copy` is not implemented for `String`, which is required by `Foo: Copy` + | help: create an inline `const` block: `const { Foo(String::new()) }` | note: required for `Foo` to implement `Copy` --> $DIR/trait-error.rs:1:10 @@ -10,13 +13,7 @@ note: required for `Foo` to implement `Copy` LL | #[derive(Copy, Clone)] | ^^^^ unsatisfied trait bound introduced in this `derive` macro = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: Foo = Foo(String::new()); -LL ~ [ARRAY_REPEAT_VALUE; 4]; - | error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-fn-in-vec.stderr b/tests/ui/consts/const-fn-in-vec.stderr index 12098e8199cd7..7c6b3bee9404b 100644 --- a/tests/ui/consts/const-fn-in-vec.stderr +++ b/tests/ui/consts/const-fn-in-vec.stderr @@ -2,45 +2,36 @@ error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:1:47 | LL | static _MAYBE_STRINGS: [Option; 5] = [None; 5]; - | ^^^^ the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | ^^^^ + | | + | the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | help: create an inline `const` block: `const { None }` | = note: required for `Option` to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information -help: consider creating a new `const` item and initializing it with the result of the constructor to be used in the repeat position - | -LL + const ARRAY_REPEAT_VALUE: Option = None; -LL ~ static _MAYBE_STRINGS: [Option; 5] = [ARRAY_REPEAT_VALUE; 5]; - | error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:7:34 | LL | let _strings: [String; 5] = [String::new(); 5]; - | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | ^^^^^^^^^^^^^ + | | + | the trait `Copy` is not implemented for `String` + | help: create an inline `const` block: `const { String::new() }` | = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information -help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: String = String::new(); -LL ~ let _strings: [String; 5] = [ARRAY_REPEAT_VALUE; 5]; - | error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:9:48 | LL | let _maybe_strings: [Option; 5] = [None; 5]; - | ^^^^ the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | ^^^^ + | | + | the trait `Copy` is not implemented for `String`, which is required by `Option: Copy` + | help: create an inline `const` block: `const { None }` | = note: required for `Option` to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array - = help: create an inline `const` block, see RFC #2920 for more information -help: consider creating a new `const` item and initializing it with the result of the constructor to be used in the repeat position - | -LL ~ const ARRAY_REPEAT_VALUE: Option = None; -LL ~ let _maybe_strings: [Option; 5] = [ARRAY_REPEAT_VALUE; 5]; - | error: aborting due to 3 previous errors From 8ffb5f936a17190ad9aae442fe52c709521c5b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 13 Jun 2024 17:16:28 +0200 Subject: [PATCH 12/17] compiletest: make the crash test error message abit more informative --- src/tools/compiletest/src/runtest.rs | 9 +++++---- triagebot.toml | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 72b57d91c234e..1a4101e4de80b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -374,11 +374,12 @@ impl<'test> TestCx<'test> { // if a test does not crash, consider it an error if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) { - self.fatal( - "test no longer crashes/triggers ICE! Please give it a mearningful name, \ + self.fatal(&format!( + "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful name, \ add a doc-comment to the start of the test explaining why it exists and \ - move it to tests/ui or wherever you see fit.", - ); + move it to tests/ui or wherever you see fit. Adding 'Fixes #' to your PR description \ + ensures that the corresponding ticket is auto-closed upon merge." + )); } } diff --git a/triagebot.toml b/triagebot.toml index 3abff0f1c784e..70fb14c332848 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -811,6 +811,9 @@ If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/util [mentions."src/bootstrap/src/core/build_steps/llvm.rs"] message = "This PR changes how LLVM is built. Consider updating src/bootstrap/download-ci-llvm-stamp." +[mentions."test/crashes"] +message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the correspondig `ui` subdir and add 'Fixes #' to the pr description to autoclose the issue upon merge." + [mentions."tests/ui/deriving/deriving-all-codegen.stdout"] message = "Changes to the code generated for builtin derived traits." cc = ["@nnethercote"] From 1c4d0ced58ee9452b26efaac93af59f63fe109f2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 20 Jun 2024 13:10:11 +0000 Subject: [PATCH 13/17] Separate the lifetimes of the `BorrowckInferCtxt` from the other borrowed items --- .../rustc_borrowck/src/borrowck_errors.rs | 2 +- .../src/diagnostics/bound_region_errors.rs | 14 +++++----- .../src/diagnostics/conflict_errors.rs | 4 +-- .../src/diagnostics/explain_borrow.rs | 2 +- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +-- .../src/diagnostics/move_errors.rs | 2 +- .../src/diagnostics/mutability_errors.rs | 2 +- .../src/diagnostics/outlives_suggestion.rs | 8 +++--- .../src/diagnostics/region_errors.rs | 2 +- .../src/diagnostics/region_name.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 26 ++++++++++--------- compiler/rustc_borrowck/src/prefixes.rs | 2 +- compiler/rustc_borrowck/src/used_muts.rs | 10 +++---- 13 files changed, 41 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 8a2936c265796..7f0b32bb1a65e 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -6,7 +6,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, 'cx, 'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { self.infcx.dcx() } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 5e10f14f31b54..b2cc6bbf44436 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -52,7 +52,7 @@ impl<'tcx> UniverseInfo<'tcx> { pub(crate) fn report_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, placeholder: ty::PlaceholderRegion, error_element: RegionElement, cause: ObligationCause<'tcx>, @@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -160,7 +160,7 @@ trait TypeOpInfo<'tcx> { #[instrument(level = "debug", skip(self, mbcx))] fn report_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, placeholder: ty::PlaceholderRegion, error_element: RegionElement, cause: ObligationCause<'tcx>, @@ -233,7 +233,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -270,7 +270,7 @@ where fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -336,7 +336,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 197da3eb64164..b1f2a51f35a78 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -4243,7 +4243,7 @@ enum AnnotatedBorrowFnSignature<'tcx> { impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { /// Annotate the provided diagnostic with information about borrow from the fn signature that /// helps explain. - pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, 'tcx>, diag: &mut Diag<'_>) -> String { + pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, '_, 'tcx>, diag: &mut Diag<'_>) -> String { match self { &AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => { diag.span_label( diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index e3ad92a5b2bf5..65b7b9d0f594f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -389,7 +389,7 @@ impl<'tcx> BorrowExplanation<'tcx> { } } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { fn free_region_constraint_info( &self, borrow_region: RegionVid, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 5b4269caccb53..01b9918474a58 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -771,7 +771,7 @@ struct CapturedMessageOpt { maybe_reinitialized_locations_is_empty: bool, } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 5a7bca9ab036f..098135fa90869 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> { }, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { +impl<'a, 'tcx> MirBorrowckCtxt<'_, 'a, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index e0b18536dd563..564a7f7923ec7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -30,7 +30,7 @@ pub(crate) enum AccessKind { Mutate, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { +impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 1a42e551597bb..bdc5b3f7b19d8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -75,7 +75,7 @@ impl OutlivesSuggestionBuilder { /// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`. fn region_vid_to_name( &self, - mbcx: &MirBorrowckCtxt<'_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_>, region: RegionVid, ) -> Option { mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable) @@ -84,7 +84,7 @@ impl OutlivesSuggestionBuilder { /// Compiles a list of all suggestions to be printed in the final big suggestion. fn compile_all_suggestions( &self, - mbcx: &MirBorrowckCtxt<'_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_>, ) -> SmallVec<[SuggestedConstraint; 2]> { let mut suggested = SmallVec::new(); @@ -160,7 +160,7 @@ impl OutlivesSuggestionBuilder { /// Emit an intermediate note on the given `Diag` if the involved regions are suggestable. pub(crate) fn intermediate_suggestion( &mut self, - mbcx: &MirBorrowckCtxt<'_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_>, errci: &ErrorConstraintInfo<'_>, diag: &mut Diag<'_>, ) { @@ -179,7 +179,7 @@ impl OutlivesSuggestionBuilder { /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// suggestion including all collected constraints. - pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) { + pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_>) { // No constraints to add? Done. if self.constraints_to_add.is_empty() { debug!("No constraints to suggest."); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index c214c52880a94..2cd56c46ca009 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) span: Span, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { +impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 25a0d40218bbb..ec45938febc7e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -198,7 +198,7 @@ impl rustc_errors::IntoDiagArg for RegionName { } } -impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId { self.body.source.def_id().expect_local() } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index b3b53e9cb79ed..ac8459300043e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -310,11 +310,11 @@ fn do_mir_borrowck<'tcx>( promoted_mbcx.report_move_errors(); diags = promoted_mbcx.diags; - struct MoveVisitor<'a, 'cx, 'tcx> { - ctxt: &'a mut MirBorrowckCtxt<'cx, 'tcx>, + struct MoveVisitor<'a, 'b, 'cx, 'tcx> { + ctxt: &'a mut MirBorrowckCtxt<'b, 'cx, 'tcx>, } - impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> { + impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { if let Operand::Move(place) = operand { self.ctxt.check_movable_place(location, *place); @@ -528,15 +528,15 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { } } -struct MirBorrowckCtxt<'cx, 'tcx> { +struct MirBorrowckCtxt<'a, 'cx, 'tcx> { infcx: &'cx BorrowckInferCtxt<'tcx>, param_env: ParamEnv<'tcx>, - body: &'cx Body<'tcx>, - move_data: &'cx MoveData<'tcx>, + body: &'a Body<'tcx>, + move_data: &'a MoveData<'tcx>, /// Map from MIR `Location` to `LocationIndex`; created /// when MIR borrowck begins. - location_table: &'cx LocationTable, + location_table: &'a LocationTable, movable_coroutine: bool, /// This keeps track of whether local variables are free-ed when the function @@ -605,7 +605,9 @@ struct MirBorrowckCtxt<'cx, 'tcx> { // 2. loans made in overlapping scopes do not conflict // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> + for MirBorrowckCtxt<'_, 'cx, 'tcx> +{ type FlowState = Flows<'cx, 'tcx>; fn visit_statement_before_primary_effect( @@ -969,8 +971,8 @@ impl InitializationRequiringAction { } } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { - fn body(&self) -> &'cx Body<'tcx> { +impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { + fn body(&self) -> &'a Body<'tcx> { self.body } @@ -2002,7 +2004,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } fn check_parent_of_field<'cx, 'tcx>( - this: &mut MirBorrowckCtxt<'cx, 'tcx>, + this: &mut MirBorrowckCtxt<'_, 'cx, 'tcx>, location: Location, base: PlaceRef<'tcx>, span: Span, @@ -2476,7 +2478,7 @@ mod diags { } } - impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { + impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { pub fn buffer_error(&mut self, diag: Diag<'tcx>) { self.diags.buffer_error(diag); } diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 8a3a089d0eeba..225e2245c44eb 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -34,7 +34,7 @@ pub(super) enum PrefixSet { Shallow, } -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { /// Returns an iterator over the prefixes of `place` /// (inclusive) from longest to smallest, potentially /// terminating the iteration early based on `kind`. diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index dea1c7823a5c1..dcd9fa7c28f44 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -6,7 +6,7 @@ use rustc_middle::mir::{ use crate::MirBorrowckCtxt; -impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes /// of the `unused_mut` lint. /// @@ -45,13 +45,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// MIR visitor for collecting used mutable variables. /// The 'visit lifetime represents the duration of the MIR walk. -struct GatherUsedMutsVisitor<'visit, 'cx, 'tcx> { +struct GatherUsedMutsVisitor<'visit, 'a, 'cx, 'tcx> { temporary_used_locals: FxIndexSet, never_initialized_mut_locals: &'visit mut FxIndexSet, - mbcx: &'visit mut MirBorrowckCtxt<'cx, 'tcx>, + mbcx: &'visit mut MirBorrowckCtxt<'a, 'cx, 'tcx>, } -impl GatherUsedMutsVisitor<'_, '_, '_> { +impl GatherUsedMutsVisitor<'_, '_, '_, '_> { fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) { // Remove any locals that we found were initialized from the // `never_initialized_mut_locals` set. At the end, the only remaining locals will @@ -63,7 +63,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_> { } } -impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tcx> { +impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, '_, 'cx, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { debug!("visit_terminator: terminator={:?}", terminator); match &terminator.kind { From 8fc6b3de190cc4b669082a094ed1cc5d89d8f9d7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Jun 2024 14:28:08 +0000 Subject: [PATCH 14/17] Separate the mir body lifetime from the other lifetimes --- .../rustc_borrowck/src/borrowck_errors.rs | 2 +- .../src/diagnostics/bound_region_errors.rs | 14 ++-- .../src/diagnostics/conflict_errors.rs | 8 +- .../src/diagnostics/explain_borrow.rs | 2 +- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +- .../src/diagnostics/move_errors.rs | 2 +- .../src/diagnostics/mutability_errors.rs | 2 +- .../src/diagnostics/outlives_suggestion.rs | 8 +- .../src/diagnostics/region_errors.rs | 2 +- .../src/diagnostics/region_name.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 73 ++++++++++--------- compiler/rustc_borrowck/src/prefixes.rs | 2 +- compiler/rustc_borrowck/src/used_muts.rs | 10 +-- 13 files changed, 70 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 7f0b32bb1a65e..f26f8711dd40b 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -6,7 +6,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, 'cx, 'tcx> { +impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { self.infcx.dcx() } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index b2cc6bbf44436..d46febffba862 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -52,7 +52,7 @@ impl<'tcx> UniverseInfo<'tcx> { pub(crate) fn report_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, placeholder: ty::PlaceholderRegion, error_element: RegionElement, cause: ObligationCause<'tcx>, @@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -160,7 +160,7 @@ trait TypeOpInfo<'tcx> { #[instrument(level = "debug", skip(self, mbcx))] fn report_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, placeholder: ty::PlaceholderRegion, error_element: RegionElement, cause: ObligationCause<'tcx>, @@ -233,7 +233,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -270,7 +270,7 @@ where fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, @@ -336,7 +336,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { fn nice_error( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index b1f2a51f35a78..1cc7fee718e87 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -4243,7 +4243,11 @@ enum AnnotatedBorrowFnSignature<'tcx> { impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { /// Annotate the provided diagnostic with information about borrow from the fn signature that /// helps explain. - pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, '_, 'tcx>, diag: &mut Diag<'_>) -> String { + pub(crate) fn emit( + &self, + cx: &MirBorrowckCtxt<'_, '_, '_, 'tcx>, + diag: &mut Diag<'_>, + ) -> String { match self { &AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => { diag.span_label( diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 65b7b9d0f594f..6165a718a3030 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -389,7 +389,7 @@ impl<'tcx> BorrowExplanation<'tcx> { } } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { fn free_region_constraint_info( &self, borrow_region: RegionVid, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 01b9918474a58..842ed38f1e294 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -771,7 +771,7 @@ struct CapturedMessageOpt { maybe_reinitialized_locations_is_empty: bool, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( &self, diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 098135fa90869..12fa4c4f5ee05 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> { }, } -impl<'a, 'tcx> MirBorrowckCtxt<'_, 'a, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 564a7f7923ec7..93fac3181ba4b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -30,7 +30,7 @@ pub(crate) enum AccessKind { Mutate, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index bdc5b3f7b19d8..082111a642c22 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -75,7 +75,7 @@ impl OutlivesSuggestionBuilder { /// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`. fn region_vid_to_name( &self, - mbcx: &MirBorrowckCtxt<'_, '_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, region: RegionVid, ) -> Option { mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable) @@ -84,7 +84,7 @@ impl OutlivesSuggestionBuilder { /// Compiles a list of all suggestions to be printed in the final big suggestion. fn compile_all_suggestions( &self, - mbcx: &MirBorrowckCtxt<'_, '_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, ) -> SmallVec<[SuggestedConstraint; 2]> { let mut suggested = SmallVec::new(); @@ -160,7 +160,7 @@ impl OutlivesSuggestionBuilder { /// Emit an intermediate note on the given `Diag` if the involved regions are suggestable. pub(crate) fn intermediate_suggestion( &mut self, - mbcx: &MirBorrowckCtxt<'_, '_, '_>, + mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>, errci: &ErrorConstraintInfo<'_>, diag: &mut Diag<'_>, ) { @@ -179,7 +179,7 @@ impl OutlivesSuggestionBuilder { /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// suggestion including all collected constraints. - pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_>) { + pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_, '_>) { // No constraints to add? Done. if self.constraints_to_add.is_empty() { debug!("No constraints to suggest."); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 2cd56c46ca009..245ce790e4987 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) span: Span, } -impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index ec45938febc7e..356416d1a7563 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -198,7 +198,7 @@ impl rustc_errors::IntoDiagArg for RegionName { } } -impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId { self.body.source.def_id().expect_local() } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ac8459300043e..69efee2fbdc14 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -310,11 +310,11 @@ fn do_mir_borrowck<'tcx>( promoted_mbcx.report_move_errors(); diags = promoted_mbcx.diags; - struct MoveVisitor<'a, 'b, 'cx, 'tcx> { - ctxt: &'a mut MirBorrowckCtxt<'b, 'cx, 'tcx>, + struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> { + ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>, } - impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> { + impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { if let Operand::Move(place) = operand { self.ctxt.check_movable_place(location, *place); @@ -528,10 +528,10 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { } } -struct MirBorrowckCtxt<'a, 'cx, 'tcx> { +struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { infcx: &'cx BorrowckInferCtxt<'tcx>, param_env: ParamEnv<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>, /// Map from MIR `Location` to `LocationIndex`; created @@ -605,16 +605,16 @@ struct MirBorrowckCtxt<'a, 'cx, 'tcx> { // 2. loans made in overlapping scopes do not conflict // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> - for MirBorrowckCtxt<'_, 'cx, 'tcx> +impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> + for MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { - type FlowState = Flows<'cx, 'tcx>; + type FlowState = Flows<'mir, 'tcx>; fn visit_statement_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'cx, 'tcx>, - stmt: &'cx Statement<'tcx>, + flow_state: &Flows<'mir, 'tcx>, + stmt: &'mir Statement<'tcx>, location: Location, ) { debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state); @@ -683,8 +683,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> fn visit_terminator_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'cx, 'tcx>, - term: &'cx Terminator<'tcx>, + flow_state: &Flows<'mir, 'tcx>, + term: &'mir Terminator<'tcx>, loc: Location, ) { debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state); @@ -794,8 +794,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> fn visit_terminator_after_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'cx, 'tcx>, - term: &'cx Terminator<'tcx>, + flow_state: &Flows<'mir, 'tcx>, + term: &'mir Terminator<'tcx>, loc: Location, ) { let span = term.source_info.span; @@ -971,8 +971,8 @@ impl InitializationRequiringAction { } } -impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { - fn body(&self) -> &'a Body<'tcx> { +impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { + fn body(&self) -> &'mir Body<'tcx> { self.body } @@ -988,7 +988,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { place_span: (Place<'tcx>, Span), kind: (AccessDepth, ReadOrWrite), is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { let (sd, rw) = kind; @@ -1038,7 +1038,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { place_span: (Place<'tcx>, Span), sd: AccessDepth, rw: ReadOrWrite, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) -> bool { let mut error_reported = false; let borrow_set = Rc::clone(&self.borrow_set); @@ -1179,7 +1179,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { location: Location, place_span: (Place<'tcx>, Span), kind: AccessDepth, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { // Write of P[i] or *P requires P init'd. self.check_if_assigned_path_is_moved(location, place_span, flow_state); @@ -1196,8 +1196,8 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { fn consume_rvalue( &mut self, location: Location, - (rvalue, span): (&'cx Rvalue<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + (rvalue, span): (&'mir Rvalue<'tcx>, Span), + flow_state: &Flows<'mir, 'tcx>, ) { match rvalue { &Rvalue::Ref(_ /*rgn*/, bk, place) => { @@ -1454,8 +1454,8 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { fn consume_operand( &mut self, location: Location, - (operand, span): (&'cx Operand<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + (operand, span): (&'mir Operand<'tcx>, Span), + flow_state: &Flows<'mir, 'tcx>, ) { match *operand { Operand::Copy(place) => { @@ -1575,7 +1575,12 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { } } - fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'cx, 'tcx>) { + fn check_activations( + &mut self, + location: Location, + span: Span, + flow_state: &Flows<'mir, 'tcx>, + ) { // Two-phase borrow support: For each activation that is newly // generated at this statement, check if it interferes with // another borrow. @@ -1738,7 +1743,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1843,7 +1848,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1942,7 +1947,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { &mut self, location: Location, (place, span): (Place<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { debug!("check_if_assigned_path_is_moved place: {:?}", place); @@ -2003,12 +2008,12 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { } } - fn check_parent_of_field<'cx, 'tcx>( - this: &mut MirBorrowckCtxt<'_, 'cx, 'tcx>, + fn check_parent_of_field<'mir, 'tcx>( + this: &mut MirBorrowckCtxt<'_, 'mir, '_, 'tcx>, location: Location, base: PlaceRef<'tcx>, span: Span, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) { // rust-lang/rust#21232: Until Rust allows reads from the // initialized parts of partially initialized structs, we @@ -2099,7 +2104,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { (place, span): (Place<'tcx>, Span), kind: ReadOrWrite, is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, location: Location, ) -> bool { debug!( @@ -2215,7 +2220,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { fn is_local_ever_initialized( &self, local: Local, - flow_state: &Flows<'cx, 'tcx>, + flow_state: &Flows<'mir, 'tcx>, ) -> Option { let mpi = self.move_data.rev_lookup.find_local(local)?; let ii = &self.move_data.init_path_map[mpi]; @@ -2223,7 +2228,7 @@ impl<'a, 'cx, 'tcx> MirBorrowckCtxt<'a, 'cx, 'tcx> { } /// Adds the place into the used mutable variables set - fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'cx, 'tcx>) { + fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) { match root_place { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { // If the local may have been initialized, and it is now currently being @@ -2478,7 +2483,7 @@ mod diags { } } - impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { + impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { pub fn buffer_error(&mut self, diag: Diag<'tcx>) { self.diags.buffer_error(diag); } diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 225e2245c44eb..5d3ac1c409a95 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -34,7 +34,7 @@ pub(super) enum PrefixSet { Shallow, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Returns an iterator over the prefixes of `place` /// (inclusive) from longest to smallest, potentially /// terminating the iteration early based on `kind`. diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index dcd9fa7c28f44..25e1f6268e062 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -6,7 +6,7 @@ use rustc_middle::mir::{ use crate::MirBorrowckCtxt; -impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes /// of the `unused_mut` lint. /// @@ -45,13 +45,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, 'cx, 'tcx> { /// MIR visitor for collecting used mutable variables. /// The 'visit lifetime represents the duration of the MIR walk. -struct GatherUsedMutsVisitor<'visit, 'a, 'cx, 'tcx> { +struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'cx, 'tcx> { temporary_used_locals: FxIndexSet, never_initialized_mut_locals: &'visit mut FxIndexSet, - mbcx: &'visit mut MirBorrowckCtxt<'a, 'cx, 'tcx>, + mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx>, } -impl GatherUsedMutsVisitor<'_, '_, '_, '_> { +impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> { fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) { // Remove any locals that we found were initialized from the // `never_initialized_mut_locals` set. At the end, the only remaining locals will @@ -63,7 +63,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_, '_> { } } -impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, '_, 'cx, 'tcx> { +impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, '_, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { debug!("visit_terminator: terminator={:?}", terminator); match &terminator.kind { From 84474a25a414e3d3c9582e576738de367790be1c Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 24 Jun 2024 17:42:08 +0300 Subject: [PATCH 15/17] Small fixme in core now that NonZero is generic --- library/core/src/num/mod.rs | 8 -------- library/core/src/num/uint_macros.rs | 7 ++----- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index ab1ede38979da..034af6a0d5731 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -483,7 +483,6 @@ impl u8 { Self = u8, ActualT = u8, SignedT = i8, - NonZeroT = NonZero, BITS = 8, MAX = 255, rot = 2, @@ -1098,7 +1097,6 @@ impl u16 { Self = u16, ActualT = u16, SignedT = i16, - NonZeroT = NonZero, BITS = 16, MAX = 65535, rot = 4, @@ -1147,7 +1145,6 @@ impl u32 { Self = u32, ActualT = u32, SignedT = i32, - NonZeroT = NonZero, BITS = 32, MAX = 4294967295, rot = 8, @@ -1171,7 +1168,6 @@ impl u64 { Self = u64, ActualT = u64, SignedT = i64, - NonZeroT = NonZero, BITS = 64, MAX = 18446744073709551615, rot = 12, @@ -1195,7 +1191,6 @@ impl u128 { Self = u128, ActualT = u128, SignedT = i128, - NonZeroT = NonZero, BITS = 128, MAX = 340282366920938463463374607431768211455, rot = 16, @@ -1221,7 +1216,6 @@ impl usize { Self = usize, ActualT = u16, SignedT = isize, - NonZeroT = NonZero, BITS = 16, MAX = 65535, rot = 4, @@ -1246,7 +1240,6 @@ impl usize { Self = usize, ActualT = u32, SignedT = isize, - NonZeroT = NonZero, BITS = 32, MAX = 4294967295, rot = 8, @@ -1271,7 +1264,6 @@ impl usize { Self = usize, ActualT = u64, SignedT = isize, - NonZeroT = NonZero, BITS = 64, MAX = 18446744073709551615, rot = 12, diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 00450c2cda3e6..ffe2ca2440e65 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3,7 +3,6 @@ macro_rules! uint_impl { Self = $SelfT:ty, ActualT = $ActualT:ident, SignedT = $SignedT:ident, - NonZeroT = $NonZeroT:ty, // There are all for use *only* in doc comments. // As such, they're all passed as literals -- passing them as a string @@ -1216,8 +1215,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn checked_ilog2(self) -> Option { - // FIXME: Simply use `NonZero::new` once it is actually generic. - if let Some(x) = <$NonZeroT>::new(self) { + if let Some(x) = NonZero::new(self) { Some(x.ilog2()) } else { None @@ -1239,8 +1237,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn checked_ilog10(self) -> Option { - // FIXME: Simply use `NonZero::new` once it is actually generic. - if let Some(x) = <$NonZeroT>::new(self) { + if let Some(x) = NonZero::new(self) { Some(x.ilog10()) } else { None From 45261ff2ec9b1837a39ec653c043ca70c91163e1 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 24 Jun 2024 18:38:55 +0300 Subject: [PATCH 16/17] add @kobzol to bootstrap team for triagebot Signed-off-by: onur-ozkan --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 3abff0f1c784e..9187759d14cb5 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -949,6 +949,7 @@ bootstrap = [ "@albertlarsan68", "@onur-ozkan", "@clubby789", + "@kobzol", ] infra-ci = [ "@Mark-Simulacrum", From 13fca73f4937fe4bb318321525a0fd666e9da16e Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sun, 12 May 2024 21:37:53 -0700 Subject: [PATCH 17/17] Replace `MaybeUninit::uninit_array()` with array repeat expression. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is possible now that inline const blocks are stable; the idea was even mentioned as an alternative when `uninit_array()` was added: > if it’s stabilized soon enough maybe it’s not worth having a > standard library method that will be replaceable with > `let buffer = [MaybeUninit::::uninit(); $N];` Const array repetition and inline const blocks are now stable (in the next release), so that circumstance has come to pass, and we no longer have reason to want `uninit_array()` other than convenience. Therefore, let’s evaluate the inconvenience by not using `uninit_array()` in the standard library, before potentially deleting it entirely. --- compiler/rustc_data_structures/src/lib.rs | 1 - compiler/rustc_data_structures/src/sip128.rs | 2 +- .../src/collections/vec_deque/into_iter.rs | 2 +- library/alloc/src/lib.rs | 1 - library/alloc/src/vec/into_iter.rs | 2 +- library/core/src/array/iter.rs | 8 ++++---- library/core/src/array/mod.rs | 4 ++-- library/core/src/fmt/float.rs | 18 ++++++++++-------- library/core/src/iter/adapters/copied.rs | 2 +- library/core/src/iter/adapters/filter.rs | 2 +- library/core/src/iter/adapters/filter_map.rs | 2 +- library/core/src/iter/adapters/map_windows.rs | 5 +++-- library/core/src/lib.rs | 2 -- library/core/src/mem/maybe_uninit.rs | 3 +-- library/core/src/net/display_buffer.rs | 2 +- library/core/src/slice/sort/stable/mod.rs | 2 +- library/core/tests/lib.rs | 2 -- library/std/src/fs/tests.rs | 2 +- library/std/src/lib.rs | 2 -- library/std/src/net/tcp/tests.rs | 2 +- library/std/src/process/tests.rs | 2 +- library/std/src/sys/pal/windows/mod.rs | 2 +- 22 files changed, 32 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 9781aae22eb3e..cddc67d1578e3 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -27,7 +27,6 @@ #![feature(lint_reasons)] #![feature(macro_metavar_expr)] #![feature(map_try_insert)] -#![feature(maybe_uninit_uninit_array)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs index 4c9acfe0f7155..fed23df10dcf4 100644 --- a/compiler/rustc_data_structures/src/sip128.rs +++ b/compiler/rustc_data_structures/src/sip128.rs @@ -188,7 +188,7 @@ impl SipHasher128 { pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 { let mut hasher = SipHasher128 { nbuf: 0, - buf: MaybeUninit::uninit_array(), + buf: [MaybeUninit::uninit(); BUFFER_WITH_SPILL_CAPACITY], state: State { v0: key0 ^ 0x736f6d6570736575, // The XOR with 0xee is only done on 128-bit algorithm version. diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 692af7c197a30..4747517393c66 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -132,7 +132,7 @@ impl Iterator for IntoIter { fn next_chunk( &mut self, ) -> Result<[Self::Item; N], array::IntoIter> { - let mut raw_arr = MaybeUninit::uninit_array(); + let mut raw_arr = [const { MaybeUninit::uninit() }; N]; let raw_arr_ptr = raw_arr.as_mut_ptr().cast(); let (head, tail) = self.inner.as_slices(); diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index ecb019b49c64c..a1a2404a2ee5a 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -135,7 +135,6 @@ #![feature(layout_for_ptr)] #![feature(local_waker)] #![feature(maybe_uninit_slice)] -#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array_transpose)] #![feature(panic_internals)] #![feature(pattern)] diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index c47989337708f..3bd89eaa6cb5a 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -254,7 +254,7 @@ impl Iterator for IntoIter { #[inline] fn next_chunk(&mut self) -> Result<[T; N], core::array::IntoIter> { - let mut raw_ary = MaybeUninit::uninit_array(); + let mut raw_ary = [const { MaybeUninit::uninit() }; N]; let len = self.len(); diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index b314d0536a35a..3585bf07b597c 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -101,7 +101,6 @@ impl IntoIter { /// ``` /// #![feature(array_into_iter_constructors)] /// #![feature(maybe_uninit_uninit_array_transpose)] - /// #![feature(maybe_uninit_uninit_array)] /// use std::array::IntoIter; /// use std::mem::MaybeUninit; /// @@ -111,7 +110,7 @@ impl IntoIter { /// fn next_chunk( /// it: &mut impl Iterator, /// ) -> Result<[T; N], IntoIter> { - /// let mut buffer = MaybeUninit::uninit_array(); + /// let mut buffer = [const { MaybeUninit::uninit() }; N]; /// let mut i = 0; /// while i < N { /// match it.next() { @@ -203,7 +202,7 @@ impl IntoIter { #[unstable(feature = "array_into_iter_constructors", issue = "91583")] #[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")] pub const fn empty() -> Self { - let buffer = MaybeUninit::uninit_array(); + let buffer = [const { MaybeUninit::uninit() }; N]; let initialized = 0..0; // SAFETY: We're telling it that none of the elements are initialized, @@ -405,7 +404,8 @@ impl Clone for IntoIter { fn clone(&self) -> Self { // Note, we don't really need to match the exact same alive range, so // we can just clone into offset 0 regardless of where `self` is. - let mut new = Self { data: MaybeUninit::uninit_array(), alive: IndexRange::zero_to(0) }; + let mut new = + Self { data: [const { MaybeUninit::uninit() }; N], alive: IndexRange::zero_to(0) }; // Clone all alive elements. for (src, dst) in iter::zip(self.as_slice(), &mut new.data) { diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 3e4eadbb7c979..8285c64ed2966 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -127,7 +127,7 @@ where R: Try, R::Residual: Residual<[R::Output; N]>, { - let mut array = MaybeUninit::uninit_array::(); + let mut array = [const { MaybeUninit::uninit() }; N]; match try_from_fn_erased(&mut array, cb) { ControlFlow::Break(r) => FromResidual::from_residual(r), ControlFlow::Continue(()) => { @@ -918,7 +918,7 @@ impl Drop for Guard<'_, T> { pub(crate) fn iter_next_chunk( iter: &mut impl Iterator, ) -> Result<[T; N], IntoIter> { - let mut array = MaybeUninit::uninit_array::(); + let mut array = [const { MaybeUninit::uninit() }; N]; let r = iter_next_chunk_erased(&mut array, iter); match r { Ok(()) => { diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index 7f23d3c09567c..80c45fce2f0a0 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -35,8 +35,8 @@ fn float_to_decimal_common_exact( where T: flt2dec::DecodableFloat, { - let mut buf: [MaybeUninit; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 - let mut parts: [MaybeUninit>; 4] = MaybeUninit::uninit_array(); + let mut buf: [MaybeUninit; 1024] = [MaybeUninit::uninit(); 1024]; // enough for f32 and f64 + let mut parts: [MaybeUninit>; 4] = [MaybeUninit::uninit(); 4]; let formatted = flt2dec::to_exact_fixed_str( flt2dec::strategy::grisu::format_exact, *num, @@ -62,8 +62,9 @@ where T: flt2dec::DecodableFloat, { // enough for f32 and f64 - let mut buf: [MaybeUninit; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); - let mut parts: [MaybeUninit>; 4] = MaybeUninit::uninit_array(); + let mut buf: [MaybeUninit; flt2dec::MAX_SIG_DIGITS] = + [MaybeUninit::uninit(); flt2dec::MAX_SIG_DIGITS]; + let mut parts: [MaybeUninit>; 4] = [MaybeUninit::uninit(); 4]; let formatted = flt2dec::to_shortest_str( flt2dec::strategy::grisu::format_shortest, *num, @@ -107,8 +108,8 @@ fn float_to_exponential_common_exact( where T: flt2dec::DecodableFloat, { - let mut buf: [MaybeUninit; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 - let mut parts: [MaybeUninit>; 6] = MaybeUninit::uninit_array(); + let mut buf: [MaybeUninit; 1024] = [MaybeUninit::uninit(); 1024]; // enough for f32 and f64 + let mut parts: [MaybeUninit>; 6] = [MaybeUninit::uninit(); 6]; let formatted = flt2dec::to_exact_exp_str( flt2dec::strategy::grisu::format_exact, *num, @@ -135,8 +136,9 @@ where T: flt2dec::DecodableFloat, { // enough for f32 and f64 - let mut buf: [MaybeUninit; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); - let mut parts: [MaybeUninit>; 6] = MaybeUninit::uninit_array(); + let mut buf: [MaybeUninit; flt2dec::MAX_SIG_DIGITS] = + [MaybeUninit::uninit(); flt2dec::MAX_SIG_DIGITS]; + let mut parts: [MaybeUninit>; 6] = [MaybeUninit::uninit(); 6]; let formatted = flt2dec::to_shortest_exp_str( flt2dec::strategy::grisu::format_shortest, *num, diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 6d82d1581f79d..d772e7b36e09e 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -202,7 +202,7 @@ where T: Copy, { fn spec_next_chunk(&mut self) -> Result<[T; N], array::IntoIter> { - let mut raw_array = MaybeUninit::uninit_array(); + let mut raw_array = [const { MaybeUninit::uninit() }; N]; let len = self.len(); diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index a7f1fde6975c0..ca23d1b13a88b 100644 --- a/library/core/src/iter/adapters/filter.rs +++ b/library/core/src/iter/adapters/filter.rs @@ -64,7 +64,7 @@ where fn next_chunk( &mut self, ) -> Result<[Self::Item; N], array::IntoIter> { - let mut array: [MaybeUninit; N] = MaybeUninit::uninit_array(); + let mut array: [MaybeUninit; N] = [const { MaybeUninit::uninit() }; N]; struct Guard<'a, T> { array: &'a mut [MaybeUninit], diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index 1a5f9e6265454..2126619a58a87 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -68,7 +68,7 @@ where fn next_chunk( &mut self, ) -> Result<[Self::Item; N], array::IntoIter> { - let mut array: [MaybeUninit; N] = MaybeUninit::uninit_array(); + let mut array: [MaybeUninit; N] = [const { MaybeUninit::uninit() }; N]; struct Guard<'a, T> { array: &'a mut [MaybeUninit], diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs index 5f39b24583427..182775121369e 100644 --- a/library/core/src/iter/adapters/map_windows.rs +++ b/library/core/src/iter/adapters/map_windows.rs @@ -110,7 +110,8 @@ impl MapWindowsInner { impl Buffer { fn try_from_iter(iter: &mut impl Iterator) -> Option { let first_half = crate::array::iter_next_chunk(iter).ok()?; - let buffer = [MaybeUninit::new(first_half).transpose(), MaybeUninit::uninit_array()]; + let buffer = + [MaybeUninit::new(first_half).transpose(), [const { MaybeUninit::uninit() }; N]]; Some(Self { buffer, start: 0 }) } @@ -204,7 +205,7 @@ impl Buffer { impl Clone for Buffer { fn clone(&self) -> Self { let mut buffer = Buffer { - buffer: [MaybeUninit::uninit_array(), MaybeUninit::uninit_array()], + buffer: [[const { MaybeUninit::uninit() }; N], [const { MaybeUninit::uninit() }; N]], start: self.start, }; buffer.as_uninit_array_mut().write(self.as_array_ref().clone()); diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2d0b8825f433b..d1692729a31b4 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -140,7 +140,6 @@ #![feature(const_likely)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] -#![feature(const_maybe_uninit_uninit_array)] #![feature(const_nonnull_new)] #![feature(const_num_midpoint)] #![feature(const_option)] @@ -177,7 +176,6 @@ #![feature(is_ascii_octdigit)] #![feature(isqrt)] #![feature(link_cfg)] -#![feature(maybe_uninit_uninit_array)] #![feature(offset_of_enum)] #![feature(offset_of_nested)] #![feature(panic_internals)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 4175d4a33294b..24ebe33bb2c1f 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -917,11 +917,10 @@ impl MaybeUninit { /// # Examples /// /// ``` - /// #![feature(maybe_uninit_uninit_array)] /// #![feature(maybe_uninit_array_assume_init)] /// use std::mem::MaybeUninit; /// - /// let mut array: [MaybeUninit; 3] = MaybeUninit::uninit_array(); + /// let mut array: [MaybeUninit; 3] = [MaybeUninit::uninit(); 3]; /// array[0].write(0); /// array[1].write(1); /// array[2].write(2); diff --git a/library/core/src/net/display_buffer.rs b/library/core/src/net/display_buffer.rs index b7e778605fc0a..6619c85f483ef 100644 --- a/library/core/src/net/display_buffer.rs +++ b/library/core/src/net/display_buffer.rs @@ -11,7 +11,7 @@ pub struct DisplayBuffer { impl DisplayBuffer { #[inline] pub const fn new() -> Self { - Self { buf: MaybeUninit::uninit_array(), len: 0 } + Self { buf: [MaybeUninit::uninit(); SIZE], len: 0 } } #[inline] diff --git a/library/core/src/slice/sort/stable/mod.rs b/library/core/src/slice/sort/stable/mod.rs index 3d3fe2e70b7b4..18f7b2ac54af5 100644 --- a/library/core/src/slice/sort/stable/mod.rs +++ b/library/core/src/slice/sort/stable/mod.rs @@ -104,7 +104,7 @@ struct AlignedStorage { impl AlignedStorage { fn new() -> Self { - Self { _align: [], storage: MaybeUninit::uninit_array() } + Self { _align: [], storage: [const { MaybeUninit::uninit() }; N] } } fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit] { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 3a2c98db0d50a..57127df51ebdd 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -54,8 +54,6 @@ #![feature(slice_split_once)] #![feature(split_as_slice)] #![feature(maybe_uninit_fill)] -#![feature(maybe_uninit_slice)] -#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_write_slice)] #![feature(maybe_uninit_uninit_array_transpose)] #![feature(min_specialization)] diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 62a268facb638..b75579d6d5e01 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -406,7 +406,7 @@ fn file_test_read_buf() { let filename = &tmpdir.join("test"); check!(fs::write(filename, &[1, 2, 3, 4])); - let mut buf: [MaybeUninit; 128] = MaybeUninit::uninit_array(); + let mut buf: [MaybeUninit; 128] = [MaybeUninit::uninit(); 128]; let mut buf = BorrowedBuf::from(buf.as_mut_slice()); let mut file = check!(File::open(filename)); check!(file.read_buf(buf.unfilled())); diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index caa8c7375ec45..27ed2e4137c7e 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -337,7 +337,6 @@ #![feature(hint_assert_unchecked)] #![feature(ip)] #![feature(maybe_uninit_slice)] -#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_write_slice)] #![feature(panic_can_unwind)] #![feature(panic_info_message)] @@ -407,7 +406,6 @@ #![feature(const_ip)] #![feature(const_ipv4)] #![feature(const_ipv6)] -#![feature(const_maybe_uninit_uninit_array)] #![feature(const_waker)] #![feature(thread_local_internals)] // tidy-alphabetical-end diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs index ec8b62f968754..3ad046733a634 100644 --- a/library/std/src/net/tcp/tests.rs +++ b/library/std/src/net/tcp/tests.rs @@ -301,7 +301,7 @@ fn read_buf() { }); let mut s = t!(srv.accept()).0; - let mut buf: [MaybeUninit; 128] = MaybeUninit::uninit_array(); + let mut buf: [MaybeUninit; 128] = [MaybeUninit::uninit(); 128]; let mut buf = BorrowedBuf::from(buf.as_mut_slice()); t!(s.read_buf(buf.unfilled())); assert_eq!(buf.filled(), &[1, 2, 3, 4]); diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index 07d4de5c1a26e..63455a274faaa 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -137,7 +137,7 @@ fn child_stdout_read_buf() { let child = cmd.spawn().unwrap(); let mut stdout = child.stdout.unwrap(); - let mut buf: [MaybeUninit; 128] = MaybeUninit::uninit_array(); + let mut buf: [MaybeUninit; 128] = [MaybeUninit::uninit(); 128]; let mut buf = BorrowedBuf::from(buf.as_mut_slice()); stdout.read_buf(buf.unfilled()).unwrap(); diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 402a205977b07..cd948d39f1496 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -227,7 +227,7 @@ where // This initial size also works around `GetFullPathNameW` returning // incorrect size hints for some short paths: // https://github.com/dylni/normpath/issues/5 - let mut stack_buf: [MaybeUninit; 512] = MaybeUninit::uninit_array(); + let mut stack_buf: [MaybeUninit; 512] = [MaybeUninit::uninit(); 512]; let mut heap_buf: Vec> = Vec::new(); unsafe { let mut n = stack_buf.len();