Auto merge of #70204 - Centril:unshackled-lowering, r=Zoxc

Liberate `rustc_ast_lowering` from `rustc`

The whole point of this PR is the very last commit, in which we remove `rustc` as one of `rustc_ast_lowering`'s dependencies, thereby improving `./x.py` parallelism and working towards https://github.com/rust-lang/rust/issues/65031.

Noteworthy:
- From `rustc::arena` we move logic into `arena`, in particular `declare_arena!`. This is then used in `rustc_ast_lowering` so that lowering has its own separate arena.
- Some linting code is unfortunately moved to `rustc_session::lint` cause its used both in `rustc_lint` and `rustc_ast_lowering`, and this is their common dependency.
- `rustc_session::CrateDisambiguator` is moved into `rustc_ast` so that `rustc::hir::map::definitions` can be moved into `rustc_hir`, so that `rustc_ast_lowering` can stop referring to `rustc::hir`.

r? @Zoxc
This commit is contained in:
bors 2020-03-23 03:10:48 +00:00
commit 37c945dd61
27 changed files with 384 additions and 375 deletions

View File

@ -3477,8 +3477,8 @@ dependencies = [
name = "rustc_ast_lowering"
version = "0.0.0"
dependencies = [
"arena",
"log",
"rustc",
"rustc_ast",
"rustc_ast_pretty",
"rustc_data_structures",
@ -3725,6 +3725,7 @@ name = "rustc_hir"
version = "0.0.0"
dependencies = [
"lazy_static 1.4.0",
"log",
"rustc_ast",
"rustc_ast_pretty",
"rustc_data_structures",

View File

@ -488,5 +488,187 @@ impl DroplessArena {
}
}
/// Calls the destructor for an object when dropped.
struct DropType {
drop_fn: unsafe fn(*mut u8),
obj: *mut u8,
}
unsafe fn drop_for_type<T>(to_drop: *mut u8) {
std::ptr::drop_in_place(to_drop as *mut T)
}
impl Drop for DropType {
fn drop(&mut self) {
unsafe { (self.drop_fn)(self.obj) }
}
}
/// An arena which can be used to allocate any type.
/// Allocating in this arena is unsafe since the type system
/// doesn't know which types it contains. In order to
/// allocate safely, you must store a PhantomData<T>
/// alongside this arena for each type T you allocate.
#[derive(Default)]
pub struct DropArena {
/// A list of destructors to run when the arena drops.
/// Ordered so `destructors` gets dropped before the arena
/// since its destructor can reference memory in the arena.
destructors: RefCell<Vec<DropType>>,
arena: DroplessArena,
}
impl DropArena {
#[inline]
pub unsafe fn alloc<T>(&self, object: T) -> &mut T {
let mem =
self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
// Write into uninitialized memory.
ptr::write(mem, object);
let result = &mut *mem;
// Record the destructor after doing the allocation as that may panic
// and would cause `object`'s destuctor to run twice if it was recorded before
self.destructors
.borrow_mut()
.push(DropType { drop_fn: drop_for_type::<T>, obj: result as *mut T as *mut u8 });
result
}
#[inline]
pub unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
if vec.is_empty() {
return &mut [];
}
let len = vec.len();
let start_ptr = self
.arena
.alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>())
as *mut _ as *mut T;
let mut destructors = self.destructors.borrow_mut();
// Reserve space for the destructors so we can't panic while adding them
destructors.reserve(len);
// Move the content to the arena by copying it and then forgetting
// the content of the SmallVec
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
mem::forget(vec.drain(..));
// Record the destructors after doing the allocation as that may panic
// and would cause `object`'s destuctor to run twice if it was recorded before
for i in 0..len {
destructors.push(DropType {
drop_fn: drop_for_type::<T>,
obj: start_ptr.offset(i as isize) as *mut u8,
});
}
slice::from_raw_parts_mut(start_ptr, len)
}
}
#[macro_export]
macro_rules! arena_for_type {
([][$ty:ty]) => {
$crate::TypedArena<$ty>
};
([few $(, $attrs:ident)*][$ty:ty]) => {
::std::marker::PhantomData<$ty>
};
([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
$crate::arena_for_type!([$($attrs),*]$args)
};
}
#[macro_export]
macro_rules! which_arena_for_type {
([][$arena:expr]) => {
::std::option::Option::Some($arena)
};
([few$(, $attrs:ident)*][$arena:expr]) => {
::std::option::Option::None
};
([$ignore:ident$(, $attrs:ident)*]$args:tt) => {
$crate::which_arena_for_type!([$($attrs),*]$args)
};
}
#[macro_export]
macro_rules! declare_arena {
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
#[derive(Default)]
pub struct Arena<$tcx> {
pub dropless: $crate::DroplessArena,
drop: $crate::DropArena,
$($name: $crate::arena_for_type!($a[$ty]),)*
}
#[marker]
pub trait ArenaAllocatable {}
impl<T: Copy> ArenaAllocatable for T {}
unsafe trait ArenaField<'tcx>: Sized {
/// Returns a specific arena to allocate from.
/// If `None` is returned, the `DropArena` will be used.
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>>;
}
unsafe impl<'tcx, T> ArenaField<'tcx> for T {
#[inline]
default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>> {
panic!()
}
}
$(
#[allow(unused_lifetimes)]
impl<$tcx> ArenaAllocatable for $ty {}
unsafe impl<$tcx> ArenaField<$tcx> for $ty {
#[inline]
fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a $crate::TypedArena<Self>> {
$crate::which_arena_for_type!($a[&_arena.$name])
}
}
)*
impl<'tcx> Arena<'tcx> {
#[inline]
pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
if !::std::mem::needs_drop::<T>() {
return self.dropless.alloc(value);
}
match <T as ArenaField<'tcx>>::arena(self) {
::std::option::Option::Some(arena) => arena.alloc(value),
::std::option::Option::None => unsafe { self.drop.alloc(value) },
}
}
#[inline]
pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] {
if value.is_empty() {
return &mut [];
}
self.dropless.alloc_slice(value)
}
pub fn alloc_from_iter<'a, T: ArenaAllocatable>(
&'a self,
iter: impl ::std::iter::IntoIterator<Item = T>,
) -> &'a mut [T] {
if !::std::mem::needs_drop::<T>() {
return self.dropless.alloc_from_iter(iter);
}
match <T as ArenaField<'tcx>>::arena(self) {
::std::option::Option::Some(arena) => arena.alloc_from_iter(iter),
::std::option::Option::None => unsafe { self.drop.alloc_from_iter(iter) },
}
}
}
}
}
#[cfg(test)]
mod tests;

