use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token::special_idents;
-use syntax::print::pprust::lifetime_to_string;
-use syntax::visit;
-use syntax::visit::Visitor;
use util::nodemap::NodeMap;
+use rustc_front::hir;
+use rustc_front::print::pprust::lifetime_to_string;
+use rustc_front::visit::{self, Visitor, FnKind};
+
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum DefRegion {
DefStaticRegion,
trait_ref_hack: bool,
// List of labels in the function/method currently under analysis.
- labels_in_fn: Vec<(ast::Ident, Span)>,
+ labels_in_fn: Vec<(ast::Name, Span)>,
}
enum ScopeChain<'a> {
/// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
/// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
- EarlyScope(subst::ParamSpace, &'a Vec<ast::LifetimeDef>, Scope<'a>),
+ EarlyScope(subst::ParamSpace, &'a Vec<hir::LifetimeDef>, Scope<'a>),
/// LateScope(['a, 'b, ...], s) extends s with late-bound
/// lifetimes introduced by the declaration binder_id.
- LateScope(&'a Vec<ast::LifetimeDef>, Scope<'a>),
+ LateScope(&'a Vec<hir::LifetimeDef>, Scope<'a>),
/// lifetimes introduced by items within a code block are scoped
/// to that block.
BlockScope(region::DestructionScopeData, Scope<'a>),
static ROOT_SCOPE: ScopeChain<'static> = RootScope;
-pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegionMap {
+pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap {
let mut named_region_map = NodeMap();
visit::walk_crate(&mut LifetimeContext {
sess: sess,
}
impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
- fn visit_item(&mut self, item: &ast::Item) {
+ fn visit_item(&mut self, item: &hir::Item) {
// Items save/restore the set of labels. This way inner items
// can freely reuse names, be they loop labels or lifetimes.
let saved = replace(&mut self.labels_in_fn, vec![]);
// Items always introduce a new root scope
self.with(RootScope, |_, this| {
match item.node {
- ast::ItemFn(..) => {
+ hir::ItemFn(..) => {
// Fn lifetimes get added in visit_fn below:
visit::walk_item(this, item);
}
- ast::ItemExternCrate(_) |
- ast::ItemUse(_) |
- ast::ItemMod(..) |
- ast::ItemMac(..) |
- ast::ItemDefaultImpl(..) |
- ast::ItemForeignMod(..) |
- ast::ItemStatic(..) |
- ast::ItemConst(..) => {
+ hir::ItemExternCrate(_) |
+ hir::ItemUse(_) |
+ hir::ItemMod(..) |
+ hir::ItemDefaultImpl(..) |
+ hir::ItemForeignMod(..) |
+ hir::ItemStatic(..) |
+ hir::ItemConst(..) => {
// These sorts of items have no lifetime parameters at all.
visit::walk_item(this, item);
}
- ast::ItemTy(_, ref generics) |
- ast::ItemEnum(_, ref generics) |
- ast::ItemStruct(_, ref generics) |
- ast::ItemTrait(_, ref generics, _, _) |
- ast::ItemImpl(_, _, ref generics, _, _, _) => {
+ hir::ItemTy(_, ref generics) |
+ hir::ItemEnum(_, ref generics) |
+ hir::ItemStruct(_, ref generics) |
+ hir::ItemTrait(_, ref generics, _, _) |
+ hir::ItemImpl(_, _, ref generics, _, _, _) => {
// These kinds of items have only early bound lifetime parameters.
let lifetimes = &generics.lifetimes;
let early_scope = EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE);
replace(&mut self.labels_in_fn, saved);
}
- fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
+ fn visit_foreign_item(&mut self, item: &hir::ForeignItem) {
// Items save/restore the set of labels. This way inner items
// can freely reuse names, be they loop labels or lifetimes.
let saved = replace(&mut self.labels_in_fn, vec![]);
// Items always introduce a new root scope
self.with(RootScope, |_, this| {
match item.node {
- ast::ForeignItemFn(_, ref generics) => {
+ hir::ForeignItemFn(_, ref generics) => {
this.visit_early_late(subst::FnSpace, generics, |this| {
visit::walk_foreign_item(this, item);
})
}
- ast::ForeignItemStatic(..) => {
+ hir::ForeignItemStatic(..) => {
visit::walk_foreign_item(this, item);
}
}
replace(&mut self.labels_in_fn, saved);
}
- fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
- b: &'v ast::Block, s: Span, _: ast::NodeId) {
+ fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
+ b: &'v hir::Block, s: Span, _: ast::NodeId) {
match fk {
- visit::FkItemFn(_, generics, _, _, _, _) => {
+ FnKind::ItemFn(_, generics, _, _, _, _) => {
self.visit_early_late(subst::FnSpace, generics, |this| {
this.walk_fn(fk, fd, b, s)
})
}
- visit::FkMethod(_, sig, _) => {
+ FnKind::Method(_, sig, _) => {
self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
this.walk_fn(fk, fd, b, s)
})
}
- visit::FkClosure(..) => {
+ FnKind::Closure(..) => {
self.walk_fn(fk, fd, b, s)
}
}
}
- fn visit_ty(&mut self, ty: &ast::Ty) {
+ fn visit_ty(&mut self, ty: &hir::Ty) {
match ty.node {
- ast::TyBareFn(ref c) => {
- visit::walk_lifetime_decls_helper(self, &c.lifetimes);
+ hir::TyBareFn(ref c) => {
self.with(LateScope(&c.lifetimes, self.scope), |old_scope, this| {
// a bare fn has no bounds, so everything
// contained within is scoped within its binder.
visit::walk_ty(this, ty);
});
}
- ast::TyPath(None, ref path) => {
+ hir::TyPath(None, ref path) => {
// if this path references a trait, then this will resolve to
// a trait ref, which introduces a binding scope.
match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
}
}
- fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+ fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
// We reset the labels on every trait item, so that different
// methods in an impl can reuse label names.
let saved = replace(&mut self.labels_in_fn, vec![]);
- if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
+ if let hir::MethodTraitItem(ref sig, None) = trait_item.node {
self.visit_early_late(
subst::FnSpace, &sig.generics,
|this| visit::walk_trait_item(this, trait_item))
replace(&mut self.labels_in_fn, saved);
}
- fn visit_block(&mut self, b: &ast::Block) {
+ fn visit_block(&mut self, b: &hir::Block) {
self.with(BlockScope(region::DestructionScopeData::new(b.id),
self.scope),
|_, this| visit::walk_block(this, b));
}
- fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
+ fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
if lifetime_ref.name == special_idents::static_lifetime.name {
self.insert_lifetime(lifetime_ref, DefStaticRegion);
return;
self.resolve_lifetime_ref(lifetime_ref);
}
- fn visit_generics(&mut self, generics: &ast::Generics) {
+ fn visit_generics(&mut self, generics: &hir::Generics) {
for ty_param in generics.ty_params.iter() {
- visit::walk_ty_param_bounds_helper(self, &ty_param.bounds);
+ walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
match ty_param.default {
Some(ref ty) => self.visit_ty(&**ty),
None => {}
}
for predicate in &generics.where_clause.predicates {
match predicate {
- &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ref bounded_ty,
+ &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ ref bounded_ty,
ref bounds,
ref bound_lifetimes,
.. }) => {
|old_scope, this| {
this.check_lifetime_defs(old_scope, bound_lifetimes);
this.visit_ty(&**bounded_ty);
- visit::walk_ty_param_bounds_helper(this, bounds);
+ walk_list!(this, visit_ty_param_bound, bounds);
});
self.trait_ref_hack = false;
result
} else {
self.visit_ty(&**bounded_ty);
- visit::walk_ty_param_bounds_helper(self, bounds);
+ walk_list!(self, visit_ty_param_bound, bounds);
}
}
- &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+ &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
ref bounds,
.. }) => {
- self.visit_lifetime_ref(lifetime);
+ self.visit_lifetime(lifetime);
for bound in bounds {
- self.visit_lifetime_ref(bound);
+ self.visit_lifetime(bound);
}
}
- &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ id,
+ &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ id,
ref path,
ref ty,
.. }) => {
}
fn visit_poly_trait_ref(&mut self,
- trait_ref: &ast::PolyTraitRef,
- _modifier: &ast::TraitBoundModifier) {
+ trait_ref: &hir::PolyTraitRef,
+ _modifier: &hir::TraitBoundModifier) {
debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
if !self.trait_ref_hack || !trait_ref.bound_lifetimes.is_empty() {
fn shadower_label(span: Span) -> Shadower {
Shadower { kind: ShadowKind::Label, span: span }
}
-fn original_lifetime(l: &ast::Lifetime) -> Original {
+fn original_lifetime(l: &hir::Lifetime) -> Original {
Original { kind: ShadowKind::Lifetime, span: l.span }
}
-fn shadower_lifetime(l: &ast::Lifetime) -> Shadower {
+fn shadower_lifetime(l: &hir::Lifetime) -> Shadower {
Shadower { kind: ShadowKind::Lifetime, span: l.span }
}
sess: &Session, name: ast::Name, orig: Original, shadower: Shadower) {
if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
// lifetime/lifetime shadowing is an error
- sess.span_err(shadower.span,
- &format!("{} name `{}` shadows a \
- {} name that is already in scope",
- shadower.kind.desc(), name, orig.kind.desc()));
+ span_err!(sess, shadower.span, E0496,
+ "{} name `{}` shadows a \
+ {} name that is already in scope",
+ shadower.kind.desc(), name, orig.kind.desc());
} else {
// shadowing involving a label is only a warning, due to issues with
// labels and lifetimes not being macro-hygienic.
// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
// if one of the label shadows a lifetime or another label.
-fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
+fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) {
struct GatherLabels<'a> {
sess: &'a Session,
scope: Scope<'a>,
- labels_in_fn: &'a mut Vec<(ast::Ident, Span)>,
+ labels_in_fn: &'a mut Vec<(ast::Name, Span)>,
}
let mut gather = GatherLabels {
return;
impl<'v, 'a> Visitor<'v> for GatherLabels<'a> {
- fn visit_expr(&mut self, ex: &'v ast::Expr) {
+ fn visit_expr(&mut self, ex: &'v hir::Expr) {
// do not recurse into closures defined in the block
// since they are treated as separate fns from the POV of
// labels_in_fn
- if let ast::ExprClosure(..) = ex.node {
+ if let hir::ExprClosure(..) = ex.node {
return
}
if let Some(label) = expression_label(ex) {
for &(prior, prior_span) in &self.labels_in_fn[..] {
// FIXME (#24278): non-hygienic comparison
- if label.name == prior.name {
+ if label == prior {
signal_shadowing_problem(self.sess,
- label.name,
+ label,
original_label(prior_span),
shadower_label(ex.span));
}
visit::walk_expr(self, ex)
}
- fn visit_item(&mut self, _: &ast::Item) {
+ fn visit_item(&mut self, _: &hir::Item) {
// do not recurse into items defined in the block
}
}
- fn expression_label(ex: &ast::Expr) -> Option<ast::Ident> {
+ fn expression_label(ex: &hir::Expr) -> Option<ast::Name> {
match ex.node {
- ast::ExprWhile(_, _, Some(label)) |
- ast::ExprWhileLet(_, _, _, Some(label)) |
- ast::ExprForLoop(_, _, _, Some(label)) |
- ast::ExprLoop(_, Some(label)) => Some(label),
+ hir::ExprWhile(_, _, Some(label)) |
+ hir::ExprLoop(_, Some(label)) => Some(label.name),
_ => None,
}
}
fn check_if_label_shadows_lifetime<'a>(sess: &'a Session,
mut scope: Scope<'a>,
- label: ast::Ident,
+ label: ast::Name,
label_span: Span) {
loop {
match *scope {
LateScope(lifetimes, s) => {
for lifetime_def in lifetimes {
// FIXME (#24278): non-hygienic comparison
- if label.name == lifetime_def.lifetime.name {
+ if label == lifetime_def.lifetime.name {
signal_shadowing_problem(
sess,
- label.name,
+ label,
original_lifetime(&lifetime_def.lifetime),
shadower_label(label_span));
return;
// labels of the function body and swaps them in before visiting
// the function body itself.
fn walk_fn<'b>(&mut self,
- fk: visit::FnKind,
- fd: &ast::FnDecl,
- fb: &'b ast::Block,
+ fk: FnKind,
+ fd: &hir::FnDecl,
+ fb: &'b hir::Block,
_span: Span) {
match fk {
- visit::FkItemFn(_, generics, _, _, _, _) => {
+ FnKind::ItemFn(_, generics, _, _, _, _) => {
visit::walk_fn_decl(self, fd);
self.visit_generics(generics);
}
- visit::FkMethod(_, sig, _) => {
+ FnKind::Method(_, sig, _) => {
visit::walk_fn_decl(self, fd);
self.visit_generics(&sig.generics);
self.visit_explicit_self(&sig.explicit_self);
}
- visit::FkClosure(..) => {
+ FnKind::Closure(..) => {
visit::walk_fn_decl(self, fd);
}
}
/// ordering is not important there.
fn visit_early_late<F>(&mut self,
early_space: subst::ParamSpace,
- generics: &ast::Generics,
+ generics: &hir::Generics,
walk: F) where
F: FnOnce(&mut LifetimeContext),
{
});
}
- fn resolve_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
+ fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
// Walk up the scope chain, tracking the number of fn scopes
// that we pass through, until we find a lifetime with the
// given name or we run out of scopes. If we encounter a code
fn resolve_free_lifetime_ref(&mut self,
scope_data: region::DestructionScopeData,
- lifetime_ref: &ast::Lifetime,
+ lifetime_ref: &hir::Lifetime,
scope: Scope) {
debug!("resolve_free_lifetime_ref \
scope_data: {:?} lifetime_ref: {:?} scope: {:?}",
}
- fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) {
+ fn unresolved_lifetime_ref(&self, lifetime_ref: &hir::Lifetime) {
span_err!(self.sess, lifetime_ref.span, E0261,
"use of undeclared lifetime name `{}`",
lifetime_ref.name);
}
- fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<ast::LifetimeDef>) {
+ fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<hir::LifetimeDef>) {
for i in 0..lifetimes.len() {
let lifetime_i = &lifetimes[i];
fn check_lifetime_def_for_shadowing(&self,
mut old_scope: Scope,
- lifetime: &ast::Lifetime)
+ lifetime: &hir::Lifetime)
{
for &(label, label_span) in &self.labels_in_fn {
// FIXME (#24278): non-hygienic comparison
- if lifetime.name == label.name {
+ if lifetime.name == label {
signal_shadowing_problem(self.sess,
lifetime.name,
original_label(label_span),
}
fn insert_lifetime(&mut self,
- lifetime_ref: &ast::Lifetime,
+ lifetime_ref: &hir::Lifetime,
def: DefRegion) {
if lifetime_ref.id == ast::DUMMY_NODE_ID {
self.sess.span_bug(lifetime_ref.span,
}
}
-fn search_lifetimes<'a>(lifetimes: &'a Vec<ast::LifetimeDef>,
- lifetime_ref: &ast::Lifetime)
- -> Option<(u32, &'a ast::Lifetime)> {
+fn search_lifetimes<'a>(lifetimes: &'a Vec<hir::LifetimeDef>,
+ lifetime_ref: &hir::Lifetime)
+ -> Option<(u32, &'a hir::Lifetime)> {
for (i, lifetime_decl) in lifetimes.iter().enumerate() {
if lifetime_decl.lifetime.name == lifetime_ref.name {
return Some((i as u32, &lifetime_decl.lifetime));
///////////////////////////////////////////////////////////////////////////
-pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::LifetimeDef> {
+pub fn early_bound_lifetimes<'a>(generics: &'a hir::Generics) -> Vec<hir::LifetimeDef> {
let referenced_idents = early_bound_lifetime_names(generics);
if referenced_idents.is_empty() {
return Vec::new();
/// Given a set of generic declarations, returns a list of names containing all early bound
/// lifetime names for those generics. (In fact, this list may also contain other names.)
-fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
+fn early_bound_lifetime_names(generics: &hir::Generics) -> Vec<ast::Name> {
// Create two lists, dividing the lifetimes into early/late bound.
// Initially, all of them are considered late, but we will move
// things from late into early as we go if we find references to
FreeLifetimeCollector { early_bound: &mut early_bound,
late_bound: &mut late_bound };
for ty_param in generics.ty_params.iter() {
- visit::walk_ty_param_bounds_helper(&mut collector, &ty_param.bounds);
+ walk_list!(&mut collector, visit_ty_param_bound, &ty_param.bounds);
}
for predicate in &generics.where_clause.predicates {
match predicate {
- &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounds,
+ &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bounds,
ref bounded_ty,
..}) => {
collector.visit_ty(&**bounded_ty);
- visit::walk_ty_param_bounds_helper(&mut collector, bounds);
+ walk_list!(&mut collector, visit_ty_param_bound, bounds);
}
- &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+ &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
ref bounds,
..}) => {
- collector.visit_lifetime_ref(lifetime);
+ collector.visit_lifetime(lifetime);
for bound in bounds {
- collector.visit_lifetime_ref(bound);
+ collector.visit_lifetime(bound);
}
}
- &ast::WherePredicate::EqPredicate(_) => unimplemented!()
+ &hir::WherePredicate::EqPredicate(_) => unimplemented!()
}
}
}
}
impl<'a, 'v> Visitor<'v> for FreeLifetimeCollector<'a> {
- fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
+ fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) {
shuffle(self.early_bound, self.late_bound,
lifetime_ref.name);
}