1
Fork 0

Rollup merge of #61968 - eddyb:hir-noclone, r=petrochenkov

rustc: disallow cloning HIR nodes.

Besides being inefficient, cloning also risks creating broken HIR (without properly recreating all the IDs and whatnot, in which case you might as well reconstruct the entire node without ever `Clone`-ing anything).

We detect *some* detrimental situations (based on the occurrence of `HirId`s, I believe?), but it's better to statically disallow it, IMO.

One of the examples that is fixed by this PR is `tcx.hir().fn_decl{,_by_hir_id}`, which was cloning an entire `hir::FnDecl` *every single time it was called*.

r? @petrochenkov cc @rust-lang/compiler
This commit is contained in:
Mazdak Farrokhzad 2019-06-20 08:36:03 +02:00 committed by GitHub
commit 942a7fec30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 567 additions and 576 deletions

View file

@ -608,15 +608,7 @@ impl<'a> LoweringContext<'a> {
});
if let Some(hir_id) = item_hir_id {
let item_generics = match self.lctx.items.get(&hir_id).unwrap().node {
hir::ItemKind::Impl(_, _, _, ref generics, ..)
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
generics.params.clone()
}
_ => HirVec::new(),
};
self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node {
this.with_trait_impl_ref(opt_trait_ref, |this| {
@ -1054,14 +1046,22 @@ impl<'a> LoweringContext<'a> {
// This should only be used with generics that have already had their
// in-band lifetimes added. In practice, this means that this function is
// only used when lowering a child item of a trait or impl.
fn with_parent_impl_lifetime_defs<T, F>(&mut self,
params: &HirVec<hir::GenericParam>,
fn with_parent_item_lifetime_defs<T, F>(&mut self,
parent_hir_id: hir::HirId,
f: F
) -> T where
F: FnOnce(&mut LoweringContext<'_>) -> T,
{
let old_len = self.in_scope_lifetimes.len();
let lt_def_names = params.iter().filter_map(|param| match param.kind {
let parent_generics = match self.items.get(&parent_hir_id).unwrap().node {
hir::ItemKind::Impl(_, _, _, ref generics, ..)
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
&generics.params[..]
}
_ => &[],
};
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
hir::GenericParamKind::Lifetime { .. } => Some(param.name.ident().modern()),
_ => None,
});
@ -1113,8 +1113,7 @@ impl<'a> LoweringContext<'a> {
lowered_generics.params = lowered_generics
.params
.iter()
.cloned()
.into_iter()
.chain(in_band_defs)
.collect();
@ -3114,8 +3113,8 @@ impl<'a> LoweringContext<'a> {
&NodeMap::default(),
itctx.reborrow(),
);
let trait_ref = self.with_parent_impl_lifetime_defs(
&bound_generic_params,
let trait_ref = self.with_in_scope_lifetime_defs(
&p.bound_generic_params,
|this| this.lower_trait_ref(&p.trait_ref, itctx),
);
@ -3602,8 +3601,7 @@ impl<'a> LoweringContext<'a> {
// Essentially a single `use` which imports two names is desugared into
// two imports.
for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) {
let vis = vis.clone();
let ident = ident.clone();
let ident = *ident;
let mut path = path.clone();
for seg in &mut path.segments {
seg.id = self.sess.next_node_id();
@ -3616,19 +3614,7 @@ impl<'a> LoweringContext<'a> {
let path =
this.lower_path_extra(res, &path, ParamMode::Explicit, None);
let item = hir::ItemKind::Use(P(path), hir::UseKind::Single);
let vis_kind = match vis.node {
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
let path = this.renumber_segment_ids(path);
hir::VisibilityKind::Restricted {
path,
hir_id: this.next_id(),
}
}
};
let vis = respan(vis.span, vis_kind);
let vis = this.rebuild_vis(&vis);
this.insert_item(
hir::Item {
@ -3692,8 +3678,6 @@ impl<'a> LoweringContext<'a> {
for &(ref use_tree, id) in trees {
let new_hir_id = self.lower_node_id(id);
let mut vis = vis.clone();
let mut ident = ident.clone();
let mut prefix = prefix.clone();
// Give the segments new node-ids since they are being cloned.
@ -3707,6 +3691,9 @@ impl<'a> LoweringContext<'a> {
// own its own names, we have to adjust the owner before
// lowering the rest of the import.
self.with_hir_id_owner(id, |this| {
let mut vis = this.rebuild_vis(&vis);
let mut ident = *ident;
let item = this.lower_use_tree(use_tree,
&prefix,
id,
@ -3714,20 +3701,6 @@ impl<'a> LoweringContext<'a> {
&mut ident,
attrs);
let vis_kind = match vis.node {
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
let path = this.renumber_segment_ids(path);
hir::VisibilityKind::Restricted {
path: path,
hir_id: this.next_id(),
}
}
};
let vis = respan(vis.span, vis_kind);
this.insert_item(
hir::Item {
hir_id: new_hir_id,
@ -3773,15 +3746,35 @@ impl<'a> LoweringContext<'a> {
/// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
/// many times in the HIR tree; for each occurrence, we need to assign distinct
/// `NodeId`s. (See, e.g., #56128.)
fn renumber_segment_ids(&mut self, path: &P<hir::Path>) -> P<hir::Path> {
debug!("renumber_segment_ids(path = {:?})", path);
let mut path = path.clone();
for seg in path.segments.iter_mut() {
if seg.hir_id.is_some() {
seg.hir_id = Some(self.next_id());
}
fn rebuild_use_path(&mut self, path: &hir::Path) -> hir::Path {
debug!("rebuild_use_path(path = {:?})", path);
let segments = path.segments.iter().map(|seg| hir::PathSegment {
ident: seg.ident,
hir_id: seg.hir_id.map(|_| self.next_id()),
res: seg.res,
args: None,
infer_args: seg.infer_args,
}).collect();
hir::Path {
span: path.span,
res: path.res,
segments,
}
path
}
fn rebuild_vis(&mut self, vis: &hir::Visibility) -> hir::Visibility {
let vis_kind = match vis.node {
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
hir::VisibilityKind::Restricted {
path: P(self.rebuild_use_path(path)),
hir_id: self.next_id(),
}
}
};
respan(vis.span, vis_kind)
}
fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {

View file

@ -51,11 +51,11 @@ impl<'hir> Entry<'hir> {
}
}
fn fn_decl(&self) -> Option<&FnDecl> {
fn fn_decl(&self) -> Option<&'hir FnDecl> {
match self.node {
Node::Item(ref item) => {
match item.node {
ItemKind::Fn(ref fn_decl, _, _, _) => Some(&fn_decl),
ItemKind::Fn(ref fn_decl, _, _, _) => Some(fn_decl),
_ => None,
}
}
@ -76,7 +76,7 @@ impl<'hir> Entry<'hir> {
Node::Expr(ref expr) => {
match expr.node {
ExprKind::Closure(_, ref fn_decl, ..) => Some(&fn_decl),
ExprKind::Closure(_, ref fn_decl, ..) => Some(fn_decl),
_ => None,
}
}
@ -412,9 +412,9 @@ impl<'hir> Map<'hir> {
self.forest.krate.body(id)
}
pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<FnDecl> {
pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl> {
if let Some(entry) = self.find_entry(hir_id) {
entry.fn_decl().cloned()
entry.fn_decl()
} else {
bug!("no entry for hir_id `{}`", hir_id)
}

View file

@ -155,7 +155,7 @@ pub const DUMMY_HIR_ID: HirId = HirId {
pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
pub struct Lifetime {
pub hir_id: HirId,
pub span: Span,
@ -295,7 +295,7 @@ impl Lifetime {
/// A `Path` is essentially Rust's notion of a name; for instance,
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(RustcEncodable, RustcDecodable, HashStable)]
pub struct Path {
pub span: Span,
/// The resolution for the path.
@ -324,7 +324,7 @@ impl fmt::Display for Path {
/// A segment of a path: an identifier, an optional lifetime, and a set of
/// types.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct PathSegment {
/// The identifier portion of this path segment.
#[stable_hasher(project(name))]
@ -383,27 +383,23 @@ impl PathSegment {
}
}
// FIXME: hack required because you can't create a static
// `GenericArgs`, so you can't just return a `&GenericArgs`.
pub fn with_generic_args<F, R>(&self, f: F) -> R
where F: FnOnce(&GenericArgs) -> R
{
let dummy = GenericArgs::none();
f(if let Some(ref args) = self.args {
&args
pub fn generic_args(&self) -> &GenericArgs {
if let Some(ref args) = self.args {
args
} else {
&dummy
})
const DUMMY: &GenericArgs = &GenericArgs::none();
DUMMY
}
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct ConstArg {
pub value: AnonConst,
pub span: Span,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum GenericArg {
Lifetime(Lifetime),
Type(Ty),
@ -435,7 +431,7 @@ impl GenericArg {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct GenericArgs {
/// The generic arguments for this path segment.
pub args: HirVec<GenericArg>,
@ -449,7 +445,7 @@ pub struct GenericArgs {
}
impl GenericArgs {
pub fn none() -> Self {
pub const fn none() -> Self {
Self {
args: HirVec::new(),
bindings: HirVec::new(),
@ -509,7 +505,7 @@ pub enum TraitBoundModifier {
/// `typeck::collect::compute_bounds` matches these against
/// the "special" built-in traits (see `middle::lang_items`) and
/// detects `Copy`, `Send` and `Sync`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum GenericBound {
Trait(PolyTraitRef, TraitBoundModifier),
Outlives(Lifetime),
@ -545,7 +541,7 @@ pub enum LifetimeParamKind {
Error,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum GenericParamKind {
/// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
Lifetime {
@ -560,7 +556,7 @@ pub enum GenericParamKind {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct GenericParam {
pub hir_id: HirId,
pub name: ParamName,
@ -580,7 +576,7 @@ pub struct GenericParamCount {
/// Represents lifetimes and type parameters attached to a declaration
/// of a function, enum, trait, etc.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Generics {
pub params: HirVec<GenericParam>,
pub where_clause: WhereClause,
@ -588,7 +584,7 @@ pub struct Generics {
}
impl Generics {
pub fn empty() -> Generics {
pub const fn empty() -> Generics {
Generics {
params: HirVec::new(),
where_clause: WhereClause {
@ -642,7 +638,7 @@ pub enum SyntheticTyParamKind {
}
/// A where-clause in a definition.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct WhereClause {
pub predicates: HirVec<WherePredicate>,
// Only valid if predicates isn't empty.
@ -660,7 +656,7 @@ impl WhereClause {
}
/// A single predicate in a where-clause.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum WherePredicate {
/// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
BoundPredicate(WhereBoundPredicate),
@ -681,7 +677,7 @@ impl WherePredicate {
}
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct WhereBoundPredicate {
pub span: Span,
/// Any generics from a `for` binding.
@ -693,7 +689,7 @@ pub struct WhereBoundPredicate {
}
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct WhereRegionPredicate {
pub span: Span,
pub lifetime: Lifetime,
@ -701,7 +697,7 @@ pub struct WhereRegionPredicate {
}
/// An equality predicate (e.g., `T = int`); currently unsupported.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct WhereEqPredicate {
pub hir_id: HirId,
pub span: Span,
@ -709,7 +705,7 @@ pub struct WhereEqPredicate {
pub rhs_ty: P<Ty>,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct ModuleItems {
// Use BTreeSets here so items are in the same order as in the
// list of all items in Crate
@ -724,7 +720,7 @@ pub struct ModuleItems {
/// For more details, see the [rustc guide].
///
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct Crate {
pub module: Mod,
pub attrs: HirVec<Attribute>,
@ -819,7 +815,7 @@ impl Crate {
/// A macro definition, in this crate or imported from another.
///
/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct MacroDef {
pub name: Name,
pub vis: Visibility,
@ -833,7 +829,7 @@ pub struct MacroDef {
/// A block of statements `{ .. }`, which may have a label (in this case the
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
/// the `rules` being anything but `DefaultBlock`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Block {
/// Statements in a block.
pub stmts: HirVec<Stmt>,
@ -851,7 +847,7 @@ pub struct Block {
pub targeted_by_break: bool,
}
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(RustcEncodable, RustcDecodable, HashStable)]
pub struct Pat {
#[stable_hasher(ignore)]
pub hir_id: HirId,
@ -914,7 +910,7 @@ impl Pat {
/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
/// are treated the same as` x: x, y: ref y, z: ref mut z`,
/// except `is_shorthand` is true.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct FieldPat {
#[stable_hasher(ignore)]
pub hir_id: HirId,
@ -929,7 +925,7 @@ pub struct FieldPat {
/// Explicit binding annotations given in the HIR for a binding. Note
/// that this is not the final binding *mode* that we infer after type
/// inference.
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum BindingAnnotation {
/// No binding annotation given: this means that the final binding mode
/// will depend on whether we have skipped through a `&` reference
@ -956,7 +952,7 @@ pub enum RangeEnd {
Excluded,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum PatKind {
/// Represents a wildcard pattern (i.e., `_`).
Wild,
@ -1001,8 +997,8 @@ pub enum PatKind {
Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Mutability {
MutMutable,
MutImmutable,
@ -1018,7 +1014,7 @@ impl Mutability {
}
}
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)]
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Hash, HashStable)]
pub enum BinOpKind {
/// The `+` operator (addition).
Add,
@ -1152,7 +1148,7 @@ impl Into<ast::BinOpKind> for BinOpKind {
pub type BinOp = Spanned<BinOpKind>;
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)]
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Hash, HashStable)]
pub enum UnOp {
/// The `*` operator (deferencing).
UnDeref,
@ -1181,7 +1177,7 @@ impl UnOp {
}
/// A statement.
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(RustcEncodable, RustcDecodable)]
pub struct Stmt {
pub hir_id: HirId,
pub node: StmtKind,
@ -1196,7 +1192,7 @@ impl fmt::Debug for Stmt {
}
/// The contents of a statement.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(RustcEncodable, RustcDecodable, HashStable)]
pub enum StmtKind {
/// A local (`let`) binding.
Local(P<Local>),
@ -1223,7 +1219,7 @@ impl StmtKind {
}
/// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Local {
pub pat: P<Pat>,
/// Type annotation, if any (otherwise the type will be inferred).
@ -1240,7 +1236,7 @@ pub struct Local {
/// Represents a single arm of a `match` expression, e.g.
/// `<pats> (if <guard>) => <body>`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Arm {
#[stable_hasher(ignore)]
pub hir_id: HirId,
@ -1254,12 +1250,12 @@ pub struct Arm {
pub body: P<Expr>,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum Guard {
If(P<Expr>),
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Field {
#[stable_hasher(ignore)]
pub hir_id: HirId,
@ -1269,7 +1265,7 @@ pub struct Field {
pub is_shorthand: bool,
}
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum BlockCheckMode {
DefaultBlock,
UnsafeBlock(UnsafeSource),
@ -1277,7 +1273,7 @@ pub enum BlockCheckMode {
PopUnsafeBlock(UnsafeSource),
}
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum UnsafeSource {
CompilerGenerated,
UserProvided,
@ -1309,7 +1305,7 @@ pub struct BodyId {
///
/// All bodies have an **owner**, which can be accessed via the HIR
/// map using `body_owner_def_id()`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct Body {
pub arguments: HirVec<Arg>,
pub value: Expr,
@ -1383,7 +1379,7 @@ pub struct AnonConst {
}
/// An expression
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(RustcEncodable, RustcDecodable)]
pub struct Expr {
pub span: Span,
pub node: ExprKind,
@ -1494,7 +1490,7 @@ impl fmt::Debug for Expr {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ExprKind {
/// A `box x` expression.
Box(P<Expr>),
@ -1602,7 +1598,7 @@ pub enum ExprKind {
}
/// Represents an optionally `Self`-qualified value/type path or associated extension.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum QPath {
/// Path to a definition, optionally "fully-qualified" with a `Self`
/// type, if the path points to an associated item in a trait.
@ -1622,7 +1618,7 @@ pub enum QPath {
}
/// Hints at the original code for a let statement.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum LocalSource {
/// A `match _ { .. }`.
Normal,
@ -1644,7 +1640,7 @@ pub enum LocalSource {
}
/// Hints at the original code for a `match _ { .. }`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
pub enum MatchSource {
/// A `match _ { .. }`.
Normal,
@ -1668,7 +1664,7 @@ pub enum MatchSource {
}
/// The loop type that yielded an `ExprKind::Loop`.
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum LoopSource {
/// A `loop { .. }` loop.
Loop,
@ -1678,7 +1674,7 @@ pub enum LoopSource {
ForLoop,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum LoopIdError {
OutsideLoopScope,
UnlabeledCfInWhileCondition,
@ -1696,7 +1692,7 @@ impl fmt::Display for LoopIdError {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Destination {
// This is `Some(_)` iff there is an explicit user-specified `label
pub label: Option<Label>,
@ -1707,8 +1703,8 @@ pub struct Destination {
}
/// Whether a generator contains self-references, causing it to be `!Unpin`.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum GeneratorMovability {
/// May contain self-references, `!Unpin`.
Static,
@ -1717,7 +1713,7 @@ pub enum GeneratorMovability {
}
/// The yield kind that caused an `ExprKind::Yield`.
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub enum YieldSource {
/// An `<expr>.await`.
Await,
@ -1734,7 +1730,7 @@ impl fmt::Display for YieldSource {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum CaptureClause {
CaptureByValue,
CaptureByRef,
@ -1742,14 +1738,14 @@ pub enum CaptureClause {
// N.B., if you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct MutTy {
pub ty: P<Ty>,
pub mutbl: Mutability,
}
/// Represents a method's signature in a trait declaration or implementation.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct MethodSig {
pub header: FnHeader,
pub decl: P<FnDecl>,
@ -1767,7 +1763,7 @@ pub struct TraitItemId {
/// possibly including a default implementation. A trait item is
/// either required (meaning it doesn't have an implementation, just a
/// signature) or provided (meaning it has a default implementation).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct TraitItem {
pub ident: Ident,
pub hir_id: HirId,
@ -1778,7 +1774,7 @@ pub struct TraitItem {
}
/// Represents a trait method's body (or just argument names).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum TraitMethod {
/// No default body in the trait, just a signature.
Required(HirVec<Ident>),
@ -1788,7 +1784,7 @@ pub enum TraitMethod {
}
/// Represents a trait method or associated constant or type
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum TraitItemKind {
/// An associated constant with an optional value (otherwise `impl`s must contain a value).
Const(P<Ty>, Option<BodyId>),
@ -1808,7 +1804,7 @@ pub struct ImplItemId {
}
/// Represents anything within an `impl` block
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct ImplItem {
pub ident: Ident,
pub hir_id: HirId,
@ -1821,7 +1817,7 @@ pub struct ImplItem {
}
/// Represents various kinds of content within an `impl`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ImplItemKind {
/// An associated constant of the given type, set to the constant result
/// of the expression
@ -1848,7 +1844,7 @@ pub enum ImplItemKind {
/// Binding(...),
/// }
/// ```
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct TypeBinding {
pub hir_id: HirId,
#[stable_hasher(project(name))]
@ -1858,7 +1854,7 @@ pub struct TypeBinding {
}
// Represents the two kinds of type bindings.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum TypeBindingKind {
/// E.g., `Foo<Bar: Send>`.
Constraint {
@ -1879,7 +1875,7 @@ impl TypeBinding {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(RustcEncodable, RustcDecodable)]
pub struct Ty {
pub hir_id: HirId,
pub node: TyKind,
@ -1894,7 +1890,7 @@ impl fmt::Debug for Ty {
}
/// Not represented directly in the AST; referred to by name through a `ty_path`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)]
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
pub enum PrimTy {
Int(IntTy),
Uint(UintTy),
@ -1904,7 +1900,7 @@ pub enum PrimTy {
Char,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct BareFnTy {
pub unsafety: Unsafety,
pub abi: Abi,
@ -1913,7 +1909,7 @@ pub struct BareFnTy {
pub arg_names: HirVec<Ident>,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct ExistTy {
pub generics: Generics,
pub bounds: GenericBounds,
@ -1933,7 +1929,7 @@ pub enum ExistTyOrigin {
}
/// The various kinds of types recognized by the compiler.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum TyKind {
/// A variable length slice (i.e., `[T]`).
Slice(P<Ty>),
@ -1975,7 +1971,7 @@ pub enum TyKind {
CVarArgs(Lifetime),
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct InlineAsmOutput {
pub constraint: Symbol,
pub is_rw: bool,
@ -1998,14 +1994,14 @@ pub struct InlineAsm {
}
/// Represents an argument in a function header.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Arg {
pub pat: P<Pat>,
pub hir_id: HirId,
}
/// Represents the header (not the body) of a function declaration.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct FnDecl {
/// The types of the function's arguments.
///
@ -2018,7 +2014,7 @@ pub struct FnDecl {
}
/// Represents what type of implicit self a function has, if any.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ImplicitSelfKind {
/// Represents a `fn x(self);`.
Imm,
@ -2123,7 +2119,7 @@ impl fmt::Debug for ImplPolarity {
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum FunctionRetTy {
/// Return type is not specified.
///
@ -2153,7 +2149,7 @@ impl FunctionRetTy {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
@ -2162,25 +2158,25 @@ pub struct Mod {
pub item_ids: HirVec<ItemId>,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct ForeignMod {
pub abi: Abi,
pub items: HirVec<ForeignItem>,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct GlobalAsm {
pub asm: Symbol,
#[stable_hasher(ignore)] // This is used for error reporting
pub ctxt: SyntaxContext,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct EnumDef {
pub variants: HirVec<Variant>,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct VariantKind {
/// Name of the variant.
#[stable_hasher(project(name))]
@ -2219,7 +2215,7 @@ pub enum UseKind {
/// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
/// trait being referred to but just a unique `HirId` that serves as a key
/// within the resolution map.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct TraitRef {
pub path: Path,
// Don't hash the ref_id. It is tracked via the thing it is used to access
@ -2241,7 +2237,7 @@ impl TraitRef {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct PolyTraitRef {
/// The `'a` in `<'a> Foo<&'a T>`.
pub bound_generic_params: HirVec<GenericParam>,
@ -2254,7 +2250,7 @@ pub struct PolyTraitRef {
pub type Visibility = Spanned<VisibilityKind>;
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub enum VisibilityKind {
Public,
Crate(CrateSugar),
@ -2289,7 +2285,7 @@ impl VisibilityKind {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct StructField {
pub span: Span,
#[stable_hasher(project(name))]
@ -2309,7 +2305,7 @@ impl StructField {
}
/// Fields and constructor IDs of enum variants and structs.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum VariantData {
/// A struct variant.
///
@ -2354,7 +2350,7 @@ pub struct ItemId {
/// An item
///
/// The name might be a dummy name in case of anonymous items
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(RustcEncodable, RustcDecodable, Debug)]
pub struct Item {
pub ident: Ident,
pub hir_id: HirId,
@ -2364,7 +2360,7 @@ pub struct Item {
pub span: Span,
}
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct FnHeader {
pub unsafety: Unsafety,
pub constness: Constness,
@ -2381,7 +2377,7 @@ impl FnHeader {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ItemKind {
/// An `extern crate` item, with optional *original* crate name if the crate was renamed.
///
@ -2484,7 +2480,7 @@ impl ItemKind {
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct TraitItemRef {
pub id: TraitItemId,
#[stable_hasher(project(name))]
@ -2500,7 +2496,7 @@ pub struct TraitItemRef {
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct ImplItemRef {
pub id: ImplItemId,
#[stable_hasher(project(name))]
@ -2519,7 +2515,7 @@ pub enum AssocItemKind {
Existential,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct ForeignItem {
#[stable_hasher(project(name))]
pub ident: Ident,
@ -2531,7 +2527,7 @@ pub struct ForeignItem {
}
/// An item within an `extern` block.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ForeignItemKind {
/// A foreign function.
Fn(P<FnDecl>, HirVec<Ident>, Generics),

View file

@ -625,10 +625,10 @@ impl<'a> State<'a> {
self.word_space("for ?")?;
self.print_trait_ref(&ptr.trait_ref)?;
} else {
real_bounds.push(b.clone());
real_bounds.push(b);
}
}
self.print_bounds(":", &real_bounds[..])?;
self.print_bounds(":", real_bounds)?;
self.s.word(";")?;
self.end()?; // end the outer ibox
}
@ -698,10 +698,10 @@ impl<'a> State<'a> {
self.word_space("for ?")?;
self.print_trait_ref(&ptr.trait_ref)?;
} else {
real_bounds.push(b.clone());
real_bounds.push(b);
}
}
self.print_bounds(":", &real_bounds[..])?;
self.print_bounds(":", real_bounds)?;
self.print_where_clause(&generics.where_clause)?;
self.s.word(" ")?;
self.bopen()?;
@ -724,11 +724,11 @@ impl<'a> State<'a> {
self.word_space("for ?")?;
self.print_trait_ref(&ptr.trait_ref)?;
} else {
real_bounds.push(b.clone());
real_bounds.push(b);
}
}
self.nbsp()?;
self.print_bounds("=", &real_bounds[..])?;
self.print_bounds("=", real_bounds)?;
self.print_where_clause(&generics.where_clause)?;
self.s.word(";")?;
}
@ -1194,12 +1194,11 @@ impl<'a> State<'a> {
self.s.word(".")?;
self.print_ident(segment.ident)?;
segment.with_generic_args(|generic_args| {
if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
return self.print_generic_args(&generic_args, segment.infer_args, true);
}
Ok(())
})?;
let generic_args = segment.generic_args();
if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
self.print_generic_args(generic_args, segment.infer_args, true)?;
}
self.print_call_post(base_args)
}
@ -1559,11 +1558,9 @@ impl<'a> State<'a> {
self.s.word("::")?
}
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident)?;
segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args, segment.infer_args,
colons_before_params)
})?;
self.print_ident(segment.ident)?;
self.print_generic_args(segment.generic_args(), segment.infer_args,
colons_before_params)?;
}
}
@ -1572,10 +1569,8 @@ impl<'a> State<'a> {
pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> {
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident)?;
segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args, segment.infer_args, false)
})?;
self.print_ident(segment.ident)?;
self.print_generic_args(segment.generic_args(), segment.infer_args, false)?;
}
Ok(())
}
@ -1600,11 +1595,9 @@ impl<'a> State<'a> {
}
if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident)?;
segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args,
segment.infer_args,
colons_before_params)
})?;
self.print_generic_args(segment.generic_args(),
segment.infer_args,
colons_before_params)?;
}
}
@ -1612,11 +1605,9 @@ impl<'a> State<'a> {
self.s.word("::")?;
let item_segment = path.segments.last().unwrap();
self.print_ident(item_segment.ident)?;
item_segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args,
item_segment.infer_args,
colons_before_params)
})
self.print_generic_args(item_segment.generic_args(),
item_segment.infer_args,
colons_before_params)
}
hir::QPath::TypeRelative(ref qself, ref item_segment) => {
self.s.word("<")?;
@ -1624,11 +1615,9 @@ impl<'a> State<'a> {
self.s.word(">")?;
self.s.word("::")?;
self.print_ident(item_segment.ident)?;
item_segment.with_generic_args(|generic_args| {
self.print_generic_args(generic_args,
item_segment.infer_args,
colons_before_params)
})
self.print_generic_args(item_segment.generic_args(),
item_segment.infer_args,
colons_before_params)
}
}
}
@ -2009,31 +1998,34 @@ impl<'a> State<'a> {
}
}
pub fn print_bounds(&mut self, prefix: &'static str, bounds: &[hir::GenericBound])
-> io::Result<()> {
if !bounds.is_empty() {
self.s.word(prefix)?;
let mut first = true;
for bound in bounds {
if !(first && prefix.is_empty()) {
self.nbsp()?;
}
if first {
first = false;
} else {
self.word_space("+")?;
}
pub fn print_bounds<'b>(
&mut self,
prefix: &'static str,
bounds: impl IntoIterator<Item = &'b hir::GenericBound>,
) -> io::Result<()> {
let mut first = true;
for bound in bounds {
if first {
self.s.word(prefix)?;
}
if !(first && prefix.is_empty()) {
self.nbsp()?;
}
if first {
first = false;
} else {
self.word_space("+")?;
}
match bound {
GenericBound::Trait(tref, modifier) => {
if modifier == &TraitBoundModifier::Maybe {
self.s.word("?")?;
}
self.print_poly_trait_ref(tref)?;
}
GenericBound::Outlives(lt) => {
self.print_lifetime(lt)?;
match bound {
GenericBound::Trait(tref, modifier) => {
if modifier == &TraitBoundModifier::Maybe {
self.s.word("?")?;
}
self.print_poly_trait_ref(tref)?;
}
GenericBound::Outlives(lt) => {
self.print_lifetime(lt)?;
}
}
}

View file

@ -1050,10 +1050,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
(self.tcx.sess.source_map().def_span(span), self.tcx.hir().body(id).arguments.iter()
.map(|arg| {
if let hir::Pat {
node: hir::PatKind::Tuple(args, _),
node: hir::PatKind::Tuple(ref args, _),
span,
..
} = arg.pat.clone().into_inner() {
} = *arg.pat {
ArgKind::Tuple(
Some(span),
args.iter().map(|pat| {

View file

@ -1815,8 +1815,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// as the HIR doesn't have full types for closure arguments.
let return_ty = *sig.output().skip_binder();
let mut return_span = fn_decl.output.span();
if let hir::FunctionRetTy::Return(ty) = fn_decl.output {
if let hir::TyKind::Rptr(lifetime, _) = ty.into_inner().node {
if let hir::FunctionRetTy::Return(ty) = &fn_decl.output {
if let hir::TyKind::Rptr(lifetime, _) = ty.node {
return_span = lifetime.span;
}
}

View file

@ -97,15 +97,15 @@ pub enum SizedByDefault {
No,
}
struct ConvertedBinding<'tcx> {
struct ConvertedBinding<'a, 'tcx> {
item_name: ast::Ident,
kind: ConvertedBindingKind<'tcx>,
kind: ConvertedBindingKind<'a, 'tcx>,
span: Span,
}
enum ConvertedBindingKind<'tcx> {
enum ConvertedBindingKind<'a, 'tcx> {
Equality(Ty<'tcx>),
Constraint(P<[hir::GenericBound]>),
Constraint(&'a [hir::GenericBound]),
}
#[derive(PartialEq)]
@ -191,15 +191,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
item_segment: &hir::PathSegment)
-> SubstsRef<'tcx>
{
let (substs, assoc_bindings, _) = item_segment.with_generic_args(|generic_args| {
self.create_substs_for_ast_path(
span,
def_id,
generic_args,
item_segment.infer_args,
None,
)
});
let (substs, assoc_bindings, _) = self.create_substs_for_ast_path(
span,
def_id,
item_segment.generic_args(),
item_segment.infer_args,
None,
);
assoc_bindings.first().map(|b| Self::prohibit_assoc_ty_binding(self.tcx(), b.span));
@ -598,7 +596,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
generic_args: &'a hir::GenericArgs,
infer_args: bool,
self_ty: Option<Ty<'tcx>>)
-> (SubstsRef<'tcx>, Vec<ConvertedBinding<'tcx>>, Option<Vec<Span>>)
-> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, Option<Vec<Span>>)
{
// If the type is parameterized by this region, then replace this
// region with the current anon region binding (in other words,
@ -740,7 +738,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
hir::TypeBindingKind::Equality { ref ty } =>
ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty)),
hir::TypeBindingKind::Constraint { ref bounds } =>
ConvertedBindingKind::Constraint(bounds.clone()),
ConvertedBindingKind::Constraint(bounds),
};
ConvertedBinding {
item_name: binding.ident,
@ -861,21 +859,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
ty::TraitRef::new(trait_def_id, substs)
}
fn create_substs_for_ast_trait_ref(
fn create_substs_for_ast_trait_ref<'a>(
&self,
span: Span,
trait_def_id: DefId,
self_ty: Ty<'tcx>,
trait_segment: &hir::PathSegment,
) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'tcx>>, Option<Vec<Span>>) {
trait_segment: &'a hir::PathSegment,
) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, Option<Vec<Span>>) {
debug!("create_substs_for_ast_trait_ref(trait_segment={:?})",
trait_segment);
let trait_def = self.tcx().trait_def(trait_def_id);
if !self.tcx().features().unboxed_closures &&
trait_segment.with_generic_args(|generic_args| generic_args.parenthesized)
!= trait_def.paren_sugar {
trait_segment.generic_args().parenthesized != trait_def.paren_sugar
{
// For now, require that parenthetical notation be used only with `Fn()` etc.
let msg = if trait_def.paren_sugar {
"the precise format of `Fn`-family traits' type parameters is subject to change. \
@ -887,13 +885,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span, GateIssue::Language, msg);
}
trait_segment.with_generic_args(|generic_args| {
self.create_substs_for_ast_path(span,
trait_def_id,
generic_args,
trait_segment.infer_args,
Some(self_ty))
})
self.create_substs_for_ast_path(span,
trait_def_id,
trait_segment.generic_args(),
trait_segment.infer_args,
Some(self_ty))
}
fn trait_defines_associated_type_named(&self,
@ -916,7 +912,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
for ab in ast_bounds {
if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
if unbound.is_none() {
unbound = Some(ptr.trait_ref.clone());
unbound = Some(&ptr.trait_ref);
} else {
span_err!(
tcx.sess,
@ -931,7 +927,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let kind_id = tcx.lang_items().require(SizedTraitLangItem);
match unbound {
Some(ref tpb) => {
Some(tpb) => {
// FIXME(#8559) currently requires the unbound to be built-in.
if let Ok(kind_id) = kind_id {
if tpb.path.res != Res::Def(DefKind::Trait, kind_id) {
@ -1052,7 +1048,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&self,
hir_ref_id: hir::HirId,
trait_ref: ty::PolyTraitRef<'tcx>,
binding: &ConvertedBinding<'tcx>,
binding: &ConvertedBinding<'_, 'tcx>,
bounds: &mut Bounds<'tcx>,
speculative: bool,
dup_bindings: &mut FxHashMap<DefId, Span>,
@ -1169,7 +1165,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}), binding.span));
}
ConvertedBindingKind::Constraint(ref ast_bounds) => {
ConvertedBindingKind::Constraint(ast_bounds) => {
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
//
// `<T as Iterator>::Item: Debug`
@ -1765,47 +1761,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&self, segments: T) -> bool {
let mut has_err = false;
for segment in segments {
segment.with_generic_args(|generic_args| {
let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
for arg in &generic_args.args {
let (span, kind) = match arg {
hir::GenericArg::Lifetime(lt) => {
if err_for_lt { continue }
err_for_lt = true;
has_err = true;
(lt.span, "lifetime")
}
hir::GenericArg::Type(ty) => {
if err_for_ty { continue }
err_for_ty = true;
has_err = true;
(ty.span, "type")
}
hir::GenericArg::Const(ct) => {
if err_for_ct { continue }
err_for_ct = true;
(ct.span, "const")
}
};
let mut err = struct_span_err!(
self.tcx().sess,
span,
E0109,
"{} arguments are not allowed for this type",
kind,
);
err.span_label(span, format!("{} argument not allowed", kind));
err.emit();
if err_for_lt && err_for_ty && err_for_ct {
break;
let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
for arg in &segment.generic_args().args {
let (span, kind) = match arg {
hir::GenericArg::Lifetime(lt) => {
if err_for_lt { continue }
err_for_lt = true;
has_err = true;
(lt.span, "lifetime")
}
}
for binding in &generic_args.bindings {
has_err = true;
Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
hir::GenericArg::Type(ty) => {
if err_for_ty { continue }
err_for_ty = true;
has_err = true;
(ty.span, "type")
}
hir::GenericArg::Const(ct) => {
if err_for_ct { continue }
err_for_ct = true;
(ct.span, "const")
}
};
let mut err = struct_span_err!(
self.tcx().sess,
span,
E0109,
"{} arguments are not allowed for this type",
kind,
);
err.span_label(span, format!("{} argument not allowed", kind));
err.emit();
if err_for_lt && err_for_ty && err_for_ct {
break;
}
})
}
for binding in &segment.generic_args().bindings {
has_err = true;
Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
break;
}
}
has_err
}

View file

@ -3696,39 +3696,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
/// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, ast::Ident)> {
fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> {
let parent = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(blk_id));
self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
}
/// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
fn get_node_fn_decl(&self, node: Node<'_>) -> Option<(hir::FnDecl, ast::Ident, bool)> {
fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
match node {
Node::Item(&hir::Item {
ident, node: hir::ItemKind::Fn(ref decl, ..), ..
}) => decl.clone().and_then(|decl| {
}) => {
// This is less than ideal, it will not suggest a return type span on any
// method called `main`, regardless of whether it is actually the entry point,
// but it will still present it as the reason for the expected type.
Some((decl, ident, ident.name != sym::main))
}),
}
Node::TraitItem(&hir::TraitItem {
ident, node: hir::TraitItemKind::Method(hir::MethodSig {
ref decl, ..
}, ..), ..
}) => decl.clone().and_then(|decl| Some((decl, ident, true))),
}) => Some((decl, ident, true)),
Node::ImplItem(&hir::ImplItem {
ident, node: hir::ImplItemKind::Method(hir::MethodSig {
ref decl, ..
}, ..), ..
}) => decl.clone().and_then(|decl| Some((decl, ident, false))),
}) => Some((decl, ident, false)),
_ => None,
}
}
/// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
/// suggestion can be made, `None` otherwise.
pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, bool)> {
pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> {
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
// `while` before reaching it, as block tail returns are not available in them.
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {

View file

@ -165,7 +165,7 @@ impl ItemCtxt<'tcx> {
ItemCtxt { tcx, item_def_id }
}
pub fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
pub fn to_ty(&self, ast_ty: &'tcx hir::Ty) -> Ty<'tcx> {
AstConv::ast_ty_to_ty(self, ast_ty)
}
}
@ -338,7 +338,7 @@ impl ItemCtxt<'tcx> {
/// bounds for a type parameter `X` if `X::Foo` is used.
fn type_parameter_bounds_in_generics(
&self,
ast_generics: &hir::Generics,
ast_generics: &'tcx hir::Generics,
param_id: hir::HirId,
ty: Ty<'tcx>,
only_self_bounds: OnlySelfBounds,
@ -1909,7 +1909,9 @@ fn explicit_predicates_of<'tcx>(
let mut is_default_impl_trait = None;
let icx = ItemCtxt::new(tcx, def_id);
let no_generics = hir::Generics::empty();
const NO_GENERICS: &hir::Generics = &hir::Generics::empty();
let empty_trait_items = HirVec::new();
let mut predicates = UniquePredicates::new();
@ -1991,17 +1993,17 @@ fn explicit_predicates_of<'tcx>(
}
}
_ => &no_generics,
_ => NO_GENERICS,
}
}
Node::ForeignItem(item) => match item.node {
ForeignItemKind::Static(..) => &no_generics,
ForeignItemKind::Static(..) => NO_GENERICS,
ForeignItemKind::Fn(_, _, ref generics) => generics,
ForeignItemKind::Type => &no_generics,
ForeignItemKind::Type => NO_GENERICS,
},
_ => &no_generics,
_ => NO_GENERICS,
};
let generics = tcx.generics_of(def_id);
@ -2205,7 +2207,7 @@ fn explicit_predicates_of<'tcx>(
fn predicates_from_bound<'tcx>(
astconv: &dyn AstConv<'tcx>,
param_ty: Ty<'tcx>,
bound: &hir::GenericBound,
bound: &'tcx hir::GenericBound,
) -> Vec<(ty::Predicate<'tcx>, Span)> {
match *bound {
hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
@ -2227,7 +2229,7 @@ fn predicates_from_bound<'tcx>(
fn compute_sig_of_foreign_fn_decl<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
decl: &hir::FnDecl,
decl: &'tcx hir::FnDecl,
abi: abi::Abi,
) -> ty::PolyFnSig<'tcx> {
let unsafety = if abi == abi::Abi::RustIntrinsic {

View file

@ -159,7 +159,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
// Clean the crate, translating the entire libsyntax AST to one that is
// understood by rustdoc.
let mut module = self.module.clean(cx);
let mut module = self.module.as_ref().unwrap().clean(cx);
let mut masked_crates = FxHashSet::default();
match module.inner {
@ -600,7 +600,7 @@ pub struct Module {
pub is_crate: bool,
}
impl Clean<Item> for doctree::Module {
impl Clean<Item> for doctree::Module<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let name = if self.name.is_some() {
self.name.expect("No name provided").clean(cx)
@ -620,7 +620,7 @@ impl Clean<Item> for doctree::Module {
items.extend(self.unions.iter().map(|x| x.clean(cx)));
items.extend(self.enums.iter().map(|x| x.clean(cx)));
items.extend(self.fns.iter().map(|x| x.clean(cx)));
items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx)));
items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
items.extend(self.mods.iter().map(|x| x.clean(cx)));
items.extend(self.typedefs.iter().map(|x| x.clean(cx)));
items.extend(self.existentials.iter().map(|x| x.clean(cx)));
@ -1920,10 +1920,10 @@ pub struct Function {
pub ret_types: Vec<Type>,
}
impl Clean<Item> for doctree::Function {
impl Clean<Item> for doctree::Function<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let (generics, decl) = enter_impl_trait(cx, || {
(self.generics.clean(cx), (&self.decl, self.body).clean(cx))
(self.generics.clean(cx), (self.decl, self.body).clean(cx))
});
let did = cx.tcx.hir().local_def_id_from_hir_id(self.id);
@ -2128,7 +2128,7 @@ pub struct Trait {
pub is_auto: bool,
}
impl Clean<Item> for doctree::Trait {
impl Clean<Item> for doctree::Trait<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let attrs = self.attrs.clean(cx);
let is_spotlight = attrs.has_doc_flag(sym::spotlight);
@ -2143,7 +2143,7 @@ impl Clean<Item> for doctree::Trait {
inner: TraitItem(Trait {
auto: self.is_auto.clean(cx),
unsafety: self.unsafety,
items: self.items.clean(cx),
items: self.items.iter().map(|ti| ti.clean(cx)).collect(),
generics: self.generics.clean(cx),
bounds: self.bounds.clean(cx),
is_spotlight,
@ -2159,7 +2159,7 @@ pub struct TraitAlias {
pub bounds: Vec<GenericBound>,
}
impl Clean<Item> for doctree::TraitAlias {
impl Clean<Item> for doctree::TraitAlias<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let attrs = self.attrs.clean(cx);
Item {
@ -2809,7 +2809,8 @@ impl Clean<Type> for hir::Ty {
let mut ty_substs = FxHashMap::default();
let mut lt_substs = FxHashMap::default();
let mut ct_substs = FxHashMap::default();
provided_params.with_generic_args(|generic_args| {
let generic_args = provided_params.generic_args();
{
let mut indices: GenericParamCount = Default::default();
for param in generics.params.iter() {
match param.kind {
@ -2852,11 +2853,11 @@ impl Clean<Type> for hir::Ty {
_ => None,
}
});
if let Some(ty) = type_.cloned() {
if let Some(ty) = type_ {
ty_substs.insert(ty_param_def_id, ty.clean(cx));
} else if let Some(default) = default.clone() {
ty_substs.insert(ty_param_def_id,
default.into_inner().clean(cx));
default.clean(cx));
}
indices.types += 1;
}
@ -2876,7 +2877,7 @@ impl Clean<Type> for hir::Ty {
_ => None,
}
});
if let Some(ct) = const_.cloned() {
if let Some(ct) = const_ {
ct_substs.insert(const_param_def_id, ct.clean(cx));
}
// FIXME(const_generics:defaults)
@ -2884,26 +2885,26 @@ impl Clean<Type> for hir::Ty {
}
}
}
});
}
return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
}
resolve_type(cx, path.clean(cx), self.hir_id)
}
TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref p)) => {
let mut segments: Vec<_> = p.segments.clone().into();
segments.pop();
let trait_path = hir::Path {
span: p.span,
let segments = if p.is_global() { &p.segments[1..] } else { &p.segments };
let trait_segments = &segments[..segments.len() - 1];
let trait_path = self::Path {
global: p.is_global(),
res: Res::Def(
DefKind::Trait,
cx.tcx.associated_item(p.res.def_id()).container.id(),
),
segments: segments.into(),
segments: trait_segments.clean(cx),
};
Type::QPath {
name: p.segments.last().expect("segments were empty").ident.name.clean(cx),
self_type: box qself.clean(cx),
trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id)
trait_: box resolve_type(cx, trait_path, self.hir_id)
}
}
TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
@ -3234,7 +3235,7 @@ pub struct Union {
pub fields_stripped: bool,
}
impl Clean<Item> for doctree::Struct {
impl Clean<Item> for doctree::Struct<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
@ -3254,7 +3255,7 @@ impl Clean<Item> for doctree::Struct {
}
}
impl Clean<Item> for doctree::Union {
impl Clean<Item> for doctree::Union<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
@ -3301,7 +3302,7 @@ pub struct Enum {
pub variants_stripped: bool,
}
impl Clean<Item> for doctree::Enum {
impl Clean<Item> for doctree::Enum<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
@ -3325,7 +3326,7 @@ pub struct Variant {
pub kind: VariantKind,
}
impl Clean<Item> for doctree::Variant {
impl Clean<Item> for doctree::Variant<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
@ -3537,7 +3538,7 @@ impl Clean<PathSegment> for hir::PathSegment {
fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
PathSegment {
name: self.ident.name.clean(cx),
args: self.with_generic_args(|generic_args| generic_args.clean(cx))
args: self.generic_args().clean(cx),
}
}
}
@ -3630,7 +3631,7 @@ pub struct Typedef {
pub generics: Generics,
}
impl Clean<Item> for doctree::Typedef {
impl Clean<Item> for doctree::Typedef<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
@ -3654,7 +3655,7 @@ pub struct Existential {
pub generics: Generics,
}
impl Clean<Item> for doctree::Existential {
impl Clean<Item> for doctree::Existential<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
@ -3704,7 +3705,7 @@ pub struct Static {
pub expr: String,
}
impl Clean<Item> for doctree::Static {
impl Clean<Item> for doctree::Static<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
Item {
@ -3730,7 +3731,7 @@ pub struct Constant {
pub expr: String,
}
impl Clean<Item> for doctree::Constant {
impl Clean<Item> for doctree::Constant<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
@ -3800,11 +3801,11 @@ pub fn get_auto_trait_and_blanket_impls(
.chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id))
}
impl Clean<Vec<Item>> for doctree::Impl {
impl Clean<Vec<Item>> for doctree::Impl<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
let mut ret = Vec::new();
let trait_ = self.trait_.clean(cx);
let items = self.items.clean(cx);
let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>();
// If this impl block is an implementation of the Deref trait, then we
// need to try inlining the target's inherent impl blocks as well.
@ -3901,7 +3902,7 @@ fn build_deref_target_impls(cx: &DocContext<'_>,
}
}
impl Clean<Vec<Item>> for doctree::ExternCrate {
impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| {
@ -3940,7 +3941,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate {
}
}
impl Clean<Vec<Item>> for doctree::Import {
impl Clean<Vec<Item>> for doctree::Import<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
// We consider inlining the documentation of `pub use` statements, but we
// forcefully don't inline if this is not public or if the
@ -4016,22 +4017,11 @@ pub struct ImportSource {
pub did: Option<DefId>,
}
impl Clean<Vec<Item>> for hir::ForeignMod {
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
let mut items = self.items.clean(cx);
for item in &mut items {
if let ForeignFunctionItem(ref mut f) = item.inner {
f.header.abi = self.abi;
}
}
items
}
}
impl Clean<Item> for hir::ForeignItem {
impl Clean<Item> for doctree::ForeignItem<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let inner = match self.node {
let inner = match self.kind {
hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => {
let abi = cx.tcx.hir().get_foreign_abi(self.id);
let (generics, decl) = enter_impl_trait(cx, || {
(generics.clean(cx), (&**decl, &names[..]).clean(cx))
});
@ -4041,7 +4031,7 @@ impl Clean<Item> for hir::ForeignItem {
generics,
header: hir::FnHeader {
unsafety: hir::Unsafety::Unsafe,
abi: Abi::Rust,
abi,
constness: hir::Constness::NotConst,
asyncness: hir::IsAsync::NotAsync,
},
@ -4061,16 +4051,14 @@ impl Clean<Item> for hir::ForeignItem {
}
};
let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
Item {
name: Some(self.ident.clean(cx)),
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: local_did,
source: self.whence.clean(cx),
def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
visibility: self.vis.clean(cx),
stability: get_stability(cx, local_did),
deprecation: get_deprecation(cx, local_did),
stability: self.stab.clean(cx),
deprecation: self.depr.clean(cx),
inner,
}
}
@ -4245,7 +4233,7 @@ pub struct Macro {
pub imported_from: Option<String>,
}
impl Clean<Item> for doctree::Macro {
impl Clean<Item> for doctree::Macro<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let name = self.name.clean(cx);
Item {
@ -4274,7 +4262,7 @@ pub struct ProcMacro {
pub helpers: Vec<String>,
}
impl Clean<Item> for doctree::ProcMacro {
impl Clean<Item> for doctree::ProcMacro<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),

View file

@ -7,52 +7,55 @@ use syntax::ast::{Name, NodeId};
use syntax::attr;
use syntax::ext::base::MacroKind;
use syntax::ptr::P;
use syntax::source_map::Spanned;
use syntax_pos::{self, Span};
use rustc::hir;
use rustc::hir::def_id::CrateNum;
pub struct Module {
pub struct Module<'hir> {
pub name: Option<Name>,
pub attrs: hir::HirVec<ast::Attribute>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub where_outer: Span,
pub where_inner: Span,
pub extern_crates: Vec<ExternCrate>,
pub imports: Vec<Import>,
pub structs: Vec<Struct>,
pub unions: Vec<Union>,
pub enums: Vec<Enum>,
pub fns: Vec<Function>,
pub mods: Vec<Module>,
pub extern_crates: Vec<ExternCrate<'hir>>,
pub imports: Vec<Import<'hir>>,
pub structs: Vec<Struct<'hir>>,
pub unions: Vec<Union<'hir>>,
pub enums: Vec<Enum<'hir>>,
pub fns: Vec<Function<'hir>>,
pub mods: Vec<Module<'hir>>,
pub id: NodeId,
pub typedefs: Vec<Typedef>,
pub existentials: Vec<Existential>,
pub statics: Vec<Static>,
pub constants: Vec<Constant>,
pub traits: Vec<Trait>,
pub vis: hir::Visibility,
pub typedefs: Vec<Typedef<'hir>>,
pub existentials: Vec<Existential<'hir>>,
pub statics: Vec<Static<'hir>>,
pub constants: Vec<Constant<'hir>>,
pub traits: Vec<Trait<'hir>>,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub impls: Vec<Impl>,
pub foreigns: Vec<hir::ForeignMod>,
pub macros: Vec<Macro>,
pub proc_macros: Vec<ProcMacro>,
pub trait_aliases: Vec<TraitAlias>,
pub impls: Vec<Impl<'hir>>,
pub foreigns: Vec<ForeignItem<'hir>>,
pub macros: Vec<Macro<'hir>>,
pub proc_macros: Vec<ProcMacro<'hir>>,
pub trait_aliases: Vec<TraitAlias<'hir>>,
pub is_crate: bool,
}
impl Module {
pub fn new(name: Option<Name>) -> Module {
impl Module<'hir> {
pub fn new(
name: Option<Name>,
attrs: &'hir hir::HirVec<ast::Attribute>,
vis: &'hir hir::Visibility,
) -> Module<'hir> {
Module {
name : name,
id: ast::CRATE_NODE_ID,
vis: Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited },
vis,
stab: None,
depr: None,
where_outer: syntax_pos::DUMMY_SP,
where_inner: syntax_pos::DUMMY_SP,
attrs : hir::HirVec::new(),
attrs,
extern_crates: Vec::new(),
imports : Vec::new(),
structs : Vec::new(),
@ -85,167 +88,178 @@ pub enum StructType {
Unit,
}
pub struct Struct {
pub vis: hir::Visibility,
pub struct Struct<'hir> {
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub id: hir::HirId,
pub struct_type: StructType,
pub name: Name,
pub generics: hir::Generics,
pub attrs: hir::HirVec<ast::Attribute>,
pub fields: hir::HirVec<hir::StructField>,
pub generics: &'hir hir::Generics,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub fields: &'hir [hir::StructField],
pub whence: Span,
}
pub struct Union {
pub vis: hir::Visibility,
pub struct Union<'hir> {
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub id: hir::HirId,
pub struct_type: StructType,
pub name: Name,
pub generics: hir::Generics,
pub attrs: hir::HirVec<ast::Attribute>,
pub fields: hir::HirVec<hir::StructField>,
pub generics: &'hir hir::Generics,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub fields: &'hir [hir::StructField],
pub whence: Span,
}
pub struct Enum {
pub vis: hir::Visibility,
pub struct Enum<'hir> {
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub variants: hir::HirVec<Variant>,
pub generics: hir::Generics,
pub attrs: hir::HirVec<ast::Attribute>,
pub variants: Vec<Variant<'hir>>,
pub generics: &'hir hir::Generics,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub id: hir::HirId,
pub whence: Span,
pub name: Name,
}
pub struct Variant {
pub struct Variant<'hir> {
pub name: Name,
pub id: hir::HirId,
pub attrs: hir::HirVec<ast::Attribute>,
pub def: hir::VariantData,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub def: &'hir hir::VariantData,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub whence: Span,
}
pub struct Function {
pub decl: hir::FnDecl,
pub attrs: hir::HirVec<ast::Attribute>,
pub struct Function<'hir> {
pub decl: &'hir hir::FnDecl,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub id: hir::HirId,
pub name: Name,
pub vis: hir::Visibility,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub header: hir::FnHeader,
pub whence: Span,
pub generics: hir::Generics,
pub generics: &'hir hir::Generics,
pub body: hir::BodyId,
}
pub struct Typedef {
pub ty: P<hir::Ty>,
pub gen: hir::Generics,
pub struct Typedef<'hir> {
pub ty: &'hir P<hir::Ty>,
pub gen: &'hir hir::Generics,
pub name: Name,
pub id: hir::HirId,
pub attrs: hir::HirVec<ast::Attribute>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub whence: Span,
pub vis: hir::Visibility,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
}
pub struct Existential {
pub exist_ty: hir::ExistTy,
pub struct Existential<'hir> {
pub exist_ty: &'hir hir::ExistTy,
pub name: Name,
pub id: hir::HirId,
pub attrs: hir::HirVec<ast::Attribute>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub whence: Span,
pub vis: hir::Visibility,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
}
#[derive(Debug)]
pub struct Static {
pub type_: P<hir::Ty>,
pub struct Static<'hir> {
pub type_: &'hir P<hir::Ty>,
pub mutability: hir::Mutability,
pub expr: hir::BodyId,
pub name: Name,
pub attrs: hir::HirVec<ast::Attribute>,
pub vis: hir::Visibility,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub id: hir::HirId,
pub whence: Span,
}
pub struct Constant {
pub type_: P<hir::Ty>,
pub struct Constant<'hir> {
pub type_: &'hir P<hir::Ty>,
pub expr: hir::BodyId,
pub name: Name,
pub attrs: hir::HirVec<ast::Attribute>,
pub vis: hir::Visibility,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub id: hir::HirId,
pub whence: Span,
}
pub struct Trait {
pub struct Trait<'hir> {
pub is_auto: hir::IsAuto,
pub unsafety: hir::Unsafety,
pub name: Name,
pub items: hir::HirVec<hir::TraitItem>,
pub generics: hir::Generics,
pub bounds: hir::HirVec<hir::GenericBound>,
pub attrs: hir::HirVec<ast::Attribute>,
pub items: Vec<&'hir hir::TraitItem>,
pub generics: &'hir hir::Generics,
pub bounds: &'hir hir::HirVec<hir::GenericBound>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub id: hir::HirId,
pub whence: Span,
pub vis: hir::Visibility,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
}
pub struct TraitAlias {
pub struct TraitAlias<'hir> {
pub name: Name,
pub generics: hir::Generics,
pub bounds: hir::HirVec<hir::GenericBound>,
pub attrs: hir::HirVec<ast::Attribute>,
pub generics: &'hir hir::Generics,
pub bounds: &'hir hir::HirVec<hir::GenericBound>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub id: hir::HirId,
pub whence: Span,
pub vis: hir::Visibility,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
}
#[derive(Debug)]
pub struct Impl {
pub struct Impl<'hir> {
pub unsafety: hir::Unsafety,
pub polarity: hir::ImplPolarity,
pub defaultness: hir::Defaultness,
pub generics: hir::Generics,
pub trait_: Option<hir::TraitRef>,
pub for_: P<hir::Ty>,
pub items: hir::HirVec<hir::ImplItem>,
pub attrs: hir::HirVec<ast::Attribute>,
pub generics: &'hir hir::Generics,
pub trait_: &'hir Option<hir::TraitRef>,
pub for_: &'hir P<hir::Ty>,
pub items: Vec<&'hir hir::ImplItem>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub whence: Span,
pub vis: hir::Visibility,
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub id: hir::HirId,
}
pub struct ForeignItem<'hir> {
pub vis: &'hir hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
pub id: hir::HirId,
pub name: Name,
pub kind: &'hir hir::ForeignItemKind,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub whence: Span,
}
// For Macro we store the DefId instead of the NodeId, since we also create
// these imported macro_rules (which only have a DUMMY_NODE_ID).
pub struct Macro {
pub struct Macro<'hir> {
pub name: Name,
pub def_id: hir::def_id::DefId,
pub attrs: hir::HirVec<ast::Attribute>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub whence: Span,
pub matchers: hir::HirVec<Span>,
pub stab: Option<attr::Stability>,
@ -253,31 +267,31 @@ pub struct Macro {
pub imported_from: Option<Name>,
}
pub struct ExternCrate {
pub struct ExternCrate<'hir> {
pub name: Name,
pub cnum: CrateNum,
pub path: Option<String>,
pub vis: hir::Visibility,
pub attrs: hir::HirVec<ast::Attribute>,
pub vis: &'hir hir::Visibility,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub whence: Span,
}
pub struct Import {
pub struct Import<'hir> {
pub name: Name,
pub id: hir::HirId,
pub vis: hir::Visibility,
pub attrs: hir::HirVec<ast::Attribute>,
pub path: hir::Path,
pub vis: &'hir hir::Visibility,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub path: &'hir hir::Path,
pub glob: bool,
pub whence: Span,
}
pub struct ProcMacro {
pub struct ProcMacro<'hir> {
pub name: Name,
pub id: hir::HirId,
pub kind: MacroKind,
pub helpers: Vec<Name>,
pub attrs: hir::HirVec<ast::Attribute>,
pub attrs: &'hir hir::HirVec<ast::Attribute>,
pub whence: Span,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,

View file

@ -29,8 +29,7 @@ use crate::doctree::*;
// framework from syntax?.
pub struct RustdocVisitor<'a, 'tcx> {
pub module: Module,
pub attrs: hir::HirVec<ast::Attribute>,
pub module: Option<Module<'tcx>>,
pub cx: &'a core::DocContext<'tcx>,
view_item_stack: FxHashSet<hir::HirId>,
inlining: bool,
@ -47,8 +46,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let mut stack = FxHashSet::default();
stack.insert(hir::CRATE_HIR_ID);
RustdocVisitor {
module: Module::new(None),
attrs: hir::HirVec::new(),
module: None,
cx,
view_item_stack: stack,
inlining: false,
@ -77,92 +75,91 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
.and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id))
}
pub fn visit(&mut self, krate: &hir::Crate) {
self.attrs = krate.attrs.clone();
self.module = self.visit_mod_contents(krate.span,
krate.attrs.clone(),
Spanned { span: syntax_pos::DUMMY_SP,
pub fn visit(&mut self, krate: &'tcx hir::Crate) {
let mut module = self.visit_mod_contents(krate.span,
&krate.attrs,
&Spanned { span: syntax_pos::DUMMY_SP,
node: hir::VisibilityKind::Public },
hir::CRATE_HIR_ID,
&krate.module,
None);
// Attach the crate's exported macros to the top-level module:
let macro_exports: Vec<_> =
krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)).collect();
self.module.macros.extend(macro_exports);
self.module.is_crate = true;
module.macros.extend(
krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)),
);
module.is_crate = true;
self.module = Some(module);
self.cx.renderinfo.borrow_mut().exact_paths = self.exact_paths.take().unwrap();
}
pub fn visit_variant_data(&mut self, item: &hir::Item,
name: ast::Name, sd: &hir::VariantData,
generics: &hir::Generics) -> Struct {
pub fn visit_variant_data(&mut self, item: &'tcx hir::Item,
name: ast::Name, sd: &'tcx hir::VariantData,
generics: &'tcx hir::Generics) -> Struct<'tcx> {
debug!("Visiting struct");
let struct_type = struct_type_from_def(&*sd);
Struct {
id: item.hir_id,
struct_type,
name,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
attrs: item.attrs.clone(),
generics: generics.clone(),
fields: sd.fields().iter().cloned().collect(),
attrs: &item.attrs,
generics,
fields: sd.fields(),
whence: item.span
}
}
pub fn visit_union_data(&mut self, item: &hir::Item,
name: ast::Name, sd: &hir::VariantData,
generics: &hir::Generics) -> Union {
pub fn visit_union_data(&mut self, item: &'tcx hir::Item,
name: ast::Name, sd: &'tcx hir::VariantData,
generics: &'tcx hir::Generics) -> Union<'tcx> {
debug!("Visiting union");
let struct_type = struct_type_from_def(&*sd);
Union {
id: item.hir_id,
struct_type,
name,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
attrs: item.attrs.clone(),
generics: generics.clone(),
fields: sd.fields().iter().cloned().collect(),
attrs: &item.attrs,
generics,
fields: sd.fields(),
whence: item.span
}
}
pub fn visit_enum_def(&mut self, it: &hir::Item,
name: ast::Name, def: &hir::EnumDef,
params: &hir::Generics) -> Enum {
pub fn visit_enum_def(&mut self, it: &'tcx hir::Item,
name: ast::Name, def: &'tcx hir::EnumDef,
generics: &'tcx hir::Generics) -> Enum<'tcx> {
debug!("Visiting enum");
Enum {
name,
variants: def.variants.iter().map(|v| Variant {
name: v.node.ident.name,
id: v.node.id,
attrs: v.node.attrs.clone(),
attrs: &v.node.attrs,
stab: self.stability(v.node.id),
depr: self.deprecation(v.node.id),
def: v.node.data.clone(),
def: &v.node.data,
whence: v.span,
}).collect(),
vis: it.vis.clone(),
vis: &it.vis,
stab: self.stability(it.hir_id),
depr: self.deprecation(it.hir_id),
generics: params.clone(),
attrs: it.attrs.clone(),
generics,
attrs: &it.attrs,
id: it.hir_id,
whence: it.span,
}
}
pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
name: ast::Name, fd: &hir::FnDecl,
pub fn visit_fn(&mut self, om: &mut Module<'tcx>, item: &'tcx hir::Item,
name: ast::Name, decl: &'tcx hir::FnDecl,
header: hir::FnHeader,
gen: &hir::Generics,
generics: &'tcx hir::Generics,
body: hir::BodyId) {
debug!("Visiting fn");
let macro_kind = item.attrs.iter().filter_map(|a| {
@ -208,7 +205,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: item.hir_id,
kind,
helpers,
attrs: item.attrs.clone(),
attrs: &item.attrs,
whence: item.span,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
@ -217,14 +214,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
None => {
om.fns.push(Function {
id: item.hir_id,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
attrs: item.attrs.clone(),
decl: fd.clone(),
attrs: &item.attrs,
decl,
name,
whence: item.span,
generics: gen.clone(),
generics,
header,
body,
});
@ -232,15 +229,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}
pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribute>,
vis: hir::Visibility, id: hir::HirId,
m: &hir::Mod,
name: Option<ast::Name>) -> Module {
let mut om = Module::new(name);
pub fn visit_mod_contents(&mut self, span: Span, attrs: &'tcx hir::HirVec<ast::Attribute>,
vis: &'tcx hir::Visibility, id: hir::HirId,
m: &'tcx hir::Mod,
name: Option<ast::Name>) -> Module<'tcx> {
let mut om = Module::new(name, attrs, vis);
om.where_outer = span;
om.where_inner = m.inner;
om.attrs = attrs;
om.vis = vis.clone();
om.stab = self.stability(id);
om.depr = self.deprecation(id);
om.id = self.cx.tcx.hir().hir_to_node_id(id);
@ -269,7 +264,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
res: Res,
renamed: Option<ast::Ident>,
glob: bool,
om: &mut Module,
om: &mut Module<'tcx>,
please_inline: bool) -> bool {
fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool {
@ -359,14 +354,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
true
}
Node::ForeignItem(it) if !glob => {
// Generate a fresh `extern {}` block if we want to inline a foreign item.
om.foreigns.push(hir::ForeignMod {
abi: tcx.hir().get_foreign_abi(it.hir_id),
items: vec![hir::ForeignItem {
ident: renamed.unwrap_or(it.ident),
.. it.clone()
}].into(),
});
let prev = mem::replace(&mut self.inlining, true);
self.visit_foreign_item(it, renamed, om);
self.inlining = prev;
true
}
Node::MacroDef(def) if !glob => {
@ -379,8 +369,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
ret
}
pub fn visit_item(&mut self, item: &hir::Item,
renamed: Option<ast::Ident>, om: &mut Module) {
pub fn visit_item(&mut self, item: &'tcx hir::Item,
renamed: Option<ast::Ident>, om: &mut Module<'tcx>) {
debug!("Visiting item {:?}", item);
let ident = renamed.unwrap_or(item.ident);
@ -391,15 +381,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
match item.node {
hir::ItemKind::ForeignMod(ref fm) => {
// If inlining we only want to include public functions.
om.foreigns.push(if self.inlining {
hir::ForeignMod {
abi: fm.abi,
items: fm.items.iter().filter(|i| i.vis.node.is_pub()).cloned().collect(),
}
} else {
fm.clone()
});
for item in &fm.items {
self.visit_foreign_item(item, None, om);
}
}
// If we're inlining, skip private items.
_ if self.inlining && !item.vis.node.is_pub() => {}
@ -411,8 +395,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
.unwrap_or(LOCAL_CRATE),
name: ident.name,
path: orig_name.map(|x|x.to_string()),
vis: item.vis.clone(),
attrs: item.attrs.clone(),
vis: &item.vis,
attrs: &item.attrs,
whence: item.span,
})
}
@ -454,17 +438,17 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
om.imports.push(Import {
name: ident.name,
id: item.hir_id,
vis: item.vis.clone(),
attrs: item.attrs.clone(),
path: (**path).clone(),
vis: &item.vis,
attrs: &item.attrs,
path,
glob: is_glob,
whence: item.span,
});
}
hir::ItemKind::Mod(ref m) => {
om.mods.push(self.visit_mod_contents(item.span,
item.attrs.clone(),
item.vis.clone(),
&item.attrs,
&item.vis,
item.hir_id,
m,
Some(ident.name)));
@ -479,13 +463,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.visit_fn(om, item, ident.name, &**fd, header, gen, body),
hir::ItemKind::Ty(ref ty, ref gen) => {
let t = Typedef {
ty: ty.clone(),
gen: gen.clone(),
ty,
gen,
name: ident.name,
id: item.hir_id,
attrs: item.attrs.clone(),
attrs: &item.attrs,
whence: item.span,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
};
@ -493,75 +477,75 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
},
hir::ItemKind::Existential(ref exist_ty) => {
let t = Existential {
exist_ty: exist_ty.clone(),
exist_ty,
name: ident.name,
id: item.hir_id,
attrs: item.attrs.clone(),
attrs: &item.attrs,
whence: item.span,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
};
om.existentials.push(t);
},
hir::ItemKind::Static(ref ty, ref mut_, ref exp) => {
hir::ItemKind::Static(ref type_, mutability, expr) => {
let s = Static {
type_: ty.clone(),
mutability: mut_.clone(),
expr: exp.clone(),
type_,
mutability,
expr,
id: item.hir_id,
name: ident.name,
attrs: item.attrs.clone(),
attrs: &item.attrs,
whence: item.span,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
};
om.statics.push(s);
},
hir::ItemKind::Const(ref ty, ref exp) => {
hir::ItemKind::Const(ref type_, expr) => {
let s = Constant {
type_: ty.clone(),
expr: exp.clone(),
type_,
expr,
id: item.hir_id,
name: ident.name,
attrs: item.attrs.clone(),
attrs: &item.attrs,
whence: item.span,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
};
om.constants.push(s);
},
hir::ItemKind::Trait(is_auto, unsafety, ref gen, ref b, ref item_ids) => {
hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
let items = item_ids.iter()
.map(|ti| self.cx.tcx.hir().trait_item(ti.id).clone())
.map(|ti| self.cx.tcx.hir().trait_item(ti.id))
.collect();
let t = Trait {
is_auto,
unsafety,
name: ident.name,
items,
generics: gen.clone(),
bounds: b.iter().cloned().collect(),
generics,
bounds,
id: item.hir_id,
attrs: item.attrs.clone(),
attrs: &item.attrs,
whence: item.span,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
};
om.traits.push(t);
},
hir::ItemKind::TraitAlias(ref gen, ref b) => {
hir::ItemKind::TraitAlias(ref generics, ref bounds) => {
let t = TraitAlias {
name: ident.name,
generics: gen.clone(),
bounds: b.iter().cloned().collect(),
generics,
bounds,
id: item.hir_id,
attrs: item.attrs.clone(),
attrs: &item.attrs,
whence: item.span,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
};
@ -571,28 +555,28 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::ItemKind::Impl(unsafety,
polarity,
defaultness,
ref gen,
ref tr,
ref ty,
ref generics,
ref trait_,
ref for_,
ref item_ids) => {
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
// them up regardless of where they're located.
if !self.inlining && tr.is_none() {
if !self.inlining && trait_.is_none() {
let items = item_ids.iter()
.map(|ii| self.cx.tcx.hir().impl_item(ii.id).clone())
.map(|ii| self.cx.tcx.hir().impl_item(ii.id))
.collect();
let i = Impl {
unsafety,
polarity,
defaultness,
generics: gen.clone(),
trait_: tr.clone(),
for_: ty.clone(),
generics,
trait_,
for_,
items,
attrs: item.attrs.clone(),
attrs: &item.attrs,
id: item.hir_id,
whence: item.span,
vis: item.vis.clone(),
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
};
@ -602,12 +586,31 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem,
renamed: Option<ast::Ident>, om: &mut Module<'tcx>) {
// If inlining we only want to include public functions.
if self.inlining && !item.vis.node.is_pub() {
return;
}
om.foreigns.push(ForeignItem {
id: item.hir_id,
name: renamed.unwrap_or(item.ident).name,
kind: &item.node,
vis: &item.vis,
stab: self.stability(item.hir_id),
depr: self.deprecation(item.hir_id),
attrs: &item.attrs,
whence: item.span
});
}
// Convert each `exported_macro` into a doc item.
fn visit_local_macro(
&self,
def: &hir::MacroDef,
def: &'tcx hir::MacroDef,
renamed: Option<ast::Name>
) -> Macro {
) -> Macro<'tcx> {
debug!("visit_local_macro: {}", def.name);
let tts = def.body.trees().collect::<Vec<_>>();
// Extract the spans of all matchers. They represent the "interface" of the macro.
@ -616,7 +619,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
Macro {
def_id: self.cx.tcx.hir().local_def_id_from_hir_id(def.hir_id),
attrs: def.attrs.clone(),
attrs: &def.attrs,
name: renamed.unwrap_or(def.name),
whence: def.span,
matchers,

View file

@ -12,6 +12,8 @@
#![deny(unused_lifetimes)]
#![feature(bind_by_move_pattern_guards)]
#![feature(const_fn)]
#![feature(const_transmute)]
#![feature(crate_visibility_modifier)]
#![feature(label_break_value)]
#![feature(nll)]

View file

@ -133,8 +133,15 @@ impl<T: Encodable> Encodable for P<T> {
}
impl<T> P<[T]> {
pub fn new() -> P<[T]> {
P { ptr: Default::default() }
pub const fn new() -> P<[T]> {
// HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>`
// (as trait methods, `default` in this case, can't be `const fn` yet).
P {
ptr: unsafe {
use std::ptr::NonNull;
std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>)
},
}
}
#[inline(never)]