@@ -20,6 +20,7 @@ use std::cmp::Equiv;
20
20
use std:: local_data;
21
21
use std:: rand;
22
22
use std:: rand:: RngUtil ;
23
+ use std:: ptr:: to_unsafe_ptr;
23
24
24
25
#[ deriving( Clone , Encodable , Decodable , Eq , IterBytes ) ]
25
26
pub enum binop {
@@ -544,15 +545,31 @@ pub fn gensym_ident(str : &str) -> ast::Ident {
544
545
}
545
546
546
547
// create a fresh name that maps to the same string as the old one.
548
+ // note that this guarantees that ptr_eq(ident_to_str(src),interner_get(fresh_name(src)));
549
+ // that is, that the new name and the old one are connected to ptr_eq strings.
547
550
pub fn fresh_name ( src : & ast:: Ident ) -> Name {
548
551
gensym ( ident_to_str ( src) )
549
552
// following: debug version. Could work in final except that it's incompatible with
550
553
// good error messages and uses of struct names in ambiguous could-be-binding
551
- // locations.
554
+ // locations. Also definitely destroys the guarantee given above about ptr_eq.
552
555
/*let num = rand::rng().gen_uint_range(0,0xffff);
553
556
gensym(fmt!("%s_%u",ident_to_str(src),num))*/
554
557
}
555
558
559
+ // it looks like there oughta be a str_ptr_eq fn, but no one bothered to implement it?
560
+ pub fn str_ptr_eq < T > ( a : @str , b : @str ) -> bool {
561
+ // doesn't compile! ...because of rebase mangling. this should be fixed
562
+ // in the commit that follows this.
563
+ let ( a_ptr, b_ptr) : ( * uint , * uint ) = ( to_unsafe_ptr ( a) , to_unsafe_ptr ( b) ) ;
564
+ a_ptr == b_ptr
565
+ }
566
+
567
+
568
+
569
+ // return true when two identifiers refer (through the intern table) to the same ptr_eq
570
+ // string. This is used to compare identifiers in places where hygienic comparison is
571
+ // not wanted (i.e. not lexical vars).
572
+
556
573
// create a fresh mark.
557
574
pub fn fresh_mark ( ) -> Mrk {
558
575
gensym ( "mark" )
@@ -698,5 +715,19 @@ pub fn is_reserved_keyword(tok: &Token) -> bool {
698
715
#[ cfg( test) ]
699
716
mod test {
700
717
use super :: * ;
718
+ use std:: io;
719
+ use std:: managed;
720
+ use ast;
721
+ use ast_util;
722
+
723
+
724
+ #[ test] fn t1 ( ) {
725
+ let ghi = str_to_ident ( "ghi" ) ;
726
+ assert_eq ! ( ident_to_str( & ghi) , @"ghi" ) ;
727
+ let fresh = ast:: Ident :: new ( fresh_name ( & ghi) ) ;
728
+ assert_eq ! ( ident_to_str( & fresh) , @"ghi" ) ;
729
+ assert ! ( str_ptr_eq( ident_to_str( & ghi) , ident_to_str( & fresh) ) ) ;
730
+ assert_eq ! ( 3 , 4 ) ;
731
+ }
701
732
702
733
}
0 commit comments