From 3e569dd2dff023378debce3b98e19bf3ef8c6904 Mon Sep 17 00:00:00 2001 From: Roxane Fruytier Date: Tue, 29 Jun 2021 14:15:58 -0400 Subject: [PATCH 01/11] Remove lang items Send, UnwindSafe and RefUnwindSafe --- compiler/rustc_hir/src/lang_items.rs | 3 --- compiler/rustc_passes/src/lang_items.rs | 3 --- compiler/rustc_span/src/symbol.rs | 5 ++--- library/core/src/marker.rs | 3 +++ library/std/src/panic.rs | 4 ++-- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index bab685006eafc..28ae08030e630 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -348,7 +348,4 @@ language_item_table! { Range, sym::Range, range_struct, Target::Struct; RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct; RangeTo, sym::RangeTo, range_to_struct, Target::Struct; - Send, sym::send, send_trait, Target::Trait; - UnwindSafe, sym::unwind_safe, unwind_safe_trait, Target::Trait; - RefUnwindSafe, sym::ref_unwind_safe, ref_unwind_safe_trait, Target::Trait; } diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 118fcca4508ea..f57f5fd56d284 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -257,9 +257,6 @@ impl LanguageItemCollector<'tcx> { | LangItem::Unpin | LangItem::Termination | LangItem::Try - | LangItem::Send - | LangItem::UnwindSafe - | LangItem::RefUnwindSafe => Some(0), // Not a trait diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index be4f12c6d1cb8..38e19dcb678aa 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -947,7 +947,7 @@ symbols! { receiver, recursion_limit, reexport_test_harness_main, - ref_unwind_safe, + ref_unwind_safe_trait, reference, reflect, reg, @@ -1073,7 +1073,6 @@ symbols! { self_in_typedefs, self_struct_ctor, semitransparent, - send, send_trait, shl, shl_assign, @@ -1299,7 +1298,7 @@ symbols! { unused_qualifications, unwind, unwind_attributes, - unwind_safe, + unwind_safe_trait, unwrap, unwrap_or, use_extern_macros, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 271565693d66e..d00fb2284b884 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -31,7 +31,10 @@ use crate::hash::Hasher; /// [ub]: ../../reference/behavior-considered-undefined.html #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "send_trait")] +<<<<<<< HEAD #[lang = "send"] +======= +>>>>>>> Remove lang items Send, UnwindSafe and RefUnwindSafe #[rustc_on_unimplemented( message = "`{Self}` cannot be sent between threads safely", label = "`{Self}` cannot be sent between threads safely" diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index ee069eefd4541..7931c4c0a5fca 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -133,7 +133,7 @@ pub fn panic_any(msg: M) -> ! { /// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be /// implemented for any closed over variables passed to `catch_unwind`. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[cfg_attr(not(test), lang = "unwind_safe")] +#[rustc_diagnostic_item = "unwind_safe_trait"] #[rustc_on_unimplemented( message = "the type `{Self}` may not be safely transferred across an unwind boundary", label = "`{Self}` may not be safely transferred across an unwind boundary" @@ -149,7 +149,7 @@ pub auto trait UnwindSafe {} /// This is a "helper marker trait" used to provide impl blocks for the /// [`UnwindSafe`] trait, for more information see that documentation. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[cfg_attr(not(test), lang = "ref_unwind_safe")] +#[rustc_diagnostic_item = "ref_unwind_safe_trait"] #[rustc_on_unimplemented( message = "the type `{Self}` may contain interior mutability and a reference may not be safely \ transferrable across a catch_unwind boundary", From 06afafd492c151d0521240bbee94a595a4e006e5 Mon Sep 17 00:00:00 2001 From: Roxane Fruytier Date: Tue, 29 Jun 2021 14:17:25 -0400 Subject: [PATCH 02/11] Use diagnostic items to check for Send, UnwindSafe and RefUnwindSafe traits --- .../src/traits/error_reporting/suggestions.rs | 6 ++++-- compiler/rustc_typeck/src/check/upvar.rs | 6 +++--- library/std/src/panic.rs | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5c35b515f3d02..13c14d26b70f4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -690,12 +690,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Blacklist traits for which it would be nonsensical to suggest borrowing. // For instance, immutable references are always Copy, so suggesting to // borrow would always succeed, but it's probably not what the user wanted. - let blacklist: Vec<_> = - [LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized, LangItem::Send] + let mut blacklist: Vec<_> = + [LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized] .iter() .filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok()) .collect(); + blacklist.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap()); + let span = obligation.cause.span; let param_env = obligation.param_env; let trait_ref = trait_ref.skip_binder(); diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 7b5b14ae6c831..197c4e3b319ab 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -663,7 +663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.need_2229_migrations_for_trait( min_captures, var_hir_id, - tcx.lang_items().send_trait(), + tcx.get_diagnostic_item(sym::send_trait), ) { auto_trait_reasons.insert("`Send`"); } @@ -679,7 +679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.need_2229_migrations_for_trait( min_captures, var_hir_id, - tcx.lang_items().unwind_safe_trait(), + tcx.get_diagnostic_item(sym::unwind_safe_trait), ) { auto_trait_reasons.insert("`UnwindSafe`"); } @@ -687,7 +687,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.need_2229_migrations_for_trait( min_captures, var_hir_id, - tcx.lang_items().ref_unwind_safe_trait(), + tcx.get_diagnostic_item(sym::ref_unwind_safe_trait), ) { auto_trait_reasons.insert("`RefUnwindSafe`"); } diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 7931c4c0a5fca..7bc987db8814b 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -133,7 +133,7 @@ pub fn panic_any(msg: M) -> ! { /// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be /// implemented for any closed over variables passed to `catch_unwind`. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[rustc_diagnostic_item = "unwind_safe_trait"] +#[cfg_attr(not(test), rustc_diagnostic_item = "unwind_safe_trait")] #[rustc_on_unimplemented( message = "the type `{Self}` may not be safely transferred across an unwind boundary", label = "`{Self}` may not be safely transferred across an unwind boundary" @@ -149,7 +149,7 @@ pub auto trait UnwindSafe {} /// This is a "helper marker trait" used to provide impl blocks for the /// [`UnwindSafe`] trait, for more information see that documentation. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[rustc_diagnostic_item = "ref_unwind_safe_trait"] +#[cfg_attr(not(test), rustc_diagnostic_item = "ref_unwind_safe_trait")] #[rustc_on_unimplemented( message = "the type `{Self}` may contain interior mutability and a reference may not be safely \ transferrable across a catch_unwind boundary", From cc3af7091caeaf91851f2999dea3225d0d5d39b0 Mon Sep 17 00:00:00 2001 From: Roxane Date: Tue, 29 Jun 2021 20:26:37 -0400 Subject: [PATCH 03/11] Rename variable --- .../src/traits/error_reporting/suggestions.rs | 10 +++++----- library/core/src/marker.rs | 4 ---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 13c14d26b70f4..b85d2a50f0579 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -687,16 +687,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return false; } - // Blacklist traits for which it would be nonsensical to suggest borrowing. + // List of traits for which it would be nonsensical to suggest borrowing. // For instance, immutable references are always Copy, so suggesting to // borrow would always succeed, but it's probably not what the user wanted. - let mut blacklist: Vec<_> = + let mut never_suggest_borrow: Vec<_> = [LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized] .iter() .filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok()) .collect(); - blacklist.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap()); + never_suggest_borrow.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap()); let span = obligation.cause.span; let param_env = obligation.param_env; @@ -799,7 +799,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ty::TraitRef::new(trait_ref.def_id, imm_substs), trait_ref, false, - &blacklist[..], + &never_suggest_borrow[..], ) { return true; } else { @@ -807,7 +807,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ty::TraitRef::new(trait_ref.def_id, mut_substs), trait_ref, true, - &blacklist[..], + &never_suggest_borrow[..], ); } } else { diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index d00fb2284b884..fb957348bebd3 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -31,10 +31,6 @@ use crate::hash::Hasher; /// [ub]: ../../reference/behavior-considered-undefined.html #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "send_trait")] -<<<<<<< HEAD -#[lang = "send"] -======= ->>>>>>> Remove lang items Send, UnwindSafe and RefUnwindSafe #[rustc_on_unimplemented( message = "`{Self}` cannot be sent between threads safely", label = "`{Self}` cannot be sent between threads safely" From 3b2ad49a7ad7f7e3edcd50477e7fd30df8a21876 Mon Sep 17 00:00:00 2001 From: Janik Rabe Date: Thu, 1 Jul 2021 21:56:10 +0100 Subject: [PATCH 04/11] Update BTreeSet::drain_filter documentation This commit makes the documentation of `BTreeSet::drain_filter` more consistent with that of `BTreeMap::drain_filter` after the changes in f0b8166870bd73a872642f090ae6b88e2bef922a. In particular, this explicitly documents the iteration order. --- library/alloc/src/collections/btree/set.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 737932d931c02..d9abb8f4c77f4 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -941,18 +941,20 @@ impl BTreeSet { BTreeSet { map: self.map.split_off(key) } } - /// Creates an iterator which uses a closure to determine if a value should be removed. + /// Creates an iterator that visits all values in ascending order and uses a closure + /// to determine if a value should be removed. /// - /// If the closure returns true, then the value is removed and yielded. - /// If the closure returns false, the value will remain in the list and will not be yielded - /// by the iterator. + /// If the closure returns `true`, the value is removed from the set and yielded. If + /// the closure returns `false`, or panics, the value remains in the set and will + /// not be yielded. /// - /// If the iterator is only partially consumed or not consumed at all, each of the remaining - /// values will still be subjected to the closure and removed and dropped if it returns true. + /// If the iterator is only partially consumed or not consumed at all, each of the + /// remaining values is still subjected to the closure and removed and dropped if it + /// returns `true`. /// - /// It is unspecified how many more values will be subjected to the closure - /// if a panic occurs in the closure, or if a panic occurs while dropping a value, or if the - /// `DrainFilter` itself is leaked. + /// It is unspecified how many more values will be subjected to the closure if a + /// panic occurs in the closure, or if a panic occurs while dropping a value, or if + /// the `DrainFilter` itself is leaked. /// /// # Examples /// From 27b55e636f43fdb6e49e200db79f3591993dcb98 Mon Sep 17 00:00:00 2001 From: Justus K Date: Tue, 6 Jul 2021 19:00:35 +0200 Subject: [PATCH 05/11] Document rustdoc with `--document-private-items` --- src/bootstrap/doc.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 7ec3c2d738a67..d3f2c87c0d22f 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -600,7 +600,7 @@ impl Step for Rustc { } macro_rules! tool_doc { - ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(, binary=$bin:expr)?) => { + ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?], binary=$bin:expr) => { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct $tool { stage: u32, @@ -669,9 +669,9 @@ macro_rules! tool_doc { cargo.arg("-p").arg($krate); )+ - $(if !$bin { + if !$bin { cargo.rustdocflag("--document-private-items"); - })? + } cargo.rustdocflag("--enable-index-page"); cargo.rustdocflag("--show-type-layout"); cargo.rustdocflag("-Zunstable-options"); @@ -681,7 +681,13 @@ macro_rules! tool_doc { } } -tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"]); +tool_doc!( + Rustdoc, + "rustdoc-tool", + "src/tools/rustdoc", + ["rustdoc", "rustdoc-json-types"], + binary = false +); tool_doc!( Rustfmt, "rustfmt-nightly", From bd674b1e0b45a52aaf2dfdeed829d7d45f211a74 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Wed, 7 Jul 2021 16:32:04 -0400 Subject: [PATCH 06/11] Update .mailmap file --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 5d9bc173364da..01fc991375c4a 100644 --- a/.mailmap +++ b/.mailmap @@ -116,6 +116,7 @@ Herman J. Radtke III Herman J. Radtke III Ivan Ivaschenko J. J. Weber +Jacob Pratt Jakub Adam Wieczorek Jakub Adam Wieczorek Jakub Adam Wieczorek From 07f903e0e0816821c41a19774f029086b557738b Mon Sep 17 00:00:00 2001 From: Lamb Date: Sat, 3 Jul 2021 12:07:06 +0200 Subject: [PATCH 07/11] fn must be const if marked with stability attribut MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove trailing newline fix: test with attribute but missing const Update compiler/rustc_passes/src/stability.rs Co-authored-by: Léo Lanteri Thauvin Add test for extern functions fix: using span_help instead of span_suggestion add test for some ABIs + fmt fix Update compiler/rustc_passes/src/stability.rs Co-authored-by: Léo Lanteri Thauvin Refractor and add test for `impl const` Add test to make sure no output + cleanup condition ----------------------------- remove stdcall test, failing CI test C abi is already tested in this, so it is not that useful to test another one. The tested code is blind to which specific ABI for now, as long as it's not an intrinsic one --- .../src/error_codes/E0542.md | 4 +- .../src/error_codes/E0545.md | 4 +- .../src/error_codes/E0547.md | 4 +- compiler/rustc_passes/src/stability.rs | 61 ++++++++++++- .../rustc-const-stability-require-const.rs | 47 ++++++++++ ...rustc-const-stability-require-const.stderr | 86 +++++++++++++++++++ .../ui/consts/rustc-impl-const-stability.rs | 21 +++++ 7 files changed, 220 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/consts/rustc-const-stability-require-const.rs create mode 100644 src/test/ui/consts/rustc-const-stability-require-const.stderr create mode 100644 src/test/ui/consts/rustc-impl-const-stability.rs diff --git a/compiler/rustc_error_codes/src/error_codes/E0542.md b/compiler/rustc_error_codes/src/error_codes/E0542.md index 7cb58f9d0cb74..7fecfeaa57c28 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0542.md +++ b/compiler/rustc_error_codes/src/error_codes/E0542.md @@ -10,7 +10,7 @@ Erroneous code example: fn _stable_fn() {} #[rustc_const_stable(feature = "_stable_const_fn")] // invalid -fn _stable_const_fn() {} +const fn _stable_const_fn() {} #[stable(feature = "_deprecated_fn", since = "0.1.0")] #[rustc_deprecated( @@ -29,7 +29,7 @@ To fix this issue, you need to provide the `since` field. Example: fn _stable_fn() {} #[rustc_const_stable(feature = "_stable_const_fn", since = "1.0.0")] // ok! -fn _stable_const_fn() {} +const fn _stable_const_fn() {} #[stable(feature = "_deprecated_fn", since = "0.1.0")] #[rustc_deprecated( diff --git a/compiler/rustc_error_codes/src/error_codes/E0545.md b/compiler/rustc_error_codes/src/error_codes/E0545.md index 9fb935a3ab1ab..7aba084f4d3aa 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0545.md +++ b/compiler/rustc_error_codes/src/error_codes/E0545.md @@ -10,7 +10,7 @@ Erroneous code example: fn _unstable_fn() {} #[rustc_const_unstable(feature = "_unstable_const_fn", issue = "0")] // invalid -fn _unstable_const_fn() {} +const fn _unstable_const_fn() {} ``` To fix this issue, you need to provide a correct value in the `issue` field. @@ -24,7 +24,7 @@ Example: fn _unstable_fn() {} #[rustc_const_unstable(feature = "_unstable_const_fn", issue = "1")] // ok! -fn _unstable_const_fn() {} +const fn _unstable_const_fn() {} ``` See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix diff --git a/compiler/rustc_error_codes/src/error_codes/E0547.md b/compiler/rustc_error_codes/src/error_codes/E0547.md index 1aa4b35424884..4950325df6400 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0547.md +++ b/compiler/rustc_error_codes/src/error_codes/E0547.md @@ -10,7 +10,7 @@ Erroneous code example: fn _unstable_fn() {} #[rustc_const_unstable(feature = "_unstable_const_fn")] // invalid -fn _unstable_const_fn() {} +const fn _unstable_const_fn() {} ``` To fix this issue, you need to provide the `issue` field. Example: @@ -26,7 +26,7 @@ fn _unstable_fn() {} feature = "_unstable_const_fn", issue = "none" )] // ok! -fn _unstable_const_fn() {} +const fn _unstable_const_fn() {} ``` See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 5830245e837e4..cd8dd6984d5b9 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -20,6 +20,7 @@ use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use rustc_target::spec::abi::Abi; use std::cmp::Ordering; use std::iter; @@ -95,10 +96,12 @@ struct Annotator<'a, 'tcx> { impl<'a, 'tcx> Annotator<'a, 'tcx> { // Determine the stability for a node based on its attributes and inherited // stability. The stability is recorded in the index and used as the parent. + // If the node is a function, `fn_sig` is its signature fn annotate( &mut self, hir_id: HirId, item_sp: Span, + fn_sig: Option<&'tcx hir::FnSig<'tcx>>, kind: AnnotationKind, inherit_deprecation: InheritDeprecation, inherit_const_stability: InheritConstStability, @@ -163,13 +166,30 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp); + let mut const_span = None; - let const_stab = const_stab.map(|(const_stab, _)| { + let const_stab = const_stab.map(|(const_stab, const_span_node)| { let const_stab = self.tcx.intern_const_stability(const_stab); self.index.const_stab_map.insert(hir_id, const_stab); + const_span = Some(const_span_node); const_stab }); + // If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI, + // check if the function/method is const or the parent impl block is const + if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig) { + if fn_sig.header.abi != Abi::RustIntrinsic + && fn_sig.header.abi != Abi::PlatformIntrinsic + && !fn_sig.header.is_const() + { + if !self.in_trait_impl + || (self.in_trait_impl && !self.tcx.is_const_fn_raw(hir_id.owner.to_def_id())) + { + missing_const_err(&self.tcx.sess, fn_sig.span, const_span); + } + } + } + // `impl const Trait for Type` items forward their const stability to their // immediate children. if const_stab.is_none() { @@ -367,6 +387,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { let orig_in_trait_impl = self.in_trait_impl; let mut kind = AnnotationKind::Required; let mut const_stab_inherit = InheritConstStability::No; + let mut fn_sig = None; + match i.kind { // Inherent impls and foreign modules serve only as containers for other items, // they don't have their own stability. They still can be annotated as unstable @@ -387,6 +409,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { self.annotate( ctor_hir_id, i.span, + None, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -395,12 +418,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { ) } } + hir::ItemKind::Fn(ref item_fn_sig, _, _) => { + fn_sig = Some(item_fn_sig); + } _ => {} } self.annotate( i.hir_id(), i.span, + fn_sig, kind, InheritDeprecation::Yes, const_stab_inherit, @@ -411,9 +438,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { } fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) { + let fn_sig = match ti.kind { + hir::TraitItemKind::Fn(ref fn_sig, _) => Some(fn_sig), + _ => None, + }; + self.annotate( ti.hir_id(), ti.span, + fn_sig, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -427,9 +460,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) { let kind = if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required }; + + let fn_sig = match ii.kind { + hir::ImplItemKind::Fn(ref fn_sig, _) => Some(fn_sig), + _ => None, + }; + self.annotate( ii.hir_id(), ii.span, + fn_sig, kind, InheritDeprecation::Yes, InheritConstStability::No, @@ -444,6 +484,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { self.annotate( var.id, var.span, + None, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -453,6 +494,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { v.annotate( ctor_hir_id, var.span, + None, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -470,6 +512,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { self.annotate( s.hir_id, s.span, + None, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -484,6 +527,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { self.annotate( i.hir_id(), i.span, + None, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -498,6 +542,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { self.annotate( md.hir_id(), md.span, + None, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -517,6 +562,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { self.annotate( p.hir_id, p.span, + None, kind, InheritDeprecation::No, InheritConstStability::No, @@ -687,6 +733,7 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> { annotator.annotate( hir::CRATE_HIR_ID, krate.item.inner, + None, AnnotationKind::Required, InheritDeprecation::Yes, InheritConstStability::No, @@ -969,3 +1016,15 @@ fn duplicate_feature_err(sess: &Session, span: Span, feature: Symbol) { struct_span_err!(sess, span, E0636, "the feature `{}` has already been declared", feature) .emit(); } + +fn missing_const_err(session: &Session, fn_sig_span: Span, const_span: Span) { + const ERROR_MSG: &'static str = "attributes `#[rustc_const_unstable]` \ + and `#[rustc_const_stable]` require \ + the function or method to be `const`"; + + session + .struct_span_err(fn_sig_span, ERROR_MSG) + .span_help(fn_sig_span, "make the function or method const") + .span_label(const_span, "attribute specified here") + .emit(); +} diff --git a/src/test/ui/consts/rustc-const-stability-require-const.rs b/src/test/ui/consts/rustc-const-stability-require-const.rs new file mode 100644 index 0000000000000..4fb259b335c71 --- /dev/null +++ b/src/test/ui/consts/rustc-const-stability-require-const.rs @@ -0,0 +1,47 @@ +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "foo", since = "1.0.0")] + +#[stable(feature = "foo", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_foo", issue = "none")] +pub fn foo() {} +//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + +#[stable(feature = "bar", since = "1.0.0")] +#[rustc_const_stable(feature = "const_bar", since = "1.0.0")] +pub fn bar() {} +//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + +#[stable(feature = "potato", since = "1.0.0")] +pub struct Potato; + +impl Potato { + #[stable(feature = "salad", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_salad", issue = "none")] + pub fn salad(&self) -> &'static str { "mmmmmm" } + //~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + + #[stable(feature = "roasted", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_roasted", issue = "none")] + pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } + //~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` +} + +#[stable(feature = "bar", since = "1.0.0")] +#[rustc_const_stable(feature = "const_bar", since = "1.0.0")] +pub extern "C" fn bar_c() {} +//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + +#[stable(feature = "foo", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_foo", issue = "none")] +pub extern "C" fn foo_c() {} +//~^ ERROR attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + + +#[stable(feature = "foobar", since = "1.0.0")] +#[rustc_const_unstable(feature = "foobar_const", issue = "none")] +pub const fn foobar() {} + +#[stable(feature = "barfoo", since = "1.0.0")] +#[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")] +pub const fn barfoo() {} diff --git a/src/test/ui/consts/rustc-const-stability-require-const.stderr b/src/test/ui/consts/rustc-const-stability-require-const.stderr new file mode 100644 index 0000000000000..1027b9311b7a6 --- /dev/null +++ b/src/test/ui/consts/rustc-const-stability-require-const.stderr @@ -0,0 +1,86 @@ +error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:7:1 + | +LL | #[rustc_const_unstable(feature = "const_foo", issue = "none")] + | -------------------------------------------------------------- attribute specified here +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:7:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + +error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:12:1 + | +LL | #[rustc_const_stable(feature = "const_bar", since = "1.0.0")] + | ------------------------------------------------------------- attribute specified here +LL | pub fn bar() {} + | ^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:12:1 + | +LL | pub fn bar() {} + | ^^^^^^^^^^^^ + +error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:21:5 + | +LL | #[rustc_const_unstable(feature = "const_salad", issue = "none")] + | ---------------------------------------------------------------- attribute specified here +LL | pub fn salad(&self) -> &'static str { "mmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:21:5 + | +LL | pub fn salad(&self) -> &'static str { "mmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:26:5 + | +LL | #[rustc_const_unstable(feature = "const_roasted", issue = "none")] + | ------------------------------------------------------------------ attribute specified here +LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:26:5 + | +LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:32:1 + | +LL | #[rustc_const_stable(feature = "const_bar", since = "1.0.0")] + | ------------------------------------------------------------- attribute specified here +LL | pub extern "C" fn bar_c() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:32:1 + | +LL | pub extern "C" fn bar_c() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:37:1 + | +LL | #[rustc_const_unstable(feature = "const_foo", issue = "none")] + | -------------------------------------------------------------- attribute specified here +LL | pub extern "C" fn foo_c() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:37:1 + | +LL | pub extern "C" fn foo_c() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/consts/rustc-impl-const-stability.rs b/src/test/ui/consts/rustc-impl-const-stability.rs new file mode 100644 index 0000000000000..01daa1c9cb42f --- /dev/null +++ b/src/test/ui/consts/rustc-impl-const-stability.rs @@ -0,0 +1,21 @@ +// build-pass + +#![crate_type = "lib"] +#![allow(incomplete_features)] +#![feature(staged_api)] +#![feature(const_trait_impl)] +#![stable(feature = "foo", since = "1.0.0")] + + +#[stable(feature = "potato", since = "1.27.0")] +pub struct Data { + _data: u128 +} + +#[stable(feature = "potato", since = "1.27.0")] +impl const Default for Data { + #[rustc_const_unstable(feature = "data_foo", issue = "none")] + fn default() -> Data { + Data { _data: 42 } + } +} From ff618977aa8334b5529eb7dd891ff4b52ae63fde Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 8 Jul 2021 12:44:25 +0100 Subject: [PATCH 08/11] mailmap: Add alternative addresses for myself At least one of these is already in-tree; it seems plausible that others might appear too. Signed-off-by: Ian Jackson --- .mailmap | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.mailmap b/.mailmap index 8b504084266bb..5c7836beeb9a6 100644 --- a/.mailmap +++ b/.mailmap @@ -113,6 +113,9 @@ Hanna Kruppe Heather Heather Herman J. Radtke III Herman J. Radtke III +Ian Jackson +Ian Jackson +Ian Jackson Ilyong Cho inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com> Ivan Ivaschenko From a2654fb64c9c9d368063b488693d8da17bc9b4e9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 5 May 2021 21:31:25 +0200 Subject: [PATCH 09/11] Rework SESSION_GLOBALS API to prevent overwriting it --- compiler/rustc_ast/src/util/comments/tests.rs | 10 ++-- compiler/rustc_ast_pretty/src/pprust/tests.rs | 6 +- compiler/rustc_errors/src/json/tests.rs | 7 +-- compiler/rustc_expand/src/mut_visit/tests.rs | 6 +- compiler/rustc_expand/src/parse/tests.rs | 24 ++++---- compiler/rustc_expand/src/tests.rs | 4 +- .../rustc_expand/src/tokenstream/tests.rs | 20 +++---- compiler/rustc_interface/src/interface.rs | 2 +- compiler/rustc_interface/src/tests.rs | 10 ++-- compiler/rustc_interface/src/util.rs | 15 ++--- .../rustc_mir/src/transform/coverage/tests.rs | 4 +- compiler/rustc_parse_format/src/tests.rs | 3 +- compiler/rustc_span/src/hygiene.rs | 9 +-- compiler/rustc_span/src/lev_distance/tests.rs | 4 +- compiler/rustc_span/src/lib.rs | 60 ++++++++++++++++--- compiler/rustc_span/src/span_encoding.rs | 3 +- compiler/rustc_span/src/symbol.rs | 4 +- compiler/rustc_span/src/symbol/tests.rs | 4 +- src/librustdoc/clean/cfg/tests.rs | 18 +++--- src/librustdoc/doctest.rs | 2 +- src/librustdoc/html/highlight/tests.rs | 6 +- .../passes/unindent_comments/tests.rs | 4 +- .../ui-fulldeps/mod_dir_path_canonicalized.rs | 2 +- src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 2 +- src/tools/clippy/clippy_lints/src/doc.rs | 12 ++-- src/tools/error_index_generator/main.rs | 3 +- src/tools/rustfmt/src/formatting.rs | 2 +- 27 files changed, 146 insertions(+), 100 deletions(-) diff --git a/compiler/rustc_ast/src/util/comments/tests.rs b/compiler/rustc_ast/src/util/comments/tests.rs index 98ab653e45f70..6d137f3774fe7 100644 --- a/compiler/rustc_ast/src/util/comments/tests.rs +++ b/compiler/rustc_ast/src/util/comments/tests.rs @@ -1,9 +1,9 @@ use super::*; -use rustc_span::with_default_session_globals; +use rustc_span::create_default_session_globals_then; #[test] fn test_block_doc_comment_1() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let comment = "\n * Test \n ** Test\n * Test\n"; let stripped = beautify_doc_string(Symbol::intern(comment)); assert_eq!(stripped.as_str(), " Test \n* Test\n Test"); @@ -12,7 +12,7 @@ fn test_block_doc_comment_1() { #[test] fn test_block_doc_comment_2() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let comment = "\n * Test\n * Test\n"; let stripped = beautify_doc_string(Symbol::intern(comment)); assert_eq!(stripped.as_str(), " Test\n Test"); @@ -21,7 +21,7 @@ fn test_block_doc_comment_2() { #[test] fn test_block_doc_comment_3() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let comment = "\n let a: *i32;\n *a = 5;\n"; let stripped = beautify_doc_string(Symbol::intern(comment)); assert_eq!(stripped.as_str(), " let a: *i32;\n *a = 5;"); @@ -30,7 +30,7 @@ fn test_block_doc_comment_3() { #[test] fn test_line_doc_comment() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let stripped = beautify_doc_string(Symbol::intern(" test")); assert_eq!(stripped.as_str(), " test"); let stripped = beautify_doc_string(Symbol::intern("! test")); diff --git a/compiler/rustc_ast_pretty/src/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs index 8abd85a5a5214..6c8d42f33eb5a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/tests.rs +++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs @@ -1,8 +1,8 @@ use super::*; use rustc_ast as ast; +use rustc_span::create_default_session_globals_then; use rustc_span::symbol::Ident; -use rustc_span::with_default_session_globals; fn fun_to_string( decl: &ast::FnDecl, @@ -24,7 +24,7 @@ fn variant_to_string(var: &ast::Variant) -> String { #[test] fn test_fun_to_string() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let abba_ident = Ident::from_str("abba"); let decl = @@ -39,7 +39,7 @@ fn test_fun_to_string() { #[test] fn test_variant_to_string() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let ident = Ident::from_str("principal_skinner"); let var = ast::Variant { diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index e69e868c8ede5..d055937ac36e3 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -39,16 +39,11 @@ impl Write for Shared { } } -fn with_default_session_globals(f: impl FnOnce()) { - let session_globals = rustc_span::SessionGlobals::new(rustc_span::edition::DEFAULT_EDITION); - rustc_span::SESSION_GLOBALS.set(&session_globals, f); -} - /// Test the span yields correct positions in JSON. fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { let expected_output = TestData { spans: vec![expected_output] }; - with_default_session_globals(|| { + rustc_span::create_default_session_globals_then(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned()); diff --git a/compiler/rustc_expand/src/mut_visit/tests.rs b/compiler/rustc_expand/src/mut_visit/tests.rs index 7e7155ad27876..0068539fb3bd4 100644 --- a/compiler/rustc_expand/src/mut_visit/tests.rs +++ b/compiler/rustc_expand/src/mut_visit/tests.rs @@ -3,8 +3,8 @@ use crate::tests::{matches_codepattern, string_to_crate}; use rustc_ast as ast; use rustc_ast::mut_visit::MutVisitor; use rustc_ast_pretty::pprust; +use rustc_span::create_default_session_globals_then; use rustc_span::symbol::Ident; -use rustc_span::with_default_session_globals; // This version doesn't care about getting comments or doc-strings in. fn print_crate_items(krate: &ast::Crate) -> String { @@ -38,7 +38,7 @@ macro_rules! assert_pred { // Make sure idents get transformed everywhere. #[test] fn ident_transformation() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let mut zz_visitor = ToZzIdentMutVisitor; let mut krate = string_to_crate("#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); @@ -55,7 +55,7 @@ fn ident_transformation() { // Make sure idents get transformed even inside macro defs. #[test] fn ident_transformation_in_defs() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let mut zz_visitor = ToZzIdentMutVisitor; let mut krate = string_to_crate( "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index 288efe22982fa..6402a81e7c1a5 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -10,9 +10,9 @@ use rustc_errors::PResult; use rustc_parse::new_parser_from_source_str; use rustc_parse::parser::ForceCollect; use rustc_session::parse::ParseSess; +use rustc_span::create_default_session_globals_then; use rustc_span::source_map::FilePathMapping; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::with_default_session_globals; use rustc_span::{BytePos, FileName, Pos, Span}; use std::path::PathBuf; @@ -51,7 +51,7 @@ fn string_to_item(source_str: String) -> Option> { #[should_panic] #[test] fn bad_path_expr_1() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { string_to_expr("::abc::def::return".to_string()); }) } @@ -59,7 +59,7 @@ fn bad_path_expr_1() { // Checks the token-tree-ization of macros. #[test] fn string_to_tts_macro() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let tts: Vec<_> = string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect(); let tts: &[TokenTree] = &tts[..]; @@ -96,7 +96,7 @@ fn string_to_tts_macro() { #[test] fn string_to_tts_1() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let tts = string_to_stream("fn a (b : i32) { b; }".to_string()); let expected = TokenStream::new(vec![ @@ -131,7 +131,7 @@ fn string_to_tts_1() { #[test] fn parse_use() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let use_s = "use foo::bar::baz;"; let vitem = string_to_item(use_s.to_string()).unwrap(); let vitem_s = item_to_string(&vitem); @@ -146,7 +146,7 @@ fn parse_use() { #[test] fn parse_extern_crate() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let ex_s = "extern crate foo;"; let vitem = string_to_item(ex_s.to_string()).unwrap(); let vitem_s = item_to_string(&vitem); @@ -184,7 +184,7 @@ fn get_spans_of_pat_idents(src: &str) -> Vec { #[test] fn span_of_self_arg_pat_idents_are_correct() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let srcs = [ "impl z { fn a (&self, &myarg: i32) {} }", "impl z { fn a (&mut self, &myarg: i32) {} }", @@ -208,7 +208,7 @@ fn span_of_self_arg_pat_idents_are_correct() { #[test] fn parse_exprs() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { // just make sure that they parse.... string_to_expr("3 + 4".to_string()); string_to_expr("a::z.froob(b,&(987+3))".to_string()); @@ -217,7 +217,7 @@ fn parse_exprs() { #[test] fn attrs_fix_bug() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { string_to_item( "pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) -> Result, String> { @@ -238,7 +238,7 @@ let mut fflags: c_int = wb(); #[test] fn crlf_doc_comments() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let sess = sess(); let name_1 = FileName::Custom("crlf_source_1".to_string()); @@ -272,7 +272,7 @@ fn ttdelim_span() { new_parser_from_source_str(sess, name, source).parse_expr() } - with_default_session_globals(|| { + create_default_session_globals_then(|| { let sess = sess(); let expr = parse_expr_from_source_str( PathBuf::from("foo").into(), @@ -300,7 +300,7 @@ fn ttdelim_span() { // See `recurse_into_file_modules` in the parser. #[test] fn out_of_line_mod() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let item = parse_item_from_source_str( PathBuf::from("foo").into(), "mod foo { struct S; mod this_does_not_exist; }".to_owned(), diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index f2345ff2707e9..ed3aa1eaca84e 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -2,8 +2,8 @@ use rustc_ast as ast; use rustc_ast::tokenstream::TokenStream; use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream}; use rustc_session::parse::ParseSess; +use rustc_span::create_default_session_if_not_set_then; use rustc_span::source_map::{FilePathMapping, SourceMap}; -use rustc_span::with_default_session_globals; use rustc_span::{BytePos, MultiSpan, Span}; use rustc_data_structures::sync::Lrc; @@ -124,7 +124,7 @@ impl Write for Shared { } fn test_harness(file_text: &str, span_labels: Vec, expected_output: &str) { - with_default_session_globals(|| { + create_default_session_if_not_set_then(|_| { let output = Arc::new(Mutex::new(Vec::new())); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/compiler/rustc_expand/src/tokenstream/tests.rs b/compiler/rustc_expand/src/tokenstream/tests.rs index 8b546e7e4a343..31052bfb54ce8 100644 --- a/compiler/rustc_expand/src/tokenstream/tests.rs +++ b/compiler/rustc_expand/src/tokenstream/tests.rs @@ -2,7 +2,7 @@ use crate::tests::string_to_stream; use rustc_ast::token; use rustc_ast::tokenstream::{Spacing, TokenStream, TokenStreamBuilder, TokenTree}; -use rustc_span::with_default_session_globals; +use rustc_span::create_default_session_globals_then; use rustc_span::{BytePos, Span, Symbol}; use smallvec::smallvec; @@ -20,7 +20,7 @@ fn joint(tree: TokenTree) -> TokenStream { #[test] fn test_concat() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test_res = string_to_ts("foo::bar::baz"); let test_fst = string_to_ts("foo::bar"); let test_snd = string_to_ts("::baz"); @@ -33,7 +33,7 @@ fn test_concat() { #[test] fn test_to_from_bijection() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test_start = string_to_ts("foo::bar(baz)"); let test_end = test_start.trees().collect(); assert_eq!(test_start, test_end) @@ -42,7 +42,7 @@ fn test_to_from_bijection() { #[test] fn test_eq_0() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test_res = string_to_ts("foo"); let test_eqs = string_to_ts("foo"); assert_eq!(test_res, test_eqs) @@ -51,7 +51,7 @@ fn test_eq_0() { #[test] fn test_eq_1() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test_res = string_to_ts("::bar::baz"); let test_eqs = string_to_ts("::bar::baz"); assert_eq!(test_res, test_eqs) @@ -60,7 +60,7 @@ fn test_eq_1() { #[test] fn test_eq_3() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test_res = string_to_ts(""); let test_eqs = string_to_ts(""); assert_eq!(test_res, test_eqs) @@ -69,7 +69,7 @@ fn test_eq_3() { #[test] fn test_diseq_0() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test_res = string_to_ts("::bar::baz"); let test_eqs = string_to_ts("bar::baz"); assert_eq!(test_res == test_eqs, false) @@ -78,7 +78,7 @@ fn test_diseq_0() { #[test] fn test_diseq_1() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test_res = string_to_ts("(bar,baz)"); let test_eqs = string_to_ts("bar,baz"); assert_eq!(test_res == test_eqs, false) @@ -87,7 +87,7 @@ fn test_diseq_1() { #[test] fn test_is_empty() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let test0: TokenStream = Vec::::new().into_iter().collect(); let test1: TokenStream = TokenTree::token(token::Ident(Symbol::intern("a"), false), sp(0, 1)).into(); @@ -101,7 +101,7 @@ fn test_is_empty() { #[test] fn test_dotdotdot() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let mut builder = TokenStreamBuilder::new(); builder.push(joint(TokenTree::token(token::Dot, sp(0, 1)))); builder.push(joint(TokenTree::token(token::Dot, sp(1, 2)))); diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index a1090ee316db4..086c49c73972f 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -76,7 +76,7 @@ impl Compiler { /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`. pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option)> { - rustc_span::with_default_session_globals(move || { + rustc_span::create_default_session_if_not_set_then(move |_| { let cfg = cfgspecs .into_iter() .map(|s| { diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index b252409a92ada..a053253ec16e0 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -107,7 +107,7 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) { // When the user supplies --test we should implicitly supply --cfg test #[test] fn test_switch_implies_cfg_test() { - rustc_span::with_default_session_globals(|| { + rustc_span::create_default_session_globals_then(|| { let matches = optgroups().parse(&["--test".to_string()]).unwrap(); let (sess, cfg) = mk_session(matches); let cfg = build_configuration(&sess, to_crate_config(cfg)); @@ -118,7 +118,7 @@ fn test_switch_implies_cfg_test() { // When the user supplies --test and --cfg test, don't implicitly add another --cfg test #[test] fn test_switch_implies_cfg_test_unless_cfg_test() { - rustc_span::with_default_session_globals(|| { + rustc_span::create_default_session_globals_then(|| { let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap(); let (sess, cfg) = mk_session(matches); let cfg = build_configuration(&sess, to_crate_config(cfg)); @@ -130,20 +130,20 @@ fn test_switch_implies_cfg_test_unless_cfg_test() { #[test] fn test_can_print_warnings() { - rustc_span::with_default_session_globals(|| { + rustc_span::create_default_session_globals_then(|| { let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap(); let (sess, _) = mk_session(matches); assert!(!sess.diagnostic().can_emit_warnings()); }); - rustc_span::with_default_session_globals(|| { + rustc_span::create_default_session_globals_then(|| { let matches = optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap(); let (sess, _) = mk_session(matches); assert!(sess.diagnostic().can_emit_warnings()); }); - rustc_span::with_default_session_globals(|| { + rustc_span::create_default_session_globals_then(|| { let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap(); let (sess, _) = mk_session(matches); assert!(sess.diagnostic().can_emit_warnings()); diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index d1d0eee365d48..4f51ce620427b 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -150,7 +150,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Se crate::callbacks::setup_callbacks(); let main_handler = move || { - rustc_span::with_session_globals(edition, || { + rustc_span::create_session_globals_then(edition, || { io::set_output_capture(stderr.clone()); f() }) @@ -171,12 +171,13 @@ unsafe fn handle_deadlock() { rustc_data_structures::sync::assert_sync::>(); let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>); - let session_globals = rustc_span::SESSION_GLOBALS.with(|sg| sg as *const _); + let session_globals = rustc_span::with_session_globals(|sg| sg as *const _); let session_globals = &*session_globals; thread::spawn(move || { tls::enter_context(icx, |_| { - rustc_span::SESSION_GLOBALS - .set(session_globals, || tls::with(|tcx| tcx.queries.deadlock(tcx, ®istry))) + rustc_span::set_session_globals_then(session_globals, || { + tls::with(|tcx| tcx.queries.deadlock(tcx, ®istry)) + }) }); }); } @@ -203,13 +204,13 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals R + Se let with_pool = move |pool: &rayon::ThreadPool| pool.install(f); - rustc_span::with_session_globals(edition, || { - rustc_span::SESSION_GLOBALS.with(|session_globals| { + rustc_span::create_session_globals_then(edition, || { + rustc_span::with_session_globals(|session_globals| { // The main handler runs for each Rayon worker thread and sets up // the thread local rustc uses. `session_globals` is captured and set // on the new threads. let main_handler = move |thread: rayon::ThreadBuilder| { - rustc_span::SESSION_GLOBALS.set(session_globals, || { + rustc_span::set_session_globals_then(session_globals, || { io::set_output_capture(stderr.clone()); thread.run() }) diff --git a/compiler/rustc_mir/src/transform/coverage/tests.rs b/compiler/rustc_mir/src/transform/coverage/tests.rs index b04c2d542d459..e5b3059a5995f 100644 --- a/compiler/rustc_mir/src/transform/coverage/tests.rs +++ b/compiler/rustc_mir/src/transform/coverage/tests.rs @@ -22,7 +22,7 @@ //! are unrelated to the `TyCtxt` global. Without initializing the `Span` session globals, some //! basic, coverage-specific features would be impossible to test, but thankfully initializing these //! globals is comparatively simpler. The easiest way is to wrap the test in a closure argument -//! to: `rustc_span::with_default_session_globals(|| { test_here(); })`. +//! to: `rustc_span::create_default_session_globals_then(|| { test_here(); })`. use super::counters; use super::debug; @@ -677,7 +677,7 @@ fn synthesize_body_span_from_terminators(mir_body: &Body<'_>) -> Span { #[test] fn test_make_bcb_counters() { - rustc_span::with_default_session_globals(|| { + rustc_span::create_default_session_globals_then(|| { let mir_body = goto_switchint(); let body_span = synthesize_body_span_from_terminators(&mir_body); let mut basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body); diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index 9fd0497fffee5..b7693a85ad955 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -144,8 +144,7 @@ fn format_align_fill() { } #[test] fn format_counts() { - use rustc_span::{edition, SessionGlobals, SESSION_GLOBALS}; - SESSION_GLOBALS.set(&SessionGlobals::new(edition::DEFAULT_EDITION), || { + rustc_span::create_default_session_globals_then(|| { same( "{:10x}", &[NextArgument(Argument { diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 913aeeca78beb..b2da51f8f38d2 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -26,7 +26,7 @@ use crate::edition::Edition; use crate::symbol::{kw, sym, Symbol}; -use crate::SESSION_GLOBALS; +use crate::with_session_globals; use crate::{BytePos, CachingSourceMapView, ExpnIdCache, SourceFile, Span, DUMMY_SP}; use crate::def_id::{CrateNum, DefId, DefPathHash, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -201,7 +201,7 @@ impl HygieneData { } pub fn with T>(f: F) -> T { - SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.hygiene_data.borrow_mut())) + with_session_globals(|session_globals| f(&mut *session_globals.hygiene_data.borrow_mut())) } fn fresh_expn(&mut self, mut expn_data: Option) -> ExpnId { @@ -1367,8 +1367,9 @@ fn update_disambiguator(expn_id: ExpnId) { } } - let source_map = SESSION_GLOBALS - .with(|session_globals| session_globals.source_map.borrow().as_ref().unwrap().clone()); + let source_map = with_session_globals(|session_globals| { + session_globals.source_map.borrow().as_ref().unwrap().clone() + }); let mut ctx = DummyHashStableContext { caching_source_map: CachingSourceMapView::new(&source_map) }; diff --git a/compiler/rustc_span/src/lev_distance/tests.rs b/compiler/rustc_span/src/lev_distance/tests.rs index 90e20afc8f538..11822e9ef9742 100644 --- a/compiler/rustc_span/src/lev_distance/tests.rs +++ b/compiler/rustc_span/src/lev_distance/tests.rs @@ -21,8 +21,8 @@ fn test_lev_distance() { #[test] fn test_find_best_match_for_name() { - use crate::with_default_session_globals; - with_default_session_globals(|| { + use crate::create_default_session_globals_then; + create_default_session_globals_then(|| { let input = vec![Symbol::intern("aaab"), Symbol::intern("aaabc")]; assert_eq!( find_best_match_for_name(&input, Symbol::intern("aaaa"), None), diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index a8c28c8e46949..3ddb10d2a06de 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -97,19 +97,65 @@ impl SessionGlobals { } } -pub fn with_session_globals(edition: Edition, f: impl FnOnce() -> R) -> R { +#[inline] +pub fn create_session_globals_then(edition: Edition, f: impl FnOnce() -> R) -> R { + assert!( + !SESSION_GLOBALS.is_set(), + "SESSION_GLOBALS should never be overwritten! \ + Use another thread if you need another SessionGlobals" + ); let session_globals = SessionGlobals::new(edition); SESSION_GLOBALS.set(&session_globals, f) } -pub fn with_default_session_globals(f: impl FnOnce() -> R) -> R { - with_session_globals(edition::DEFAULT_EDITION, f) +#[inline] +pub fn set_session_globals_then(session_globals: &SessionGlobals, f: impl FnOnce() -> R) -> R { + assert!( + !SESSION_GLOBALS.is_set(), + "SESSION_GLOBALS should never be overwritten! \ + Use another thread if you need another SessionGlobals" + ); + SESSION_GLOBALS.set(session_globals, f) +} + +#[inline] +pub fn create_default_session_if_not_set_then(f: F) -> R +where + F: FnOnce(&SessionGlobals) -> R, +{ + create_session_if_not_set_then(edition::DEFAULT_EDITION, f) +} + +#[inline] +pub fn create_session_if_not_set_then(edition: Edition, f: F) -> R +where + F: FnOnce(&SessionGlobals) -> R, +{ + if !SESSION_GLOBALS.is_set() { + let session_globals = SessionGlobals::new(edition); + SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f)) + } else { + SESSION_GLOBALS.with(f) + } +} + +#[inline] +pub fn with_session_globals(f: F) -> R +where + F: FnOnce(&SessionGlobals) -> R, +{ + SESSION_GLOBALS.with(f) +} + +#[inline] +pub fn create_default_session_globals_then(f: impl FnOnce() -> R) -> R { + create_session_globals_then(edition::DEFAULT_EDITION, f) } // If this ever becomes non thread-local, `decode_syntax_context` // and `decode_expn_id` will need to be updated to handle concurrent // deserialization. -scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals); +scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals); // FIXME: We should use this enum or something like it to get rid of the // use of magic `/rust/1.x/...` paths across the board. @@ -855,13 +901,13 @@ impl Decodable for Span { /// the `SourceMap` provided to this function. If that is not available, /// we fall back to printing the raw `Span` field values. pub fn with_source_map T>(source_map: Lrc, f: F) -> T { - SESSION_GLOBALS.with(|session_globals| { + with_session_globals(|session_globals| { *session_globals.source_map.borrow_mut() = Some(source_map); }); struct ClearSourceMap; impl Drop for ClearSourceMap { fn drop(&mut self) { - SESSION_GLOBALS.with(|session_globals| { + with_session_globals(|session_globals| { session_globals.source_map.borrow_mut().take(); }); } @@ -880,7 +926,7 @@ pub fn debug_with_source_map( } pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { - SESSION_GLOBALS.with(|session_globals| { + with_session_globals(|session_globals| { if let Some(source_map) = &*session_globals.source_map.borrow() { debug_with_source_map(span, f, source_map) } else { diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 5ea39b343b5c1..cb017709c6c7b 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -5,7 +5,6 @@ // See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28 use crate::hygiene::SyntaxContext; -use crate::SESSION_GLOBALS; use crate::{BytePos, SpanData}; use rustc_data_structures::fx::FxIndexSet; @@ -122,5 +121,5 @@ impl SpanInterner { // If an interner exists, return it. Otherwise, prepare a fresh one. #[inline] fn with_span_interner T>(f: F) -> T { - SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.span_interner.lock())) + crate::with_session_globals(|session_globals| f(&mut *session_globals.span_interner.lock())) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index be4f12c6d1cb8..a308d1efca1da 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -13,7 +13,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::str; -use crate::{Edition, Span, DUMMY_SP, SESSION_GLOBALS}; +use crate::{with_session_globals, Edition, Span, DUMMY_SP}; #[cfg(test)] mod tests; @@ -1790,7 +1790,7 @@ impl Ident { #[inline] fn with_interner T>(f: F) -> T { - SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock())) + with_session_globals(|session_globals| f(&mut *session_globals.symbol_interner.lock())) } /// An alternative to [`Symbol`], useful when the chars within the symbol need to diff --git a/compiler/rustc_span/src/symbol/tests.rs b/compiler/rustc_span/src/symbol/tests.rs index 47da03424b770..11dea265b4e66 100644 --- a/compiler/rustc_span/src/symbol/tests.rs +++ b/compiler/rustc_span/src/symbol/tests.rs @@ -1,6 +1,6 @@ use super::*; -use crate::{edition, SessionGlobals}; +use crate::create_default_session_globals_then; #[test] fn interner_tests() { @@ -18,7 +18,7 @@ fn interner_tests() { #[test] fn without_first_quote_test() { - SESSION_GLOBALS.set(&SessionGlobals::new(edition::DEFAULT_EDITION), || { + create_default_session_globals_then(|| { let i = Ident::from_str("'break"); assert_eq!(i.without_first_quote().name, kw::Break); }); diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 34b9cbcb6793a..275d1b3ebd938 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -2,8 +2,8 @@ use super::*; use rustc_ast::attr; use rustc_ast::Path; +use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::with_default_session_globals; use rustc_span::DUMMY_SP; fn word_cfg(s: &str) -> Cfg { @@ -52,7 +52,7 @@ macro_rules! dummy_meta_item_list { #[test] fn test_cfg_not() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { assert_eq!(!Cfg::False, Cfg::True); assert_eq!(!Cfg::True, Cfg::False); assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test")))); @@ -70,7 +70,7 @@ fn test_cfg_not() { #[test] fn test_cfg_and() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let mut x = Cfg::False; x &= Cfg::True; assert_eq!(x, Cfg::False); @@ -154,7 +154,7 @@ fn test_cfg_and() { #[test] fn test_cfg_or() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let mut x = Cfg::True; x |= Cfg::False; assert_eq!(x, Cfg::True); @@ -238,7 +238,7 @@ fn test_cfg_or() { #[test] fn test_parse_ok() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let mi = dummy_meta_item_word("all"); assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); @@ -271,7 +271,7 @@ fn test_parse_ok() { #[test] fn test_parse_err() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { let mi = attr::mk_name_value_item(Ident::from_str("foo"), LitKind::Bool(false), DUMMY_SP); assert!(Cfg::parse(&mi).is_err()); @@ -303,7 +303,7 @@ fn test_parse_err() { #[test] fn test_render_short_html() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { assert_eq!(word_cfg("unix").render_short_html(), "Unix"); assert_eq!(name_value_cfg("target_os", "macos").render_short_html(), "macOS"); assert_eq!(name_value_cfg("target_pointer_width", "16").render_short_html(), "16-bit"); @@ -358,7 +358,7 @@ fn test_render_short_html() { #[test] fn test_render_long_html() { - with_default_session_globals(|| { + create_default_session_globals_then(|| { assert_eq!( word_cfg("unix").render_long_html(), "This is supported on Unix only." @@ -442,7 +442,7 @@ fn test_render_long_html() { fn test_simplify_with() { // This is a tiny subset of things that could be simplified, but it likely covers 90% of // real world usecases well. - with_default_session_globals(|| { + create_default_session_globals_then(|| { let foo = word_cfg("foo"); let bar = word_cfg("bar"); let baz = word_cfg("baz"); diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 1281f76fd0fdc..cd914f05e680c 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -513,7 +513,7 @@ crate fn make_test( // Uses librustc_ast to parse the doctest and find if there's a main fn and the extern // crate already is included. let result = rustc_driver::catch_fatal_errors(|| { - rustc_span::with_session_globals(edition, || { + rustc_span::create_session_if_not_set_then(edition, |_| { use rustc_errors::emitter::{Emitter, EmitterWriter}; use rustc_errors::Handler; use rustc_parse::maybe_new_parser_from_source_str; diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs index a0da2c963d167..a505865b149c4 100644 --- a/src/librustdoc/html/highlight/tests.rs +++ b/src/librustdoc/html/highlight/tests.rs @@ -1,8 +1,8 @@ use super::write_code; use crate::html::format::Buffer; use expect_test::expect_file; +use rustc_span::create_default_session_globals_then; use rustc_span::edition::Edition; -use rustc_span::with_default_session_globals; const STYLE: &str = r#"