Skip to content

Commit 4600212

Browse files
committed
Fix inner statics having the same symbol name
Before, the path name for all items defined in methods of traits and impls never took into account the name of the method. This meant that if you had two statics of the same name in two different methods the statics would end up having the same symbol named (even after mangling) because the path components leading to the symbol were exactly the same (just __extensions__ and the static name). It turns out that if you add the symbol "A" twice to LLVM, it automatically makes the second one "A1" instead of "A". What this meant is that in local crate compilations we never found this bug. Even across crates, this was never a problem. The problem arises when you have generic methods that don't get generated at compile-time of a library. If the statics were re-added to LLVM by a client crate of a library in a different order, you would reference different constants (the integer suffixes wouldn't be guaranteed to be the same). This fixes the problem by adding the method name to symbol path when building the ast_map. In doing so, two symbols in two different methods are disambiguated against.
1 parent 4f151b3 commit 4600212

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

src/libsyntax/ast_map.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,15 @@ impl Ctx {
153153
for a in decl.inputs.iter() {
154154
self.map.insert(a.id, node_arg);
155155
}
156+
match *fk {
157+
visit::fk_method(name, _, _) => { self.path.push(path_name(name)) }
158+
_ => {}
159+
}
156160
visit::walk_fn(self, fk, decl, body, sp, id, ());
161+
match *fk {
162+
visit::fk_method(*) => { self.path.pop(); }
163+
_ => {}
164+
}
157165
}
158166

159167
fn map_stmt(&mut self, stmt: @stmt) {

src/test/auxiliary/inner_static.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub struct A<T>;
12+
13+
impl<T> A<T> {
14+
pub fn foo(&self) -> int {
15+
static a: int = 5;
16+
return a
17+
}
18+
19+
pub fn bar(&self) -> int {
20+
static a: int = 3;
21+
return a;
22+
}
23+
}
24+
25+
pub fn foo() -> int {
26+
let a = A::<()>;
27+
return a.foo() + a.bar();
28+
}

src/test/run-pass/inner-static.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:inner_static.rs
12+
// xfail-fast
13+
14+
extern mod inner_static;
15+
16+
pub fn main() {
17+
let a = inner_static::A::<()>;
18+
assert_eq!(a.bar(), 3);
19+
}

0 commit comments

Comments
 (0)