View File

@ -1,11 +1,3 @@
use arena::{DroplessArena, TypedArena};
use smallvec::SmallVec;
use std::cell::RefCell;
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::slice;
/// This declares a list of types which can be allocated by `Arena`.
///
/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
@ -128,231 +120,13 @@ macro_rules! arena_types {
// Interned types
[] tys: rustc::ty::TyS<$tcx>,
// HIR types
[few] hir_krate: rustc_hir::Crate<$tcx>,
[] arm: rustc_hir::Arm<$tcx>,
[] attribute: rustc_ast::ast::Attribute,
[] block: rustc_hir::Block<$tcx>,
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
[few] global_asm: rustc_hir::GlobalAsm,
[] generic_arg: rustc_hir::GenericArg<$tcx>,
[] generic_args: rustc_hir::GenericArgs<$tcx>,
[] generic_bound: rustc_hir::GenericBound<$tcx>,
[] generic_param: rustc_hir::GenericParam<$tcx>,
[] expr: rustc_hir::Expr<$tcx>,
[] field: rustc_hir::Field<$tcx>,
[] field_pat: rustc_hir::FieldPat<$tcx>,
[] fn_decl: rustc_hir::FnDecl<$tcx>,
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
[] inline_asm: rustc_hir::InlineAsm<$tcx>,
[] local: rustc_hir::Local<$tcx>,
[few] macro_def: rustc_hir::MacroDef<$tcx>,
[] param: rustc_hir::Param<$tcx>,
[] pat: rustc_hir::Pat<$tcx>,
[] path: rustc_hir::Path<$tcx>,
[] path_segment: rustc_hir::PathSegment<$tcx>,
[] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
[] qpath: rustc_hir::QPath<$tcx>,
[] stmt: rustc_hir::Stmt<$tcx>,
[] struct_field: rustc_hir::StructField<$tcx>,
[] trait_item_ref: rustc_hir::TraitItemRef,
[] ty: rustc_hir::Ty<$tcx>,
[] type_binding: rustc_hir::TypeBinding<$tcx>,
[] variant: rustc_hir::Variant<$tcx>,
[] where_predicate: rustc_hir::WherePredicate<$tcx>,
// HIR query types
[few] indexed_hir: rustc::hir::map::IndexedHir<$tcx>,
[few] hir_definitions: rustc::hir::map::definitions::Definitions,
[few] hir_definitions: rustc_hir::definitions::Definitions,
[] hir_owner: rustc::hir::Owner<$tcx>,
[] hir_owner_nodes: rustc::hir::OwnerNodes<$tcx>,
], $tcx);
)
}
macro_rules! arena_for_type {
([][$ty:ty]) => {
TypedArena<$ty>
};
([few $(, $attrs:ident)*][$ty:ty]) => {
PhantomData<$ty>
};
([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
arena_for_type!([$($attrs),*]$args)
};
}
macro_rules! declare_arena {
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
#[derive(Default)]
pub struct Arena<$tcx> {
pub dropless: DroplessArena,
drop: DropArena,
$($name: arena_for_type!($a[$ty]),)*
}
}
}
macro_rules! which_arena_for_type {
([][$arena:expr]) => {
Some($arena)
};
([few$(, $attrs:ident)*][$arena:expr]) => {
None
};
([$ignore:ident$(, $attrs:ident)*]$args:tt) => {
which_arena_for_type!([$($attrs),*]$args)
};
}
macro_rules! impl_arena_allocatable {
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
$(
impl ArenaAllocatable for $ty {}
unsafe impl<$tcx> ArenaField<$tcx> for $ty {
#[inline]
fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> {
which_arena_for_type!($a[&_arena.$name])
}
}
)*
}
}
arena_types!(declare_arena, [], 'tcx);
arena_types!(impl_arena_allocatable, [], 'tcx);
#[marker]
pub trait ArenaAllocatable {}
impl<T: Copy> ArenaAllocatable for T {}
unsafe trait ArenaField<'tcx>: Sized {
/// Returns a specific arena to allocate from.
/// If `None` is returned, the `DropArena` will be used.
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;
}
unsafe impl<'tcx, T> ArenaField<'tcx> for T {
#[inline]
default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> {
panic!()
}
}
impl<'tcx> Arena<'tcx> {
#[inline]
pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
if !mem::needs_drop::<T>() {
return self.dropless.alloc(value);
}
match <T as ArenaField<'tcx>>::arena(self) {
Some(arena) => arena.alloc(value),
None => unsafe { self.drop.alloc(value) },
}
}
#[inline]
pub fn alloc_slice<T: Copy>(&self, value: &[T]) -> &mut [T] {
if value.is_empty() {
return &mut [];
}
self.dropless.alloc_slice(value)
}
pub fn alloc_from_iter<T: ArenaAllocatable, I: IntoIterator<Item = T>>(
&'a self,
iter: I,
) -> &'a mut [T] {
if !mem::needs_drop::<T>() {
return self.dropless.alloc_from_iter(iter);
}
match <T as ArenaField<'tcx>>::arena(self) {
Some(arena) => arena.alloc_from_iter(iter),
None => unsafe { self.drop.alloc_from_iter(iter) },
}
}
}
/// Calls the destructor for an object when dropped.
struct DropType {
drop_fn: unsafe fn(*mut u8),
obj: *mut u8,
}
unsafe fn drop_for_type<T>(to_drop: *mut u8) {
std::ptr::drop_in_place(to_drop as *mut T)
}
impl Drop for DropType {
fn drop(&mut self) {
unsafe { (self.drop_fn)(self.obj) }
}
}
/// An arena which can be used to allocate any type.
/// Allocating in this arena is unsafe since the type system
/// doesn't know which types it contains. In order to
/// allocate safely, you must store a PhantomData<T>
/// alongside this arena for each type T you allocate.
#[derive(Default)]
struct DropArena {
/// A list of destructors to run when the arena drops.
/// Ordered so `destructors` gets dropped before the arena
/// since its destructor can reference memory in the arena.
destructors: RefCell<Vec<DropType>>,
arena: DroplessArena,
}
impl DropArena {
#[inline]
unsafe fn alloc<T>(&self, object: T) -> &mut T {
let mem =
self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
// Write into uninitialized memory.
ptr::write(mem, object);
let result = &mut *mem;
// Record the destructor after doing the allocation as that may panic
// and would cause `object`'s destuctor to run twice if it was recorded before
self.destructors
.borrow_mut()
.push(DropType { drop_fn: drop_for_type::<T>, obj: result as *mut T as *mut u8 });
result
}
#[inline]
unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
if vec.is_empty() {
return &mut [];
}
let len = vec.len();
let start_ptr = self
.arena
.alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>())
as *mut _ as *mut T;
let mut destructors = self.destructors.borrow_mut();
// Reserve space for the destructors so we can't panic while adding them
destructors.reserve(len);
// Move the content to the arena by copying it and then forgetting
// the content of the SmallVec
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
mem::forget(vec.drain(..));
// Record the destructors after doing the allocation as that may panic
// and would cause `object`'s destuctor to run twice if it was recorded before
for i in 0..len {
destructors.push(DropType {
drop_fn: drop_for_type::<T>,
obj: start_ptr.offset(i as isize) as *mut u8,
});
}
slice::from_raw_parts_mut(start_ptr, len)
}
}
arena_types!(arena::declare_arena, [], 'tcx);

View File

@ -1,7 +1,4 @@
use self::collector::NodeCollector;
pub use self::definitions::{
DefKey, DefPath, DefPathData, DefPathHash, Definitions, DisambiguatedDefPathData,
};
use crate::hir::{Owner, OwnerNodes};
use crate::ty::query::Providers;
@ -10,6 +7,9 @@ use rustc_ast::ast::{self, Name, NodeId};
use rustc_data_structures::svh::Svh;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
pub use rustc_hir::definitions;
pub use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
pub use rustc_hir::definitions::{Definitions, DisambiguatedDefPathData};
use rustc_hir::intravisit;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::print::Nested;
@ -23,7 +23,6 @@ use rustc_target::spec::abi::Abi;
pub mod blocks;
mod collector;
pub mod definitions;
mod hir_id_validator;
pub use hir_id_validator::check_crate;

View File

@ -3,7 +3,7 @@ use std::cmp;
use crate::ich::StableHashingContext;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_hir::HirId;
use rustc_session::lint::{builtin, Level, Lint, LintId};
use rustc_session::{DiagnosticMessageId, Session};
@ -350,45 +350,3 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
ExpnKind::Macro(..) => true, // definitely a plugin
}
}
pub fn add_elided_lifetime_in_path_suggestion(
sess: &Session,
db: &mut DiagnosticBuilder<'_>,
n: usize,
path_span: Span,
incl_angl_brckt: bool,
insertion_span: Span,
anon_lts: String,
) {
let (replace_span, suggestion) = if incl_angl_brckt {
(insertion_span, anon_lts)
} else {
// When possible, prefer a suggestion that replaces the whole
// `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
// at a point (which makes for an ugly/confusing label)
if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
// But our spans can get out of whack due to macros; if the place we think
// we want to insert `'_` isn't even within the path expression's span, we
// should bail out of making any suggestion rather than panicking on a
// subtract-with-overflow or string-slice-out-out-bounds (!)
// FIXME: can we do better?
if insertion_span.lo().0 < path_span.lo().0 {
return;
}
let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
if insertion_index > snippet.len() {
return;
}
let (before, after) = snippet.split_at(insertion_index);
(path_span, format!("{}{}{}", before, anon_lts, after))
} else {
(insertion_span, anon_lts)
}
};
db.span_suggestion(
replace_span,
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
suggestion,
Applicability::MachineApplicable,
);
}

