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:
commit
37c945dd61
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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>
|
||||
|
35
src/librustc_ast/crate_disambiguator.rs
Normal file
35
src/librustc_ast/crate_disambiguator.rs
Normal 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);
|
@ -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;
|
||||
|
@ -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" }
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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) }
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
49
src/librustc_hir/arena.rs
Normal 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);
|
||||
)
|
||||
}
|
@ -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
|
||||
}
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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))))
|
||||
})
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user