Skip to content

Commit

Permalink
librustc: Add support for type parameters in the middle of paths.
Browse files Browse the repository at this point in the history
For example, `foo::<T>::bar::<U>`.

This doesn't enforce that the type parameters are in the right
positions, however.
  • Loading branch information
pcwalton committed Aug 28, 2013
1 parent 5c35047 commit 3b6314c
Show file tree
Hide file tree
Showing 25 changed files with 692 additions and 388 deletions.
17 changes: 12 additions & 5 deletions src/librustc/front/std_inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use syntax::attr;
use syntax::codemap::dummy_sp;
use syntax::codemap;
use syntax::fold;
use syntax::opt_vec;

static STD_VERSION: &'static str = "0.8-pre";

Expand Down Expand Up @@ -90,12 +91,18 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate {
let prelude_path = ast::Path {
span: dummy_sp(),
global: false,
idents: ~[
sess.ident_of("std"),
sess.ident_of("prelude")
segments: ~[
ast::PathSegment {
identifier: sess.ident_of("std"),
lifetime: None,
types: opt_vec::Empty,
},
ast::PathSegment {
identifier: sess.ident_of("prelude"),
lifetime: None,
types: opt_vec::Empty,
},
],
rp: None,
types: ~[]
};

let vp = @spanned(ast::view_path_glob(prelude_path, n2));
Expand Down
31 changes: 20 additions & 11 deletions src/librustc/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ use front::config;

use std::vec;
use syntax::ast_util::*;
use syntax::attr::AttrMetaMethods;
use syntax::attr;
use syntax::codemap::{dummy_sp, span, ExpnInfo, NameAndSpan};
use syntax::codemap;
use syntax::ext::base::ExtCtxt;
use syntax::fold;
use syntax::opt_vec;
use syntax::print::pprust;
use syntax::{ast, ast_util};
use syntax::attr::AttrMetaMethods;

type node_id_gen = @fn() -> ast::NodeId;

Expand Down Expand Up @@ -383,19 +384,27 @@ fn nospan<T>(t: T) -> codemap::spanned<T> {
}

fn path_node(ids: ~[ast::ident]) -> ast::Path {
ast::Path { span: dummy_sp(),
global: false,
idents: ids,
rp: None,
types: ~[] }
ast::Path {
span: dummy_sp(),
global: false,
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
identifier: identifier,
lifetime: None,
types: opt_vec::Empty,
}).collect()
}
}

fn path_node_global(ids: ~[ast::ident]) -> ast::Path {
ast::Path { span: dummy_sp(),
global: true,
idents: ids,
rp: None,
types: ~[] }
ast::Path {
span: dummy_sp(),
global: true,
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
identifier: identifier,
lifetime: None,
types: opt_vec::Empty,
}).collect()
}
}

#[cfg(stage0)]
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_name(ecx, ebml_w, item.ident);
encode_attributes(ebml_w, item.attrs);
match ty.node {
ast::ty_path(ref path, ref bounds, _) if path.idents.len() == 1 => {
ast::ty_path(ref path, ref bounds, _) if path.segments
.len() == 1 => {
assert!(bounds.is_none());
encode_impl_type_basename(ecx, ebml_w,
ast_util::path_to_ident(path));
Expand Down
20 changes: 14 additions & 6 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,20 @@ fn parse_path(st: &mut PState) -> @ast::Path {
':' => { next(st); next(st); }
c => {
if c == '(' {
return @ast::Path { span: dummy_sp(),
global: false,
idents: idents,
rp: None,
types: ~[] };
} else { idents.push(parse_ident_(st, is_last)); }
return @ast::Path {
span: dummy_sp(),
global: false,
segments: idents.consume_iter().transform(|identifier| {
ast::PathSegment {
identifier: identifier,
lifetime: None,
types: opt_vec::Empty,
}
}).collect()
};
} else {
idents.push(parse_ident_(st, is_last));
}
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/check_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
// to handle on-demand instantiation of functions via
// foo::<bar> in a const. Currently that is only done on
// a path in trans::callee that only works in block contexts.
if pth.types.len() != 0 {
if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
sess.span_err(
e.span, "paths in constants may only refer to \
items without type parameters");
Expand Down
14 changes: 11 additions & 3 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,21 +251,29 @@ impl PrivacyVisitor {
match def {
def_static_method(method_id, _, _) => {
debug!("found static method def, checking it");
self.check_method_common(span, method_id, path.idents.last())
self.check_method_common(span,
method_id,
&path.segments.last().identifier)
}
def_fn(def_id, _) => {
if def_id.crate == LOCAL_CRATE {
if self.local_item_is_private(span, def_id.node) &&
!self.privileged_items.iter().any(|x| x == &def_id.node) {
self.tcx.sess.span_err(span,
fmt!("function `%s` is private",
token::ident_to_str(path.idents.last())));
token::ident_to_str(
&path.segments
.last()
.identifier)));
}
} else if csearch::get_item_visibility(self.tcx.sess.cstore,
def_id) != public {
self.tcx.sess.span_err(span,
fmt!("function `%s` is private",
token::ident_to_str(path.idents.last())));
token::ident_to_str(
&path.segments
.last()
.identifier)));
}
}
_ => {}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
Some(&ast::def_trait(did)) |
Some(&ast::def_struct(did)) => {
if did.crate == ast::LOCAL_CRATE {
if cx.region_is_relevant(&path.rp) {
if cx.region_is_relevant(&path.segments.last().lifetime) {
cx.add_dep(did.node);
}
} else {
Expand All @@ -837,7 +837,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
Some(variance) => {
debug!("reference to external, rp'd type %s",
pprust::ty_to_str(ty, sess.intr()));
if cx.region_is_relevant(&path.rp) {
if cx.region_is_relevant(&path.segments.last().lifetime) {
let rv = cx.add_variance(variance);
cx.add_rp(cx.item_id, rv)
}
Expand All @@ -860,7 +860,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
ast::ty_path(ref path, _, _) => {
// type parameters are---for now, anyway---always invariant
do cx.with_ambient_variance(rv_invariant) {
for tp in path.types.iter() {
for tp in path.segments.iter().flat_map(|s| s.types.iter()) {
visitor.visit_ty(tp, cx);
}
}
Expand Down
Loading

0 comments on commit 3b6314c

Please sign in to comment.