use syntax::feature_gate::{self, AttributeType};
use syntax::json::JsonEmitter;
use syntax::source_map;
- use syntax::symbol::Symbol;
use syntax::parse::{self, ParseSess};
use syntax_pos::{MultiSpan, Span};
use util::profiling::SelfProfiler;
/// Cap lint level specified by a driver specifically.
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
-
- /// All the crate names specified with `--extern`, and the builtin ones.
- /// Starting with the Rust 2018 edition, absolute paths resolve in this set.
- pub extern_prelude: FxHashSet<Symbol>,
}
pub struct PerfStats {
match self.opts.maybe_sysroot {
Some(ref sysroot) => sysroot,
None => self.default_sysroot
- .as_ref()
- .expect("missing sysroot and default_sysroot in Session"),
+ .as_ref()
+ .expect("missing sysroot and default_sysroot in Session"),
}
}
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
pub fn set_incr_session_load_dep_graph(&self, load: bool) {
let mut incr_comp_session = self.incr_comp_session.borrow_mut();
- match *incr_comp_session {
- IncrCompSession::Active {
- ref mut load_dep_graph,
- ..
- } => {
- *load_dep_graph = load;
- }
- _ => {}
+ if let IncrCompSession::Active { ref mut load_dep_graph, .. } = *incr_comp_session {
+ *load_dep_graph = load;
}
}
/// This expends fuel if applicable, and records fuel if applicable.
pub fn consider_optimizing<T: Fn() -> String>(&self, crate_name: &str, msg: T) -> bool {
let mut ret = true;
- match self.optimization_fuel_crate {
- Some(ref c) if c == crate_name => {
- assert!(self.query_threads() == 1);
+ if let Some(ref c) = self.optimization_fuel_crate {
+ if c == crate_name {
+ assert_eq!(self.query_threads(), 1);
let fuel = self.optimization_fuel_limit.get();
ret = fuel != 0;
if fuel == 0 && !self.out_of_fuel.get() {
self.optimization_fuel_limit.set(fuel - 1);
}
}
- _ => {}
}
- match self.print_fuel_crate {
- Some(ref c) if c == crate_name => {
- assert!(self.query_threads() == 1);
+ if let Some(ref c) = self.print_fuel_crate {
+ if c == crate_name {
+ assert_eq!(self.query_threads(), 1);
self.print_fuel.set(self.print_fuel.get() + 1);
}
- _ => {}
}
ret
}
source_map: Lrc<source_map::SourceMap>,
) -> Session {
let host_triple = TargetTriple::from_triple(config::host_triple());
- let host = match Target::search(&host_triple) {
- Ok(t) => t,
- Err(e) => {
- span_diagnostic
- .fatal(&format!("Error loading host specification: {}", e))
- .raise();
- }
- };
+ let host = Target::search(&host_triple).unwrap_or_else(|e|
+ span_diagnostic
+ .fatal(&format!("Error loading host specification: {}", e))
+ .raise()
+ );
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
let p_s = parse::ParseSess::with_span_handler(span_diagnostic, source_map);
let print_fuel_crate = sopts.debugging_opts.print_fuel.clone();
let print_fuel = LockCell::new(0);
- let working_dir = match env::current_dir() {
- Ok(dir) => dir,
- Err(e) => p_s.span_diagnostic
+ let working_dir = env::current_dir().unwrap_or_else(|e|
+ p_s.span_diagnostic
.fatal(&format!("Current directory is invalid: {}", e))
- .raise(),
- };
+ .raise()
+ );
let working_dir = file_path_mapping.map_prefix(working_dir);
let cgu_reuse_tracker = if sopts.debugging_opts.query_dep_graph {
CguReuseTracker::new_disabled()
};
-
- let mut extern_prelude: FxHashSet<Symbol> =
- sopts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
-
- // HACK(eddyb) this ignores the `no_{core,std}` attributes.
- // FIXME(eddyb) warn (somewhere) if core/std is used with `no_{core,std}`.
- // if !attr::contains_name(&krate.attrs, "no_core") {
- // if !attr::contains_name(&krate.attrs, "no_std") {
- extern_prelude.insert(Symbol::intern("core"));
- extern_prelude.insert(Symbol::intern("std"));
- extern_prelude.insert(Symbol::intern("meta"));
-
let sess = Session {
target: target_cfg,
host,
has_global_allocator: Once::new(),
has_panic_handler: Once::new(),
driver_lint_caps: FxHashMap(),
- extern_prelude,
};
validate_commandline_args_with_session_available(&sess);
use middle::stability;
use mir::{self, Mir, interpret};
use mir::interpret::Allocation;
-use ty::subst::{CanonicalSubsts, Kind, Substs, Subst};
+use ty::subst::{CanonicalUserSubsts, Kind, Substs, Subst};
use ty::ReprOptions;
use traits;
use traits::{Clause, Clauses, GoalKind, Goal, Goals};
/// If the user wrote `foo.collect::<Vec<_>>()`, then the
/// canonical substitutions would include only `for<X> { Vec<X>
/// }`.
- user_substs: ItemLocalMap<CanonicalSubsts<'tcx>>,
+ user_substs: ItemLocalMap<CanonicalUserSubsts<'tcx>>,
adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
self.node_substs.get(&id.local_id).cloned()
}
- pub fn user_substs_mut(&mut self) -> LocalTableInContextMut<'_, CanonicalSubsts<'tcx>> {
+ pub fn user_substs_mut(&mut self) -> LocalTableInContextMut<'_, CanonicalUserSubsts<'tcx>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.user_substs
}
}
- pub fn user_substs(&self, id: hir::HirId) -> Option<CanonicalSubsts<'tcx>> {
+ pub fn user_substs(&self, id: hir::HirId) -> Option<CanonicalUserSubsts<'tcx>> {
validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
self.user_substs.get(&id.local_id).cloned()
}
freevars: FxHashMap<DefId, Lrc<Vec<hir::Freevar>>>,
maybe_unused_trait_imports: FxHashSet<DefId>,
-
maybe_unused_extern_crates: Vec<(DefId, Span)>,
+ pub extern_prelude: FxHashSet<ast::Name>,
// Internal cache for metadata decoding. No need to track deps on this.
pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
.into_iter()
.map(|(id, sp)| (hir.local_def_id(id), sp))
.collect(),
+ extern_prelude: resolutions.extern_prelude,
hir,
def_path_hash_to_def_id,
queries: query::Queries::new(
// printing the `CrateRoot` so we don't prepend a `crate::` to paths.
let mut is_prelude_crate = false;
if let DefPathData::CrateRoot = self.def_key(parent_did).disambiguated_data.data {
- if self.sess.extern_prelude.contains(&data.as_interned_str().as_symbol()) {
+ if self.extern_prelude.contains(&data.as_interned_str().as_symbol()) {
is_prelude_crate = true;
}
}
match ty.sty {
ty::Adt(adt_def, _) => Some(adt_def.did),
- ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()),
+ ty::Dynamic(data, ..) => Some(data.principal().def_id()),
ty::Array(subty, _) |
ty::Slice(subty) => characteristic_def_id_of_type(subty),
use ty::util::{IntTypeExt, Discr};
use ty::walk::TypeWalker;
use util::captures::Captures;
- use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
+ use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet};
use arena::SyncDroplessArena;
use session::DataTypeKind;
use syntax_pos::{DUMMY_SP, Span};
use smallvec;
+use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
HashStable};
pub maybe_unused_trait_imports: NodeSet,
pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
pub export_map: ExportMap,
+ pub extern_prelude: FxHashSet<Name>,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
/// "Universes" are used during type- and trait-checking in the
/// presence of `for<..>` binders to control what sets of names are
/// visible. Universes are arranged into a tree: the root universe
-/// contains names that are always visible. But when you enter into
-/// some subuniverse, then it may add names that are only visible
-/// within that subtree (but it can still name the names of its
-/// ancestor universes).
+/// contains names that are always visible. Each child then adds a new
+/// set of names that are visible, in addition to those of its parent.
+/// We say that the child universe "extends" the parent universe with
+/// new names.
///
/// To make this more concrete, consider this program:
///
/// ```
///
/// The struct name `Foo` is in the root universe U0. But the type
-/// parameter `T`, introduced on `bar`, is in a subuniverse U1 --
-/// i.e., within `bar`, we can name both `T` and `Foo`, but outside of
-/// `bar`, we cannot name `T`. Then, within the type of `y`, the
-/// region `'a` is in a subuniverse U2 of U1, because we can name it
-/// inside the fn type but not outside.
+/// parameter `T`, introduced on `bar`, is in an extended universe U1
+/// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
+/// of `bar`, we cannot name `T`. Then, within the type of `y`, the
+/// region `'a` is in a universe U2 that extends U1, because we can
+/// name it inside the fn type but not outside.
///
/// Universes are used to do type- and trait-checking around these
/// "forall" binders (also called **universal quantification**). The
/// declared, but a type name in a non-zero universe is a placeholder
/// type -- an idealized representative of "types in general" that we
/// use for checking generic functions.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-pub struct UniverseIndex(u32);
-
-impl UniverseIndex {
- /// The root universe, where things that the user defined are
- /// visible.
- pub const ROOT: Self = UniverseIndex(0);
+newtype_index! {
+ pub struct UniverseIndex {
+ DEBUG_FORMAT = "U{}",
+ }
+}
- /// The "max universe" -- this isn't really a valid universe, but
- /// it's useful sometimes as a "starting value" when you are
- /// taking the minimum of a (non-empty!) set of universes.
- pub const MAX: Self = UniverseIndex(::std::u32::MAX);
+impl_stable_hash_for!(struct UniverseIndex { private });
- /// Creates a universe index from the given integer. Not to be
- /// used lightly lest you pick a bad value. But sometimes we
- /// convert universe indices into integers and back for various
- /// reasons.
- pub fn from_u32(index: u32) -> Self {
- UniverseIndex(index)
- }
+impl UniverseIndex {
+ pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0);
- /// A "subuniverse" corresponds to being inside a `forall` quantifier.
- /// So, for example, suppose we have this type in universe `U`:
+ /// Returns the "next" universe index in order -- this new index
+ /// is considered to extend all previous universes. This
+ /// corresponds to entering a `forall` quantifier. So, for
+ /// example, suppose we have this type in universe `U`:
///
/// ```
/// for<'a> fn(&'a u32)
/// ```
///
/// Once we "enter" into this `for<'a>` quantifier, we are in a
- /// subuniverse of `U` -- in this new universe, we can name the
- /// region `'a`, but that region was not nameable from `U` because
- /// it was not in scope there.
- pub fn subuniverse(self) -> UniverseIndex {
- UniverseIndex(self.0.checked_add(1).unwrap())
- }
-
- /// True if the names in this universe are a subset of the names in `other`.
- pub fn is_subset_of(self, other: UniverseIndex) -> bool {
- self.0 <= other.0
- }
-
- pub fn as_u32(&self) -> u32 {
- self.0
- }
-
- pub fn as_usize(&self) -> usize {
- self.0 as usize
- }
-}
-
-impl fmt::Debug for UniverseIndex {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(fmt, "U{}", self.as_u32())
- }
-}
-
-impl From<u32> for UniverseIndex {
- fn from(index: u32) -> Self {
- UniverseIndex(index)
+ /// new universe that extends `U` -- in this new universe, we can
+ /// name the region `'a`, but that region was not nameable from
+ /// `U` because it was not in scope there.
+ pub fn next_universe(self) -> UniverseIndex {
+ UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
+ }
+
+ /// True if `self` can name a name from `other` -- in other words,
+ /// if the set of names in `self` is a superset of those in
+ /// `other`.
+ pub fn can_name(self, other: UniverseIndex) -> bool {
+ self.private >= other.private
}
}
use std::any::Any;
use std::env;
-use std::ffi::{OsStr, OsString};
+use std::ffi::OsString;
use std::fs;
use std::io::{self, Write};
use std::iter;
trait_map: resolver.trait_map,
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
maybe_unused_extern_crates: resolver.maybe_unused_extern_crates,
+ extern_prelude: resolver.extern_prelude,
},
analysis: ty::CrateAnalysis {
.cloned()
.collect();
missing_fragment_specifiers.sort();
+
for span in missing_fragment_specifiers {
let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
let msg = "missing fragment specifier";
.collect();
let mut file = fs::File::create(&deps_filename)?;
for path in out_filenames {
- write!(file, "{}: {}\n\n", path.display(), files.join(" "))?;
+ writeln!(file, "{}: {}\n", path.display(), files.join(" "))?;
}
// Emit a fake target for each input file to the compilation. This
Ok(())
})();
- match result {
- Ok(()) => {}
- Err(e) => {
- sess.fatal(&format!(
- "error writing dependencies to `{}`: {}",
- deps_filename.display(),
- e
- ));
- }
+ if let Err(e) = result {
+ sess.fatal(&format!(
+ "error writing dependencies to `{}`: {}",
+ deps_filename.display(),
+ e
+ ));
}
}
Symbol::intern("proc-macro"),
Symbol::intern("bin")
];
+
if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().node {
let span = spanned.span;
let lev_candidate = find_best_match_for_name(
}
None
}
- _ => {
+ None => {
session
.struct_span_err(a.span, "`crate_type` requires a value")
.note("for example: `#![crate_type=\"lib\"]`")
base.push(::rustc_codegen_utils::link::default_output_for_target(
session,
));
+ } else {
+ base.sort();
+ base.dedup();
}
- base.sort();
- base.dedup();
}
- base.into_iter()
- .filter(|crate_type| {
- let res = !::rustc_codegen_utils::link::invalid_output_for_target(session, *crate_type);
+ base.retain(|crate_type| {
+ let res = !::rustc_codegen_utils::link::invalid_output_for_target(session, *crate_type);
- if !res {
- session.warn(&format!(
- "dropping unsupported crate type `{}` for target `{}`",
- *crate_type, session.opts.target_triple
- ));
- }
+ if !res {
+ session.warn(&format!(
+ "dropping unsupported crate type `{}` for target `{}`",
+ *crate_type, session.opts.target_triple
+ ));
+ }
- res
- })
- .collect()
+ res
+ });
+
+ base
}
pub fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
// "-" as input file will cause the parser to read from stdin so we
// have to make up a name
// We want to toss everything after the final '.'
- let dirpath = match *odir {
- Some(ref d) => d.clone(),
- None => PathBuf::new(),
- };
+ let dirpath = (*odir).as_ref().cloned().unwrap_or_default();
// If a crate name is present, we use it as the link name
let stem = sess.opts
.crate_name
.clone()
.or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string()))
- .unwrap_or(input.filestem());
+ .unwrap_or_else(|| input.filestem().to_owned());
OutputFilenames {
out_directory: dirpath,
sess.warn("ignoring -C extra-filename flag due to -o flag");
}
- let cur_dir = Path::new("");
-
OutputFilenames {
- out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(),
+ out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
out_filestem: out_file
.file_stem()
- .unwrap_or(OsStr::new(""))
+ .unwrap_or_default()
.to_str()
.unwrap()
.to_string(),