mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
rustc: Make static methods not leak out of traits. r=brson
This commit is contained in:
parent
a0fda80a52
commit
2b93ab5a21
@ -1299,6 +1299,38 @@ impl Resolver {
|
|||||||
let (name_bindings, new_parent) =
|
let (name_bindings, new_parent) =
|
||||||
self.add_child(ident, parent, ForbidDuplicateTypes, sp);
|
self.add_child(ident, parent, ForbidDuplicateTypes, sp);
|
||||||
|
|
||||||
|
// If the trait has static methods, then add all the static
|
||||||
|
// methods within to a new module.
|
||||||
|
//
|
||||||
|
// We only need to create the module if the trait has static
|
||||||
|
// methods, so check that first.
|
||||||
|
let mut has_static_methods = false;
|
||||||
|
for methods.each |method| {
|
||||||
|
let ty_m = trait_method_to_ty_method(*method);
|
||||||
|
match ty_m.self_ty.node {
|
||||||
|
sty_static => {
|
||||||
|
has_static_methods = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the module if necessary.
|
||||||
|
let module_parent_opt;
|
||||||
|
if has_static_methods {
|
||||||
|
let parent_link = self.get_parent_link(parent, ident);
|
||||||
|
name_bindings.define_module(privacy,
|
||||||
|
parent_link,
|
||||||
|
Some(local_def(item.id)),
|
||||||
|
false,
|
||||||
|
sp);
|
||||||
|
module_parent_opt = Some(ModuleReducedGraphParent(
|
||||||
|
name_bindings.get_module()));
|
||||||
|
} else {
|
||||||
|
module_parent_opt = None;
|
||||||
|
}
|
||||||
|
|
||||||
// Add the names of all the methods to the trait info.
|
// Add the names of all the methods to the trait info.
|
||||||
let method_names = @HashMap();
|
let method_names = @HashMap();
|
||||||
for methods.each |method| {
|
for methods.each |method| {
|
||||||
@ -1306,21 +1338,36 @@ impl Resolver {
|
|||||||
|
|
||||||
let ident = ty_m.ident;
|
let ident = ty_m.ident;
|
||||||
// Add it to the trait info if not static,
|
// Add it to the trait info if not static,
|
||||||
// add it as a name in the enclosing module otherwise.
|
// add it as a name in the trait module otherwise.
|
||||||
match ty_m.self_ty.node {
|
match ty_m.self_ty.node {
|
||||||
sty_static => {
|
sty_static => {
|
||||||
// which parent to use??
|
let def = def_static_method(
|
||||||
let (method_name_bindings, _) =
|
local_def(ty_m.id),
|
||||||
self.add_child(ident, new_parent,
|
|
||||||
ForbidDuplicateValues, ty_m.span);
|
|
||||||
let def = def_static_method(local_def(ty_m.id),
|
|
||||||
Some(local_def(item.id)),
|
Some(local_def(item.id)),
|
||||||
ty_m.purity);
|
ty_m.purity);
|
||||||
(*method_name_bindings).define_value
|
|
||||||
(Public, def, ty_m.span);
|
// For now, add to both the trait module and the
|
||||||
|
// enclosing module, for backwards compatibility.
|
||||||
|
let (method_name_bindings, _) =
|
||||||
|
self.add_child(ident,
|
||||||
|
new_parent,
|
||||||
|
ForbidDuplicateValues,
|
||||||
|
ty_m.span);
|
||||||
|
method_name_bindings.define_value(Public,
|
||||||
|
def,
|
||||||
|
ty_m.span);
|
||||||
|
|
||||||
|
let (method_name_bindings, _) =
|
||||||
|
self.add_child(ident,
|
||||||
|
module_parent_opt.get(),
|
||||||
|
ForbidDuplicateValues,
|
||||||
|
ty_m.span);
|
||||||
|
method_name_bindings.define_value(Public,
|
||||||
|
def,
|
||||||
|
ty_m.span);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
(*method_names).insert(ident, ());
|
method_names.insert(ident, ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
src/test/run-pass/static-methods-in-traits.rs
Normal file
25
src/test/run-pass/static-methods-in-traits.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
mod a {
|
||||||
|
pub trait Foo {
|
||||||
|
static pub fn foo() -> self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl int : Foo {
|
||||||
|
static pub fn foo() -> int {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl uint : Foo {
|
||||||
|
static pub fn foo() -> uint {
|
||||||
|
5u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int = a::Foo::foo();
|
||||||
|
let y: uint = a::Foo::foo();
|
||||||
|
assert x == 3;
|
||||||
|
assert y == 5;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user