Some(ref expr) => {
record_rvalue_scope_if_borrow_expr(visitor, &**expr, blk_scope);
- if is_binding_pat(&*local.pat) || is_borrowed_ty(&*local.ty) {
+ let is_borrow =
+ if let Some(ref ty) = local.ty { is_borrowed_ty(&**ty) } else { false };
+
+ if is_binding_pat(&*local.pat) || is_borrow {
record_rvalue_scope(visitor, &**expr, blk_scope);
}
}
fn resolve_local(&mut self, local: &Local) {
// Resolve the type.
- self.resolve_type(&*local.ty);
+ if let Some(ref ty) = local.ty {
+ self.resolve_type(&**ty);
+ }
// Resolve the initializer, if necessary.
match local.init {
self.collected_paths.clear();
// Just walk the initialiser and type (don't want to walk the pattern again).
- self.visit_ty(&*l.ty);
+ visit::walk_ty_opt(self, &l.ty);
visit::walk_expr_opt(self, &l.init);
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for GatherLocalsVisitor<'a, 'tcx> {
// Add explicitly-declared locals.
fn visit_local(&mut self, local: &ast::Local) {
- let o_ty = match local.ty.node {
- ast::TyInfer => None,
- _ => Some(self.fcx.to_ty(&*local.ty))
+ let o_ty = match local.ty {
+ Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
+ None => None
};
self.assign(local.span, local.id, o_ty);
debug!("Local variable {} is assigned type {}",
/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
#[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
pub struct Local {
- pub ty: P<Ty>,
pub pat: P<Pat>,
+ pub ty: Option<P<Ty>>,
pub init: Option<P<Expr>>,
pub id: NodeId,
pub span: Span,
self.pat_ident(sp, ident)
};
let local = P(ast::Local {
- ty: self.ty_infer(sp),
pat: pat,
+ ty: None,
init: Some(ex),
id: ast::DUMMY_NODE_ID,
span: sp,
self.pat_ident(sp, ident)
};
let local = P(ast::Local {
- ty: typ,
pat: pat,
+ ty: Some(typ),
init: Some(ex),
id: ast::DUMMY_NODE_ID,
span: sp,
let rewritten_local = local.map(|Local {id, pat, ty, init, source, span}| {
// expand the ty since TyFixedLengthVec contains an Expr
// and thus may have a macro use
- let expanded_ty = fld.fold_ty(ty);
+ let expanded_ty = ty.map(|t| fld.fold_ty(t));
// expand the pat (it might contain macro uses):
let expanded_pat = fld.fold_pat(pat);
// find the PatIdents in the pattern:
pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
l.map(|Local {id, pat, ty, init, source, span}| Local {
id: fld.new_id(id),
- ty: fld.fold_ty(ty),
+ ty: ty.map(|t| fld.fold_ty(t)),
pat: fld.fold_pat(pat),
init: init.map(|e| fld.fold_expr(e)),
source: source,
let lo = self.span.lo;
let pat = self.parse_pat();
- let mut ty = P(Ty {
- id: ast::DUMMY_NODE_ID,
- node: TyInfer,
- span: mk_sp(lo, lo),
- });
+ let mut ty = None;
if self.eat(&token::Colon) {
- ty = self.parse_ty_sum();
+ ty = Some(self.parse_ty_sum());
}
let init = self.parse_initializer();
P(ast::Local {
pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> {
try!(self.print_pat(&*loc.pat));
- match loc.ty.node {
- ast::TyInfer => Ok(()),
- _ => {
- try!(self.word_space(":"));
- self.print_type(&*loc.ty)
- }
+ if let Some(ref ty) = loc.ty {
+ try!(self.word_space(":"));
+ try!(self.print_type(&**ty));
}
+ Ok(())
}
pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
visitor.visit_pat(&*local.pat);
- visitor.visit_ty(&*local.ty);
+ walk_ty_opt(visitor, &local.ty);
walk_expr_opt(visitor, &local.init);
}
// Empty!
}
+pub fn walk_ty_opt<'v, V: Visitor<'v>>(visitor: &mut V, optional_type: &'v Option<P<Ty>>) {
+ match *optional_type {
+ Some(ref ty) => visitor.visit_ty(&**ty),
+ None => ()
+ }
+}
+
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
match typ.node {
TyVec(ref ty) | TyParen(ref ty) => {
pub fn walk_ty_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v TyParam) {
visitor.visit_ident(param.span, param.ident);
walk_ty_param_bounds_helper(visitor, ¶m.bounds);
- match param.default {
- Some(ref ty) => visitor.visit_ty(&**ty),
- None => {}
- }
+ walk_ty_opt(visitor, ¶m.default);
}
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {