From 39466bc58b15cca644afcdf79a152625fc75987e Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Wed, 5 Aug 2020 16:49:48 +1000 Subject: [PATCH 01/32] implement Error for &(impl Error) --- library/std/src/error.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 3b4cb859dd425..cb70b38850cbe 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -506,6 +506,27 @@ impl Error for Box { } } +#[stable(feature = "error_by_ref", since = "1.47.0")] +impl<'a, T: Error + ?Sized> Error for &'a T { + #[allow(deprecated, deprecated_in_future)] + fn description(&self) -> &str { + Error::description(&**self) + } + + #[allow(deprecated)] + fn cause(&self) -> Option<&dyn Error> { + Error::cause(&**self) + } + + fn source(&self) -> Option<&(dyn Error + 'static)> { + Error::source(&**self) + } + + fn backtrace(&self) -> Option<&Backtrace> { + Error::backtrace(&**self) + } +} + #[stable(feature = "fmt_error", since = "1.11.0")] impl Error for fmt::Error { #[allow(deprecated)] From 573ec314b635178533f68160f2dab3dd345d5df2 Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Sat, 31 Oct 2020 20:16:15 +1000 Subject: [PATCH 02/32] update stabilization to 1.49.0 --- library/std/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index cb70b38850cbe..8fd9f09b9de75 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -506,7 +506,7 @@ impl Error for Box { } } -#[stable(feature = "error_by_ref", since = "1.47.0")] +#[stable(feature = "error_by_ref", since = "1.49.0")] impl<'a, T: Error + ?Sized> Error for &'a T { #[allow(deprecated, deprecated_in_future)] fn description(&self) -> &str { From 517d462e40a308976b84797c318e912642cf521a Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 19 Nov 2020 03:39:16 +0900 Subject: [PATCH 03/32] Make std::future a re-export of core::future --- library/std/src/future.rs | 17 ----------------- library/std/src/lib.rs | 5 ++--- 2 files changed, 2 insertions(+), 20 deletions(-) delete mode 100644 library/std/src/future.rs diff --git a/library/std/src/future.rs b/library/std/src/future.rs deleted file mode 100644 index 9d9c36e9afb0f..0000000000000 --- a/library/std/src/future.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! Asynchronous values. - -#[doc(inline)] -#[stable(feature = "futures_api", since = "1.36.0")] -pub use core::future::Future; - -#[doc(inline)] -#[unstable(feature = "gen_future", issue = "50547")] -pub use core::future::{from_generator, get_context, ResumeTy}; - -#[doc(inline)] -#[stable(feature = "future_readiness_fns", since = "1.48.0")] -pub use core::future::{pending, ready, Pending, Ready}; - -#[doc(inline)] -#[unstable(feature = "into_future", issue = "67644")] -pub use core::future::IntoFuture; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index db523f05e01a5..6e9b7ef751c4b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -407,6 +407,8 @@ pub use core::cmp; pub use core::convert; #[stable(feature = "rust1", since = "1.0.0")] pub use core::default; +#[stable(feature = "futures_api", since = "1.36.0")] +pub use core::future; #[stable(feature = "rust1", since = "1.0.0")] pub use core::hash; #[stable(feature = "core_hint", since = "1.27.0")] @@ -494,9 +496,6 @@ pub mod task { pub use alloc::task::*; } -#[stable(feature = "futures_api", since = "1.36.0")] -pub mod future; - // Platform-abstraction modules #[macro_use] mod sys_common; From c387e29e9139096f8afc237b2dd1a49f32635bea Mon Sep 17 00:00:00 2001 From: James Wright Date: Thu, 10 Dec 2020 05:37:39 +0000 Subject: [PATCH 04/32] Replace magic numbers with existing constants Split long lines over 100 char line limit Fix tidy complaints --- library/core/src/time.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 88b4e2a2436e7..b1443bc33d2ff 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1067,13 +1067,23 @@ impl fmt::Debug for Duration { } if self.secs > 0 { - fmt_decimal(f, self.secs, self.nanos, 100_000_000)?; + fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10)?; f.write_str("s") - } else if self.nanos >= 1_000_000 { - fmt_decimal(f, self.nanos as u64 / 1_000_000, self.nanos % 1_000_000, 100_000)?; + } else if self.nanos >= NANOS_PER_MILLI { + fmt_decimal( + f, + (self.nanos / NANOS_PER_MILLI) as u64, + self.nanos % NANOS_PER_MILLI, + NANOS_PER_MILLI / 10, + )?; f.write_str("ms") - } else if self.nanos >= 1_000 { - fmt_decimal(f, self.nanos as u64 / 1_000, self.nanos % 1_000, 100)?; + } else if self.nanos >= NANOS_PER_MICRO { + fmt_decimal( + f, + (self.nanos / NANOS_PER_MICRO) as u64, + self.nanos % NANOS_PER_MICRO, + NANOS_PER_MICRO / 10, + )?; f.write_str("µs") } else { fmt_decimal(f, self.nanos as u64, 0, 1)?; From bbf5001b9428bbf5b4ac93f42dc7017b27c9002f Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Mon, 21 Dec 2020 18:40:34 +1000 Subject: [PATCH 05/32] bump stabilization to 1.51.0 --- library/std/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 8fd9f09b9de75..4ff60709b2079 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -506,7 +506,7 @@ impl Error for Box { } } -#[stable(feature = "error_by_ref", since = "1.49.0")] +#[stable(feature = "error_by_ref", since = "1.51.0")] impl<'a, T: Error + ?Sized> Error for &'a T { #[allow(deprecated, deprecated_in_future)] fn description(&self) -> &str { From a1c41e9ca7245e7d8ccd72c16c1e36b9d7e729f3 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 9 Jan 2021 20:53:24 +0100 Subject: [PATCH 06/32] Expand assert!(expr, args..) to include $crate for hygiene on 2021. Before 2021, this was a breaking change, as std::panic and core::panic are different. In edition 2021 they will be identical, making it possible again to apply proper hygiene here. --- compiler/rustc_builtin_macros/src/assert.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index bb6d3f6a0076c..3cffc7a75eeb1 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -23,16 +23,34 @@ pub fn expand_assert<'cx>( } }; + let is_2021 = sp.rust_2021(); + // `core::panic` and `std::panic` are different macros, so we use call-site // context to pick up whichever is currently in scope. let sp = cx.with_call_site_ctxt(sp); let panic_call = if let Some(tokens) = custom_message { + let path = if is_2021 { + // On edition 2021, we always call `$crate::panic!()`. + Path { + span: sp, + segments: cx + .std_path(&[sym::panic]) + .into_iter() + .map(|ident| PathSegment::from_ident(ident)) + .collect(), + tokens: None, + } + } else { + // Before edition 2021, we call `panic!()` unqualified, + // such that it calls either `std::panic!()` or `core::panic!()`. + Path::from_ident(Ident::new(sym::panic, sp)) + }; // Pass the custom message to panic!(). cx.expr( sp, ExprKind::MacCall(MacCall { - path: Path::from_ident(Ident::new(sym::panic, sp)), + path, args: P(MacArgs::Delimited( DelimSpan::from_single(sp), MacDelimiter::Parenthesis, From 8098ac17064ee5a1d34ffe6bc8d35a9574f2bf6e Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 9 Jan 2021 20:54:41 +0100 Subject: [PATCH 07/32] Add test for assert!() hygiene in edition 2021. --- src/test/ui/hygiene/no_implicit_prelude-2021.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/test/ui/hygiene/no_implicit_prelude-2021.rs diff --git a/src/test/ui/hygiene/no_implicit_prelude-2021.rs b/src/test/ui/hygiene/no_implicit_prelude-2021.rs new file mode 100644 index 0000000000000..0fe9ae56c6564 --- /dev/null +++ b/src/test/ui/hygiene/no_implicit_prelude-2021.rs @@ -0,0 +1,9 @@ +// check-pass +// edition:2021 + +#![no_implicit_prelude] + +fn main() { + assert!(true, "hoi"); + assert!(false, "hoi {}", 123); +} From 737867618b3c92330c42b7bb488eb0ee387f2e04 Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Tue, 19 Jan 2021 20:08:30 -0800 Subject: [PATCH 08/32] Fix sysroot option not being honored across rustc Change link_sanitizer_runtime() to check if the sanitizer library exists in the specified/session sysroot, and if it doesn't exist, use the default sysroot. --- compiler/rustc_codegen_ssa/src/back/link.rs | 28 +++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 55fddb38e10be..175094b129c8f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -887,9 +887,22 @@ fn link_sanitizers(sess: &Session, crate_type: CrateType, linker: &mut dyn Linke } fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { - let default_sysroot = filesearch::get_or_default_sysroot(); - let default_tlib = - filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.triple()); + fn find_sanitizer_runtime(sess: &Session, filename: &String) -> PathBuf { + let session_tlib = + filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple()); + let path = session_tlib.join(&filename); + if path.exists() { + return session_tlib; + } else { + let default_sysroot = filesearch::get_or_default_sysroot(); + let default_tlib = filesearch::make_target_lib_path( + &default_sysroot, + sess.opts.target_triple.triple(), + ); + return default_tlib; + } + } + let channel = option_env!("CFG_RELEASE_CHANNEL") .map(|channel| format!("-{}", channel)) .unwrap_or_default(); @@ -900,10 +913,11 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { // LLVM will link to `@rpath/*.dylib`, so we need to specify an // rpath to the library as well (the rpath should be absolute, see // PR #41352 for details). - let libname = format!("rustc{}_rt.{}", channel, name); - let rpath = default_tlib.to_str().expect("non-utf8 component in path"); + let filename = format!("rustc{}_rt.{}", channel, name); + let path = find_sanitizer_runtime(&sess, &filename); + let rpath = path.to_str().expect("non-utf8 component in path"); linker.args(&["-Wl,-rpath", "-Xlinker", rpath]); - linker.link_dylib(Symbol::intern(&libname)); + linker.link_dylib(Symbol::intern(&filename)); } "aarch64-fuchsia" | "aarch64-unknown-linux-gnu" @@ -911,7 +925,7 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { | "x86_64-unknown-freebsd" | "x86_64-unknown-linux-gnu" => { let filename = format!("librustc{}_rt.{}.a", channel, name); - let path = default_tlib.join(&filename); + let path = find_sanitizer_runtime(&sess, &filename).join(&filename); linker.link_whole_rlib(&path); } _ => {} From 3e9f27dadfea2921649837c1a282ad159ceb8684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 22 Jan 2021 08:06:01 +0100 Subject: [PATCH 09/32] Remove unnecessary closure --- compiler/rustc_typeck/src/check/check.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 8e339eb26b26c..279c4422fe129 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -932,11 +932,11 @@ pub(super) fn check_impl_items_against_trait<'tcx>( // Locate trait definition and items let trait_def = tcx.trait_def(impl_trait_ref.def_id); - let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id)); + let impl_items = impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id)); // Check existing impl methods to see if they are both present in trait // and compatible with trait signature - for impl_item in impl_items() { + for impl_item in impl_items { let namespace = impl_item.kind.namespace(); let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id)); let ty_trait_item = tcx From 58a90de9adfac7cc26fe178b3f736153b756a515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 22 Jan 2021 08:14:25 +0100 Subject: [PATCH 10/32] No peeking --- compiler/rustc_typeck/src/check/check.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 279c4422fe129..e89a063598ab7 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -854,13 +854,7 @@ pub(super) fn check_specialization_validity<'tcx>( } else { Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id))) } - }) - .peekable(); - - if ancestor_impls.peek().is_none() { - // No parent, nothing to specialize. - return; - } + }); let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| { match parent_item { From 9988821a04073360c27bd95b9535a8dceca67d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 22 Jan 2021 08:22:15 +0100 Subject: [PATCH 11/32] Move missing_item check inside condition --- compiler/rustc_typeck/src/check/check.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index e89a063598ab7..ace2ccb2fceac 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -1043,9 +1043,9 @@ pub(super) fn check_impl_items_against_trait<'tcx>( } } - // Check for missing items from trait - let mut missing_items = Vec::new(); if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) { + // Check for missing items from trait + let mut missing_items = Vec::new(); for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() { let is_implemented = ancestors .leaf_def(tcx, trait_item.ident, trait_item.kind) @@ -1058,10 +1058,10 @@ pub(super) fn check_impl_items_against_trait<'tcx>( } } } - } - if !missing_items.is_empty() { - missing_items_err(tcx, impl_span, &missing_items, full_impl_span); + if !missing_items.is_empty() { + missing_items_err(tcx, impl_span, &missing_items, full_impl_span); + } } } From d63b278c2ff01b73653397a5e2c469689ef0adf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 22 Jan 2021 18:15:55 +0100 Subject: [PATCH 12/32] Only scan through assoc items once in check_impl_items_against_trait --- compiler/rustc_typeck/src/check/check.rs | 215 ++++++++++++----------- 1 file changed, 117 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index ace2ccb2fceac..eda5a27e97e3a 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -846,15 +846,13 @@ pub(super) fn check_specialization_validity<'tcx>( Ok(ancestors) => ancestors, Err(_) => return, }; - let mut ancestor_impls = ancestors - .skip(1) - .filter_map(|parent| { - if parent.is_from_trait() { - None - } else { - Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id))) - } - }); + let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| { + if parent.is_from_trait() { + None + } else { + Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id))) + } + }); let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| { match parent_item { @@ -931,105 +929,72 @@ pub(super) fn check_impl_items_against_trait<'tcx>( // Check existing impl methods to see if they are both present in trait // and compatible with trait signature for impl_item in impl_items { - let namespace = impl_item.kind.namespace(); let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id)); - let ty_trait_item = tcx - .associated_items(impl_trait_ref.def_id) - .find_by_name_and_namespace(tcx, ty_impl_item.ident, namespace, impl_trait_ref.def_id) - .or_else(|| { - // Not compatible, but needed for the error message - tcx.associated_items(impl_trait_ref.def_id) - .filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id) - .next() - }); - - // Check that impl definition matches trait definition - if let Some(ty_trait_item) = ty_trait_item { + let associated_items = tcx.associated_items(impl_trait_ref.def_id); + + let mut items = associated_items.filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id); + + let (compatible_kind, ty_trait_item) = if let Some(ty_trait_item) = items.next() { + + let is_compatible = |ty: &&ty::AssocItem| { + match (ty.kind, &impl_item.kind) { + (ty::AssocKind::Const, hir::ImplItemKind::Const(..)) => true, + (ty::AssocKind::Fn, hir::ImplItemKind::Fn(..)) => true, + (ty::AssocKind::Type, hir::ImplItemKind::TyAlias(..)) => true, + _ => false + } + }; + + // If we don't have a compatible item, we'll use the first one whose name matches + // to report an error. + let mut compatible_kind = is_compatible(&ty_trait_item); + let mut trait_item = ty_trait_item; + + if !compatible_kind { + if let Some(ty_trait_item) = items.find(is_compatible) { + compatible_kind = true; + trait_item = ty_trait_item; + } + } + + (compatible_kind, trait_item) + } else { + continue; + }; + + if compatible_kind { match impl_item.kind { hir::ImplItemKind::Const(..) => { // Find associated const definition. - if ty_trait_item.kind == ty::AssocKind::Const { - compare_const_impl( - tcx, - &ty_impl_item, - impl_item.span, - &ty_trait_item, - impl_trait_ref, - ); - } else { - let mut err = struct_span_err!( - tcx.sess, - impl_item.span, - E0323, - "item `{}` is an associated const, \ - which doesn't match its trait `{}`", - ty_impl_item.ident, - impl_trait_ref.print_only_trait_path() - ); - err.span_label(impl_item.span, "does not match trait"); - // We can only get the spans from local trait definition - // Same for E0324 and E0325 - if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) { - err.span_label(trait_span, "item in trait"); - } - err.emit() - } + compare_const_impl( + tcx, + &ty_impl_item, + impl_item.span, + &ty_trait_item, + impl_trait_ref, + ); } hir::ImplItemKind::Fn(..) => { let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); - if ty_trait_item.kind == ty::AssocKind::Fn { - compare_impl_method( - tcx, - &ty_impl_item, - impl_item.span, - &ty_trait_item, - impl_trait_ref, - opt_trait_span, - ); - } else { - let mut err = struct_span_err!( - tcx.sess, - impl_item.span, - E0324, - "item `{}` is an associated method, \ - which doesn't match its trait `{}`", - ty_impl_item.ident, - impl_trait_ref.print_only_trait_path() - ); - err.span_label(impl_item.span, "does not match trait"); - if let Some(trait_span) = opt_trait_span { - err.span_label(trait_span, "item in trait"); - } - err.emit() - } + compare_impl_method( + tcx, + &ty_impl_item, + impl_item.span, + &ty_trait_item, + impl_trait_ref, + opt_trait_span, + ); } hir::ImplItemKind::TyAlias(_) => { let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); - if ty_trait_item.kind == ty::AssocKind::Type { - compare_ty_impl( - tcx, - &ty_impl_item, - impl_item.span, - &ty_trait_item, - impl_trait_ref, - opt_trait_span, - ); - } else { - let mut err = struct_span_err!( - tcx.sess, - impl_item.span, - E0325, - "item `{}` is an associated type, \ - which doesn't match its trait `{}`", - ty_impl_item.ident, - impl_trait_ref.print_only_trait_path() - ); - err.span_label(impl_item.span, "does not match trait"); - if let Some(trait_span) = opt_trait_span { - err.span_label(trait_span, "item in trait"); - } - err.emit() - } + compare_ty_impl( + tcx, + &ty_impl_item, + impl_item.span, + &ty_trait_item, + impl_trait_ref, + opt_trait_span, + ); } } @@ -1040,6 +1005,8 @@ pub(super) fn check_impl_items_against_trait<'tcx>( impl_id.to_def_id(), impl_item, ); + } else { + report_mismatch_error(tcx, ty_trait_item.def_id, impl_trait_ref, impl_item, &ty_impl_item); } } @@ -1065,6 +1032,58 @@ pub(super) fn check_impl_items_against_trait<'tcx>( } } +#[inline(never)] +#[cold] +fn report_mismatch_error<'tcx>( + tcx: TyCtxt<'tcx>, + trait_item_def_id: DefId, + impl_trait_ref: ty::TraitRef<'tcx>, + impl_item: &hir::ImplItem<'_>, + ty_impl_item: &ty::AssocItem, +) { + let mut err = match impl_item.kind { + hir::ImplItemKind::Const(..) => { + // Find associated const definition. + struct_span_err!( + tcx.sess, + impl_item.span, + E0323, + "item `{}` is an associated const, which doesn't match its trait `{}`", + ty_impl_item.ident, + impl_trait_ref.print_only_trait_path() + ) + } + + hir::ImplItemKind::Fn(..) => { + struct_span_err!( + tcx.sess, + impl_item.span, + E0324, + "item `{}` is an associated method, which doesn't match its trait `{}`", + ty_impl_item.ident, + impl_trait_ref.print_only_trait_path() + ) + } + + hir::ImplItemKind::TyAlias(_) => { + struct_span_err!( + tcx.sess, + impl_item.span, + E0325, + "item `{}` is an associated type, which doesn't match its trait `{}`", + ty_impl_item.ident, + impl_trait_ref.print_only_trait_path() + ) + } + }; + + err.span_label(impl_item.span, "does not match trait"); + if let Some(trait_span) = tcx.hir().span_if_local(trait_item_def_id) { + err.span_label(trait_span, "item in trait"); + } + err.emit(); +} + /// Checks whether a type can be represented in memory. In particular, it /// identifies types that contain themselves without indirection through a /// pointer, which would mean their size is unbounded. From ee639de007e952c006cee53278f9bc1fd773e7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 22 Jan 2021 18:17:53 +0100 Subject: [PATCH 13/32] Only guess span if absolutely necessary --- compiler/rustc_typeck/src/check/check.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index eda5a27e97e3a..f937970aa552f 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -894,8 +894,6 @@ pub(super) fn check_impl_items_against_trait<'tcx>( impl_trait_ref: ty::TraitRef<'tcx>, impl_item_refs: &[hir::ImplItemRef<'_>], ) { - let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span); - // If the trait reference itself is erroneous (so the compilation is going // to fail), skip checking the items here -- the `impl_item` table in `tcx` // isn't populated for such impls. @@ -1011,6 +1009,8 @@ pub(super) fn check_impl_items_against_trait<'tcx>( } if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) { + let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span); + // Check for missing items from trait let mut missing_items = Vec::new(); for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() { From aa4f5833e1e3dc468923be7be988eb9e25a9e4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 22 Jan 2021 18:19:27 +0100 Subject: [PATCH 14/32] Only query associated_items once --- compiler/rustc_typeck/src/check/check.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index f937970aa552f..fa630bb2b52e3 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -921,14 +921,13 @@ pub(super) fn check_impl_items_against_trait<'tcx>( // Locate trait definition and items let trait_def = tcx.trait_def(impl_trait_ref.def_id); - let impl_items = impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id)); + let associated_items = tcx.associated_items(impl_trait_ref.def_id); // Check existing impl methods to see if they are both present in trait // and compatible with trait signature for impl_item in impl_items { let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id)); - let associated_items = tcx.associated_items(impl_trait_ref.def_id); let mut items = associated_items.filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id); @@ -1010,7 +1009,7 @@ pub(super) fn check_impl_items_against_trait<'tcx>( if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) { let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span); - + // Check for missing items from trait let mut missing_items = Vec::new(); for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() { From f29b32983d1e885b0e141b6aac2cae281ff39a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 22 Jan 2021 18:55:37 +0100 Subject: [PATCH 15/32] Fix formatting --- compiler/rustc_typeck/src/check/check.rs | 26 ++++++++++++++---------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index fa630bb2b52e3..518090a710d3b 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -929,17 +929,15 @@ pub(super) fn check_impl_items_against_trait<'tcx>( for impl_item in impl_items { let ty_impl_item = tcx.associated_item(tcx.hir().local_def_id(impl_item.hir_id)); - let mut items = associated_items.filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id); + let mut items = + associated_items.filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id); let (compatible_kind, ty_trait_item) = if let Some(ty_trait_item) = items.next() { - - let is_compatible = |ty: &&ty::AssocItem| { - match (ty.kind, &impl_item.kind) { - (ty::AssocKind::Const, hir::ImplItemKind::Const(..)) => true, - (ty::AssocKind::Fn, hir::ImplItemKind::Fn(..)) => true, - (ty::AssocKind::Type, hir::ImplItemKind::TyAlias(..)) => true, - _ => false - } + let is_compatible = |ty: &&ty::AssocItem| match (ty.kind, &impl_item.kind) { + (ty::AssocKind::Const, hir::ImplItemKind::Const(..)) => true, + (ty::AssocKind::Fn, hir::ImplItemKind::Fn(..)) => true, + (ty::AssocKind::Type, hir::ImplItemKind::TyAlias(..)) => true, + _ => false, }; // If we don't have a compatible item, we'll use the first one whose name matches @@ -947,7 +945,7 @@ pub(super) fn check_impl_items_against_trait<'tcx>( let mut compatible_kind = is_compatible(&ty_trait_item); let mut trait_item = ty_trait_item; - if !compatible_kind { + if !compatible_kind { if let Some(ty_trait_item) = items.find(is_compatible) { compatible_kind = true; trait_item = ty_trait_item; @@ -1003,7 +1001,13 @@ pub(super) fn check_impl_items_against_trait<'tcx>( impl_item, ); } else { - report_mismatch_error(tcx, ty_trait_item.def_id, impl_trait_ref, impl_item, &ty_impl_item); + report_mismatch_error( + tcx, + ty_trait_item.def_id, + impl_trait_ref, + impl_item, + &ty_impl_item, + ); } } From 99a1dea1b7727885d2660bae665cff165fb86a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 23 Jan 2021 00:00:00 +0000 Subject: [PATCH 16/32] Do not mark unit variants as used when in path pattern Record that we are processing a pattern so that code responsible for handling path resolution can correctly decide whether to mark it as used or not. --- compiler/rustc_passes/src/dead.rs | 2 +- src/test/ui/lint/dead-code/const-and-self.rs | 21 ++++++++++++++++++- .../ui/lint/dead-code/const-and-self.stderr | 20 ++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/lint/dead-code/const-and-self.stderr diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 80a24c90421e7..3b1b53553d5e4 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -290,6 +290,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { } fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) { + self.in_pat = true; match pat.kind { PatKind::Struct(ref path, ref fields, _) => { let res = self.typeck_results().qpath_res(path, pat.hir_id); @@ -302,7 +303,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { _ => (), } - self.in_pat = true; intravisit::walk_pat(self, pat); self.in_pat = false; } diff --git a/src/test/ui/lint/dead-code/const-and-self.rs b/src/test/ui/lint/dead-code/const-and-self.rs index 1a7b3f43cda14..0bcdd6edf0d66 100644 --- a/src/test/ui/lint/dead-code/const-and-self.rs +++ b/src/test/ui/lint/dead-code/const-and-self.rs @@ -1,6 +1,6 @@ // check-pass -#![deny(dead_code)] +#![warn(dead_code)] const TLC: usize = 4; @@ -28,8 +28,27 @@ impl Foo for X { } } +enum E { + A, + B, //~ WARN variant is never constructed: `B` + C, //~ WARN variant is never constructed: `C` +} + +type F = E; + +impl E { + fn check(&self) -> bool { + match self { + Self::A => true, + Self::B => false, + F::C => false, + } + } +} + fn main() { let s = [0,1,2,3]; s.doit(); X::foo(); + E::A.check(); } diff --git a/src/test/ui/lint/dead-code/const-and-self.stderr b/src/test/ui/lint/dead-code/const-and-self.stderr new file mode 100644 index 0000000000000..c0e406189e8ab --- /dev/null +++ b/src/test/ui/lint/dead-code/const-and-self.stderr @@ -0,0 +1,20 @@ +warning: variant is never constructed: `B` + --> $DIR/const-and-self.rs:33:5 + | +LL | B, + | ^ + | +note: the lint level is defined here + --> $DIR/const-and-self.rs:3:9 + | +LL | #![warn(dead_code)] + | ^^^^^^^^^ + +warning: variant is never constructed: `C` + --> $DIR/const-and-self.rs:34:5 + | +LL | C, + | ^ + +warning: 2 warnings emitted + From 794880c6b564d67b75cc89eed1d839d301facadf Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Jan 2021 11:11:51 +0100 Subject: [PATCH 17/32] Don't provide backend_optimization_level query for extern crates --- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/lib.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 2ce5fe5ad504b..b205ea9cf6c9d 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -783,7 +783,7 @@ impl CrateInfo { } } -pub fn provide_both(providers: &mut Providers) { +pub fn provide(providers: &mut Providers) { providers.backend_optimization_level = |tcx, cratenum| { let for_speed = match tcx.sess.opts.optimize { // If globally no optimisation is done, #[optimize] has no effect. diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index e27eac3f69b00..0307117e1c8b2 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -160,13 +160,12 @@ pub struct CodegenResults { pub fn provide(providers: &mut Providers) { crate::back::symbol_export::provide(providers); - crate::base::provide_both(providers); + crate::base::provide(providers); crate::target_features::provide(providers); } pub fn provide_extern(providers: &mut Providers) { crate::back::symbol_export::provide_extern(providers); - crate::base::provide_both(providers); } /// Checks if the given filename ends with the `.rcgu.o` extension that `rustc` From d118021f8bfbfda2cd93277c15c607b2c66ff93c Mon Sep 17 00:00:00 2001 From: oli Date: Sun, 3 Jan 2021 18:46:20 +0000 Subject: [PATCH 18/32] Permit mutable references in all const contexts --- .../src/transform/check_consts/ops.rs | 71 ++++++++++++------- .../src/transform/check_consts/validation.rs | 29 +++++++- .../ui/check-static-immutable-mut-slices.rs | 2 +- .../check-static-immutable-mut-slices.stderr | 4 +- .../ui/consts/const-address-of-mut.stderr | 24 ++++--- .../ui/consts/const-eval/issue-65394.stderr | 9 ++- src/test/ui/consts/const-multi-ref.stderr | 10 +-- .../const-mut-refs/const_mut_address_of.rs | 3 +- .../const_mut_address_of.stderr | 15 ---- .../consts/const-mut-refs/const_mut_refs.rs | 4 +- .../const-mut-refs/const_mut_refs.stderr | 21 ------ .../consts/const-mut-refs/mut_ref_in_final.rs | 24 +++++++ .../const-mut-refs/mut_ref_in_final.stderr | 9 +++ .../const-mut-refs/mut_ref_in_final_ok.rs | 22 ++++++ .../const-mut-refs/mut_ref_in_final_ok.stderr | 13 ++++ src/test/ui/consts/const_let_assign3.stderr | 17 +++-- .../ui/consts/issue-17718-const-bad-values.rs | 3 +- .../issue-17718-const-bad-values.stderr | 12 +--- .../consts/projection_qualif.mut_refs.stderr | 11 +-- src/test/ui/consts/projection_qualif.rs | 2 +- .../ui/consts/projection_qualif.stock.stderr | 10 +-- .../ui/consts/read_from_static_mut_ref.rs | 5 +- .../ui/consts/read_from_static_mut_ref.stderr | 17 +++-- ...ic_mut_containing_mut_ref2.mut_refs.stderr | 8 +-- .../consts/static_mut_containing_mut_ref2.rs | 3 +- ...tatic_mut_containing_mut_ref2.stock.stderr | 9 ++- src/test/ui/error-codes/E0017.rs | 9 +-- src/test/ui/error-codes/E0017.stderr | 35 +++++---- src/test/ui/error-codes/E0388.rs | 7 +- src/test/ui/error-codes/E0388.stderr | 29 +++++--- src/test/ui/issues/issue-46604.rs | 2 +- src/test/ui/issues/issue-46604.stderr | 4 +- src/test/ui/never_type/issue-52443.stderr | 9 ++- src/test/ui/unsafe/ranged_ints2_const.rs | 6 ++ src/test/ui/unsafe/ranged_ints2_const.stderr | 11 ++- 35 files changed, 298 insertions(+), 171 deletions(-) delete mode 100644 src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr delete mode 100644 src/test/ui/consts/const-mut-refs/const_mut_refs.stderr create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 99ffb0edce9e1..23abd522cf0f3 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -268,43 +268,41 @@ impl NonConstOp for CellBorrow { } #[derive(Debug)] +/// This op is for `&mut` borrows in the trailing expression of a constant +/// which uses the "enclosing scopes rule" to leak its locals into anonymous +/// static or const items. pub struct MutBorrow(pub hir::BorrowKind); impl NonConstOp for MutBorrow { fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { - // Forbid everywhere except in const fn with a feature gate - if ccx.const_kind() == hir::ConstContext::ConstFn { - Status::Unstable(sym::const_mut_refs) - } else { - Status::Forbidden + match ccx.const_kind() { + // Mutable statics can handle mutable references in their final value + hir::ConstContext::Static(hir::Mutability::Mut) => Status::Allowed, + _ => Status::Forbidden, } } + fn importance(&self) -> DiagnosticImportance { + // If there were primary errors (like non-const function calls), do not emit further + // errors about mutable references. + DiagnosticImportance::Secondary + } + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { let raw = match self.0 { hir::BorrowKind::Raw => "raw ", hir::BorrowKind::Ref => "", }; - let mut err = if ccx.const_kind() == hir::ConstContext::ConstFn { - feature_err( - &ccx.tcx.sess.parse_sess, - sym::const_mut_refs, - span, - &format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()), - ) - } else { - let mut err = struct_span_err!( - ccx.tcx.sess, - span, - E0764, - "{}mutable references are not allowed in {}s", - raw, - ccx.const_kind(), - ); - err.span_label(span, format!("`&{}mut` is only allowed in `const fn`", raw)); - err - }; + let mut err = struct_span_err!( + ccx.tcx.sess, + span, + E0764, + "{}mutable references are not allowed in final value of {}s", + raw, + ccx.const_kind(), + ); + if ccx.tcx.sess.teach(&err.get_code().unwrap()) { err.note( "References in statics and constants may only refer \ @@ -321,6 +319,29 @@ impl NonConstOp for MutBorrow { } } +#[derive(Debug)] +pub struct TransientMutBorrow(pub hir::BorrowKind); + +impl NonConstOp for TransientMutBorrow { + fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status { + Status::Unstable(sym::const_mut_refs) + } + + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + let raw = match self.0 { + hir::BorrowKind::Raw => "raw ", + hir::BorrowKind::Ref => "", + }; + + feature_err( + &ccx.tcx.sess.parse_sess, + sym::const_mut_refs, + span, + &format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()), + ) + } +} + #[derive(Debug)] pub struct MutDeref; impl NonConstOp for MutDeref { @@ -329,7 +350,7 @@ impl NonConstOp for MutDeref { } fn importance(&self) -> DiagnosticImportance { - // Usually a side-effect of a `MutBorrow` somewhere. + // Usually a side-effect of a `TransientMutBorrow` somewhere. DiagnosticImportance::Secondary } diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 08d969b27bea5..a92997dddac6a 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -466,6 +466,29 @@ impl Validator<'mir, 'tcx> { } } } + + fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) { + match self.const_kind() { + // In a const fn all borrows are transient or point to the places given via + // references in the arguments (so we already checked them with + // TransientMutBorrow/MutBorrow as appropriate). + // The borrow checker guarantees that no new non-transient borrows are created. + // NOTE: Once we have heap allocations during CTFE we need to figure out + // how to prevent `const fn` to create long-lived allocations that point + // to mutable memory. + hir::ConstContext::ConstFn => self.check_op(ops::TransientMutBorrow(kind)), + _ => { + // Locals with StorageDead do not live beyond the evaluation and can + // thus safely be borrowed without being able to be leaked to the final + // value of the constant. + if self.local_has_storage_dead(local) { + self.check_op(ops::TransientMutBorrow(kind)); + } else { + self.check_op(ops::MutBorrow(kind)); + } + } + } + } } impl Visitor<'tcx> for Validator<'mir, 'tcx> { @@ -562,15 +585,15 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { if !is_allowed { if let BorrowKind::Mut { .. } = kind { - self.check_op(ops::MutBorrow(hir::BorrowKind::Ref)); + self.check_mut_borrow(place.local, hir::BorrowKind::Ref) } else { self.check_op(ops::CellBorrow); } } } - Rvalue::AddressOf(Mutability::Mut, _) => { - self.check_op(ops::MutBorrow(hir::BorrowKind::Raw)) + Rvalue::AddressOf(Mutability::Mut, ref place) => { + self.check_mut_borrow(place.local, hir::BorrowKind::Raw) } Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, ref place) diff --git a/src/test/ui/check-static-immutable-mut-slices.rs b/src/test/ui/check-static-immutable-mut-slices.rs index 3be02f6a0f674..8f9680778aa03 100644 --- a/src/test/ui/check-static-immutable-mut-slices.rs +++ b/src/test/ui/check-static-immutable-mut-slices.rs @@ -1,6 +1,6 @@ // Checks that immutable static items can't have mutable slices static TEST: &'static mut [isize] = &mut []; -//~^ ERROR mutable references are not allowed in statics +//~^ ERROR mutable references are not allowed pub fn main() { } diff --git a/src/test/ui/check-static-immutable-mut-slices.stderr b/src/test/ui/check-static-immutable-mut-slices.stderr index 9ffbb483d139d..fcc18cc584c54 100644 --- a/src/test/ui/check-static-immutable-mut-slices.stderr +++ b/src/test/ui/check-static-immutable-mut-slices.stderr @@ -1,8 +1,8 @@ -error[E0764]: mutable references are not allowed in statics +error[E0764]: mutable references are not allowed in final value of statics --> $DIR/check-static-immutable-mut-slices.rs:3:37 | LL | static TEST: &'static mut [isize] = &mut []; - | ^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-address-of-mut.stderr b/src/test/ui/consts/const-address-of-mut.stderr index ec2dac5a7d16f..60cdcc7df7449 100644 --- a/src/test/ui/consts/const-address-of-mut.stderr +++ b/src/test/ui/consts/const-address-of-mut.stderr @@ -1,20 +1,29 @@ -error[E0764]: raw mutable references are not allowed in constants +error[E0658]: raw mutable references are not allowed in constants --> $DIR/const-address-of-mut.rs:3:32 | LL | const A: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` + | ^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: raw mutable references are not allowed in statics +error[E0658]: raw mutable references are not allowed in statics --> $DIR/const-address-of-mut.rs:5:33 | LL | static B: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` + | ^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: raw mutable references are not allowed in statics +error[E0658]: raw mutable references are not allowed in statics --> $DIR/const-address-of-mut.rs:7:37 | LL | static mut C: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` + | ^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0658]: raw mutable references are not allowed in constant functions --> $DIR/const-address-of-mut.rs:11:13 @@ -27,5 +36,4 @@ LL | let y = &raw mut x; error: aborting due to 4 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-eval/issue-65394.stderr b/src/test/ui/consts/const-eval/issue-65394.stderr index 771d368d78391..ec229d7f53a0f 100644 --- a/src/test/ui/consts/const-eval/issue-65394.stderr +++ b/src/test/ui/consts/const-eval/issue-65394.stderr @@ -1,8 +1,11 @@ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/issue-65394.rs:8:13 | LL | let r = &mut x; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/issue-65394.rs:7:9 @@ -15,5 +18,5 @@ LL | }; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0493, E0764. +Some errors have detailed explanations: E0493, E0658. For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/const-multi-ref.stderr b/src/test/ui/consts/const-multi-ref.stderr index c0a320d46cbf9..dd5cadfe2951e 100644 --- a/src/test/ui/consts/const-multi-ref.stderr +++ b/src/test/ui/consts/const-multi-ref.stderr @@ -1,8 +1,11 @@ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/const-multi-ref.rs:6:13 | LL | let p = &mut a; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability --> $DIR/const-multi-ref.rs:16:13 @@ -15,5 +18,4 @@ LL | let p = &a; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs b/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs index 5819daa817af0..24df647f05b7e 100644 --- a/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs +++ b/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs @@ -1,3 +1,4 @@ +// check-pass #![feature(const_mut_refs)] #![feature(const_fn)] #![feature(raw_ref_op)] @@ -22,9 +23,7 @@ const fn baz(foo: &mut Foo)-> *mut usize { const _: () = { foo().bar(); - //~^ ERROR mutable references are not allowed in constants baz(&mut foo()); - //~^ ERROR mutable references are not allowed in constants }; fn main() {} diff --git a/src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr b/src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr deleted file mode 100644 index 2214ce6ee1c87..0000000000000 --- a/src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_address_of.rs:24:5 - | -LL | foo().bar(); - | ^^^^^ `&mut` is only allowed in `const fn` - -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_address_of.rs:26:9 - | -LL | baz(&mut foo()); - | ^^^^^^^^^^ `&mut` is only allowed in `const fn` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0764`. diff --git a/src/test/ui/consts/const-mut-refs/const_mut_refs.rs b/src/test/ui/consts/const-mut-refs/const_mut_refs.rs index 9099d5a1b8ea6..544458dfcd8bb 100644 --- a/src/test/ui/consts/const-mut-refs/const_mut_refs.rs +++ b/src/test/ui/consts/const-mut-refs/const_mut_refs.rs @@ -1,3 +1,4 @@ +// check-pass #![feature(const_mut_refs)] struct Foo { @@ -29,9 +30,6 @@ const fn bazz(foo: &mut Foo) -> usize { fn main() { let _: [(); foo().bar()] = [(); 1]; - //~^ ERROR mutable references are not allowed in constants let _: [(); baz(&mut foo())] = [(); 2]; - //~^ ERROR mutable references are not allowed in constants let _: [(); bazz(&mut foo())] = [(); 3]; - //~^ ERROR mutable references are not allowed in constants } diff --git a/src/test/ui/consts/const-mut-refs/const_mut_refs.stderr b/src/test/ui/consts/const-mut-refs/const_mut_refs.stderr deleted file mode 100644 index 4ca7b128b7c4b..0000000000000 --- a/src/test/ui/consts/const-mut-refs/const_mut_refs.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_refs.rs:31:17 - | -LL | let _: [(); foo().bar()] = [(); 1]; - | ^^^^^ `&mut` is only allowed in `const fn` - -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_refs.rs:33:21 - | -LL | let _: [(); baz(&mut foo())] = [(); 2]; - | ^^^^^^^^^^ `&mut` is only allowed in `const fn` - -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_refs.rs:35:22 - | -LL | let _: [(); bazz(&mut foo())] = [(); 3]; - | ^^^^^^^^^^ `&mut` is only allowed in `const fn` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0764`. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs new file mode 100644 index 0000000000000..c85acd3b84987 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -0,0 +1,24 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] +const NULL: *mut i32 = std::ptr::null_mut(); +const A: *const i32 = &4; + +// It could be made sound to allow it to compile, +// but we do not want to allow this to compile, +// as that would be an enormous footgun in oli-obk's opinion. +const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed + +// Could be ok, but the same analysis that prevents the mutable one above will also bail out here +// Using a block with some complex content, because just `&45` would get promoted, +// which is not what we want to test here. +const C: *const i32 = &{ + let mut x = 42; + x += 3; + x +}; + +fn main() { + println!("{}", unsafe { *A }); + unsafe { *B = 4 } // Bad news +} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr new file mode 100644 index 0000000000000..6d570052aebb1 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -0,0 +1,9 @@ +error[E0764]: mutable references are not allowed in final value of constants + --> $DIR/mut_ref_in_final.rs:10:21 + | +LL | const B: *mut i32 = &mut 4; + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0764`. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs new file mode 100644 index 0000000000000..3f2995df2d769 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs @@ -0,0 +1,22 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] + +use std::cell::UnsafeCell; +struct NotAMutex(UnsafeCell); + +unsafe impl Sync for NotAMutex {} + +const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +// `BAR` works, because `&42` promotes immediately instead of relying on +// "final value lifetime extension". +const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42)); + +fn main() { + unsafe { + **FOO.0.get() = 99; + assert_eq!(**FOO.0.get(), 99); + } +} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr new file mode 100644 index 0000000000000..8b51e44e16956 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr @@ -0,0 +1,13 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final_ok.rs:10:65 + | +LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/const_let_assign3.stderr b/src/test/ui/consts/const_let_assign3.stderr index dc86e178a42c3..3eac61c0ce670 100644 --- a/src/test/ui/consts/const_let_assign3.stderr +++ b/src/test/ui/consts/const_let_assign3.stderr @@ -7,19 +7,24 @@ LL | const fn foo(&mut self, x: u32) { = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/const_let_assign3.rs:16:5 | LL | s.foo(3); - | ^ `&mut` is only allowed in `const fn` + | ^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/const_let_assign3.rs:22:13 | LL | let y = &mut x; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error: aborting due to 3 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/issue-17718-const-bad-values.rs b/src/test/ui/consts/issue-17718-const-bad-values.rs index 49023f18ddbfb..62bbb3b569c37 100644 --- a/src/test/ui/consts/issue-17718-const-bad-values.rs +++ b/src/test/ui/consts/issue-17718-const-bad-values.rs @@ -1,10 +1,9 @@ const C1: &'static mut [usize] = &mut []; -//~^ ERROR: mutable references are not allowed in constants +//~^ ERROR: mutable references are not allowed static mut S: usize = 3; const C2: &'static mut usize = unsafe { &mut S }; //~^ ERROR: constants cannot refer to statics //~| ERROR: constants cannot refer to statics -//~| ERROR: mutable references are not allowed in constants fn main() {} diff --git a/src/test/ui/consts/issue-17718-const-bad-values.stderr b/src/test/ui/consts/issue-17718-const-bad-values.stderr index 7c50978d4ebb8..7e02fa4686f2f 100644 --- a/src/test/ui/consts/issue-17718-const-bad-values.stderr +++ b/src/test/ui/consts/issue-17718-const-bad-values.stderr @@ -1,8 +1,8 @@ -error[E0764]: mutable references are not allowed in constants +error[E0764]: mutable references are not allowed in final value of constants --> $DIR/issue-17718-const-bad-values.rs:1:34 | LL | const C1: &'static mut [usize] = &mut []; - | ^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^ error[E0013]: constants cannot refer to statics --> $DIR/issue-17718-const-bad-values.rs:5:46 @@ -20,13 +20,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S }; | = help: consider extracting the value of the `static` to a `const`, and referring to that -error[E0764]: mutable references are not allowed in constants - --> $DIR/issue-17718-const-bad-values.rs:5:41 - | -LL | const C2: &'static mut usize = unsafe { &mut S }; - | ^^^^^^ `&mut` is only allowed in `const fn` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0013, E0764. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/projection_qualif.mut_refs.stderr b/src/test/ui/consts/projection_qualif.mut_refs.stderr index fad8f011f75f5..0945a23f3b123 100644 --- a/src/test/ui/consts/projection_qualif.mut_refs.stderr +++ b/src/test/ui/consts/projection_qualif.mut_refs.stderr @@ -1,9 +1,3 @@ -error[E0764]: mutable references are not allowed in constants - --> $DIR/projection_qualif.rs:10:27 - | -LL | let b: *mut u32 = &mut a; - | ^^^^^^ `&mut` is only allowed in `const fn` - error[E0658]: dereferencing raw pointers in constants is unstable --> $DIR/projection_qualif.rs:11:18 | @@ -13,7 +7,6 @@ LL | unsafe { *b = 5; } = note: see issue #51911 for more information = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs index 5e2584a6e951a..d35df330bb8c3 100644 --- a/src/test/ui/consts/projection_qualif.rs +++ b/src/test/ui/consts/projection_qualif.rs @@ -7,7 +7,7 @@ use std::cell::Cell; const FOO: &u32 = { let mut a = 42; { - let b: *mut u32 = &mut a; //~ ERROR mutable references are not allowed in constants + let b: *mut u32 = &mut a; //[stock]~ ERROR mutable references are not allowed in constants unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants } &{a} diff --git a/src/test/ui/consts/projection_qualif.stock.stderr b/src/test/ui/consts/projection_qualif.stock.stderr index fad8f011f75f5..e451898caba43 100644 --- a/src/test/ui/consts/projection_qualif.stock.stderr +++ b/src/test/ui/consts/projection_qualif.stock.stderr @@ -1,8 +1,11 @@ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/projection_qualif.rs:10:27 | LL | let b: *mut u32 = &mut a; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0658]: dereferencing raw pointers in constants is unstable --> $DIR/projection_qualif.rs:11:18 @@ -15,5 +18,4 @@ LL | unsafe { *b = 5; } error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/read_from_static_mut_ref.rs b/src/test/ui/consts/read_from_static_mut_ref.rs index 5faa983ab09f7..665c305e9617f 100644 --- a/src/test/ui/consts/read_from_static_mut_ref.rs +++ b/src/test/ui/consts/read_from_static_mut_ref.rs @@ -1,9 +1,8 @@ -// We are keeping this test in case we decide to allow mutable references in statics again #![feature(const_mut_refs)] #![allow(const_err)] -static OH_NO: &mut i32 = &mut 42; -//~^ ERROR mutable references are not allowed in statics +static OH_NO: &mut i32 = &mut 42; //~ ERROR mutable references are not allowed fn main() { assert_eq!(*OH_NO, 42); + *OH_NO = 43; //~ ERROR cannot assign to `*OH_NO`, as `OH_NO` is an immutable static } diff --git a/src/test/ui/consts/read_from_static_mut_ref.stderr b/src/test/ui/consts/read_from_static_mut_ref.stderr index c936ac0b7d585..373220878ec2a 100644 --- a/src/test/ui/consts/read_from_static_mut_ref.stderr +++ b/src/test/ui/consts/read_from_static_mut_ref.stderr @@ -1,9 +1,16 @@ -error[E0764]: mutable references are not allowed in statics - --> $DIR/read_from_static_mut_ref.rs:5:26 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/read_from_static_mut_ref.rs:4:26 | LL | static OH_NO: &mut i32 = &mut 42; - | ^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^ -error: aborting due to previous error +error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item + --> $DIR/read_from_static_mut_ref.rs:7:5 + | +LL | *OH_NO = 43; + | ^^^^^^^^^^^ cannot assign + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0764`. +Some errors have detailed explanations: E0594, E0764. +For more information about an error, try `rustc --explain E0594`. diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr index 36c280ca5c607..8db75dd63cf2a 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr @@ -1,9 +1,9 @@ -error[E0764]: mutable references are not allowed in statics - --> $DIR/static_mut_containing_mut_ref2.rs:7:46 +error[E0080]: could not evaluate static initializer + --> $DIR/static_mut_containing_mut_ref2.rs:7:45 | LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer error: aborting due to previous error -For more information about this error, try `rustc --explain E0764`. +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.rs b/src/test/ui/consts/static_mut_containing_mut_ref2.rs index 2821d1a015435..61368546083db 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.rs @@ -5,6 +5,7 @@ static mut STDERR_BUFFER_SPACE: u8 = 0; pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; -//~^ ERROR mutable references are not allowed in statics +//[mut_refs]~^ ERROR could not evaluate static initializer +//[stock]~^^ ERROR mutable references are not allowed in statics fn main() {} diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr index 36c280ca5c607..5cdcea2323109 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr @@ -1,9 +1,12 @@ -error[E0764]: mutable references are not allowed in statics +error[E0658]: mutable references are not allowed in statics --> $DIR/static_mut_containing_mut_ref2.rs:7:46 | LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0764`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs index 262f7bc72c739..c211ad1a2f8f6 100644 --- a/src/test/ui/error-codes/E0017.rs +++ b/src/test/ui/error-codes/E0017.rs @@ -2,12 +2,13 @@ static X: i32 = 1; const C: i32 = 2; static mut M: i32 = 3; -const CR: &'static mut i32 = &mut C; //~ ERROR E0764 +const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| WARN taking a mutable -static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0764 +static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658 //~| ERROR cannot borrow + //~| ERROR mutable references are not allowed -static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764 +static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| WARN taking a mutable -static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR E0764 +static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR mutable references are not fn main() {} diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index ea591587e6daa..9b094b1975730 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -13,17 +13,26 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in constants +error[E0764]: mutable references are not allowed in final value of constants --> $DIR/E0017.rs:5:30 | LL | const CR: &'static mut i32 = &mut C; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error[E0764]: mutable references are not allowed in statics +error[E0658]: mutation through a reference is not allowed in statics --> $DIR/E0017.rs:7:39 | LL | static STATIC_REF: &'static mut i32 = &mut X; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0017.rs:7:39 + | +LL | static STATIC_REF: &'static mut i32 = &mut X; + | ^^^^^^ error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0017.rs:7:39 @@ -32,7 +41,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; | ^^^^^^ cannot borrow as mutable warning: taking a mutable reference to a `const` item - --> $DIR/E0017.rs:10:38 + --> $DIR/E0017.rs:11:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ @@ -45,19 +54,19 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0017.rs:10:38 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0017.rs:11:38 | LL | static CONST_REF: &'static mut i32 = &mut C; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0017.rs:12:52 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0017.rs:13:52 | LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error: aborting due to 5 previous errors; 2 warnings emitted +error: aborting due to 6 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0596, E0764. +Some errors have detailed explanations: E0596, E0658, E0764. For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/error-codes/E0388.rs b/src/test/ui/error-codes/E0388.rs index bb0c4979b9ac9..6049d95f0d277 100644 --- a/src/test/ui/error-codes/E0388.rs +++ b/src/test/ui/error-codes/E0388.rs @@ -1,12 +1,13 @@ static X: i32 = 1; const C: i32 = 2; -const CR: &'static mut i32 = &mut C; //~ ERROR E0764 +const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| WARN taking a mutable static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow - //~| ERROR E0764 + //~| ERROR E0658 + //~| ERROR mutable references are not allowed -static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764 +static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| WARN taking a mutable fn main() {} diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 73e0b139cd056..74d6a92e170d4 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -13,17 +13,26 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in constants +error[E0764]: mutable references are not allowed in final value of constants --> $DIR/E0388.rs:4:30 | LL | const CR: &'static mut i32 = &mut C; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error[E0764]: mutable references are not allowed in statics +error[E0658]: mutation through a reference is not allowed in statics --> $DIR/E0388.rs:6:39 | LL | static STATIC_REF: &'static mut i32 = &mut X; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0388.rs:6:39 + | +LL | static STATIC_REF: &'static mut i32 = &mut X; + | ^^^^^^ error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0388.rs:6:39 @@ -32,7 +41,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; | ^^^^^^ cannot borrow as mutable warning: taking a mutable reference to a `const` item - --> $DIR/E0388.rs:9:38 + --> $DIR/E0388.rs:10:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ @@ -45,13 +54,13 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0388.rs:9:38 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0388.rs:10:38 | LL | static CONST_REF: &'static mut i32 = &mut C; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error: aborting due to 4 previous errors; 2 warnings emitted +error: aborting due to 5 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0596, E0764. +Some errors have detailed explanations: E0596, E0658, E0764. For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/issues/issue-46604.rs b/src/test/ui/issues/issue-46604.rs index 273187a5a13be..6ec6e7bdcb81e 100644 --- a/src/test/ui/issues/issue-46604.rs +++ b/src/test/ui/issues/issue-46604.rs @@ -1,4 +1,4 @@ -static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //~ ERROR E0764 +static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //~ ERROR mutable references are not allowed fn write>(buffer: T) { } fn main() { diff --git a/src/test/ui/issues/issue-46604.stderr b/src/test/ui/issues/issue-46604.stderr index 5421721dec2e3..488be0e7731e6 100644 --- a/src/test/ui/issues/issue-46604.stderr +++ b/src/test/ui/issues/issue-46604.stderr @@ -1,8 +1,8 @@ -error[E0764]: mutable references are not allowed in statics +error[E0764]: mutable references are not allowed in final value of statics --> $DIR/issue-46604.rs:1:25 | LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; - | ^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^^^^^^^^^^^^^^ error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item --> $DIR/issue-46604.rs:6:5 diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr index 051896cb89c8f..1683841e9d781 100644 --- a/src/test/ui/never_type/issue-52443.stderr +++ b/src/test/ui/never_type/issue-52443.stderr @@ -39,11 +39,14 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct LL | [(); { for _ in 0usize.. {}; 0}]; | ^^^^^^^^ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/issue-52443.rs:9:21 | LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants --> $DIR/issue-52443.rs:9:21 @@ -53,5 +56,5 @@ LL | [(); { for _ in 0usize.. {}; 0}]; error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0015, E0308, E0744, E0764. +Some errors have detailed explanations: E0015, E0308, E0658, E0744. For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/unsafe/ranged_ints2_const.rs b/src/test/ui/unsafe/ranged_ints2_const.rs index 65e0d79308ca3..b7178c2b52bfb 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.rs +++ b/src/test/ui/unsafe/ranged_ints2_const.rs @@ -18,3 +18,9 @@ const fn bar() -> NonZero { let y = unsafe { &mut x.0 }; //~ ERROR mutable references unsafe { NonZero(1) } } + +const fn boo() -> NonZero { + let mut x = unsafe { NonZero(1) }; + unsafe { let y = &mut x.0; } //~ ERROR mutable references + unsafe { NonZero(1) } +} diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr index 5ce4296458e6d..a0dc950e76dd1 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.stderr +++ b/src/test/ui/unsafe/ranged_ints2_const.stderr @@ -16,6 +16,15 @@ LL | let y = unsafe { &mut x.0 }; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:24:22 + | +LL | unsafe { let y = &mut x.0; } + | ^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block --> $DIR/ranged_ints2_const.rs:11:13 | @@ -24,7 +33,7 @@ LL | let y = &mut x.0; | = note: mutating layout constrained fields cannot statically be checked for valid values -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0133, E0658. For more information about an error, try `rustc --explain E0133`. From b217fab9608f97fc99c77f4cac5909df0e59db0c Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 16 Jan 2021 17:27:59 +0000 Subject: [PATCH 19/32] Rename tests to what their code actually does --- .../ui/consts/{projection_qualif.rs => write_to_mut_ref_dest.rs} | 0 ...read_from_static_mut_ref.rs => write_to_static_via_mut_ref.rs} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/consts/{projection_qualif.rs => write_to_mut_ref_dest.rs} (100%) rename src/test/ui/consts/{read_from_static_mut_ref.rs => write_to_static_via_mut_ref.rs} (100%) diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/write_to_mut_ref_dest.rs similarity index 100% rename from src/test/ui/consts/projection_qualif.rs rename to src/test/ui/consts/write_to_mut_ref_dest.rs diff --git a/src/test/ui/consts/read_from_static_mut_ref.rs b/src/test/ui/consts/write_to_static_via_mut_ref.rs similarity index 100% rename from src/test/ui/consts/read_from_static_mut_ref.rs rename to src/test/ui/consts/write_to_static_via_mut_ref.rs From 3cd0b46baca1848b577f2172935a139663697643 Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 16 Jan 2021 17:31:22 +0000 Subject: [PATCH 20/32] Fix a comment that only made sense in the context of a dataflow based mutability check --- src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs index c85acd3b84987..98960ec6c6e8a 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -9,9 +9,8 @@ const A: *const i32 = &4; // as that would be an enormous footgun in oli-obk's opinion. const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed -// Could be ok, but the same analysis that prevents the mutable one above will also bail out here -// Using a block with some complex content, because just `&45` would get promoted, -// which is not what we want to test here. +// Ok, because no references to mutable data exist here, since the `{}` moves +// its value and then takes a reference to that. const C: *const i32 = &{ let mut x = 42; x += 3; From 00e62fabf101571c337fdce24544e94b0e0fda9c Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 16 Jan 2021 18:05:51 +0000 Subject: [PATCH 21/32] Adjust wording of a diagnostic --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 2 +- src/test/ui/check-static-immutable-mut-slices.stderr | 2 +- src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr | 2 +- src/test/ui/consts/issue-17718-const-bad-values.stderr | 2 +- ..._refs.stderr => write_to_mut_ref_dest.mut_refs.stderr} | 2 +- ...if.stock.stderr => write_to_mut_ref_dest.stock.stderr} | 4 ++-- ..._mut_ref.stderr => write_to_static_via_mut_ref.stderr} | 6 +++--- src/test/ui/error-codes/E0017.stderr | 8 ++++---- src/test/ui/error-codes/E0388.stderr | 6 +++--- src/test/ui/issues/issue-46604.stderr | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) rename src/test/ui/consts/{projection_qualif.mut_refs.stderr => write_to_mut_ref_dest.mut_refs.stderr} (91%) rename src/test/ui/consts/{projection_qualif.stock.stderr => write_to_mut_ref_dest.stock.stderr} (90%) rename src/test/ui/consts/{read_from_static_mut_ref.stderr => write_to_static_via_mut_ref.stderr} (69%) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 23abd522cf0f3..6e7262151777f 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -298,7 +298,7 @@ impl NonConstOp for MutBorrow { ccx.tcx.sess, span, E0764, - "{}mutable references are not allowed in final value of {}s", + "{}mutable references are not allowed in the final value of {}s", raw, ccx.const_kind(), ); diff --git a/src/test/ui/check-static-immutable-mut-slices.stderr b/src/test/ui/check-static-immutable-mut-slices.stderr index fcc18cc584c54..a32a94c1315ab 100644 --- a/src/test/ui/check-static-immutable-mut-slices.stderr +++ b/src/test/ui/check-static-immutable-mut-slices.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/check-static-immutable-mut-slices.rs:3:37 | LL | static TEST: &'static mut [isize] = &mut []; diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 6d570052aebb1..57bf5f7395de4 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/mut_ref_in_final.rs:10:21 | LL | const B: *mut i32 = &mut 4; diff --git a/src/test/ui/consts/issue-17718-const-bad-values.stderr b/src/test/ui/consts/issue-17718-const-bad-values.stderr index 7e02fa4686f2f..ce60aaa0797f8 100644 --- a/src/test/ui/consts/issue-17718-const-bad-values.stderr +++ b/src/test/ui/consts/issue-17718-const-bad-values.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/issue-17718-const-bad-values.rs:1:34 | LL | const C1: &'static mut [usize] = &mut []; diff --git a/src/test/ui/consts/projection_qualif.mut_refs.stderr b/src/test/ui/consts/write_to_mut_ref_dest.mut_refs.stderr similarity index 91% rename from src/test/ui/consts/projection_qualif.mut_refs.stderr rename to src/test/ui/consts/write_to_mut_ref_dest.mut_refs.stderr index 0945a23f3b123..3ee50907461ca 100644 --- a/src/test/ui/consts/projection_qualif.mut_refs.stderr +++ b/src/test/ui/consts/write_to_mut_ref_dest.mut_refs.stderr @@ -1,5 +1,5 @@ error[E0658]: dereferencing raw pointers in constants is unstable - --> $DIR/projection_qualif.rs:11:18 + --> $DIR/write_to_mut_ref_dest.rs:11:18 | LL | unsafe { *b = 5; } | ^^^^^^ diff --git a/src/test/ui/consts/projection_qualif.stock.stderr b/src/test/ui/consts/write_to_mut_ref_dest.stock.stderr similarity index 90% rename from src/test/ui/consts/projection_qualif.stock.stderr rename to src/test/ui/consts/write_to_mut_ref_dest.stock.stderr index e451898caba43..2b6d1d3267b61 100644 --- a/src/test/ui/consts/projection_qualif.stock.stderr +++ b/src/test/ui/consts/write_to_mut_ref_dest.stock.stderr @@ -1,5 +1,5 @@ error[E0658]: mutable references are not allowed in constants - --> $DIR/projection_qualif.rs:10:27 + --> $DIR/write_to_mut_ref_dest.rs:10:27 | LL | let b: *mut u32 = &mut a; | ^^^^^^ @@ -8,7 +8,7 @@ LL | let b: *mut u32 = &mut a; = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0658]: dereferencing raw pointers in constants is unstable - --> $DIR/projection_qualif.rs:11:18 + --> $DIR/write_to_mut_ref_dest.rs:11:18 | LL | unsafe { *b = 5; } | ^^^^^^ diff --git a/src/test/ui/consts/read_from_static_mut_ref.stderr b/src/test/ui/consts/write_to_static_via_mut_ref.stderr similarity index 69% rename from src/test/ui/consts/read_from_static_mut_ref.stderr rename to src/test/ui/consts/write_to_static_via_mut_ref.stderr index 373220878ec2a..d19e998d61736 100644 --- a/src/test/ui/consts/read_from_static_mut_ref.stderr +++ b/src/test/ui/consts/write_to_static_via_mut_ref.stderr @@ -1,11 +1,11 @@ -error[E0764]: mutable references are not allowed in final value of statics - --> $DIR/read_from_static_mut_ref.rs:4:26 +error[E0764]: mutable references are not allowed in the final value of statics + --> $DIR/write_to_static_via_mut_ref.rs:4:26 | LL | static OH_NO: &mut i32 = &mut 42; | ^^^^^^^ error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item - --> $DIR/read_from_static_mut_ref.rs:7:5 + --> $DIR/write_to_static_via_mut_ref.rs:7:5 | LL | *OH_NO = 43; | ^^^^^^^^^^^ cannot assign diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index 9b094b1975730..7d959b6d148ed 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -13,7 +13,7 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/E0017.rs:5:30 | LL | const CR: &'static mut i32 = &mut C; @@ -28,7 +28,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0017.rs:7:39 | LL | static STATIC_REF: &'static mut i32 = &mut X; @@ -54,13 +54,13 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0017.rs:11:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0017.rs:13:52 | LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 74d6a92e170d4..4886a156d2ea5 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -13,7 +13,7 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/E0388.rs:4:30 | LL | const CR: &'static mut i32 = &mut C; @@ -28,7 +28,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0388.rs:6:39 | LL | static STATIC_REF: &'static mut i32 = &mut X; @@ -54,7 +54,7 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0388.rs:10:38 | LL | static CONST_REF: &'static mut i32 = &mut C; diff --git a/src/test/ui/issues/issue-46604.stderr b/src/test/ui/issues/issue-46604.stderr index 488be0e7731e6..7faa2d79ba483 100644 --- a/src/test/ui/issues/issue-46604.stderr +++ b/src/test/ui/issues/issue-46604.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/issue-46604.rs:1:25 | LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; From 14f39aa81a8e0861c5cc8227c08b60f037a87947 Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 16 Jan 2021 18:06:12 +0000 Subject: [PATCH 22/32] Do not allow arbitrary mutable references in `static mut`, just keep with the existing exceptions --- compiler/rustc_mir/src/transform/check_consts/ops.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 6e7262151777f..6f98760a7b0ad 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -274,12 +274,8 @@ impl NonConstOp for CellBorrow { pub struct MutBorrow(pub hir::BorrowKind); impl NonConstOp for MutBorrow { - fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { - match ccx.const_kind() { - // Mutable statics can handle mutable references in their final value - hir::ConstContext::Static(hir::Mutability::Mut) => Status::Allowed, - _ => Status::Forbidden, - } + fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status { + Status::Forbidden } fn importance(&self) -> DiagnosticImportance { From cd0987115765efdf4f834f0f0bf24c4cef063b1a Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 23 Jan 2021 11:58:58 +0000 Subject: [PATCH 23/32] Cover more cases in the test suite --- .../consts/const-mut-refs/mut_ref_in_final.rs | 45 +++++++++++++++ .../const-mut-refs/mut_ref_in_final.stderr | 57 ++++++++++++++++++- .../const-mut-refs/mut_ref_in_final_ok.rs | 22 ------- .../const-mut-refs/mut_ref_in_final_ok.stderr | 13 ----- 4 files changed, 99 insertions(+), 38 deletions(-) delete mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs delete mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs index 98960ec6c6e8a..b2230697037f3 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,9 @@ #![feature(const_mut_refs)] #![feature(const_fn)] +#![feature(const_transmute)] #![feature(raw_ref_op)] +#![feature(const_raw_ptr_deref)] + const NULL: *mut i32 = std::ptr::null_mut(); const A: *const i32 = &4; @@ -9,6 +12,25 @@ const A: *const i32 = &4; // as that would be an enormous footgun in oli-obk's opinion. const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed +// Ok, no actual mutable allocation exists +const B2: Option<&mut i32> = None; + +// Not ok, can't prove that no mutable allocation ends up in final value +const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR temporary value dropped while borrowed + +const fn helper() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour, who doesn't love tests like this. + // This code never gets executed, because the static checks fail before that. + Some(&mut *(42 as *mut i32)) +} } +// Check that we do not look into function bodies. +// We treat all functions as not returning a mutable reference, because there is no way to +// do that without causing the borrow checker to complain (see the B5/helper2 test below). +const B4: Option<&mut i32> = helper(); + +const fn helper2(x: &mut i32) -> Option<&mut i32> { Some(x) } +const B5: Option<&mut i32> = helper2(&mut 42); //~ ERROR temporary value dropped while borrowed + // Ok, because no references to mutable data exist here, since the `{}` moves // its value and then takes a reference to that. const C: *const i32 = &{ @@ -17,7 +39,30 @@ const C: *const i32 = &{ x }; +use std::cell::UnsafeCell; +struct NotAMutex(UnsafeCell); + +unsafe impl Sync for NotAMutex {} + +const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +// `BAR` works, because `&42` promotes immediately instead of relying on +// the enclosing scope rule. +const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42)); + fn main() { println!("{}", unsafe { *A }); unsafe { *B = 4 } // Bad news + + unsafe { + **FOO.0.get() = 99; + assert_eq!(**FOO.0.get(), 99); + } } diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 57bf5f7395de4..389b88955cec4 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,9 +1,60 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:10:21 + --> $DIR/mut_ref_in_final.rs:13:21 | LL | const B: *mut i32 = &mut 4; | ^^^^^^ -error: aborting due to previous error +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:19:40 + | +LL | const B3: Option<&mut i32> = Some(&mut 42); + | ----------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:32:43 + | +LL | const B5: Option<&mut i32> = helper2(&mut 42); + | -------------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:47:65 + | +LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:50:67 + | +LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a static requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:53:71 + | +LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a static requires that borrow lasts for `'static` + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0764`. +Some errors have detailed explanations: E0716, E0764. +For more information about an error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs deleted file mode 100644 index 3f2995df2d769..0000000000000 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![feature(const_mut_refs)] -#![feature(const_fn)] -#![feature(raw_ref_op)] - -use std::cell::UnsafeCell; -struct NotAMutex(UnsafeCell); - -unsafe impl Sync for NotAMutex {} - -const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); -//~^ ERROR temporary value dropped while borrowed - -// `BAR` works, because `&42` promotes immediately instead of relying on -// "final value lifetime extension". -const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42)); - -fn main() { - unsafe { - **FOO.0.get() = 99; - assert_eq!(**FOO.0.get(), 99); - } -} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr deleted file mode 100644 index 8b51e44e16956..0000000000000 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final_ok.rs:10:65 - | -LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); - | -------------------------------^^-- - | | | | - | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use - | using this value as a constant requires that borrow lasts for `'static` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0716`. From 819b008d8be8d154d9561bed1e4b770c741f23a2 Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 23 Jan 2021 12:35:45 +0000 Subject: [PATCH 24/32] Put dynamic check tests into their own file --- .../consts/const-mut-refs/mut_ref_in_final.rs | 15 ++-------- .../const-mut-refs/mut_ref_in_final.stderr | 22 +++++++-------- .../mut_ref_in_final_dynamic_check.rs | 28 +++++++++++++++++++ .../mut_ref_in_final_dynamic_check.stderr | 23 +++++++++++++++ 4 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs index b2230697037f3..166ba20f124e6 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,5 @@ #![feature(const_mut_refs)] #![feature(const_fn)] -#![feature(const_transmute)] #![feature(raw_ref_op)] #![feature(const_raw_ptr_deref)] @@ -18,18 +17,8 @@ const B2: Option<&mut i32> = None; // Not ok, can't prove that no mutable allocation ends up in final value const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR temporary value dropped while borrowed -const fn helper() -> Option<&'static mut i32> { unsafe { - // Undefined behaviour, who doesn't love tests like this. - // This code never gets executed, because the static checks fail before that. - Some(&mut *(42 as *mut i32)) -} } -// Check that we do not look into function bodies. -// We treat all functions as not returning a mutable reference, because there is no way to -// do that without causing the borrow checker to complain (see the B5/helper2 test below). -const B4: Option<&mut i32> = helper(); - -const fn helper2(x: &mut i32) -> Option<&mut i32> { Some(x) } -const B5: Option<&mut i32> = helper2(&mut 42); //~ ERROR temporary value dropped while borrowed +const fn helper(x: &mut i32) -> Option<&mut i32> { Some(x) } +const B4: Option<&mut i32> = helper(&mut 42); //~ ERROR temporary value dropped while borrowed // Ok, because no references to mutable data exist here, since the `{}` moves // its value and then takes a reference to that. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 389b88955cec4..cbae74cce6f6b 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,11 +1,11 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:13:21 + --> $DIR/mut_ref_in_final.rs:12:21 | LL | const B: *mut i32 = &mut 4; | ^^^^^^ error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:19:40 + --> $DIR/mut_ref_in_final.rs:18:40 | LL | const B3: Option<&mut i32> = Some(&mut 42); | ----------^^- @@ -15,17 +15,17 @@ LL | const B3: Option<&mut i32> = Some(&mut 42); | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:32:43 + --> $DIR/mut_ref_in_final.rs:21:42 | -LL | const B5: Option<&mut i32> = helper2(&mut 42); - | -------------^^- - | | | | - | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use +LL | const B4: Option<&mut i32> = helper(&mut 42); + | ------------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:47:65 + --> $DIR/mut_ref_in_final.rs:36:65 | LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -35,7 +35,7 @@ LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:50:67 + --> $DIR/mut_ref_in_final.rs:39:67 | LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -45,7 +45,7 @@ LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | using this value as a static requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:53:71 + --> $DIR/mut_ref_in_final.rs:42:71 | LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs new file mode 100644 index 0000000000000..1e856ec0a0acc --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -0,0 +1,28 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] +#![feature(const_raw_ptr_deref)] + +// This file checks that our dynamic checks catch things that the static checks miss. +// We do not have static checks for these, because we do not look into function bodies. +// We treat all functions as not returning a mutable reference, because there is no way to +// do that without causing the borrow checker to complain (see the B4/helper test in +// mut_ref_in_final.rs). + +const fn helper() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour (integer as pointer), who doesn't love tests like this. + // This code never gets executed, because the static checks fail before that. + Some(&mut *(42 as *mut i32)) //~ ERROR any use of this value will cause an error +} } +// The error is an evaluation error and not a validation error, so the error is reported +// directly at the site where it occurs. +const A: Option<&mut i32> = helper(); + +const fn helper2() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour (dangling pointer), who doesn't love tests like this. + // This code never gets executed, because the static checks fail before that. + Some(&mut *(&mut 42 as *mut i32)) +} } +const B: Option<&mut i32> = helper2(); //~ ERROR encountered dangling pointer in final constant + +fn main() {} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr new file mode 100644 index 0000000000000..0bbf84b71bb68 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -0,0 +1,23 @@ +error: any use of this value will cause an error + --> $DIR/mut_ref_in_final_dynamic_check.rs:15:10 + | +LL | Some(&mut *(42 as *mut i32)) + | ^^^^^^^^^^^^^^^^^^^^^^ + | | + | unable to turn bytes into a pointer + | inside `helper` at $DIR/mut_ref_in_final_dynamic_check.rs:15:10 + | inside `A` at $DIR/mut_ref_in_final_dynamic_check.rs:19:29 +... +LL | const A: Option<&mut i32> = helper(); + | ------------------------------------- + | + = note: `#[deny(const_err)]` on by default + +error: encountered dangling pointer in final constant + --> $DIR/mut_ref_in_final_dynamic_check.rs:26:1 + | +LL | const B: Option<&mut i32> = helper2(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 1129e8678038cfc938559b90b4155dde8b84edf3 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 23 Jan 2021 18:05:59 +0100 Subject: [PATCH 25/32] Cleanup `render_stability_since_raw` to remove code duplication --- src/librustdoc/html/render/mod.rs | 43 ++++++++++++------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 26afd705740b2..f15d43b7b1600 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2934,34 +2934,25 @@ fn render_stability_since_raw( containing_ver: Option<&str>, containing_const_ver: Option<&str>, ) { - let ver = ver.and_then(|inner| if !inner.is_empty() { Some(inner) } else { None }); + let ver = ver.filter(|inner| !inner.is_empty()); + let const_ver = const_ver.filter(|inner| !inner.is_empty()); - let const_ver = const_ver.and_then(|inner| if !inner.is_empty() { Some(inner) } else { None }); - - if let Some(v) = ver { - if let Some(cv) = const_ver { - if const_ver != containing_const_ver { - write!( - w, - "{0} (const: {1})", - v, cv - ); - } else if ver != containing_ver { - write!( - w, - "{0}", - v - ); - } - } else { - if ver != containing_ver { - write!( - w, - "{0}", - v - ); - } + match (ver, const_ver) { + (Some(v), Some(cv)) if const_ver != containing_const_ver => { + write!( + w, + "{0} (const: {1})", + v, cv + ); + } + (Some(v), _) if ver != containing_ver => { + write!( + w, + "{0}", + v + ); } + _ => {} } } From 9b1d27d440d58edcb4c673798c60181c03c084c1 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Fri, 22 Jan 2021 10:54:53 +0100 Subject: [PATCH 26/32] Add option to control doctest run directory This option will allow splitting the compile-time from the run-time directory of doctest invocations and is one step to solve https://github.com/rust-lang/cargo/issues/8993#issuecomment-760088944 --- src/librustdoc/config.rs | 5 ++++ src/librustdoc/doctest.rs | 3 +++ src/librustdoc/lib.rs | 8 +++++++ .../rustdoc-ui/run-directory.correct.stdout | 6 +++++ .../rustdoc-ui/run-directory.incorrect.stdout | 6 +++++ src/test/rustdoc-ui/run-directory.rs | 23 +++++++++++++++++++ 6 files changed, 51 insertions(+) create mode 100644 src/test/rustdoc-ui/run-directory.correct.stdout create mode 100644 src/test/rustdoc-ui/run-directory.incorrect.stdout create mode 100644 src/test/rustdoc-ui/run-directory.rs diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e43ea965c0423..508bed072e61d 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -103,6 +103,8 @@ crate struct Options { crate should_test: bool, /// List of arguments to pass to the test harness, if running tests. crate test_args: Vec, + /// The working directory in which to run tests. + crate test_run_directory: Option, /// Optional path to persist the doctest executables to, defaults to a /// temporary directory if not set. crate persist_doctests: Option, @@ -175,6 +177,7 @@ impl fmt::Debug for Options { .field("lint_cap", &self.lint_cap) .field("should_test", &self.should_test) .field("test_args", &self.test_args) + .field("test_run_directory", &self.test_run_directory) .field("persist_doctests", &self.persist_doctests) .field("default_passes", &self.default_passes) .field("manual_passes", &self.manual_passes) @@ -572,6 +575,7 @@ impl Options { let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some(); let static_root_path = matches.opt_str("static-root-path"); let generate_search_filter = !matches.opt_present("disable-per-crate-search"); + let test_run_directory = matches.opt_str("test-run-directory").map(PathBuf::from); let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from); let test_builder = matches.opt_str("test-builder").map(PathBuf::from); let codegen_options_strs = matches.opt_strs("C"); @@ -613,6 +617,7 @@ impl Options { display_warnings, show_coverage, crate_version, + test_run_directory, persist_doctests, runtool, runtool_args, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c87ab833f7a5e..09cbd94e4ac3f 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -365,6 +365,9 @@ fn run_test( } else { cmd = Command::new(output_file); } + if let Some(run_directory) = options.test_run_directory { + cmd.current_dir(run_directory); + } match cmd.output() { Err(e) => return Err(TestFailure::ExecutionError(e)), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 719aca612f50d..d823f789013ff 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -167,6 +167,14 @@ fn opts() -> Vec { stable("test-args", |o| { o.optmulti("", "test-args", "arguments to pass to the test runner", "ARGS") }), + unstable("test-run-directory", |o| { + o.optopt( + "", + "test-run-directory", + "The working directory in which to run tests", + "PATH", + ) + }), stable("target", |o| o.optopt("", "target", "target triple to document", "TRIPLE")), stable("markdown-css", |o| { o.optmulti( diff --git a/src/test/rustdoc-ui/run-directory.correct.stdout b/src/test/rustdoc-ui/run-directory.correct.stdout new file mode 100644 index 0000000000000..e9b2754794a78 --- /dev/null +++ b/src/test/rustdoc-ui/run-directory.correct.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/run-directory.rs - foo (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/run-directory.incorrect.stdout b/src/test/rustdoc-ui/run-directory.incorrect.stdout new file mode 100644 index 0000000000000..97a5dbc5c0cd1 --- /dev/null +++ b/src/test/rustdoc-ui/run-directory.incorrect.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/run-directory.rs - foo (line 19) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/run-directory.rs b/src/test/rustdoc-ui/run-directory.rs new file mode 100644 index 0000000000000..78431c0e80b59 --- /dev/null +++ b/src/test/rustdoc-ui/run-directory.rs @@ -0,0 +1,23 @@ +// this test asserts that the cwd of doctest invocations is set correctly. + +// revisions: correct incorrect +// check-pass +// [correct]compile-flags:--test --test-run-directory={{src-base}} +// [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// assert_eq!( +/// std::fs::read_to_string("run-directory.rs").unwrap(), +/// include_str!("run-directory.rs"), +/// ); +/// ``` +#[cfg(correct)] +pub fn foo() {} + +/// ``` +/// assert!(std::fs::read_to_string("run-directory.rs").is_err()); +/// ``` +#[cfg(incorrect)] +pub fn foo() {} From 20a460e1cf23262b46a7e9672a02c5f07b91eff5 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 23 Jan 2021 18:41:04 +0100 Subject: [PATCH 27/32] Fix rendering of stabilization version for trait implementors --- src/librustdoc/html/render/mod.rs | 8 ++++---- .../rustdoc/implementor-stable-version.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/test/rustdoc/implementor-stable-version.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f15d43b7b1600..bfaadc38763c3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2471,7 +2471,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: fn render_implementor( cx: &Context<'_>, implementor: &Impl, - parent: &clean::Item, + trait_: &clean::Item, w: &mut Buffer, implementor_dups: &FxHashMap, aliases: &[String], @@ -2491,11 +2491,11 @@ fn render_implementor( w, cx, implementor, - parent, + trait_, AssocItemLink::Anchor(None), RenderMode::Normal, - implementor.impl_item.stable_since(cx.tcx()).as_deref(), - implementor.impl_item.const_stable_since(cx.tcx()).as_deref(), + trait_.stable_since(cx.tcx()).as_deref(), + trait_.const_stable_since(cx.tcx()).as_deref(), false, Some(use_absolute), false, diff --git a/src/test/rustdoc/implementor-stable-version.rs b/src/test/rustdoc/implementor-stable-version.rs new file mode 100644 index 0000000000000..0a065d8095bf2 --- /dev/null +++ b/src/test/rustdoc/implementor-stable-version.rs @@ -0,0 +1,19 @@ +#![crate_name = "foo"] + +#![feature(staged_api)] + +#[stable(feature = "bar", since = "OLD 1.0")] +pub trait Bar {} + +#[stable(feature = "baz", since = "OLD 1.0")] +pub trait Baz {} + +pub struct Foo; + +// @has foo/trait.Bar.html '//div[@id="implementors-list"]//span[@class="since"]' 'NEW 2.0' +#[stable(feature = "foobar", since = "NEW 2.0")] +impl Bar for Foo {} + +// @!has foo/trait.Baz.html '//div[@id="implementors-list"]//span[@class="since"]' 'OLD 1.0' +#[stable(feature = "foobaz", since = "OLD 1.0")] +impl Baz for Foo {} From 14aa12fcc2ebee6edfd6092a51122a6a6ba78d4d Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 22 Jan 2021 06:57:33 +0100 Subject: [PATCH 28/32] Replace version_check dependency with own version parsing code This gives compiler maintainers a better degree of control over how the version gets parsed and is a good way to ensure that there are no changes of behaviour in the future. Also, issue a warning if the version is invalid instead of erroring so that we stay forwards compatible with possible future changes of the versioning scheme. Last, this improves the present test a little. --- Cargo.lock | 1 - compiler/rustc_attr/Cargo.toml | 1 - compiler/rustc_attr/src/builtin.rs | 32 ++++- .../feature-gates/feature-gate-cfg-version.rs | 30 +++-- .../feature-gate-cfg-version.stderr | 110 +++++++++++++++--- 5 files changed, 138 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2ae22b6abd9b..ee52e34163bdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3568,7 +3568,6 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", - "version_check", ] [[package]] diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml index 5f941a0a650f8..dc0711a5b0f30 100644 --- a/compiler/rustc_attr/Cargo.toml +++ b/compiler/rustc_attr/Cargo.toml @@ -18,4 +18,3 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_ast = { path = "../rustc_ast" } -version_check = "0.9" diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index ead90f23ce7a1..26baaf07880f1 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -10,7 +10,6 @@ use rustc_session::Session; use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; -use version_check::Version; pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() @@ -526,6 +525,26 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F } } +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +struct Version { + major: u16, + minor: u16, + patch: u16, +} + +fn parse_version(s: &str, allow_appendix: bool) -> Option { + let mut components = s.split('-'); + let d = components.next()?; + if !allow_appendix && components.next().is_some() { + return None; + } + let mut digits = d.splitn(3, '.'); + let major = digits.next()?.parse().ok()?; + let minor = digits.next()?.parse().ok()?; + let patch = digits.next().unwrap_or("0").parse().ok()?; + Some(Version { major, minor, patch }) +} + /// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to /// evaluate individual items. pub fn eval_condition( @@ -555,16 +574,21 @@ pub fn eval_condition( return false; } }; - let min_version = match Version::parse(&min_version.as_str()) { + let min_version = match parse_version(&min_version.as_str(), false) { Some(ver) => ver, None => { - sess.span_diagnostic.struct_span_err(*span, "invalid version literal").emit(); + sess.span_diagnostic + .struct_span_warn( + *span, + "unknown version literal format, assuming it refers to a future version", + ) + .emit(); return false; } }; let channel = env!("CFG_RELEASE_CHANNEL"); let nightly = channel == "nightly" || channel == "dev"; - let rustc_version = Version::parse(env!("CFG_RELEASE")).unwrap(); + let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap(); // See https://github.com/rust-lang/rust/issues/64796#issuecomment-625474439 for details if nightly { rustc_version > min_version } else { rustc_version >= min_version } diff --git a/src/test/ui/feature-gates/feature-gate-cfg-version.rs b/src/test/ui/feature-gates/feature-gate-cfg-version.rs index c29ef99945e71..e35784a68d101 100644 --- a/src/test/ui/feature-gates/feature-gate-cfg-version.rs +++ b/src/test/ui/feature-gates/feature-gate-cfg-version.rs @@ -1,3 +1,9 @@ +#[cfg(version(42))] //~ ERROR: expected a version literal +//~^ ERROR `cfg(version)` is experimental and subject to change +fn foo() {} +#[cfg(version(1.20))] //~ ERROR: expected a version literal +//~^ ERROR `cfg(version)` is experimental and subject to change +fn foo() -> bool { true } #[cfg(version("1.44"))] //~^ ERROR `cfg(version)` is experimental and subject to change fn foo() -> bool { true } @@ -11,30 +17,32 @@ fn bar() -> bool { false } #[cfg(version(false))] //~ ERROR: expected a version literal //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("foo"))] //~ ERROR: invalid version literal +#[cfg(version("foo"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("999"))] +#[cfg(version("999"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("-1"))] //~ ERROR: invalid version literal +#[cfg(version("-1"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("65536"))] //~ ERROR: invalid version literal +#[cfg(version("65536"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("0"))] +#[cfg(version("0"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { true } - -#[cfg(version("1.65536.2"))] +#[cfg(version("1.0"))] +//~^ ERROR `cfg(version)` is experimental and subject to change +fn bar() -> bool { true } +#[cfg(version("1.65536.2"))] //~ WARNING: unknown version literal format +//~^ ERROR `cfg(version)` is experimental and subject to change +fn bar() -> bool { false } +#[cfg(version("1.20.0-stable"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change -fn version_check_bug() {} +fn bar() {} fn main() { - // This should fail but due to a bug in version_check `1.65536.2` is interpreted as `1.2`. - // See https://github.com/SergioBenitez/version_check/issues/11 - version_check_bug(); assert!(foo()); assert!(bar()); assert!(cfg!(version("1.42"))); //~ ERROR `cfg(version)` is experimental and subject to change diff --git a/src/test/ui/feature-gates/feature-gate-cfg-version.stderr b/src/test/ui/feature-gates/feature-gate-cfg-version.stderr index bdf160b5a0270..ae899d409ecf9 100644 --- a/src/test/ui/feature-gates/feature-gate-cfg-version.stderr +++ b/src/test/ui/feature-gates/feature-gate-cfg-version.stderr @@ -1,6 +1,36 @@ error[E0658]: `cfg(version)` is experimental and subject to change --> $DIR/feature-gate-cfg-version.rs:1:7 | +LL | #[cfg(version(42))] + | ^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + +error: expected a version literal + --> $DIR/feature-gate-cfg-version.rs:1:15 + | +LL | #[cfg(version(42))] + | ^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:4:7 + | +LL | #[cfg(version(1.20))] + | ^^^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + +error: expected a version literal + --> $DIR/feature-gate-cfg-version.rs:4:15 + | +LL | #[cfg(version(1.20))] + | ^^^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:7:7 + | LL | #[cfg(version("1.44"))] | ^^^^^^^^^^^^^^^ | @@ -8,7 +38,7 @@ LL | #[cfg(version("1.44"))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:4:11 + --> $DIR/feature-gate-cfg-version.rs:10:11 | LL | #[cfg(not(version("1.44")))] | ^^^^^^^^^^^^^^^ @@ -17,7 +47,7 @@ LL | #[cfg(not(version("1.44")))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:8:7 + --> $DIR/feature-gate-cfg-version.rs:14:7 | LL | #[cfg(version("1.43", "1.44", "1.45"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,13 +56,13 @@ LL | #[cfg(version("1.43", "1.44", "1.45"))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error: expected single version literal - --> $DIR/feature-gate-cfg-version.rs:8:7 + --> $DIR/feature-gate-cfg-version.rs:14:7 | LL | #[cfg(version("1.43", "1.44", "1.45"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:11:7 + --> $DIR/feature-gate-cfg-version.rs:17:7 | LL | #[cfg(version(false))] | ^^^^^^^^^^^^^^ @@ -41,13 +71,13 @@ LL | #[cfg(version(false))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error: expected a version literal - --> $DIR/feature-gate-cfg-version.rs:11:15 + --> $DIR/feature-gate-cfg-version.rs:17:15 | LL | #[cfg(version(false))] | ^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:14:7 + --> $DIR/feature-gate-cfg-version.rs:20:7 | LL | #[cfg(version("foo"))] | ^^^^^^^^^^^^^^ @@ -55,14 +85,14 @@ LL | #[cfg(version("foo"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: invalid version literal - --> $DIR/feature-gate-cfg-version.rs:14:15 +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:20:15 | LL | #[cfg(version("foo"))] | ^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:17:7 + --> $DIR/feature-gate-cfg-version.rs:23:7 | LL | #[cfg(version("999"))] | ^^^^^^^^^^^^^^ @@ -70,8 +100,14 @@ LL | #[cfg(version("999"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:23:15 + | +LL | #[cfg(version("999"))] + | ^^^^^ + error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:20:7 + --> $DIR/feature-gate-cfg-version.rs:26:7 | LL | #[cfg(version("-1"))] | ^^^^^^^^^^^^^ @@ -79,14 +115,14 @@ LL | #[cfg(version("-1"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: invalid version literal - --> $DIR/feature-gate-cfg-version.rs:20:15 +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:26:15 | LL | #[cfg(version("-1"))] | ^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:23:7 + --> $DIR/feature-gate-cfg-version.rs:29:7 | LL | #[cfg(version("65536"))] | ^^^^^^^^^^^^^^^^ @@ -94,14 +130,14 @@ LL | #[cfg(version("65536"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: invalid version literal - --> $DIR/feature-gate-cfg-version.rs:23:15 +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:29:15 | LL | #[cfg(version("65536"))] | ^^^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:26:7 + --> $DIR/feature-gate-cfg-version.rs:32:7 | LL | #[cfg(version("0"))] | ^^^^^^^^^^^^ @@ -109,8 +145,23 @@ LL | #[cfg(version("0"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:32:15 + | +LL | #[cfg(version("0"))] + | ^^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:35:7 + | +LL | #[cfg(version("1.0"))] + | ^^^^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:30:7 + --> $DIR/feature-gate-cfg-version.rs:38:7 | LL | #[cfg(version("1.65536.2"))] | ^^^^^^^^^^^^^^^^^^^^ @@ -118,8 +169,29 @@ LL | #[cfg(version("1.65536.2"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:38:15 + | +LL | #[cfg(version("1.65536.2"))] + | ^^^^^^^^^^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:41:7 + | +LL | #[cfg(version("1.20.0-stable"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:41:15 + | +LL | #[cfg(version("1.20.0-stable"))] + | ^^^^^^^^^^^^^^^ + error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:40:18 + --> $DIR/feature-gate-cfg-version.rs:48:18 | LL | assert!(cfg!(version("1.42"))); | ^^^^^^^^^^^^^^^ @@ -127,6 +199,6 @@ LL | assert!(cfg!(version("1.42"))); = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: aborting due to 16 previous errors +error: aborting due to 19 previous errors; 7 warnings emitted For more information about this error, try `rustc --explain E0658`. From 351b2acd14dab76292c0e9a684d2714454cc9956 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sat, 23 Jan 2021 23:03:01 -0500 Subject: [PATCH 29/32] Make bad shlex parsing a pretty error --- src/tools/jsondocck/src/main.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 29131f686a9dc..376639ced0aa6 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -149,7 +149,20 @@ fn get_commands(template: &str) -> Result, ()> { } } - let args = cap.name("args").map_or(vec![], |m| shlex::split(m.as_str()).unwrap()); + let args = cap.name("args") + .map_or(Some(vec![]), |m| shlex::split(m.as_str())); + + let args = match args { + Some(args) => args, + None => { + print_err( + &format!("Invalid arguments to shlex::split: `{}`", cap.name("args").unwrap().as_str()), + lineno + ); + errors = true; + continue; + } + }; if !cmd.validate(&args, commands.len(), lineno) { errors = true; From c37c4213543a727870ca862d25446b3c66d8e399 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sat, 23 Jan 2021 23:17:31 -0500 Subject: [PATCH 30/32] fmt --- src/tools/jsondocck/src/main.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 376639ced0aa6..6ec292aba6495 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -149,15 +149,17 @@ fn get_commands(template: &str) -> Result, ()> { } } - let args = cap.name("args") - .map_or(Some(vec![]), |m| shlex::split(m.as_str())); + let args = cap.name("args").map_or(Some(vec![]), |m| shlex::split(m.as_str())); let args = match args { Some(args) => args, None => { print_err( - &format!("Invalid arguments to shlex::split: `{}`", cap.name("args").unwrap().as_str()), - lineno + &format!( + "Invalid arguments to shlex::split: `{}`", + cap.name("args").unwrap().as_str() + ), + lineno, ); errors = true; continue; From f8416faaaf3a1fb6ca57ff8f0b3bdf972eed266f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Sun, 24 Jan 2021 13:32:18 +0100 Subject: [PATCH 31/32] Clean up dominators_given_rpo --- .../src/graph/dominators/mod.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 1cfbce2355e3a..ad62e3c9fc8f4 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -8,7 +8,6 @@ use super::iterate::reverse_post_order; use super::ControlFlowGraph; use rustc_index::vec::{Idx, IndexVec}; -use std::borrow::BorrowMut; use std::cmp::Ordering; #[cfg(test)] @@ -20,22 +19,17 @@ pub fn dominators(graph: G) -> Dominators { dominators_given_rpo(graph, &rpo) } -fn dominators_given_rpo>( - mut graph: G, - rpo: &[G::Node], -) -> Dominators { - let start_node = graph.borrow().start_node(); +fn dominators_given_rpo(graph: G, rpo: &[G::Node]) -> Dominators { + let start_node = graph.start_node(); assert_eq!(rpo[0], start_node); // compute the post order index (rank) for each node - let mut post_order_rank: IndexVec = - (0..graph.borrow().num_nodes()).map(|_| 0).collect(); + let mut post_order_rank = IndexVec::from_elem_n(0, graph.num_nodes()); for (index, node) in rpo.iter().rev().cloned().enumerate() { post_order_rank[node] = index; } - let mut immediate_dominators: IndexVec> = - (0..graph.borrow().num_nodes()).map(|_| None).collect(); + let mut immediate_dominators = IndexVec::from_elem_n(None, graph.num_nodes()); immediate_dominators[start_node] = Some(start_node); let mut changed = true; @@ -44,7 +38,7 @@ fn dominators_given_rpo>( for &node in &rpo[1..] { let mut new_idom = None; - for pred in graph.borrow_mut().predecessors(node) { + for pred in graph.predecessors(node) { if immediate_dominators[pred].is_some() { // (*) dominators for `pred` have been calculated new_idom = Some(if let Some(new_idom) = new_idom { From a730970dffe84711b8be66c38080acf1b1109982 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 24 Jan 2021 14:15:15 +0100 Subject: [PATCH 32/32] Only call span.rust_2021() when necessary. --- compiler/rustc_builtin_macros/src/assert.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 3cffc7a75eeb1..f82269c4eee4f 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -12,25 +12,23 @@ use rustc_span::{Span, DUMMY_SP}; pub fn expand_assert<'cx>( cx: &'cx mut ExtCtxt<'_>, - sp: Span, + span: Span, tts: TokenStream, ) -> Box { - let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) { + let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) { Ok(assert) => assert, Err(mut err) => { err.emit(); - return DummyResult::any(sp); + return DummyResult::any(span); } }; - let is_2021 = sp.rust_2021(); - // `core::panic` and `std::panic` are different macros, so we use call-site // context to pick up whichever is currently in scope. - let sp = cx.with_call_site_ctxt(sp); + let sp = cx.with_call_site_ctxt(span); let panic_call = if let Some(tokens) = custom_message { - let path = if is_2021 { + let path = if span.rust_2021() { // On edition 2021, we always call `$crate::panic!()`. Path { span: sp,