diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 207359ed6968f..024594517d988 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -4,16 +4,6 @@ //! heap allocation in Rust. Boxes provide ownership for this allocation, and //! drop their contents when they go out of scope. //! -//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for -//! its allocation. It is valid to convert both ways between a [`Box`] and a -//! raw pointer allocated with the [`Global`] allocator, given that the -//! [`Layout`] used with the allocator is correct for the type. More precisely, -//! a `value: *mut T` that has been allocated with the [`Global`] allocator -//! with `Layout::for_value(&*value)` may be converted into a box using -//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut -//! T` obtained from `Box::::into_raw` may be deallocated using the -//! [`Global`] allocator with `Layout::for_value(&*value)`. -//! //! # Examples //! //! Move a value from the stack to the heap by creating a [`Box`]: @@ -61,6 +51,19 @@ //! for a `Cons`. By introducing a `Box`, which has a defined size, we know how //! big `Cons` needs to be. //! +//! # Memory layout +//! +//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for +//! its allocation. It is valid to convert both ways between a [`Box`] and a +//! raw pointer allocated with the [`Global`] allocator, given that the +//! [`Layout`] used with the allocator is correct for the type. More precisely, +//! a `value: *mut T` that has been allocated with the [`Global`] allocator +//! with `Layout::for_value(&*value)` may be converted into a box using +//! `Box::::from_raw(value)`. Conversely, the memory backing a `value: *mut +//! T` obtained from `Box::::into_raw` may be deallocated using the +//! [`Global`] allocator with `Layout::for_value(&*value)`. +//! +//! //! [dereferencing]: ../../std/ops/trait.Deref.html //! [`Box`]: struct.Box.html //! [`Global`]: ../alloc/struct.Global.html @@ -127,24 +130,38 @@ impl Box { /// /// After calling this function, the raw pointer is owned by the /// resulting `Box`. Specifically, the `Box` destructor will call - /// the destructor of `T` and free the allocated memory. Since the - /// way `Box` allocates and releases memory is unspecified, the - /// only valid pointer to pass to this function is the one taken - /// from another `Box` via the [`Box::into_raw`] function. + /// the destructor of `T` and free the allocated memory. For this + /// to be safe, the memory must have been allocated in accordance + /// with the [memory layout] used by `Box` . + /// + /// # Safety /// /// This function is unsafe because improper use may lead to /// memory problems. For example, a double-free may occur if the /// function is called twice on the same raw pointer. /// - /// [`Box::into_raw`]: struct.Box.html#method.into_raw - /// /// # Examples - /// + /// Recreate a `Box` which was previously converted to a raw pointer + /// using [`Box::into_raw`]: /// ``` /// let x = Box::new(5); /// let ptr = Box::into_raw(x); /// let x = unsafe { Box::from_raw(ptr) }; /// ``` + /// Manually create a `Box` from scratch by using the global allocator: + /// ``` + /// use std::alloc::{alloc, Layout}; + /// + /// unsafe { + /// let ptr = alloc(Layout::new::()) as *mut i32; + /// *ptr = 5; + /// let x = Box::from_raw(ptr); + /// } + /// ``` + /// + /// [memory layout]: index.html#memory-layout + /// [`Layout`]: ../alloc/struct.Layout.html + /// [`Box::into_raw`]: struct.Box.html#method.into_raw #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { @@ -157,22 +174,40 @@ impl Box { /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the - /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to convert the raw pointer back into a - /// `Box` with the [`Box::from_raw`] function. + /// caller should properly destroy `T` and release the memory, taking + /// into account the [memory layout] used by `Box`. The easiest way to + /// do this is to convert the raw pointer back into a `Box` with the + /// [`Box::from_raw`] function, allowing the `Box` destructor to perform + /// the cleanup. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This /// is so that there is no conflict with a method on the inner type. /// - /// [`Box::from_raw`]: struct.Box.html#method.from_raw - /// /// # Examples - /// + /// Converting the raw pointer back into a `Box` with [`Box::from_raw`] + /// for automatic cleanup: /// ``` - /// let x = Box::new(5); + /// let x = Box::new(String::from("Hello")); /// let ptr = Box::into_raw(x); + /// let x = unsafe { Box::from_raw(ptr) }; + /// ``` + /// Manual cleanup by explicitly running the destructor and deallocating + /// the memory: /// ``` + /// use std::alloc::{dealloc, Layout}; + /// use std::ptr; + /// + /// let x = Box::new(String::from("Hello")); + /// let p = Box::into_raw(x); + /// unsafe { + /// ptr::drop_in_place(p); + /// dealloc(p as *mut u8, Layout::new::()); + /// } + /// ``` + /// + /// [memory layout]: index.html#memory-layout + /// [`Box::from_raw`]: struct.Box.html#method.from_raw #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *mut T { @@ -184,7 +219,7 @@ impl Box { /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to convert the `NonNull` pointer + /// easiest way to do so is to convert the `NonNull` pointer /// into a raw pointer and back into a `Box` with the [`Box::from_raw`] /// function. /// @@ -203,6 +238,10 @@ impl Box { /// fn main() { /// let x = Box::new(5); /// let ptr = Box::into_raw_non_null(x); + /// + /// // Clean up the memory by converting the NonNull pointer back + /// // into a Box and letting the Box be dropped. + /// let x = unsafe { Box::from_raw(ptr.as_ptr()) }; /// } /// ``` #[unstable(feature = "box_into_raw_non_null", issue = "47336")] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 24bee6355a7cc..56869f38a4f6b 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -466,7 +466,7 @@ pub unsafe fn zeroed() -> T { /// [`MaybeUninit`]: union.MaybeUninit.html /// [inv]: union.MaybeUninit.html#initialization-invariant #[inline] -#[rustc_deprecated(since = "1.40.0", reason = "use `mem::MaybeUninit` instead")] +#[rustc_deprecated(since = "1.38.0", reason = "use `mem::MaybeUninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { intrinsics::panic_if_uninhabited::(); diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 5c28d480571e9..1f25dba2915c4 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -6,7 +6,7 @@ use crate::ty::query::Providers; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_data_structures::indexed_vec::Idx; -use syntax_pos::Span; +use syntax_pos::{Span, sym}; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::hir; @@ -69,7 +69,7 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl<'a, 'tcx> ExprVisitor<'a, 'tcx> { fn def_id_is_transmute(&self, def_id: DefId) -> bool { self.tcx.fn_sig(def_id).abi() == RustIntrinsic && - self.tcx.item_name(def_id) == "transmute" + self.tcx.item_name(def_id) == sym::transmute } fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index b5e3c4cda0a66..f16137bd2c27a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1853,7 +1853,7 @@ pub fn rustc_optgroups() -> Vec { // Convert strings provided as --cfg [cfgspec] into a crate_cfg pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option)> { - syntax::with_globals(move || { + syntax::with_default_globals(move || { let cfg = cfgspecs.into_iter().map(|s| { let sess = parse::ParseSess::new(FilePathMapping::empty()); let filename = FileName::cfg_spec_source_code(&s); @@ -2735,7 +2735,7 @@ mod tests { // When the user supplies --test we should implicitly supply --cfg test #[test] fn test_switch_implies_cfg_test() { - syntax::with_globals(|| { + syntax::with_default_globals(|| { let matches = &match optgroups().parse(&["--test".to_string()]) { Ok(m) => m, Err(f) => panic!("test_switch_implies_cfg_test: {}", f), @@ -2753,7 +2753,7 @@ mod tests { #[test] fn test_switch_implies_cfg_test_unless_cfg_test() { use syntax::symbol::sym; - syntax::with_globals(|| { + syntax::with_default_globals(|| { let matches = &match optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]) { Ok(m) => m, @@ -2771,7 +2771,7 @@ mod tests { #[test] fn test_can_print_warnings() { - syntax::with_globals(|| { + syntax::with_default_globals(|| { let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap(); let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); @@ -2779,7 +2779,7 @@ mod tests { assert!(!sess.diagnostic().flags.can_emit_warnings); }); - syntax::with_globals(|| { + syntax::with_default_globals(|| { let matches = optgroups() .parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]) .unwrap(); @@ -2789,7 +2789,7 @@ mod tests { assert!(sess.diagnostic().flags.can_emit_warnings); }); - syntax::with_globals(|| { + syntax::with_default_globals(|| { let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap(); let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 7ba7429f465a6..f9ceeb5bfc01b 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -243,15 +243,15 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { // `{Self}` is allowed Position::ArgumentNamed(s) if s == "Self" => (), // `{ThisTraitsName}` is allowed - Position::ArgumentNamed(s) if s == name => (), + Position::ArgumentNamed(s) if s == name.as_str() => (), // `{from_method}` is allowed Position::ArgumentNamed(s) if s == "from_method" => (), // `{from_desugaring}` is allowed Position::ArgumentNamed(s) if s == "from_desugaring" => (), // So is `{A}` if A is a type parameter - Position::ArgumentNamed(s) => match generics.params.iter().find(|param| - param.name == s - ) { + Position::ArgumentNamed(s) => match generics.params.iter().find(|param| { + param.name.as_str() == s + }) { Some(_) => (), None => { span_err!(tcx.sess, span, E0230, @@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { Piece::NextArgument(a) => match a.position { Position::ArgumentNamed(s) => match generic_map.get(s) { Some(val) => val, - None if s == name => { + None if s == name.as_str() => { &trait_str } None => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 91e996178e7d5..b60ef557cb84f 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2981,9 +2981,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - pub fn item_name(self, id: DefId) -> InternedString { + pub fn item_name(self, id: DefId) -> Symbol { if id.index == CRATE_DEF_INDEX { - self.original_crate_name(id.krate).as_interned_str() + self.original_crate_name(id.krate) } else { let def_key = self.def_key(id); match def_key.disambiguated_data.data { @@ -2995,7 +2995,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }), _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { bug!("item_name: no name for {:?}", self.def_path(id)); - }), + }).as_symbol(), } } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 91b708d7dbe10..c18852a832fce 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1140,14 +1140,16 @@ impl PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> match *region { ty::ReEarlyBound(ref data) => { - data.name != "" && data.name != "'_" + data.name.as_symbol() != keywords::Invalid.name() && + data.name.as_symbol() != keywords::UnderscoreLifetime.name() } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { + if name.as_symbol() != keywords::Invalid.name() && + name.as_symbol() != keywords::UnderscoreLifetime.name() { return true; } } @@ -1203,7 +1205,7 @@ impl FmtPrinter<'_, '_, '_, F> { // `explain_region()` or `note_and_explain_region()`. match *region { ty::ReEarlyBound(ref data) => { - if data.name != "" { + if data.name.as_symbol() != keywords::Invalid.name() { p!(write("{}", data.name)); return Ok(self); } @@ -1212,7 +1214,8 @@ impl FmtPrinter<'_, '_, '_, F> { ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { + if name.as_symbol() != keywords::Invalid.name() && + name.as_symbol() != keywords::UnderscoreLifetime.name() { p!(write("{}", name)); return Ok(self); } diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 6931b3542f761..0c19d770194b2 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -14,7 +14,7 @@ use syntax::{ base::{ExtCtxt, Resolver}, build::AstBuilder, expand::ExpansionConfig, - hygiene::{self, Mark, SyntaxContext}, + hygiene::{Mark, SyntaxContext}, }, mut_visit::{self, MutVisitor}, parse::ParseSess, @@ -96,7 +96,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> { ].into()), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: self.sess.edition, }); // Tie the span to the macro expansion info we just created diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 13590faa12384..b000628a3f706 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -38,6 +38,7 @@ use rustc_data_structures::small_c_str::SmallCStr; use rustc_target::abi::HasDataLayout; use libc::{c_uint, c_longlong}; +use std::collections::hash_map::Entry; use std::ffi::CString; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; @@ -45,7 +46,7 @@ use std::iter; use std::ptr; use std::path::{Path, PathBuf}; use syntax::ast; -use syntax::symbol::{Interner, InternedString, Symbol}; +use syntax::symbol::{Interner, InternedString}; use syntax_pos::{self, Span, FileName}; impl PartialEq for llvm::Metadata { @@ -787,49 +788,48 @@ pub fn file_metadata(cx: &CodegenCx<'ll, '_>, file_name, defining_crate); - let file_name = &file_name.to_string(); - let file_name_symbol = Symbol::intern(file_name); - if defining_crate == LOCAL_CRATE { - let directory = &cx.sess().working_dir.0.to_string_lossy(); - file_metadata_raw(cx, file_name, Some(file_name_symbol), - directory, Some(Symbol::intern(directory))) + let file_name = Some(file_name.to_string()); + let directory = if defining_crate == LOCAL_CRATE { + Some(cx.sess().working_dir.0.to_string_lossy().to_string()) } else { // If the path comes from an upstream crate we assume it has been made // independent of the compiler's working directory one way or another. - file_metadata_raw(cx, file_name, Some(file_name_symbol), "", None) - } + None + }; + file_metadata_raw(cx, file_name, directory) } pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { - file_metadata_raw(cx, "", None, "", None) + file_metadata_raw(cx, None, None) } fn file_metadata_raw(cx: &CodegenCx<'ll, '_>, - file_name: &str, - file_name_symbol: Option, - directory: &str, - directory_symbol: Option) + file_name: Option, + directory: Option) -> &'ll DIFile { - let key = (file_name_symbol, directory_symbol); + let key = (file_name, directory); + + match debug_context(cx).created_files.borrow_mut().entry(key) { + Entry::Occupied(o) => return o.get(), + Entry::Vacant(v) => { + let (file_name, directory) = v.key(); + debug!("file_metadata: file_name: {:?}, directory: {:?}", file_name, directory); + + let file_name = SmallCStr::new( + if let Some(file_name) = file_name { &file_name } else { "" }); + let directory = SmallCStr::new( + if let Some(directory) = directory { &directory } else { "" }); + + let file_metadata = unsafe { + llvm::LLVMRustDIBuilderCreateFile(DIB(cx), + file_name.as_ptr(), + directory.as_ptr()) + }; - if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) { - return *file_metadata; + v.insert(file_metadata); + file_metadata + } } - - debug!("file_metadata: file_name: {}, directory: {}", file_name, directory); - - let file_name = SmallCStr::new(file_name); - let directory = SmallCStr::new(directory); - - let file_metadata = unsafe { - llvm::LLVMRustDIBuilderCreateFile(DIB(cx), - file_name.as_ptr(), - directory.as_ptr()) - }; - - let mut created_files = debug_context(cx).created_files.borrow_mut(); - created_files.insert(key, file_metadata); - file_metadata } fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index f3070a03b4ed5..527290392fff4 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -37,7 +37,7 @@ use std::ffi::CString; use syntax_pos::{self, Span, Pos}; use syntax::ast; -use syntax::symbol::{Symbol, InternedString}; +use syntax::symbol::InternedString; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; use rustc_codegen_ssa::traits::*; @@ -63,7 +63,7 @@ pub struct CrateDebugContext<'a, 'tcx> { llcontext: &'a llvm::Context, llmod: &'a llvm::Module, builder: &'a mut DIBuilder<'a>, - created_files: RefCell, Option), &'a DIFile>>, + created_files: RefCell, Option), &'a DIFile>>, created_enum_disr_types: RefCell>, type_map: RefCell>, diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 6915687ceba93..1a8647ed197b5 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -264,7 +264,7 @@ fn compute_symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> return name.as_interned_str(); } // Don't mangle foreign items. - return tcx.item_name(def_id); + return tcx.item_name(def_id).as_interned_str(); } if let Some(name) = &attrs.export_name { @@ -274,7 +274,7 @@ fn compute_symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { // Don't mangle - return tcx.item_name(def_id); + return tcx.item_name(def_id).as_interned_str(); } // We want to compute the "type" of this item. Unfortunately, some diff --git a/src/librustc_data_structures/macros.rs b/src/librustc_data_structures/macros.rs index 7fc23999284a7..b851263aaf9c4 100644 --- a/src/librustc_data_structures/macros.rs +++ b/src/librustc_data_structures/macros.rs @@ -1,13 +1,12 @@ -/// A simple static assertion macro. The first argument should be a unique -/// ALL_CAPS identifier that describes the condition. +/// A simple static assertion macro. #[macro_export] -#[allow_internal_unstable(type_ascription)] +#[allow_internal_unstable(type_ascription, underscore_const_names)] macro_rules! static_assert { - ($name:ident: $test:expr) => { + ($test:expr) => { // Use the bool to access an array such that if the bool is false, the access // is out-of-bounds. #[allow(dead_code)] - static $name: () = [()][!($test: bool) as usize]; + const _: () = [()][!($test: bool) as usize]; } } diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index f2a21d61aed4a..674b2b60e44a2 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -18,6 +18,7 @@ use std::result; use std::sync::{Arc, Mutex}; use syntax; use syntax::source_map::{FileLoader, SourceMap}; +use syntax_pos::edition; pub type Result = result::Result; @@ -135,16 +136,17 @@ where { let stderr = config.stderr.take(); util::spawn_thread_pool( + config.opts.edition, config.opts.debugging_opts.threads, &stderr, || run_compiler_in_existing_thread_pool(config, f), ) } -pub fn default_thread_pool(f: F) -> R +pub fn default_thread_pool(edition: edition::Edition, f: F) -> R where F: FnOnce() -> R + Send, R: Send, { - util::spawn_thread_pool(None, &None, f) + util::spawn_thread_pool(edition, None, &None, f) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index c5ac8860ccd9b..04041f8834420 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -48,7 +48,7 @@ use syntax::util::node_count::NodeCounter; use syntax::util::lev_distance::find_best_match_for_name; use syntax::symbol::Symbol; use syntax::feature_gate::AttributeType; -use syntax_pos::{FileName, hygiene}; +use syntax_pos::{FileName, edition::Edition, hygiene}; use syntax_ext; use serialize::json; @@ -70,8 +70,6 @@ use std::ops::Generator; pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { sess.diagnostic() .set_continue_after_error(sess.opts.debugging_opts.continue_parse_after_error); - hygiene::set_default_edition(sess.edition()); - sess.profiler(|p| p.start_activity("parsing")); let krate = time(sess, "parsing", || match *input { Input::File(ref file) => parse::parse_crate_from_file(file, &sess.parse_sess), @@ -375,7 +373,7 @@ fn configure_and_expand_inner<'a>( crate_loader, &resolver_arenas, ); - syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts); + syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts, sess.edition()); // Expand all macros sess.profiler(|p| p.start_activity("macro expansion")); diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index d2d0d19180783..09bb547191f49 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -37,6 +37,7 @@ use syntax::util::lev_distance::find_best_match_for_name; use syntax::source_map::{FileLoader, RealFileLoader, SourceMap}; use syntax::symbol::{Symbol, sym}; use syntax::{self, ast, attr}; +use syntax_pos::edition::Edition; #[cfg(not(parallel_compiler))] use std::{thread, panic}; @@ -167,6 +168,7 @@ pub fn scoped_thread R + Send, R: Send>(cfg: thread::Builder, f: #[cfg(not(parallel_compiler))] pub fn spawn_thread_pool R + Send, R: Send>( + edition: Edition, _threads: Option, stderr: &Option>>>, f: F, @@ -178,7 +180,7 @@ pub fn spawn_thread_pool R + Send, R: Send>( } scoped_thread(cfg, || { - syntax::with_globals( || { + syntax::with_globals(edition, || { ty::tls::GCX_PTR.set(&Lock::new(0), || { if let Some(stderr) = stderr { io::set_panic(Some(box Sink(stderr.clone()))); @@ -191,6 +193,7 @@ pub fn spawn_thread_pool R + Send, R: Send>( #[cfg(parallel_compiler)] pub fn spawn_thread_pool R + Send, R: Send>( + edition: Edition, threads: Option, stderr: &Option>>>, f: F, @@ -213,7 +216,7 @@ pub fn spawn_thread_pool R + Send, R: Send>( let with_pool = move |pool: &ThreadPool| pool.install(move || f()); - syntax::with_globals(|| { + syntax::with_globals(edition, || { syntax::GLOBALS.with(|syntax_globals| { syntax_pos::GLOBALS.with(|syntax_pos_globals| { // The main handler runs for each Rayon worker thread and sets up diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index af4f1b88b0fb0..d17a92efb066b 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -929,7 +929,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { fn def_id_is_transmute(cx: &LateContext<'_, '_>, def_id: DefId) -> bool { cx.tcx.fn_sig(def_id).abi() == RustIntrinsic && - cx.tcx.item_name(def_id) == "transmute" + cx.tcx.item_name(def_id) == sym::transmute } } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 087256a971056..2070a38b7b85d 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -355,20 +355,20 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { return; } - let child = child.res.def_id(); - - match visible_parent_map.entry(child) { - Entry::Occupied(mut entry) => { - // If `child` is defined in crate `cnum`, ensure - // that it is mapped to a parent in `cnum`. - if child.krate == cnum && entry.get().krate != cnum { + if let Some(child) = child.res.opt_def_id() { + match visible_parent_map.entry(child) { + Entry::Occupied(mut entry) => { + // If `child` is defined in crate `cnum`, ensure + // that it is mapped to a parent in `cnum`. + if child.krate == cnum && entry.get().krate != cnum { + entry.insert(parent); + } + } + Entry::Vacant(entry) => { entry.insert(parent); + bfs_queue.push_back(child); } } - Entry::Vacant(entry) => { - entry.insert(parent); - bfs_queue.push_back(child); - } } }; @@ -432,7 +432,7 @@ impl cstore::CStore { let data = self.get_crate_data(id.krate); if let Some(ref proc_macros) = data.proc_macros { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); - } else if data.name == sym::proc_macro && data.item_name(id.index) == "quote" { + } else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote { use syntax::ext::base::SyntaxExtension; use syntax_ext::proc_macro_impl::BangProcMacro; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index d882fe6f27ecc..d2ba82b5a1c9f 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -29,7 +29,7 @@ use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; use syntax::attr; use syntax::ast::{self, Ident}; use syntax::source_map; -use syntax::symbol::{InternedString, sym}; +use syntax::symbol::{Symbol, sym}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::hygiene::Mark; use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION}; @@ -497,12 +497,13 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn item_name(&self, item_index: DefIndex) -> InternedString { + pub fn item_name(&self, item_index: DefIndex) -> Symbol { self.def_key(item_index) .disambiguated_data .data .get_opt_name() .expect("no name in item_name") + .as_symbol() } pub fn def_kind(&self, index: DefIndex) -> Option { @@ -568,7 +569,7 @@ impl<'a, 'tcx> CrateMetadata { ty::VariantDef::new( tcx, - Ident::from_interned_str(self.item_name(index)), + Ident::with_empty_ctxt(self.item_name(index)), variant_did, ctor_did, data.discr, @@ -576,7 +577,7 @@ impl<'a, 'tcx> CrateMetadata { let f = self.entry(index); ty::FieldDef { did: self.local_def_id(index), - ident: Ident::from_interned_str(self.item_name(index)), + ident: Ident::with_empty_ctxt(self.item_name(index)), vis: f.visibility.decode(self) } }).collect(), @@ -787,7 +788,7 @@ impl<'a, 'tcx> CrateMetadata { if let Some(kind) = self.def_kind(child_index) { callback(def::Export { res: Res::Def(kind, self.local_def_id(child_index)), - ident: Ident::from_interned_str(self.item_name(child_index)), + ident: Ident::with_empty_ctxt(self.item_name(child_index)), vis: self.get_visibility(child_index), span: self.entry(child_index).span.decode((self, sess)), }); @@ -982,7 +983,7 @@ impl<'a, 'tcx> CrateMetadata { self.entry(id) .children .decode(self) - .map(|index| self.item_name(index).as_symbol()) + .map(|index| self.item_name(index)) .collect() } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 939aadcc9ec9b..7f0993e799f54 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -34,7 +34,7 @@ use syntax::ast; use syntax::attr; use syntax::source_map::Spanned; use syntax::symbol::{keywords, sym}; -use syntax_pos::{self, hygiene, FileName, SourceFile, Span}; +use syntax_pos::{self, FileName, SourceFile, Span}; use log::{debug, trace}; use rustc::hir::{self, PatKind}; @@ -480,7 +480,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hash: tcx.crate_hash(LOCAL_CRATE), disambiguator: tcx.sess.local_crate_disambiguator(), panic_strategy: tcx.sess.panic_strategy(), - edition: hygiene::default_edition(), + edition: tcx.sess.edition(), has_global_allocator: has_global_allocator, has_panic_handler: has_panic_handler, has_default_lib_allocator: has_default_lib_allocator, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 5bd3a1714887d..b9224d973fe7b 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -10,7 +10,7 @@ use rustc::ty::query::Providers; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_target::spec::abi::Abi; -use syntax_pos::Span; +use syntax_pos::{Span, sym}; use std::fmt; use std::iter; @@ -100,9 +100,9 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } ty::InstanceDef::CloneShim(def_id, ty) => { let name = tcx.item_name(def_id); - if name == "clone" { + if name == sym::clone { build_clone_shim(tcx, def_id, ty) - } else if name == "clone_from" { + } else if name == sym::clone_from { debug!("make_shim({:?}: using default trait implementation", instance); return tcx.optimized_mir(def_id); } else { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index d2da1e6e3ac9d..780b3c9686b6a 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -212,8 +212,8 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> { // Create a statement which reads the discriminant into a temporary fn get_discr(&self, mir: &mut Mir<'tcx>) -> (Statement<'tcx>, Place<'tcx>) { let temp_decl = LocalDecl::new_internal(self.tcx.types.isize, mir.span); - let temp = Place::Base(PlaceBase::Local(Local::new(mir.local_decls.len()))); - mir.local_decls.push(temp_decl); + let local_decls_len = mir.local_decls.push(temp_decl); + let temp = Place::Base(PlaceBase::Local(local_decls_len)); let self_place = Place::Base(PlaceBase::Local(self_arg())); let assign = Statement { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 579f75ba51657..84e2caec68e1c 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -544,14 +544,14 @@ impl Qualif for IsNotImplicitlyPromotable { // Ensure the `IDX` values are sequential (`0..QUALIF_COUNT`). macro_rules! static_assert_seq_qualifs { ($i:expr => $first:ident $(, $rest:ident)*) => { - static_assert!(SEQ_QUALIFS: { + static_assert!({ static_assert_seq_qualifs!($i + 1 => $($rest),*); $first::IDX == $i }); }; ($i:expr =>) => { - static_assert!(SEQ_QUALIFS: QUALIF_COUNT == $i); + static_assert!(QUALIF_COUNT == $i); }; } static_assert_seq_qualifs!( diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 815821f6ff033..7d2dbff996d08 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -223,7 +223,7 @@ fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let ty::FnDef(def_id, _) = func.ty.sty { let abi = tcx.fn_sig(def_id).abi(); let name = tcx.item_name(def_id); - if abi == Abi::RustIntrinsic && name == "rustc_peek" { + if abi == Abi::RustIntrinsic && name == sym::rustc_peek { return Some((args, source_info.span)); } } diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index c2d1d5fa65af2..2ed6f868fa1ee 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -6,7 +6,6 @@ use rustc::util::nodemap::FxHashMap; use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT}; use syntax::ext::base::MacroExpanderFn; -use syntax::ext::hygiene; use syntax::symbol::{Symbol, sym}; use syntax::ast; use syntax::feature_gate::AttributeType; @@ -130,7 +129,7 @@ impl<'a> Registry<'a> { allow_internal_unsafe: false, local_inner_macros: false, unstable_feature: None, - edition: hygiene::default_edition(), + edition: self.sess.edition(), }); } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e34a33ef8fad9..d07f7b65275f1 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -17,7 +17,7 @@ use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; -use syntax::ext::hygiene::{self, Mark}; +use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{ feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES, @@ -1100,7 +1100,7 @@ impl<'a> Resolver<'a> { let def_id = self.definitions.local_def_id(item.id); let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess, &self.session.features_untracked(), - item, hygiene::default_edition())); + item, self.session.edition())); self.macro_map.insert(def_id, ext); let def = match item.node { ast::ItemKind::MacroDef(ref def) => def, _ => unreachable!() }; diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 61399e0568cb1..67113787915a3 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -418,7 +418,7 @@ mod test { use syntax::attr; use syntax::source_map::dummy_spanned; use syntax::symbol::Symbol; - use syntax::with_globals; + use syntax::with_default_globals; fn word_cfg(s: &str) -> Cfg { Cfg::Cfg(Symbol::intern(s), None) @@ -466,7 +466,7 @@ mod test { #[test] fn test_cfg_not() { - with_globals(|| { + with_default_globals(|| { assert_eq!(!Cfg::False, Cfg::True); assert_eq!(!Cfg::True, Cfg::False); assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test")))); @@ -484,7 +484,7 @@ mod test { #[test] fn test_cfg_and() { - with_globals(|| { + with_default_globals(|| { let mut x = Cfg::False; x &= Cfg::True; assert_eq!(x, Cfg::False); @@ -536,7 +536,7 @@ mod test { #[test] fn test_cfg_or() { - with_globals(|| { + with_default_globals(|| { let mut x = Cfg::True; x |= Cfg::False; assert_eq!(x, Cfg::True); @@ -588,7 +588,7 @@ mod test { #[test] fn test_parse_ok() { - with_globals(|| { + with_default_globals(|| { let mi = dummy_meta_item_word("all"); assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); @@ -622,7 +622,7 @@ mod test { #[test] fn test_parse_err() { - with_globals(|| { + with_default_globals(|| { let mi = attr::mk_name_value_item( DUMMY_SP, Ident::from_str("foo"), @@ -661,7 +661,7 @@ mod test { #[test] fn test_render_short_html() { - with_globals(|| { + with_default_globals(|| { assert_eq!( word_cfg("unix").render_short_html(), "Unix" @@ -741,7 +741,7 @@ mod test { #[test] fn test_render_long_html() { - with_globals(|| { + with_default_globals(|| { assert_eq!( word_cfg("unix").render_long_html(), "This is supported on Unix only." diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e434623d4a127..6d03a5ad63bbb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1702,7 +1702,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind { ty::GenericParamDefKind::Lifetime => None, ty::GenericParamDefKind::Type { .. } => { - if param.name == keywords::SelfUpper.name().as_str() { + if param.name.as_symbol() == keywords::SelfUpper.name() { assert_eq!(param.index, 0); return None; } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f5061b671828e..ffe277ae50bdc 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -94,9 +94,7 @@ pub fn main() { rustc_driver::set_sigpipe_handler(); env_logger::init(); let res = std::thread::Builder::new().stack_size(thread_stack_size).spawn(move || { - rustc_interface::interface::default_thread_pool(move || { - get_args().map(|args| main_args(&args)).unwrap_or(1) - }) + get_args().map(|args| main_args(&args)).unwrap_or(1) }).unwrap().join().unwrap_or(rustc_driver::EXIT_FAILURE); process::exit(res); } @@ -382,7 +380,12 @@ fn main_args(args: &[String]) -> i32 { Ok(opts) => opts, Err(code) => return code, }; + rustc_interface::interface::default_thread_pool(options.edition, move || { + main_options(options) + }) +} +fn main_options(options: config::Options) -> i32 { let diag = core::new_handler(options.error_format, None, options.debugging_options.treat_err_as_bug, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0cc99da64079c..d76d4380755f2 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -8,6 +8,7 @@ use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions}; use rustc::session::search_paths::SearchPath; use rustc::util::common::ErrorReported; use syntax::ast; +use syntax::with_globals; use syntax::source_map::SourceMap; use syntax::edition::Edition; use syntax::feature_gate::UnstableFeatures; @@ -386,13 +387,11 @@ pub fn make_test(s: &str, // Uses libsyntax to parse the doctest and find if there's a main fn and the extern // crate already is included. - let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| { + let (already_has_main, already_has_extern_crate, found_macro) = with_globals(edition, || { use crate::syntax::{parse::{self, ParseSess}, source_map::FilePathMapping}; use errors::emitter::EmitterWriter; use errors::Handler; - syntax::ext::hygiene::set_default_edition(edition); - let filename = FileName::anon_source_code(s); let source = crates + &everything_else; diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 8e6f50773abfe..2a553b2c93bd3 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -150,7 +150,7 @@ impl Command { match cvt(syscall::clone(0))? { 0 => { drop(input); - let err = self.do_exec(theirs); + let Err(err) = self.do_exec(theirs); let errno = err.raw_os_error().unwrap_or(syscall::EINVAL) as u32; let bytes = [ (errno >> 24) as u8, @@ -218,7 +218,10 @@ impl Command { } match self.setup_io(default, true) { - Ok((_, theirs)) => unsafe { self.do_exec(theirs) }, + Ok((_, theirs)) => unsafe { + let Err(e) = self.do_exec(theirs); + e + }, Err(e) => e, } } @@ -253,45 +256,38 @@ impl Command { // allocation). Instead we just close it manually. This will never // have the drop glue anyway because this code never returns (the // child will either exec() or invoke syscall::exit) - unsafe fn do_exec(&mut self, stdio: ChildPipes) -> io::Error { - macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => return e, - }) - } - + unsafe fn do_exec(&mut self, stdio: ChildPipes) -> Result { if let Some(fd) = stdio.stderr.fd() { - t!(cvt(syscall::dup2(fd, 2, &[]))); - let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFD, 0))); + cvt(syscall::dup2(fd, 2, &[]))?; + let mut flags = cvt(syscall::fcntl(2, syscall::F_GETFD, 0))?; flags &= ! syscall::O_CLOEXEC; - t!(cvt(syscall::fcntl(2, syscall::F_SETFD, flags))); + cvt(syscall::fcntl(2, syscall::F_SETFD, flags))?; } if let Some(fd) = stdio.stdout.fd() { - t!(cvt(syscall::dup2(fd, 1, &[]))); - let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFD, 0))); + cvt(syscall::dup2(fd, 1, &[]))?; + let mut flags = cvt(syscall::fcntl(1, syscall::F_GETFD, 0))?; flags &= ! syscall::O_CLOEXEC; - t!(cvt(syscall::fcntl(1, syscall::F_SETFD, flags))); + cvt(syscall::fcntl(1, syscall::F_SETFD, flags))?; } if let Some(fd) = stdio.stdin.fd() { - t!(cvt(syscall::dup2(fd, 0, &[]))); - let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFD, 0))); + cvt(syscall::dup2(fd, 0, &[]))?; + let mut flags = cvt(syscall::fcntl(0, syscall::F_GETFD, 0))?; flags &= ! syscall::O_CLOEXEC; - t!(cvt(syscall::fcntl(0, syscall::F_SETFD, flags))); + cvt(syscall::fcntl(0, syscall::F_SETFD, flags))?; } if let Some(g) = self.gid { - t!(cvt(syscall::setregid(g as usize, g as usize))); + cvt(syscall::setregid(g as usize, g as usize))?; } if let Some(u) = self.uid { - t!(cvt(syscall::setreuid(u as usize, u as usize))); + cvt(syscall::setreuid(u as usize, u as usize))?; } if let Some(ref cwd) = self.cwd { - t!(cvt(syscall::chdir(cwd))); + cvt(syscall::chdir(cwd))?; } for callback in self.closures.iter_mut() { - t!(callback()); + callback()?; } self.env.apply(); @@ -313,9 +309,9 @@ impl Command { }; let mut file = if let Some(program) = program { - t!(File::open(program.as_os_str())) + File::open(program.as_os_str())? } else { - return io::Error::from_raw_os_error(syscall::ENOENT); + return Err(io::Error::from_raw_os_error(syscall::ENOENT)); }; // Push all the arguments @@ -327,7 +323,7 @@ impl Command { let mut shebang = [0; 2]; let mut read = 0; loop { - match t!(reader.read(&mut shebang[read..])) { + match reader.read(&mut shebang[read..])? { 0 => break, n => read += n, } @@ -338,9 +334,9 @@ impl Command { // First of all, since we'll be passing another file to // fexec(), we need to manually check that we have permission // to execute this file: - let uid = t!(cvt(syscall::getuid())); - let gid = t!(cvt(syscall::getgid())); - let meta = t!(file.metadata()); + let uid = cvt(syscall::getuid())?; + let gid = cvt(syscall::getgid())?; + let meta = file.metadata()?; let mode = if uid == meta.uid() as usize { meta.mode() >> 3*2 & 0o7 @@ -350,12 +346,12 @@ impl Command { meta.mode() & 0o7 }; if mode & 1 == 0 { - return io::Error::from_raw_os_error(syscall::EPERM); + return Err(io::Error::from_raw_os_error(syscall::EPERM)); } // Second of all, we need to actually read which interpreter it wants let mut interpreter = Vec::new(); - t!(reader.read_until(b'\n', &mut interpreter)); + reader.read_until(b'\n', &mut interpreter)?; // Pop one trailing newline, if any if interpreter.ends_with(&[b'\n']) { interpreter.pop().unwrap(); @@ -373,11 +369,11 @@ impl Command { }; if let Some(ref interpreter) = interpreter { let path: &OsStr = OsStr::from_bytes(&interpreter); - file = t!(File::open(path)); + file = File::open(path)?; args.push([interpreter.as_ptr() as usize, interpreter.len()]); } else { - t!(file.seek(SeekFrom::Start(0))); + file.seek(SeekFrom::Start(0))?; } args.push([self.program.as_ptr() as usize, self.program.len()]); @@ -396,13 +392,12 @@ impl Command { } if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) { - io::Error::from_raw_os_error(err.errno as i32) + Err(io::Error::from_raw_os_error(err.errno as i32)) } else { panic!("return from exec without err"); } } - fn setup_io(&self, default: Stdio, needs_stdin: bool) -> io::Result<(StdioPipes, ChildPipes)> { let null = Stdio::Null; diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 220b1fd453131..80fe763aecc88 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -47,7 +47,7 @@ impl Command { match result { 0 => { drop(input); - let err = self.do_exec(theirs, envp.as_ref()); + let Err(err) = self.do_exec(theirs, envp.as_ref()); let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; let bytes = [ (errno >> 24) as u8, @@ -123,7 +123,8 @@ impl Command { // environment lock before we try to exec. let _lock = sys::os::env_lock(); - self.do_exec(theirs, envp.as_ref()) + let Err(e) = self.do_exec(theirs, envp.as_ref()); + e } } Err(e) => e, @@ -164,29 +165,22 @@ impl Command { &mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray> - ) -> io::Error { + ) -> Result { use crate::sys::{self, cvt_r}; - macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => return e, - }) - } - if let Some(fd) = stdio.stdin.fd() { - t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))); + cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?; } if let Some(fd) = stdio.stdout.fd() { - t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))); + cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?; } if let Some(fd) = stdio.stderr.fd() { - t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))); + cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?; } if cfg!(not(any(target_os = "l4re"))) { if let Some(u) = self.get_gid() { - t!(cvt(libc::setgid(u as gid_t))); + cvt(libc::setgid(u as gid_t))?; } if let Some(u) = self.get_uid() { // When dropping privileges from root, the `setgroups` call @@ -198,11 +192,11 @@ impl Command { // privilege dropping function. let _ = libc::setgroups(0, ptr::null()); - t!(cvt(libc::setuid(u as uid_t))); + cvt(libc::setuid(u as uid_t))?; } } if let Some(ref cwd) = *self.get_cwd() { - t!(cvt(libc::chdir(cwd.as_ptr()))); + cvt(libc::chdir(cwd.as_ptr()))?; } // emscripten has no signal support. @@ -225,18 +219,18 @@ impl Command { 0, mem::size_of::()); } else { - t!(cvt(libc::sigemptyset(&mut set))); + cvt(libc::sigemptyset(&mut set))?; } - t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, - ptr::null_mut()))); + cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, + ptr::null_mut()))?; let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL); if ret == libc::SIG_ERR { - return io::Error::last_os_error() + return Err(io::Error::last_os_error()) } } for callback in self.get_closures().iter_mut() { - t!(callback()); + callback()?; } // Although we're performing an exec here we may also return with an @@ -261,7 +255,7 @@ impl Command { } libc::execvp(self.get_argv()[0], self.get_argv().as_ptr()); - io::Error::last_os_error() + Err(io::Error::last_os_error()) } #[cfg(not(any(target_os = "macos", target_os = "freebsd", diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 0a88d2f8824d3..489fac4f1ca4c 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -5,7 +5,7 @@ use crate::attr::HasAttrs; use crate::source_map::{SourceMap, Spanned, respan}; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; -use crate::ext::hygiene::{self, Mark, SyntaxContext, Transparency}; +use crate::ext::hygiene::{Mark, SyntaxContext, Transparency}; use crate::mut_visit::{self, MutVisitor}; use crate::parse::{self, parser, DirectoryOwnership}; use crate::parse::token; @@ -713,7 +713,7 @@ impl SyntaxExtension { } } - pub fn edition(&self) -> Edition { + pub fn edition(&self, default_edition: Edition) -> Edition { match *self { SyntaxExtension::NormalTT { edition, .. } | SyntaxExtension::DeclMacro { edition, .. } | @@ -725,7 +725,7 @@ impl SyntaxExtension { SyntaxExtension::IdentTT { .. } | SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | - SyntaxExtension::BuiltinDerive(..) => hygiene::default_edition(), + SyntaxExtension::BuiltinDerive(..) => default_edition, } } } @@ -734,6 +734,7 @@ pub type NamedSyntaxExtension = (Name, SyntaxExtension); pub trait Resolver { fn next_node_id(&mut self) -> ast::NodeId; + fn get_module_scope(&mut self, id: ast::NodeId) -> Mark; fn resolve_dollar_crates(&mut self, fragment: &AstFragment); @@ -768,6 +769,7 @@ pub struct DummyResolver; impl Resolver for DummyResolver { fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID } + fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() } fn resolve_dollar_crates(&mut self, _fragment: &AstFragment) {} diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index a24e09f127eae..6e789c4c7086b 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -1,6 +1,6 @@ use crate::attr::HasAttrs; use crate::ast; -use crate::source_map::{hygiene, ExpnInfo, ExpnFormat}; +use crate::source_map::{ExpnInfo, ExpnFormat}; use crate::ext::base::ExtCtxt; use crate::ext::build::AstBuilder; use crate::parse::parser::PathStyle; @@ -64,7 +64,7 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P ].into()), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: cx.parse_sess.edition, }); let span = span.with_ctxt(cx.backtrace()); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 019ebc8566ff8..478ae4de82b74 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -5,7 +5,7 @@ use crate::source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, resp use crate::config::StripUnconfigured; use crate::ext::base::*; use crate::ext::derive::{add_derived_markers, collect_derives}; -use crate::ext::hygiene::{self, Mark, SyntaxContext}; +use crate::ext::hygiene::{Mark, SyntaxContext}; use crate::ext::placeholders::{placeholder, PlaceholderExpander}; use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; use crate::mut_visit::*; @@ -560,7 +560,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, - edition: ext.edition(), + edition: ext.edition(self.cx.parse_sess.edition), }); match *ext { @@ -805,7 +805,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { allow_internal_unstable: allow_internal_unstable.clone(), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: self.cx.parse_sess.edition, }); let input: Vec<_> = mac.node.stream().into_trees().collect(); @@ -921,7 +921,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, - edition: ext.edition(), + edition: ext.edition(self.cx.parse_sess.edition), }; match *ext { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index db10ab7af5a72..5eda975bc9ee4 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -29,6 +29,7 @@ use rustc_data_structures::sync::Lock; use rustc_data_structures::bit_set::GrowableBitSet; pub use rustc_data_structures::thin_vec::ThinVec; use ast::AttrId; +use syntax_pos::edition::Edition; // A variant of 'try!' that panics on an Err. This is used as a crutch on the // way towards a non-panic!-prone parser. It should be used for fatal parsing @@ -82,26 +83,32 @@ pub struct Globals { } impl Globals { - fn new() -> Globals { + fn new(edition: Edition) -> Globals { Globals { // We have no idea how many attributes their will be, so just // initiate the vectors with 0 bits. We'll grow them as necessary. used_attrs: Lock::new(GrowableBitSet::new_empty()), known_attrs: Lock::new(GrowableBitSet::new_empty()), - syntax_pos_globals: syntax_pos::Globals::new(), + syntax_pos_globals: syntax_pos::Globals::new(edition), } } } -pub fn with_globals(f: F) -> R +pub fn with_globals(edition: Edition, f: F) -> R where F: FnOnce() -> R { - let globals = Globals::new(); + let globals = Globals::new(edition); GLOBALS.set(&globals, || { syntax_pos::GLOBALS.set(&globals.syntax_pos_globals, f) }) } +pub fn with_default_globals(f: F) -> R + where F: FnOnce() -> R +{ + with_globals(edition::DEFAULT_EDITION, f) +} + scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals); #[macro_use] diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index f587e63e12b94..8fdd15a029f13 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -1305,7 +1305,7 @@ mod tests { use crate::util::parser_testing::{string_to_crate, matches_codepattern}; use crate::print::pprust; use crate::mut_visit; - use crate::with_globals; + use crate::with_default_globals; use super::*; // this version doesn't care about getting comments or docstrings in. @@ -1343,7 +1343,7 @@ mod tests { // make sure idents get transformed everywhere #[test] fn ident_transformation () { - with_globals(|| { + with_default_globals(|| { 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()); @@ -1358,7 +1358,7 @@ mod tests { // even inside macro defs.... #[test] fn ident_transformation_in_defs () { - with_globals(|| { + with_default_globals(|| { let mut zz_visitor = ToZzIdentMutVisitor; let mut krate = string_to_crate( "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 47da3ee6a6c78..c97d804076157 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1558,10 +1558,10 @@ mod tests { use crate::feature_gate::UnstableFeatures; use crate::parse::token; use crate::diagnostics::plugin::ErrorMap; - use crate::with_globals; + use crate::with_default_globals; use std::io; use std::path::PathBuf; - use syntax_pos::{BytePos, Span, NO_EXPANSION}; + use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_data_structures::sync::Lock; @@ -1581,6 +1581,7 @@ mod tests { raw_identifier_spans: Lock::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), buffered_lints: Lock::new(vec![]), + edition: Edition::from_session(), ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), } } @@ -1601,7 +1602,7 @@ mod tests { #[test] fn t1() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); let mut string_reader = setup(&sm, @@ -1649,7 +1650,7 @@ mod tests { #[test] fn doublecolonparsing() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); check_tokenization(setup(&sm, &sh, "a b".to_string()), @@ -1659,7 +1660,7 @@ mod tests { #[test] fn dcparsing_2() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); check_tokenization(setup(&sm, &sh, "a::b".to_string()), @@ -1669,7 +1670,7 @@ mod tests { #[test] fn dcparsing_3() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); check_tokenization(setup(&sm, &sh, "a ::b".to_string()), @@ -1679,7 +1680,7 @@ mod tests { #[test] fn dcparsing_4() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); check_tokenization(setup(&sm, &sh, "a:: b".to_string()), @@ -1689,7 +1690,7 @@ mod tests { #[test] fn character_a() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token().tok, @@ -1699,7 +1700,7 @@ mod tests { #[test] fn character_space() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token().tok, @@ -1709,7 +1710,7 @@ mod tests { #[test] fn character_escaped() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); assert_eq!(setup(&sm, &sh, "'\\n'".to_string()).next_token().tok, @@ -1719,7 +1720,7 @@ mod tests { #[test] fn lifetime_name() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); assert_eq!(setup(&sm, &sh, "'abc".to_string()).next_token().tok, @@ -1729,7 +1730,7 @@ mod tests { #[test] fn raw_string() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); assert_eq!(setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()) @@ -1741,7 +1742,7 @@ mod tests { #[test] fn literal_suffixes() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); macro_rules! test { @@ -1787,7 +1788,7 @@ mod tests { #[test] fn nested_block_comments() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); let mut lexer = setup(&sm, &sh, "/* /* */ */'a'".to_string()); @@ -1802,7 +1803,7 @@ mod tests { #[test] fn crlf_comments() { - with_globals(|| { + with_default_globals(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sh = mk_sess(sm.clone()); let mut lexer = setup(&sm, &sh, "// test\r\n/// test\r\n".to_string()); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 0611c1d9b42a5..1073fc6f3ab4d 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -13,6 +13,7 @@ use crate::print::pprust::token_to_string; use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; use rustc_data_structures::sync::{Lrc, Lock}; use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; +use syntax_pos::edition::Edition; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use std::borrow::Cow; @@ -38,6 +39,7 @@ pub struct ParseSess { pub span_diagnostic: Handler, pub unstable_features: UnstableFeatures, pub config: CrateConfig, + pub edition: Edition, pub missing_fragment_specifiers: Lock>, /// Places where raw identifiers were used. This is used for feature-gating raw identifiers. pub raw_identifier_spans: Lock>, @@ -74,6 +76,7 @@ impl ParseSess { included_mod_stack: Lock::new(vec![]), source_map, buffered_lints: Lock::new(vec![]), + edition: Edition::from_session(), ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), } } @@ -329,6 +332,23 @@ pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser<'_> { Parser::new(sess, stream, None, true, false) } +/// Given stream, the `ParseSess` and the base directory, produces a parser. +/// +/// Use this function when you are creating a parser from the token stream +/// and also care about the current working directory of the parser (e.g., +/// you are trying to resolve modules defined inside a macro invocation). +/// +/// # Note +/// +/// The main usage of this function is outside of rustc, for those who uses +/// libsyntax as a library. Please do not remove this function while refactoring +/// just because it is not used in rustc codebase! +pub fn stream_to_parser_with_base_dir<'a>(sess: &'a ParseSess, + stream: TokenStream, + base_dir: Directory<'a>) -> Parser<'a> { + Parser::new(sess, stream, Some(base_dir), true, false) +} + /// A sequence separator. pub struct SeqSep { /// The seperator token. @@ -363,7 +383,7 @@ mod tests { use crate::tokenstream::{DelimSpan, TokenTree}; use crate::util::parser_testing::string_to_stream; use crate::util::parser_testing::{string_to_expr, string_to_item}; - use crate::with_globals; + use crate::with_default_globals; use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION}; /// Parses an item. @@ -382,7 +402,7 @@ mod tests { #[should_panic] #[test] fn bad_path_expr_1() { - with_globals(|| { + with_default_globals(|| { string_to_expr("::abc::def::return".to_string()); }) } @@ -390,7 +410,7 @@ mod tests { // check the token-tree-ization of macros #[test] fn string_to_tts_macro () { - with_globals(|| { + with_default_globals(|| { use crate::symbol::sym; let tts: Vec<_> = @@ -447,7 +467,7 @@ mod tests { #[test] fn string_to_tts_1() { - with_globals(|| { + with_default_globals(|| { let tts = string_to_stream("fn a (b : i32) { b; }".to_string()); let expected = TokenStream::new(vec![ @@ -480,7 +500,7 @@ mod tests { } #[test] fn parse_use() { - with_globals(|| { + with_default_globals(|| { let use_s = "use foo::bar::baz;"; let vitem = string_to_item(use_s.to_string()).unwrap(); let vitem_s = item_to_string(&vitem); @@ -494,7 +514,7 @@ mod tests { } #[test] fn parse_extern_crate() { - with_globals(|| { + with_default_globals(|| { let ex_s = "extern crate foo;"; let vitem = string_to_item(ex_s.to_string()).unwrap(); let vitem_s = item_to_string(&vitem); @@ -531,7 +551,7 @@ mod tests { } #[test] fn span_of_self_arg_pat_idents_are_correct() { - with_globals(|| { + with_default_globals(|| { let srcs = ["impl z { fn a (&self, &myarg: i32) {} }", "impl z { fn a (&mut self, &myarg: i32) {} }", @@ -551,7 +571,7 @@ mod tests { } #[test] fn parse_exprs () { - with_globals(|| { + with_default_globals(|| { // just make sure that they parse.... string_to_expr("3 + 4".to_string()); string_to_expr("a::z.froob(b,&(987+3))".to_string()); @@ -559,7 +579,7 @@ mod tests { } #[test] fn attrs_fix_bug () { - with_globals(|| { + with_default_globals(|| { string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) -> Result, String> { #[cfg(windows)] @@ -576,7 +596,7 @@ mod tests { } #[test] fn crlf_doc_comments() { - with_globals(|| { + with_default_globals(|| { use crate::symbol::sym; let sess = ParseSess::new(FilePathMapping::empty()); @@ -613,7 +633,7 @@ mod tests { new_parser_from_source_str(sess, name, source).parse_expr() } - with_globals(|| { + with_default_globals(|| { let sess = ParseSess::new(FilePathMapping::empty()); let expr = parse_expr_from_source_str(PathBuf::from("foo").into(), "foo!( fn main() { body } )".to_string(), &sess).unwrap(); @@ -637,7 +657,7 @@ mod tests { // See `recurse_into_file_modules` in the parser. #[test] fn out_of_line_mod() { - with_globals(|| { + with_default_globals(|| { let sess = ParseSess::new(FilePathMapping::empty()); let item = parse_item_from_source_str( PathBuf::from("foo").into(), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index cd86d94f4b81c..ac240359b56b6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -3147,12 +3147,12 @@ mod tests { use crate::ast; use crate::source_map; - use crate::with_globals; + use crate::with_default_globals; use syntax_pos; #[test] fn test_fun_to_string() { - with_globals(|| { + with_default_globals(|| { let abba_ident = ast::Ident::from_str("abba"); let decl = ast::FnDecl { @@ -3180,7 +3180,7 @@ mod tests { #[test] fn test_variant_to_string() { - with_globals(|| { + with_default_globals(|| { let ident = ast::Ident::from_str("principal_skinner"); let var = source_map::respan(syntax_pos::DUMMY_SP, ast::Variant_ { diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 215618bd09ca3..8a210db91858e 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -947,7 +947,7 @@ impl SourceMap { allow_internal_unstable, allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: edition::Edition::from_session(), }); span.with_ctxt(SyntaxContext::empty().apply_mark(mark)) } diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 1be7986ad53cd..e01a3260d4993 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -3,7 +3,7 @@ use crate::attr; use crate::edition::Edition; use crate::ext::hygiene::{Mark, SyntaxContext}; use crate::symbol::{Ident, Symbol, keywords, sym}; -use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan}; +use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, respan}; use crate::ptr::P; use crate::tokenstream::TokenStream; @@ -14,7 +14,7 @@ use syntax_pos::{DUMMY_SP, Span}; /// Craft a span that will be ignored by the stability lint's /// call to source_map's `is_internal` check. /// The expanded code uses the unstable `#[prelude_import]` attribute. -fn ignored_span(sp: Span) -> Span { +fn ignored_span(sp: Span, edition: Edition) -> Span { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(ExpnInfo { call_site: DUMMY_SP, @@ -25,7 +25,7 @@ fn ignored_span(sp: Span) -> Span { ].into()), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition, }); sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) } @@ -94,7 +94,7 @@ pub fn maybe_inject_crates_ref( INJECTED_CRATE_NAME.with(|opt_name| opt_name.set(Some(name))); - let span = ignored_span(DUMMY_SP); + let span = ignored_span(DUMMY_SP, edition); krate.module.items.insert(0, P(ast::Item { attrs: vec![ast::Attribute { style: ast::AttrStyle::Outer, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 3dc7aad945939..7cd83f3e495be 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -291,7 +291,7 @@ fn generate_test_harness(sess: &ParseSess, ].into()), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: sess.edition, }); TestHarnessGenerator { diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index 3cf6699538de0..107cbe70a23d7 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -1,5 +1,5 @@ use crate::source_map::{SourceMap, FilePathMapping}; -use crate::with_globals; +use crate::with_default_globals; use errors::Handler; use errors::emitter::EmitterWriter; @@ -39,7 +39,7 @@ impl Write for Shared { } fn test_harness(file_text: &str, span_labels: Vec, expected_output: &str) { - with_globals(|| { + with_default_globals(|| { let output = Arc::new(Mutex::new(Vec::new())); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 3cb16c30a50d4..79efc6bf689c4 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -557,7 +557,7 @@ impl DelimSpan { mod tests { use super::*; use crate::syntax::ast::Ident; - use crate::with_globals; + use crate::with_default_globals; use crate::parse::token::Token; use crate::util::parser_testing::string_to_stream; use syntax_pos::{Span, BytePos, NO_EXPANSION}; @@ -572,7 +572,7 @@ mod tests { #[test] fn test_concat() { - with_globals(|| { + with_default_globals(|| { let test_res = string_to_ts("foo::bar::baz"); let test_fst = string_to_ts("foo::bar"); let test_snd = string_to_ts("::baz"); @@ -585,7 +585,7 @@ mod tests { #[test] fn test_to_from_bijection() { - with_globals(|| { + with_default_globals(|| { let test_start = string_to_ts("foo::bar(baz)"); let test_end = test_start.trees().collect(); assert_eq!(test_start, test_end) @@ -594,7 +594,7 @@ mod tests { #[test] fn test_eq_0() { - with_globals(|| { + with_default_globals(|| { let test_res = string_to_ts("foo"); let test_eqs = string_to_ts("foo"); assert_eq!(test_res, test_eqs) @@ -603,7 +603,7 @@ mod tests { #[test] fn test_eq_1() { - with_globals(|| { + with_default_globals(|| { let test_res = string_to_ts("::bar::baz"); let test_eqs = string_to_ts("::bar::baz"); assert_eq!(test_res, test_eqs) @@ -612,7 +612,7 @@ mod tests { #[test] fn test_eq_3() { - with_globals(|| { + with_default_globals(|| { let test_res = string_to_ts(""); let test_eqs = string_to_ts(""); assert_eq!(test_res, test_eqs) @@ -621,7 +621,7 @@ mod tests { #[test] fn test_diseq_0() { - with_globals(|| { + with_default_globals(|| { let test_res = string_to_ts("::bar::baz"); let test_eqs = string_to_ts("bar::baz"); assert_eq!(test_res == test_eqs, false) @@ -630,7 +630,7 @@ mod tests { #[test] fn test_diseq_1() { - with_globals(|| { + with_default_globals(|| { let test_res = string_to_ts("(bar,baz)"); let test_eqs = string_to_ts("bar,baz"); assert_eq!(test_res == test_eqs, false) @@ -639,7 +639,7 @@ mod tests { #[test] fn test_is_empty() { - with_globals(|| { + with_default_globals(|| { let test0: TokenStream = Vec::::new().into_iter().collect(); let test1: TokenStream = TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"), false)).into(); @@ -653,12 +653,14 @@ mod tests { #[test] fn test_dotdotdot() { - let mut builder = TokenStreamBuilder::new(); - builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint()); - builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint()); - builder.push(TokenTree::Token(sp(2, 3), Token::Dot)); - let stream = builder.build(); - assert!(stream.eq_unspanned(&string_to_ts("..."))); - assert_eq!(stream.trees().count(), 1); + with_default_globals(|| { + let mut builder = TokenStreamBuilder::new(); + builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint()); + builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint()); + builder.push(TokenTree::Token(sp(2, 3), Token::Dot)); + let stream = builder.build(); + assert!(stream.eq_unspanned(&string_to_ts("..."))); + assert_eq!(stream.trees().count(), 1); + }) } } diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs index 2f150d22159fa..885b5a4f333b8 100644 --- a/src/libsyntax/util/lev_distance.rs +++ b/src/libsyntax/util/lev_distance.rs @@ -101,8 +101,8 @@ fn test_lev_distance() { #[test] fn test_find_best_match_for_name() { - use crate::with_globals; - with_globals(|| { + use crate::with_default_globals; + with_default_globals(|| { let input = vec![Symbol::intern("aaab"), Symbol::intern("aaabc")]; assert_eq!( find_best_match_for_name(input.iter(), "aaaa", None), diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 508f740cac927..e5fc7aab61db4 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -42,17 +42,17 @@ pub mod proc_macro_impl; use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier}; -use syntax::ext::hygiene; use syntax::symbol::Symbol; +use syntax::edition::Edition; pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, - user_exts: Vec) { + user_exts: Vec, + edition: Edition) { deriving::register_builtin_derives(resolver); let mut register = |name, ext| { resolver.add_builtin(ast::Ident::with_empty_ctxt(name), Lrc::new(ext)); }; - macro_rules! register { ($( $name:ident: $f:expr, )*) => { $( register(Symbol::intern(stringify!($name)), @@ -63,7 +63,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, allow_internal_unsafe: false, local_inner_macros: false, unstable_feature: None, - edition: hygiene::default_edition(), + edition, }); )* } } @@ -108,7 +108,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, allow_internal_unsafe: false, local_inner_macros: false, unstable_feature: None, - edition: hygiene::default_edition(), + edition, }); register(Symbol::intern("format_args_nl"), NormalTT { @@ -120,7 +120,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, allow_internal_unsafe: false, local_inner_macros: false, unstable_feature: None, - edition: hygiene::default_edition(), + edition, }); for (name, ext) in user_exts { diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 200445d124880..a13fe65ca0ddf 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -4,7 +4,7 @@ use crate::deriving; use syntax::ast::{self, Ident}; use syntax::attr; -use syntax::source_map::{ExpnInfo, MacroAttribute, hygiene, respan}; +use syntax::source_map::{ExpnInfo, MacroAttribute, respan}; use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; @@ -358,7 +358,7 @@ fn mk_decls( ].into()), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: cx.parse_sess.edition, }); let span = DUMMY_SP.apply_mark(mark); diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 211a098022f98..8ee61a3f67f59 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -3,7 +3,7 @@ use syntax::ext::base::*; use syntax::ext::build::AstBuilder; -use syntax::ext::hygiene::{self, Mark, SyntaxContext}; +use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::attr; use syntax::ast; use syntax::print::pprust; @@ -72,7 +72,7 @@ pub fn expand_test_or_bench( ].into()), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: cx.parse_sess.edition, }); (item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)), attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))) diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 802037f6d22bb..5b1ae167ce315 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -11,7 +11,7 @@ use syntax::ext::base::*; use syntax::ext::build::AstBuilder; -use syntax::ext::hygiene::{self, Mark, SyntaxContext}; +use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ast; use syntax::source_map::respan; use syntax::symbol::{Symbol, sym}; @@ -47,7 +47,7 @@ pub fn expand( ].into()), allow_internal_unsafe: false, local_inner_macros: false, - edition: hygiene::default_edition(), + edition: ecx.parse_sess.edition, }); attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) }; diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs index 00cd00f283784..20216568426fe 100644 --- a/src/libsyntax_pos/edition.rs +++ b/src/libsyntax_pos/edition.rs @@ -1,6 +1,7 @@ use crate::symbol::{Symbol, sym}; use std::fmt; use std::str::FromStr; +use crate::GLOBALS; /// The edition of the compiler (RFC 2052) #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)] @@ -38,6 +39,10 @@ impl fmt::Display for Edition { } impl Edition { + pub fn from_session() -> Edition { + GLOBALS.with(|globals| globals.edition) + } + pub fn lint_name(&self) -> &'static str { match *self { Edition::Edition2015 => "rust_2015_compatibility", diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 1d9dc26bf6092..6e787c08504f3 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -7,7 +7,7 @@ use crate::GLOBALS; use crate::Span; -use crate::edition::{Edition, DEFAULT_EDITION}; +use crate::edition::Edition; use crate::symbol::{keywords, Symbol}; use serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -174,7 +174,6 @@ crate struct HygieneData { marks: Vec, syntax_contexts: Vec, markings: FxHashMap<(SyntaxContext, Mark, Transparency), SyntaxContext>, - default_edition: Edition, } impl HygieneData { @@ -196,7 +195,6 @@ impl HygieneData { dollar_crate_name: keywords::DollarCrate.name(), }], markings: FxHashMap::default(), - default_edition: DEFAULT_EDITION, } } @@ -205,14 +203,6 @@ impl HygieneData { } } -pub fn default_edition() -> Edition { - HygieneData::with(|data| data.default_edition) -} - -pub fn set_default_edition(edition: Edition) { - HygieneData::with(|data| data.default_edition = edition); -} - pub fn clear_markings() { HygieneData::with(|data| data.markings = FxHashMap::default()); } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 39859f25f97fb..cb5aaf7eb882f 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -26,6 +26,7 @@ use serialize::{Encodable, Decodable, Encoder, Decoder}; extern crate serialize as rustc_serialize; // used by deriving pub mod edition; +use edition::Edition; pub mod hygiene; pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, CompilerDesugaringKind}; @@ -52,14 +53,16 @@ pub struct Globals { symbol_interner: Lock, span_interner: Lock, hygiene_data: Lock, + edition: Edition, } impl Globals { - pub fn new() -> Globals { + pub fn new(edition: Edition) -> Globals { Globals { symbol_interner: Lock::new(symbol::Interner::fresh()), span_interner: Lock::new(span_encoding::SpanInterner::default()), hygiene_data: Lock::new(hygiene::HygieneData::new()), + edition, } } } @@ -356,8 +359,9 @@ impl Span { /// Edition of the crate from which this span came. pub fn edition(self) -> edition::Edition { - self.ctxt().outer().expn_info().map_or_else(|| hygiene::default_edition(), - |einfo| einfo.edition) + self.ctxt().outer().expn_info().map_or_else(|| { + Edition::from_session() + }, |einfo| einfo.edition) } #[inline] diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index a07c7eb897ec1..8b07e81e58637 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -1147,7 +1147,7 @@ impl Encodable for LocalInternedString { /// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x")) /// assert_eq!(Symbol::gensym("x").as_interned_str(), Symbol::gensym("x").as_interned_str()) /// ``` -#[derive(Clone, Copy, Eq)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct InternedString { symbol: Symbol, } @@ -1212,42 +1212,6 @@ impl Ord for InternedString { } } -impl> PartialEq for InternedString { - fn eq(&self, other: &T) -> bool { - self.with(|string| string == other.deref()) - } -} - -impl PartialEq for InternedString { - fn eq(&self, other: &InternedString) -> bool { - self.symbol == other.symbol - } -} - -impl PartialEq for str { - fn eq(&self, other: &InternedString) -> bool { - other.with(|string| self == string) - } -} - -impl<'a> PartialEq for &'a str { - fn eq(&self, other: &InternedString) -> bool { - other.with(|string| *self == string) - } -} - -impl PartialEq for String { - fn eq(&self, other: &InternedString) -> bool { - other.with(|string| self == string) - } -} - -impl<'a> PartialEq for &'a String { - fn eq(&self, other: &InternedString) -> bool { - other.with(|string| *self == string) - } -} - impl fmt::Debug for InternedString { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.with(|str| fmt::Debug::fmt(&str, f)) @@ -1276,6 +1240,7 @@ impl Encodable for InternedString { mod tests { use super::*; use crate::Globals; + use crate::edition; #[test] fn interner_tests() { @@ -1300,7 +1265,7 @@ mod tests { #[test] fn without_first_quote_test() { - GLOBALS.set(&Globals::new(), || { + GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || { let i = Ident::from_str("'break"); assert_eq!(i.without_first_quote().name, keywords::Break.name()); }); diff --git a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs index d32fafd215c07..49e137549c049 100644 --- a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs +++ b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs @@ -105,7 +105,7 @@ fn reject_stmt_parse(es: &str) { } fn main() { - syntax::with_globals(|| run()); + syntax::with_default_globals(|| run()); } fn run() { diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs index 309acb25184a8..096701bd9b3ed 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs @@ -47,6 +47,6 @@ pub fn plugin_registrar(reg: &mut Registry) { allow_internal_unsafe: false, local_inner_macros: false, unstable_feature: None, - edition: hygiene::default_edition(), + edition: reg.sess.edition(), }); } diff --git a/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs b/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs index 22a76a3d968aa..a0dca9b1da4d2 100644 --- a/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs +++ b/src/test/run-pass-fulldeps/mod_dir_path_canonicalized.rs @@ -13,7 +13,7 @@ use syntax::parse::{self, ParseSess}; mod gravy; pub fn main() { - syntax::with_globals(|| parse()); + syntax::with_default_globals(|| parse()); assert_eq!(gravy::foo(), 10); } diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs index 80e0b0102af75..659de9cf6d51b 100644 --- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs @@ -189,7 +189,7 @@ impl MutVisitor for AddParens { } fn main() { - syntax::with_globals(|| run()); + syntax::with_default_globals(|| run()); } fn run() { diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 7b1cd70273140..45efa30d9919c 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -15,7 +15,7 @@ error[E0425]: cannot find value `no` in this scope error: aborting due to previous error For more information about this error, try `rustc --explain E0425`. -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:319:13 +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:320:13 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ---- @@ -24,7 +24,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 11)' panicked at 'test thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. -', src/librustdoc/test.rs:341:17 +', src/librustdoc/test.rs:342:17 failures: diff --git a/src/test/rustdoc-ui/unparseable-doc-test.stdout b/src/test/rustdoc-ui/unparseable-doc-test.stdout index 7048ef2c58977..f31b64fbce36a 100644 --- a/src/test/rustdoc-ui/unparseable-doc-test.stdout +++ b/src/test/rustdoc-ui/unparseable-doc-test.stdout @@ -13,7 +13,7 @@ error: unterminated double quote string error: aborting due to previous error -thread '$DIR/unparseable-doc-test.rs - foo (line 6)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:319:13 +thread '$DIR/unparseable-doc-test.rs - foo (line 6)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:320:13 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 38bd3fc006dcc..3e7c7ab6379d8 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -266,7 +266,7 @@ fn main() { *slot.borrow_mut() = Some((None, String::from("https://play.rust-lang.org/"))); }); let (format, dst) = parse_args(); - let result = syntax::with_globals(move || { + let result = syntax::with_default_globals(move || { main_with_result(format, &dst) }); if let Err(e) = result {