View File

@ -396,6 +396,7 @@ macro_rules! implement_ty_decoder {
// the caller to pick any lifetime for `'tcx`, including `'static`,
// by using the unspecialized proxies to them.
rustc_hir::arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
impl<$($typaram),*> SpecializedDecoder<CrateNum>

View File

@ -0,0 +1,35 @@
// This is here because `rustc_session` wants to refer to it,
// and so does `rustc_hir`, but `rustc_hir` shouldn't refer to `rustc_session`.
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::{base_n, impl_stable_hash_via_hash};
use std::fmt;
/// Hash value constructed out of all the `-C metadata` arguments passed to the
/// compiler. Together with the crate-name forms a unique global identifier for
/// the crate.
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
pub struct CrateDisambiguator(Fingerprint);
impl CrateDisambiguator {
pub fn to_fingerprint(self) -> Fingerprint {
self.0
}
}
impl fmt::Display for CrateDisambiguator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
let (a, b) = self.0.as_value();
let as_u128 = a as u128 | ((b as u128) << 64);
f.write_str(&base_n::encode(as_u128, base_n::CASE_INSENSITIVE))
}
}
impl From<Fingerprint> for CrateDisambiguator {
fn from(fingerprint: Fingerprint) -> CrateDisambiguator {
CrateDisambiguator(fingerprint)
}
}
impl_stable_hash_via_hash!(CrateDisambiguator);

