Expose attached attributes to FnKind
abstraction so that I can look at them in borrowck.
This commit is contained in:
parent
baeae780e0
commit
213d57983d
14 changed files with 84 additions and 57 deletions
|
@ -26,7 +26,8 @@ pub use self::Code::*;
|
|||
use front::map::{self, Node};
|
||||
use syntax::abi;
|
||||
use rustc_front::hir::{Block, FnDecl};
|
||||
use syntax::ast::{Name, NodeId};
|
||||
use syntax::ast::{Attribute, Name, NodeId};
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use rustc_front::hir as ast;
|
||||
use syntax::codemap::Span;
|
||||
use rustc_front::intravisit::FnKind;
|
||||
|
@ -116,7 +117,8 @@ struct ItemFnParts<'a> {
|
|||
generics: &'a ast::Generics,
|
||||
body: &'a Block,
|
||||
id: NodeId,
|
||||
span: Span
|
||||
span: Span,
|
||||
attrs: &'a [Attribute],
|
||||
}
|
||||
|
||||
/// These are all the components one can extract from a closure expr
|
||||
|
@ -125,12 +127,13 @@ struct ClosureParts<'a> {
|
|||
decl: &'a FnDecl,
|
||||
body: &'a Block,
|
||||
id: NodeId,
|
||||
span: Span
|
||||
span: Span,
|
||||
attrs: &'a [Attribute],
|
||||
}
|
||||
|
||||
impl<'a> ClosureParts<'a> {
|
||||
fn new(d: &'a FnDecl, b: &'a Block, id: NodeId, s: Span) -> ClosureParts<'a> {
|
||||
ClosureParts { decl: d, body: b, id: id, span: s }
|
||||
fn new(d: &'a FnDecl, b: &'a Block, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
|
||||
ClosureParts { decl: d, body: b, id: id, span: s, attrs: attrs }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,37 +168,37 @@ impl<'a> FnLikeNode<'a> {
|
|||
|
||||
pub fn body(self) -> &'a Block {
|
||||
self.handle(|i: ItemFnParts<'a>| &*i.body,
|
||||
|_, _, _: &'a ast::MethodSig, _, body: &'a ast::Block, _| body,
|
||||
|_, _, _: &'a ast::MethodSig, _, body: &'a ast::Block, _, _| body,
|
||||
|c: ClosureParts<'a>| c.body)
|
||||
}
|
||||
|
||||
pub fn decl(self) -> &'a FnDecl {
|
||||
self.handle(|i: ItemFnParts<'a>| &*i.decl,
|
||||
|_, _, sig: &'a ast::MethodSig, _, _, _| &sig.decl,
|
||||
|_, _, sig: &'a ast::MethodSig, _, _, _, _| &sig.decl,
|
||||
|c: ClosureParts<'a>| c.decl)
|
||||
}
|
||||
|
||||
pub fn span(self) -> Span {
|
||||
self.handle(|i: ItemFnParts| i.span,
|
||||
|_, _, _: &'a ast::MethodSig, _, _, span| span,
|
||||
|_, _, _: &'a ast::MethodSig, _, _, span, _| span,
|
||||
|c: ClosureParts| c.span)
|
||||
}
|
||||
|
||||
pub fn id(self) -> NodeId {
|
||||
self.handle(|i: ItemFnParts| i.id,
|
||||
|id, _, _: &'a ast::MethodSig, _, _, _| id,
|
||||
|id, _, _: &'a ast::MethodSig, _, _, _, _| id,
|
||||
|c: ClosureParts| c.id)
|
||||
}
|
||||
|
||||
pub fn kind(self) -> FnKind<'a> {
|
||||
let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
|
||||
FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis)
|
||||
FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs)
|
||||
};
|
||||
let closure = |_: ClosureParts| {
|
||||
FnKind::Closure
|
||||
let closure = |c: ClosureParts<'a>| {
|
||||
FnKind::Closure(c.attrs)
|
||||
};
|
||||
let method = |_, name: Name, sig: &'a ast::MethodSig, vis, _, _| {
|
||||
FnKind::Method(name, sig, vis)
|
||||
let method = |_, name: Name, sig: &'a ast::MethodSig, vis, _, _, attrs| {
|
||||
FnKind::Method(name, sig, vis, attrs)
|
||||
};
|
||||
self.handle(item, method, closure)
|
||||
}
|
||||
|
@ -207,7 +210,8 @@ impl<'a> FnLikeNode<'a> {
|
|||
&'a ast::MethodSig,
|
||||
Option<ast::Visibility>,
|
||||
&'a ast::Block,
|
||||
Span)
|
||||
Span,
|
||||
&'a [Attribute])
|
||||
-> A,
|
||||
C: FnOnce(ClosureParts<'a>) -> A,
|
||||
{
|
||||
|
@ -224,20 +228,21 @@ impl<'a> FnLikeNode<'a> {
|
|||
abi: abi,
|
||||
vis: i.vis,
|
||||
constness: constness,
|
||||
span: i.span
|
||||
span: i.span,
|
||||
attrs: &i.attrs,
|
||||
}),
|
||||
_ => panic!("item FnLikeNode that is not fn-like"),
|
||||
},
|
||||
map::NodeTraitItem(ti) => match ti.node {
|
||||
ast::MethodTraitItem(ref sig, Some(ref body)) => {
|
||||
method(ti.id, ti.name, sig, None, body, ti.span)
|
||||
method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs)
|
||||
}
|
||||
_ => panic!("trait method FnLikeNode that is not fn-like"),
|
||||
},
|
||||
map::NodeImplItem(ii) => {
|
||||
match ii.node {
|
||||
ast::ImplItemKind::Method(ref sig, ref body) => {
|
||||
method(ii.id, ii.name, sig, Some(ii.vis), body, ii.span)
|
||||
method(ii.id, ii.name, sig, Some(ii.vis), body, ii.span, &ii.attrs)
|
||||
}
|
||||
_ => {
|
||||
panic!("impl method FnLikeNode that is not fn-like")
|
||||
|
@ -246,7 +251,11 @@ impl<'a> FnLikeNode<'a> {
|
|||
}
|
||||
map::NodeExpr(e) => match e.node {
|
||||
ast::ExprClosure(_, ref decl, ref block) =>
|
||||
closure(ClosureParts::new(&decl, &block, e.id, e.span)),
|
||||
closure(ClosureParts::new(&decl,
|
||||
&block,
|
||||
e.id,
|
||||
e.span,
|
||||
e.attrs.as_attr_slice())),
|
||||
_ => panic!("expr FnLikeNode that is not fn-like"),
|
||||
},
|
||||
_ => panic!("other FnLikeNode that is not fn-like"),
|
||||
|
|
|
@ -1017,7 +1017,7 @@ fn check_fn(cx: &mut MatchCheckCtxt,
|
|||
sp: Span,
|
||||
fn_id: NodeId) {
|
||||
match kind {
|
||||
FnKind::Closure => {}
|
||||
FnKind::Closure(_) => {}
|
||||
_ => cx.param_env = ParameterEnvironment::for_item(cx.tcx, fn_id),
|
||||
}
|
||||
|
||||
|
|
|
@ -226,10 +226,10 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &TyCtxt<'tcx>, def_id: DefId)
|
|||
};
|
||||
|
||||
match fn_like.kind() {
|
||||
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _) => {
|
||||
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => {
|
||||
Some(fn_like)
|
||||
}
|
||||
FnKind::Method(_, m, _) => {
|
||||
FnKind::Method(_, m, _, _) => {
|
||||
if m.constness == hir::Constness::Const {
|
||||
Some(fn_like)
|
||||
} else {
|
||||
|
|
|
@ -82,9 +82,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
|||
block: &'v hir::Block, span: Span, _: ast::NodeId) {
|
||||
|
||||
let (is_item_fn, is_unsafe_fn) = match fn_kind {
|
||||
FnKind::ItemFn(_, _, unsafety, _, _, _) =>
|
||||
FnKind::ItemFn(_, _, unsafety, _, _, _, _) =>
|
||||
(true, unsafety == hir::Unsafety::Unsafe),
|
||||
FnKind::Method(_, sig, _) =>
|
||||
FnKind::Method(_, sig, _, _) =>
|
||||
(true, sig.unsafety == hir::Unsafety::Unsafe),
|
||||
_ => (false, false),
|
||||
};
|
||||
|
|
|
@ -226,7 +226,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
|
|||
intravisit::walk_fn(self, fk, fd, b, s);
|
||||
self.param_envs.pop();
|
||||
}
|
||||
FnKind::Closure => {
|
||||
FnKind::Closure(..) => {
|
||||
intravisit::walk_fn(self, fk, fd, b, s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,17 +182,17 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
|||
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
|
||||
b: &'v hir::Block, s: Span, fn_id: ast::NodeId) {
|
||||
match fk {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _) => {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _, _) => {
|
||||
self.visit_early_late(subst::FnSpace, generics, |this| {
|
||||
this.add_scope_and_walk_fn(fk, fd, b, s, fn_id)
|
||||
})
|
||||
}
|
||||
FnKind::Method(_, sig, _) => {
|
||||
FnKind::Method(_, sig, _, _) => {
|
||||
self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
|
||||
this.add_scope_and_walk_fn(fk, fd, b, s, fn_id)
|
||||
})
|
||||
}
|
||||
FnKind::Closure => {
|
||||
FnKind::Closure(_) => {
|
||||
self.add_scope_and_walk_fn(fk, fd, b, s, fn_id)
|
||||
}
|
||||
}
|
||||
|
@ -471,16 +471,16 @@ impl<'a> LifetimeContext<'a> {
|
|||
fn_id: ast::NodeId) {
|
||||
|
||||
match fk {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _) => {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _, _) => {
|
||||
intravisit::walk_fn_decl(self, fd);
|
||||
self.visit_generics(generics);
|
||||
}
|
||||
FnKind::Method(_, sig, _) => {
|
||||
FnKind::Method(_, sig, _, _) => {
|
||||
intravisit::walk_fn_decl(self, fd);
|
||||
self.visit_generics(&sig.generics);
|
||||
self.visit_explicit_self(&sig.explicit_self);
|
||||
}
|
||||
FnKind::Closure => {
|
||||
FnKind::Closure(_) => {
|
||||
intravisit::walk_fn_decl(self, fd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
|
|||
self.free_region_map = old_free_region_map;
|
||||
}
|
||||
|
||||
FnKind::Closure => {
|
||||
FnKind::Closure(..) => {
|
||||
borrowck_fn(self, fk, fd, b, s, id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,19 +27,30 @@
|
|||
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use syntax::codemap::Span;
|
||||
use hir::*;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum FnKind<'a> {
|
||||
/// fn foo() or extern "Abi" fn foo()
|
||||
ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, Visibility),
|
||||
ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, Visibility, &'a [Attribute]),
|
||||
|
||||
/// fn foo(&self)
|
||||
Method(Name, &'a MethodSig, Option<Visibility>),
|
||||
Method(Name, &'a MethodSig, Option<Visibility>, &'a [Attribute]),
|
||||
|
||||
/// |x, y| {}
|
||||
Closure,
|
||||
Closure(&'a [Attribute]),
|
||||
}
|
||||
|
||||
impl<'a> FnKind<'a> {
|
||||
pub fn attrs(&self) -> &'a [Attribute] {
|
||||
match *self {
|
||||
FnKind::ItemFn(_, _, _, _, _, _, attrs) => attrs,
|
||||
FnKind::Method(_, _, _, attrs) => attrs,
|
||||
FnKind::Closure(attrs) => attrs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Each method of the Visitor trait is a hook to be potentially
|
||||
|
@ -310,7 +321,8 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
|||
unsafety,
|
||||
constness,
|
||||
abi,
|
||||
item.vis),
|
||||
item.vis,
|
||||
&item.attrs),
|
||||
declaration,
|
||||
body,
|
||||
item.span,
|
||||
|
@ -595,14 +607,14 @@ pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declarat
|
|||
|
||||
pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) {
|
||||
match function_kind {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _) => {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _, _) => {
|
||||
visitor.visit_generics(generics);
|
||||
}
|
||||
FnKind::Method(_, sig, _) => {
|
||||
FnKind::Method(_, sig, _, _) => {
|
||||
visitor.visit_generics(&sig.generics);
|
||||
visitor.visit_explicit_self(&sig.explicit_self);
|
||||
}
|
||||
FnKind::Closure => {}
|
||||
FnKind::Closure(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,7 +642,10 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
|
|||
walk_fn_decl(visitor, &sig.decl);
|
||||
}
|
||||
MethodTraitItem(ref sig, Some(ref body)) => {
|
||||
visitor.visit_fn(FnKind::Method(trait_item.name, sig, None),
|
||||
visitor.visit_fn(FnKind::Method(trait_item.name,
|
||||
sig,
|
||||
None,
|
||||
&trait_item.attrs),
|
||||
&sig.decl,
|
||||
body,
|
||||
trait_item.span,
|
||||
|
@ -652,7 +667,10 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
|
|||
visitor.visit_expr(expr);
|
||||
}
|
||||
ImplItemKind::Method(ref sig, ref body) => {
|
||||
visitor.visit_fn(FnKind::Method(impl_item.name, sig, Some(impl_item.vis)),
|
||||
visitor.visit_fn(FnKind::Method(impl_item.name,
|
||||
sig,
|
||||
Some(impl_item.vis),
|
||||
&impl_item.attrs),
|
||||
&sig.decl,
|
||||
body,
|
||||
impl_item.span,
|
||||
|
@ -758,7 +776,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
|||
walk_list!(visitor, visit_arm, arms);
|
||||
}
|
||||
ExprClosure(_, ref function_declaration, ref body) => {
|
||||
visitor.visit_fn(FnKind::Closure,
|
||||
visitor.visit_fn(FnKind::Closure(expression.attrs.as_attr_slice()),
|
||||
function_declaration,
|
||||
body,
|
||||
expression.span,
|
||||
|
|
|
@ -254,13 +254,13 @@ impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O>
|
|||
self.operation.visit_id(node_id);
|
||||
|
||||
match function_kind {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _) => {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _, _) => {
|
||||
self.visit_generics_helper(generics)
|
||||
}
|
||||
FnKind::Method(_, sig, _) => {
|
||||
FnKind::Method(_, sig, _, _) => {
|
||||
self.visit_generics_helper(&sig.generics)
|
||||
}
|
||||
FnKind::Closure => {}
|
||||
FnKind::Closure(_) => {}
|
||||
}
|
||||
|
||||
for argument in &function_declaration.inputs {
|
||||
|
|
|
@ -237,7 +237,7 @@ impl LateLintPass for NonSnakeCase {
|
|||
fk: FnKind, _: &hir::FnDecl,
|
||||
_: &hir::Block, span: Span, id: ast::NodeId) {
|
||||
match fk {
|
||||
FnKind::Method(name, _, _) => match method_context(cx, id, span) {
|
||||
FnKind::Method(name, _, _, _) => match method_context(cx, id, span) {
|
||||
MethodLateContext::PlainImpl => {
|
||||
self.check_snake_case(cx, "method", &name.as_str(), Some(span))
|
||||
},
|
||||
|
@ -246,10 +246,10 @@ impl LateLintPass for NonSnakeCase {
|
|||
},
|
||||
_ => (),
|
||||
},
|
||||
FnKind::ItemFn(name, _, _, _, _, _) => {
|
||||
FnKind::ItemFn(name, _, _, _, _, _, _) => {
|
||||
self.check_snake_case(cx, "function", &name.as_str(), Some(span))
|
||||
},
|
||||
_ => (),
|
||||
FnKind::Closure(_) => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,10 +223,10 @@ impl LateLintPass for UnsafeCode {
|
|||
fn check_fn(&mut self, cx: &LateContext, fk: FnKind, _: &hir::FnDecl,
|
||||
_: &hir::Block, span: Span, _: ast::NodeId) {
|
||||
match fk {
|
||||
FnKind::ItemFn(_, _, hir::Unsafety::Unsafe, _, _, _) =>
|
||||
FnKind::ItemFn(_, _, hir::Unsafety::Unsafe, _, _, _, _) =>
|
||||
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
|
||||
|
||||
FnKind::Method(_, sig, _) => {
|
||||
FnKind::Method(_, sig, _, _) => {
|
||||
if sig.unsafety == hir::Unsafety::Unsafe {
|
||||
cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
|
||||
}
|
||||
|
@ -670,7 +670,7 @@ impl LateLintPass for UnconditionalRecursion {
|
|||
cx.tcx.impl_or_trait_item(cx.tcx.map.local_def_id(id)).as_opt_method()
|
||||
}
|
||||
// closures can't recur, so they don't matter.
|
||||
FnKind::Closure => return
|
||||
FnKind::Closure(_) => return
|
||||
};
|
||||
|
||||
// Walk through this function (say `f`) looking to see if
|
||||
|
|
|
@ -132,7 +132,7 @@ impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
|
|||
body: &'tcx hir::Block,
|
||||
span: Span,
|
||||
id: ast::NodeId) {
|
||||
let implicit_arg_tys = if let intravisit::FnKind::Closure = fk {
|
||||
let implicit_arg_tys = if let intravisit::FnKind::Closure(..) = fk {
|
||||
vec![closure_self_ty(&self.tcx, id, body.id)]
|
||||
} else {
|
||||
vec![]
|
||||
|
|
|
@ -132,10 +132,10 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let mode = match fk {
|
||||
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _) => {
|
||||
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => {
|
||||
Mode::ConstFn
|
||||
}
|
||||
FnKind::Method(_, m, _) => {
|
||||
FnKind::Method(_, m, _, _) => {
|
||||
if m.constness == hir::Constness::Const {
|
||||
Mode::ConstFn
|
||||
} else {
|
||||
|
|
|
@ -634,16 +634,16 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
|||
_: Span,
|
||||
node_id: NodeId) {
|
||||
let rib_kind = match function_kind {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _) => {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _, _) => {
|
||||
self.visit_generics(generics);
|
||||
ItemRibKind
|
||||
}
|
||||
FnKind::Method(_, sig, _) => {
|
||||
FnKind::Method(_, sig, _, _) => {
|
||||
self.visit_generics(&sig.generics);
|
||||
self.visit_explicit_self(&sig.explicit_self);
|
||||
MethodRibKind
|
||||
}
|
||||
FnKind::Closure => ClosureRibKind(node_id),
|
||||
FnKind::Closure(_) => ClosureRibKind(node_id),
|
||||
};
|
||||
self.resolve_function(rib_kind, declaration, block);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue