diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 8c8dedeef32..292047d885d 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -23,7 +23,7 @@ use middle::pat_util::pat_bindings; use syntax::ast::*; use syntax::ast; -use syntax::ast_util::{def_id_of_def, local_def}; // mtwt_resolve +use syntax::ast_util::{def_id_of_def, local_def, mtwt_resolve}; use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; use syntax::ast_util::{Privacy, Public, Private}; use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy}; @@ -4067,10 +4067,14 @@ impl Resolver { None, visitor); } + // build a map from pattern identifiers to binding-info's. + // this is done hygienically. This could arise for a macro + // that expands into an or-pattern where one 'x' was from the + // user and one 'x' came from the macro. pub fn binding_mode_map(@mut self, pat: @Pat) -> BindingMap { let mut result = HashMap::new(); do pat_bindings(self.def_map, pat) |binding_mode, _id, sp, path| { - let name = path_to_ident(path).name; // mtwt_resolve(path_to_ident(path)); + let name = mtwt_resolve(path_to_ident(path)); result.insert(name, binding_info {span: sp, binding_mode: binding_mode}); @@ -4078,6 +4082,8 @@ impl Resolver { return result; } + // check that all of the arms in an or-pattern have exactly the + // same set of bindings, with the same binding modes for each. pub fn check_consistent_bindings(@mut self, arm: &Arm) { if arm.pats.len() == 0 { return; } let map_0 = self.binding_mode_map(arm.pats[0]); @@ -4293,7 +4299,7 @@ impl Resolver { // what you want). let ident = path.segments[0].identifier; - let renamed = ident.name; // mtwt_resolve(ident); + let renamed = mtwt_resolve(ident); match self.resolve_bare_identifier_pattern(ident) { FoundStructOrEnumVariant(def) @@ -4833,7 +4839,7 @@ impl Resolver { let search_result; match namespace { ValueNS => { - let renamed = ident.name; // mtwt_resolve(ident); + let renamed = mtwt_resolve(ident); search_result = self.search_ribs(self.value_ribs, renamed, span, DontAllowCapturingSelf); diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index dfac782929d..321ac9428ea 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -991,20 +991,19 @@ pub fn getLast(arr: &~[Mrk]) -> uint { pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool { (a.span == b.span) && (a.global == b.global) - // NOTE: ident->name in lifetimes! - && (a.rp == b.rp) - // NOTE: can a type contain an ident? - && (a.types == b.types) - && (idents_name_eq(a.idents, b.idents)) + && (segments_name_eq(a.segments, b.segments)) } -// are two arrays of idents equal when compared unhygienically? -pub fn idents_name_eq(a : &[ast::ident], b : &[ast::ident]) -> bool { +// are two arrays of segments equal when compared unhygienically? +pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> bool { if (a.len() != b.len()) { false } else { - for a.iter().enumerate().advance |(idx,id)|{ - if (id.name != b[idx].name) { + for (idx,seg) in a.iter().enumerate() { + if (seg.identifier.name != b[idx].identifier.name) + // ident -> name problems in lifetime comparison? + || (seg.lifetime != b[idx].lifetime) + || (seg.types != b[idx].types) { return false; } } @@ -1017,16 +1016,21 @@ mod test { use ast::*; use super::*; use std::io; + use opt_vec; + + fn ident_to_segment(id : &ident) -> PathSegment { + PathSegment{identifier:id.clone(), lifetime: None, types: opt_vec::Empty} + } #[test] fn idents_name_eq_test() { - assert!(idents_name_eq(~[ident{name:3,ctxt:4}, - ident{name:78,ctxt:82}], - ~[ident{name:3,ctxt:104}, - ident{name:78,ctxt:182}])); - assert!(!idents_name_eq(~[ident{name:3,ctxt:4}, - ident{name:78,ctxt:82}], - ~[ident{name:3,ctxt:104}, - ident{name:77,ctxt:182}])); + assert!(segments_name_eq([ident{name:3,ctxt:4}, + ident{name:78,ctxt:82}].map(ident_to_segment), + [ident{name:3,ctxt:104}, + ident{name:78,ctxt:182}].map(ident_to_segment))); + assert!(!segments_name_eq([ident{name:3,ctxt:4}, + ident{name:78,ctxt:82}].map(ident_to_segment), + [ident{name:3,ctxt:104}, + ident{name:77,ctxt:182}].map(ident_to_segment))); } #[test] fn xorpush_test () { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index ee7750bfd57..aa4183837e3 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -355,8 +355,8 @@ pub fn parse( match_nonterminal(_,_,_) => { bb_eis.push(ei) } match_tok(ref t) => { let mut ei_t = ei.clone(); - if (token_name_eq(t,&tok)) { - //if (token::mtwt_token_eq(t,&tok)) { + //if (token_name_eq(t,&tok)) { + if (token::mtwt_token_eq(t,&tok)) { ei_t.idx += 1; next_eis.push(ei_t); } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 311d498eec2..39e0f85920c 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -720,6 +720,15 @@ pub fn is_reserved_keyword(tok: &Token) -> bool { } } +pub fn mtwt_token_eq(t1 : &Token, t2 : &Token) -> bool { + match (t1,t2) { + (&IDENT(id1,_),&IDENT(id2,_)) => + ast_util::mtwt_resolve(id1) == ast_util::mtwt_resolve(id2), + _ => *t1 == *t2 + } +} + + #[cfg(test)] mod test { use super::*; @@ -728,6 +737,17 @@ mod test { use ast; use ast_util; + fn mark_ident(id : ast::ident, m : ast::Mrk) -> ast::ident { + ast::ident{name:id.name,ctxt:ast_util::new_mark(m,id.ctxt)} + } + + #[test] fn mtwt_token_eq_test() { + assert!(mtwt_token_eq(>,>)); + let a = str_to_ident("bac"); + let a1 = mark_ident(a,92); + assert!(mtwt_token_eq(&IDENT(a,true),&IDENT(a1,false))); + } + #[test] fn str_ptr_eq_tests(){ let a = @"abc";