View File

@ -40,6 +40,7 @@ pub mod util {
pub mod ast;
pub mod attr;
pub use attr::{with_default_globals, with_globals, GLOBALS};
pub mod crate_disambiguator;
pub mod entry;
pub mod expand;
pub mod mut_visit;

View File

@ -10,8 +10,8 @@ path = "lib.rs"
doctest = false
[dependencies]
arena = { path = "../libarena" }
log = { version = "0.4", features = ["release_max_level_info", "std"] }
rustc = { path = "../librustc" }
rustc_ast_pretty = { path = "../librustc_ast_pretty" }
rustc_hir = { path = "../librustc_hir" }
rustc_target = { path = "../librustc_target" }

View File

@ -1,6 +1,5 @@
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
use rustc::bug;
use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::ptr::P as AstP;
@ -757,7 +756,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(movability)
}
Some(hir::GeneratorKind::Async(_)) => {
bug!("non-`async` closure body turned `async` during lowering");
panic!("non-`async` closure body turned `async` during lowering");
}
None => {
if movability == Movability::Static {

View File

@ -1,8 +1,7 @@
use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
use super::{ImplTraitContext, ImplTraitPosition, ImplTraitTypeIdVisitor};
use crate::Arena;
use rustc::arena::Arena;
use rustc::bug;
use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::node_id::NodeMap;
@ -432,7 +431,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
),
ItemKind::MacroDef(..) | ItemKind::MacCall(..) => {
bug!("`TyMac` should have been expanded by now")
panic!("`TyMac` should have been expanded by now")
}
}
@ -784,7 +783,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
(generics, kind)
}
AssocItemKind::MacCall(..) => bug!("macro item shouldn't exist at this point"),
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
};
hir::TraitItem {
@ -865,7 +864,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
};
(generics, kind)
}
AssocItemKind::MacCall(..) => bug!("`TyMac` should have been expanded by now"),
AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
};
hir::ImplItem {

View File

@ -32,12 +32,10 @@
#![feature(array_value_iter)]
#![feature(crate_visibility_modifier)]
#![feature(marker_trait_attr)]
#![feature(specialization)]
#![recursion_limit = "256"]
use rustc::arena::Arena;
use rustc::dep_graph::DepGraph;
use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions};
use rustc::{bug, span_bug};
use rustc_ast::ast;
use rustc_ast::ast::*;
use rustc_ast::attr;
@ -54,6 +52,7 @@ use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
use rustc_hir::intravisit;
use rustc_hir::{ConstArg, GenericArg, ParamName};
use rustc_index::vec::IndexVec;
@ -85,6 +84,8 @@ mod path;
const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
rustc_hir::arena_types!(::arena::declare_arena, [], 'tcx);
struct LoweringContext<'a, 'hir: 'a> {
crate_root: Option<Symbol>,
@ -259,17 +260,11 @@ impl<'a> ImplTraitContext<'_, 'a> {
pub fn lower_crate<'a, 'hir>(
sess: &'a Session,
dep_graph: &'a DepGraph,
krate: &'a Crate,
resolver: &'a mut dyn Resolver,
nt_to_tokenstream: NtToTokenstream,
arena: &'hir Arena<'hir>,
) -> hir::Crate<'hir> {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
dep_graph.assert_ignored();
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
LoweringContext {
@ -672,7 +667,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
if pr.unresolved_segments() != 0 {
bug!("path not fully resolved: {:?}", pr);
panic!("path not fully resolved: {:?}", pr);
}
pr.base_res()
})
@ -1340,7 +1335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
}
TyKind::MacCall(_) => bug!("`TyKind::MacCall` should have been expanded by now"),
TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
TyKind::CVarArgs => {
self.sess.delay_span_bug(
t.span,
@ -1575,7 +1570,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::LifetimeName::Param(param_name) => {
(param_name, hir::LifetimeParamKind::Explicit)
}
_ => bug!("expected `LifetimeName::Param` or `ParamName::Plain`"),
_ => panic!("expected `LifetimeName::Param` or `ParamName::Plain`"),
};
self.output_lifetime_params.push(hir::GenericParam {
@ -2096,7 +2091,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
| hir::LifetimeName::Underscore
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
span_bug!(
self.sess.diagnostic().span_bug(
param.ident.span,
"object-lifetime-default should not occur here",
);
@ -2163,7 +2158,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::TraitRef<'hir> {
let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
hir::QPath::Resolved(None, path) => path,
qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
};
hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
}

View File

@ -1,7 +1,6 @@
use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
use super::{GenericArgsCtor, ParenthesizedGenericArgs};
use rustc::span_bug;
use rustc_ast::ast::{self, *};
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
@ -163,12 +162,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
// We should've returned in the for loop above.
span_bug!(
self.sess.diagnostic().span_bug(
p.span,
"lower_qpath: no final extension segment in {}..{}",
proj_start,
p.segments.len()
)
&format!(
"lower_qpath: no final extension segment in {}..{}",
proj_start,
p.segments.len()
),
);
}
crate fn lower_path_extra(
@ -304,7 +306,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
E0726,
"implicit elided lifetime not allowed here"
);
rustc::lint::add_elided_lifetime_in_path_suggestion(
rustc_session::lint::add_elided_lifetime_in_path_suggestion(
&self.sess,
&mut err,
expected_lifetimes,

View File

@ -20,4 +20,5 @@ rustc_errors = { path = "../librustc_errors" }
rustc_serialize = { path = "../libserialize", package = "serialize" }
rustc_ast = { path = "../librustc_ast" }
lazy_static = "1"
log = { version = "0.4", features = ["release_max_level_info", "std"] }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }

49
src/librustc_hir/arena.rs Normal file
View File

@ -0,0 +1,49 @@
/// This declares a list of types which can be allocated by `Arena`.
///
/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
/// This is faster and more memory efficient if there's only a few allocations of the type.
/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
/// faster and more memory efficient if there is lots of allocations.
///
/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
/// listed. These impls will appear in the implement_ty_decoder! macro.
#[macro_export]
macro_rules! arena_types {
($macro:path, $args:tt, $tcx:lifetime) => (
$macro!($args, [
// HIR types
[few] hir_krate: rustc_hir::Crate<$tcx>,
[] arm: rustc_hir::Arm<$tcx>,
[] attribute: rustc_ast::ast::Attribute,
[] block: rustc_hir::Block<$tcx>,
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
[few] global_asm: rustc_hir::GlobalAsm,
[] generic_arg: rustc_hir::GenericArg<$tcx>,
[] generic_args: rustc_hir::GenericArgs<$tcx>,
[] generic_bound: rustc_hir::GenericBound<$tcx>,
[] generic_param: rustc_hir::GenericParam<$tcx>,
[] expr: rustc_hir::Expr<$tcx>,
[] field: rustc_hir::Field<$tcx>,
[] field_pat: rustc_hir::FieldPat<$tcx>,
[] fn_decl: rustc_hir::FnDecl<$tcx>,
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
[] inline_asm: rustc_hir::InlineAsm<$tcx>,
[] local: rustc_hir::Local<$tcx>,
[few] macro_def: rustc_hir::MacroDef<$tcx>,
[] param: rustc_hir::Param<$tcx>,
[] pat: rustc_hir::Pat<$tcx>,
[] path: rustc_hir::Path<$tcx>,
[] path_segment: rustc_hir::PathSegment<$tcx>,
[] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
[] qpath: rustc_hir::QPath<$tcx>,
[] stmt: rustc_hir::Stmt<$tcx>,
[] struct_field: rustc_hir::StructField<$tcx>,
[] trait_item_ref: rustc_hir::TraitItemRef,
[] ty: rustc_hir::Ty<$tcx>,
[] type_binding: rustc_hir::TypeBinding<$tcx>,
[] variant: rustc_hir::Variant<$tcx>,
[] where_predicate: rustc_hir::WherePredicate<$tcx>,
], $tcx);
)
}

View File

@ -4,22 +4,24 @@
//! There are also some rather random cases (like const initializer
//! expressions) that are mostly just leftovers.
pub use crate::def_id::DefPathHash;
use crate::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use crate::hir;
use crate::hir_id::DUMMY_HIR_ID;
use rustc_ast::ast;
use rustc_ast::crate_disambiguator::CrateDisambiguator;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_index::vec::IndexVec;
use rustc_session::CrateDisambiguator;
use rustc_span::hygiene::ExpnId;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use log::debug;
use std::fmt::Write;
use std::hash::Hash;
pub use rustc_hir::def_id::DefPathHash;
/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
/// stores the `DefIndex` of its parent.
@ -345,7 +347,7 @@ impl Definitions {
pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> {
if let Some(def_id) = def_id.as_local() {
let hir_id = self.local_def_id_to_hir_id(def_id);
if hir_id != hir::DUMMY_HIR_ID { Some(hir_id) } else { None }
if hir_id != DUMMY_HIR_ID { Some(hir_id) } else { None }
} else {
None
}

View File

@ -13,7 +13,9 @@
#[macro_use]
extern crate rustc_data_structures;
mod arena;
pub mod def;
pub mod definitions;
pub use rustc_span::def_id;
mod hir;
pub mod hir_id;

View File

@ -437,12 +437,16 @@ pub fn lower_to_hir<'res, 'tcx>(
resolver: &'res mut Resolver<'_>,
dep_graph: &'res DepGraph,
krate: &'res ast::Crate,
arena: &'tcx Arena<'tcx>,
arena: &'tcx rustc_ast_lowering::Arena<'tcx>,
) -> Crate<'tcx> {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
dep_graph.assert_ignored();
// Lower AST to HIR.
let hir_crate = rustc_ast_lowering::lower_crate(
sess,
&dep_graph,
&krate,
resolver,
rustc_parse::nt_to_tokenstream,

View File

@ -68,6 +68,7 @@ pub struct Queries<'tcx> {
gcx: Once<GlobalCtxt<'tcx>>,
arena: WorkerLocal<Arena<'tcx>>,
hir_arena: WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
dep_graph_future: Query<Option<DepGraphFuture>>,
parse: Query<ast::Crate>,
@ -87,6 +88,7 @@ impl<'tcx> Queries<'tcx> {
compiler,
gcx: Once::new(),
arena: WorkerLocal::new(|_| Arena::default()),
hir_arena: WorkerLocal::new(|_| rustc_ast_lowering::Arena::default()),
dep_graph_future: Default::default(),
parse: Default::default(),
crate_name: Default::default(),
@ -218,10 +220,10 @@ impl<'tcx> Queries<'tcx> {
resolver,
&*self.dep_graph()?.peek(),
&krate,
&self.arena,
&self.hir_arena,
))
})?;
let hir = self.arena.alloc(hir);
let hir = self.hir_arena.alloc(hir);
Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver))))
})
}

View File

@ -18,8 +18,6 @@ use self::TargetLint::*;
use crate::levels::LintLevelsBuilder;
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
use rustc::hir::map::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc::lint::add_elided_lifetime_in_path_suggestion;
use rustc::lint::LintDiagnosticBuilder;
use rustc::middle::privacy::AccessLevels;
use rustc::middle::stability;
@ -32,7 +30,8 @@ use rustc_data_structures::sync;
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_session::lint::{add_elided_lifetime_in_path_suggestion, BuiltinLintDiagnostics};
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
use rustc_session::Session;
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};

View File

@ -6,8 +6,6 @@ use crate::rmeta::*;
use rustc::dep_graph::{self, DepNode, DepNodeIndex};
use rustc::hir::exports::Export;
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::middle::cstore::{CrateSource, ExternCrate};
use rustc::middle::cstore::{ForeignModule, LinkagePreference, NativeLibrary};
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
@ -29,6 +27,8 @@ use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::DefPathTable;
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc_index::vec::{Idx, IndexVec};
use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder};
use rustc_session::Session;

View File

@ -5,8 +5,6 @@ use crate::native_libs;
use crate::rmeta::{self, encoder};
use rustc::hir::exports::Export;
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::map::{DefKey, DefPath, DefPathHash};
use rustc::middle::cstore::{CrateSource, CrateStore, EncodedMetadata, NativeLibraryKind};
use rustc::middle::exported_symbols::ExportedSymbol;
use rustc::middle::stability::DeprecationEntry;
@ -19,6 +17,8 @@ use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::svh::Svh;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::DefPathTable;
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
use rustc_session::{CrateDisambiguator, Session};
use rustc_span::source_map::{self, Span, Spanned};
use rustc_span::symbol::Symbol;

