From f2a06f760bee698d3c9e1fe4cad33bf1558e3c78 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Fri, 2 Jan 2015 20:55:31 +0900 Subject: [PATCH 1/2] Make type in ast::Local optional --- src/librustc/middle/region.rs | 5 ++++- src/librustc_resolve/lib.rs | 4 +++- src/librustc_trans/save/mod.rs | 2 +- src/librustc_typeck/check/mod.rs | 6 +++--- src/libsyntax/ast.rs | 2 +- src/libsyntax/ext/build.rs | 4 ++-- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/fold.rs | 2 +- src/libsyntax/parse/parser.rs | 8 ++------ src/libsyntax/print/pprust.rs | 10 ++++------ src/libsyntax/visit.rs | 14 +++++++++----- 11 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index be89b32cdaa..0e47f338bb9 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -649,7 +649,10 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) { 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); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 10756f21551..b22b4bdc211 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3401,7 +3401,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 51ea0af8e10..4396740de4e 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -1496,7 +1496,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { 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); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 60bb96a2b84..c0ca540841f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -485,9 +485,9 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { 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 {}", diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 12432c8c78f..93750867750 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -643,8 +643,8 @@ pub enum LocalSource { /// Local represents a `let` statement, e.g., `let : = ;` #[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] pub struct Local { - pub ty: P, pub pat: P, + pub ty: Option>, pub init: Option>, pub id: NodeId, pub span: Span, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 239af188909..ea345f3a458 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -482,8 +482,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { 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, @@ -506,8 +506,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { 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, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5de7068563d..dcf25a26e2c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -712,7 +712,7 @@ fn expand_non_macro_stmt(Spanned {node, span: stmt_span}: Stmt, fld: &mut MacroE 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: diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 4f0169e31f2..c134b11a0eb 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -553,7 +553,7 @@ pub fn noop_fold_parenthesized_parameter_data(data: ParenthesizedPara pub fn noop_fold_local(l: P, fld: &mut T) -> P { 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, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 457085f5cc8..c7327a24bb6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3627,13 +3627,9 @@ impl<'a> Parser<'a> { 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 { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 02a03285d3b..3f3af4ed709 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1858,13 +1858,11 @@ impl<'a> State<'a> { 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<()> { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 40ca6354ca6..e532c76347f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -211,7 +211,7 @@ pub fn walk_view_item<'v, V: Visitor<'v>>(visitor: &mut V, vi: &'v ViewItem) { 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); } @@ -381,6 +381,13 @@ pub fn skip_ty<'v, V: Visitor<'v>>(_: &mut V, _: &'v Ty) { // Empty! } +pub fn walk_ty_opt<'v, V: Visitor<'v>>(visitor: &mut V, optional_type: &'v Option>) { + 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) => { @@ -583,10 +590,7 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, 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) { From 4ae7c38e7b3edce3343dee520fe588130f140dc8 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Fri, 2 Jan 2015 22:28:53 +0900 Subject: [PATCH 2/2] Add a pretty-print test --- src/test/pretty/let.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/pretty/let.rs diff --git a/src/test/pretty/let.rs b/src/test/pretty/let.rs new file mode 100644 index 00000000000..736ea3a0d10 --- /dev/null +++ b/src/test/pretty/let.rs @@ -0,0 +1,19 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// pp-exact + +// Check that `let x: _ = 0;` does not print as `let x = 0;`. + +fn main() { + let x: _ = 0; + + let _ = x; +}