diff options
Diffstat (limited to 'src/libsyntax/ext/format.rs')
| -rw-r--r-- | src/libsyntax/ext/format.rs | 102 |
1 files changed, 58 insertions, 44 deletions
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 5bedb1a887e..ba1d5efdd49 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -24,14 +24,14 @@ use std::vec; #[deriving(Eq)] enum ArgumentType { - Known(@str), + Known(~str), Unsigned, String, } enum Position { Exact(uint), - Named(@str), + Named(~str), } struct Context<'a> { @@ -43,12 +43,12 @@ struct Context<'a> { args: ~[@ast::Expr], arg_types: ~[Option<ArgumentType>], // Parsed named expressions and the types that we've found for them so far - names: HashMap<@str, @ast::Expr>, - name_types: HashMap<@str, ArgumentType>, + names: HashMap<~str, @ast::Expr>, + name_types: HashMap<~str, ArgumentType>, // Collection of the compiled `rt::Piece` structures pieces: ~[@ast::Expr], - name_positions: HashMap<@str, uint>, + name_positions: HashMap<~str, uint>, method_statics: ~[@ast::Item], // Updated as arguments are consumed or methods are entered @@ -105,10 +105,11 @@ impl<'a> Context<'a> { return (extra, None); } }; - let name = self.ecx.str_of(ident); + let interned_name = token::get_ident(ident.name); + let name = interned_name.get(); p.expect(&token::EQ); let e = p.parse_expr(); - match self.names.find(&name) { + match self.names.find_equiv(&name) { None => {} Some(prev) => { self.ecx.span_err(e.span, format!("duplicate argument \ @@ -118,7 +119,7 @@ impl<'a> Context<'a> { continue } } - self.names.insert(name, e); + self.names.insert(name.to_str(), e); } else { self.args.push(p.parse_expr()); self.arg_types.push(None); @@ -157,13 +158,13 @@ impl<'a> Context<'a> { Exact(i) } parse::ArgumentIs(i) => Exact(i), - parse::ArgumentNamed(s) => Named(s.to_managed()), + parse::ArgumentNamed(s) => Named(s.to_str()), }; // and finally the method being applied match arg.method { None => { - let ty = Known(arg.format.ty.to_managed()); + let ty = Known(arg.format.ty.to_str()); self.verify_arg_type(pos, ty); } Some(ref method) => { self.verify_method(pos, *method); } @@ -185,7 +186,7 @@ impl<'a> Context<'a> { self.verify_arg_type(Exact(i), Unsigned); } parse::CountIsName(s) => { - self.verify_arg_type(Named(s.to_managed()), Unsigned); + self.verify_arg_type(Named(s.to_str()), Unsigned); } parse::CountIsNextParam => { if self.check_positional_ok() { @@ -260,7 +261,13 @@ impl<'a> Context<'a> { self.ecx.span_err(self.fmtsp, msg); return; } - self.verify_same(self.args[arg].span, ty, self.arg_types[arg]); + { + let arg_type = match self.arg_types[arg] { + None => None, + Some(ref x) => Some(x) + }; + self.verify_same(self.args[arg].span, &ty, arg_type); + } if self.arg_types[arg].is_none() { self.arg_types[arg] = Some(ty); } @@ -275,10 +282,9 @@ impl<'a> Context<'a> { return; } }; - self.verify_same(span, ty, - self.name_types.find(&name).map(|&x| x)); + self.verify_same(span, &ty, self.name_types.find(&name)); if !self.name_types.contains_key(&name) { - self.name_types.insert(name, ty); + self.name_types.insert(name.clone(), ty); } // Assign this named argument a slot in the arguments array if // it hasn't already been assigned a slot. @@ -298,30 +304,36 @@ impl<'a> Context<'a> { /// /// Obviously `Some(Some(x)) != Some(Some(y))`, but we consider it true /// that: `Some(None) == Some(Some(x))` - fn verify_same(&self, sp: Span, ty: ArgumentType, - before: Option<ArgumentType>) { + fn verify_same(&self, + sp: Span, + ty: &ArgumentType, + before: Option<&ArgumentType>) { let cur = match before { None => return, Some(t) => t, }; - if ty == cur { return } + if *ty == *cur { + return + } match (cur, ty) { - (Known(cur), Known(ty)) => { + (&Known(ref cur), &Known(ref ty)) => { self.ecx.span_err(sp, format!("argument redeclared with type `{}` when \ - it was previously `{}`", ty, cur)); + it was previously `{}`", + *ty, + *cur)); } - (Known(cur), _) => { + (&Known(ref cur), _) => { self.ecx.span_err(sp, format!("argument used to format with `{}` was \ attempted to not be used for formatting", - cur)); + *cur)); } - (_, Known(ty)) => { + (_, &Known(ref ty)) => { self.ecx.span_err(sp, format!("argument previously used as a format \ argument attempted to be used as `{}`", - ty)); + *ty)); } (_, _) => { self.ecx.span_err(sp, "argument declared with multiple formats"); @@ -397,9 +409,8 @@ impl<'a> Context<'a> { self.ecx.expr_path(path) } parse::CountIsName(n) => { - let n = n.to_managed(); - let i = match self.name_positions.find_copy(&n) { - Some(i) => i, + let i = match self.name_positions.find_equiv(&n) { + Some(&i) => i, None => 0, // error already emitted elsewhere }; let i = i + self.args.len(); @@ -519,9 +530,8 @@ impl<'a> Context<'a> { // Named arguments are converted to positional arguments at // the end of the list of arguments parse::ArgumentNamed(n) => { - let n = n.to_managed(); - let i = match self.name_positions.find_copy(&n) { - Some(i) => i, + let i = match self.name_positions.find_equiv(&n) { + Some(&i) => i, None => 0, // error already emitted elsewhere }; let i = i + self.args.len(); @@ -633,14 +643,17 @@ impl<'a> Context<'a> { locals.push(self.format_arg(e.span, Exact(i), self.ecx.expr_ident(e.span, name))); } - for (&name, &e) in self.names.iter() { - if !self.name_types.contains_key(&name) { continue } + for (name, &e) in self.names.iter() { + if !self.name_types.contains_key(name) { + continue + } - let lname = self.ecx.ident_of(format!("__arg{}", name)); + let lname = self.ecx.ident_of(format!("__arg{}", *name)); let e = self.ecx.expr_addr_of(e.span, e); lets.push(self.ecx.stmt_let(e.span, false, lname, e)); - names[*self.name_positions.get(&name)] = - Some(self.format_arg(e.span, Named(name), + names[*self.name_positions.get(name)] = + Some(self.format_arg(e.span, + Named((*name).clone()), self.ecx.expr_ident(e.span, lname))); } @@ -682,16 +695,16 @@ impl<'a> Context<'a> { Some(result))) } - fn format_arg(&self, sp: Span, argno: Position, - arg: @ast::Expr) -> @ast::Expr { + fn format_arg(&self, sp: Span, argno: Position, arg: @ast::Expr) + -> @ast::Expr { let ty = match argno { - Exact(i) => self.arg_types[i].unwrap(), - Named(s) => *self.name_types.get(&s) + Exact(ref i) => self.arg_types[*i].get_ref(), + Named(ref s) => self.name_types.get(s) }; - let fmt_trait = match ty { - Known(tyname) => { - match tyname.as_slice() { + let fmt_trait = match *ty { + Known(ref tyname) => { + match (*tyname).as_slice() { "" => "Default", "?" => "Poly", "b" => "Bool", @@ -708,8 +721,9 @@ impl<'a> Context<'a> { "x" => "LowerHex", "X" => "UpperHex", _ => { - self.ecx.span_err(sp, format!("unknown format trait \ - `{}`", tyname)); + self.ecx.span_err(sp, + format!("unknown format trait `{}`", + *tyname)); "Dummy" } } |