View File

@ -2,7 +2,6 @@ use crate::rmeta::table::FixedSizeEncoding;
use crate::rmeta::*;
use log::{debug, trace};
use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::map::Map;
use rustc::middle::cstore::{EncodedMetadata, ForeignModule, LinkagePreference, NativeLibrary};
use rustc::middle::dependency_format::Linkage;
@ -23,6 +22,7 @@ use rustc_hir as hir;
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefIdSet;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::DefPathTable;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
use rustc_hir::{AnonConst, GenericParamKind};

View File

@ -1,10 +1,10 @@
use log::debug;
use rustc::hir::map::definitions::*;
use rustc_ast::ast::*;
use rustc_ast::token::{self, Token};
use rustc_ast::visit::{self, FnKind};
use rustc_expand::expand::AstFragment;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::definitions::*;
use rustc_span::hygiene::ExpnId;
use rustc_span::symbol::{kw, sym};
use rustc_span::Span;

View File

@ -1,6 +1,7 @@
pub use self::Level::*;
use rustc_ast::node_id::{NodeId, NodeMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
use rustc_span::edition::Edition;
use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
@ -367,3 +368,45 @@ macro_rules! declare_lint_pass {
$crate::impl_lint_pass!($name => [$($lint),*]);
};
}
pub fn add_elided_lifetime_in_path_suggestion(
sess: &crate::Session,
db: &mut DiagnosticBuilder<'_>,
n: usize,
path_span: Span,
incl_angl_brckt: bool,
insertion_span: Span,
anon_lts: String,
) {
let (replace_span, suggestion) = if incl_angl_brckt {
(insertion_span, anon_lts)
} else {
// When possible, prefer a suggestion that replaces the whole
// `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
// at a point (which makes for an ugly/confusing label)
if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
// But our spans can get out of whack due to macros; if the place we think
// we want to insert `'_` isn't even within the path expression's span, we
// should bail out of making any suggestion rather than panicking on a
// subtract-with-overflow or string-slice-out-out-bounds (!)
// FIXME: can we do better?
if insertion_span.lo().0 < path_span.lo().0 {
return;
}
let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
if insertion_index > snippet.len() {
return;
}
let (before, after) = snippet.split_at(insertion_index);
(path_span, format!("{}{}{}", before, anon_lts, after))
} else {
(insertion_span, anon_lts)
}
};
db.span_suggestion(
replace_span,
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
suggestion,
Applicability::MachineApplicable,
);
}

View File

@ -1,41 +1,30 @@
use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
use crate::cgu_reuse_tracker::CguReuseTracker;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use crate::config::{self, OutputType, PrintRequest, Sanitizer, SwitchWithOptPath};
use crate::filesearch;
use crate::lint;
use crate::parse::ParseSess;
use crate::search_paths::{PathKind, SearchPath};
use rustc_data_structures::profiling::duration_to_secs_str;
use rustc_errors::ErrorReported;
use rustc_data_structures::base_n;
use rustc_data_structures::impl_stable_hash_via_hash;
pub use rustc_ast::crate_disambiguator::CrateDisambiguator;
use rustc_data_structures::flock;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::jobserver::{self, Client};
use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef};
use rustc_data_structures::sync::{
self, AtomicU64, AtomicUsize, Lock, Lrc, Once, OneThread, Ordering, Ordering::SeqCst,
};
use crate::parse::ParseSess;
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::emitter::{Emitter, EmitterWriter};
use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
use rustc_errors::json::JsonEmitter;
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_span::edition::Edition;
use rustc_span::source_map;
use rustc_span::{MultiSpan, Span};
use rustc_data_structures::flock;
use rustc_data_structures::jobserver::{self, Client};
use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
use rustc_span::source_map::{self, MultiSpan, Span};
use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
use std::cell::{self, RefCell};
use std::env;
use std::fmt;
use std::io::Write;
use std::num::NonZeroU32;
use std::path::PathBuf;
@ -1193,34 +1182,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
}
/// Hash value constructed out of all the `-C metadata` arguments passed to the
/// compiler. Together with the crate-name forms a unique global identifier for
/// the crate.
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
pub struct CrateDisambiguator(Fingerprint);
impl CrateDisambiguator {
pub fn to_fingerprint(self) -> Fingerprint {
self.0
}
}
impl fmt::Display for CrateDisambiguator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
let (a, b) = self.0.as_value();
let as_u128 = a as u128 | ((b as u128) << 64);
f.write_str(&base_n::encode(as_u128, base_n::CASE_INSENSITIVE))
}
}
impl From<Fingerprint> for CrateDisambiguator {
fn from(fingerprint: Fingerprint) -> CrateDisambiguator {
CrateDisambiguator(fingerprint)
}
}
impl_stable_hash_via_hash!(CrateDisambiguator);
/// Holds data on the current incremental compilation session, if there is one.
#[derive(Debug)]
pub enum IncrCompSession {

View File

@ -1,6 +1,5 @@
mod environment;
use rustc::hir::map::definitions::DefPathData;
use rustc::hir::map::Map;
use rustc::traits::{
Clause, Clauses, DomainGoal, FromEnv, GoalKind, PolyDomainGoal, ProgramClause,
@ -13,6 +12,7 @@ use rustc_ast::ast;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_span::symbol::sym;