Skip to content

Commit 3b6314c

Browse files
committed
librustc: Add support for type parameters in the middle of paths.
For example, `foo::<T>::bar::<U>`. This doesn't enforce that the type parameters are in the right positions, however.
1 parent 5c35047 commit 3b6314c

25 files changed

+692
-388
lines changed

src/librustc/front/std_inject.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use syntax::attr;
1717
use syntax::codemap::dummy_sp;
1818
use syntax::codemap;
1919
use syntax::fold;
20+
use syntax::opt_vec;
2021

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

@@ -90,12 +91,18 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate {
9091
let prelude_path = ast::Path {
9192
span: dummy_sp(),
9293
global: false,
93-
idents: ~[
94-
sess.ident_of("std"),
95-
sess.ident_of("prelude")
94+
segments: ~[
95+
ast::PathSegment {
96+
identifier: sess.ident_of("std"),
97+
lifetime: None,
98+
types: opt_vec::Empty,
99+
},
100+
ast::PathSegment {
101+
identifier: sess.ident_of("prelude"),
102+
lifetime: None,
103+
types: opt_vec::Empty,
104+
},
96105
],
97-
rp: None,
98-
types: ~[]
99106
};
100107

101108
let vp = @spanned(ast::view_path_glob(prelude_path, n2));

src/librustc/front/test.rs

+20-11
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ use front::config;
1616

1717
use std::vec;
1818
use syntax::ast_util::*;
19+
use syntax::attr::AttrMetaMethods;
1920
use syntax::attr;
2021
use syntax::codemap::{dummy_sp, span, ExpnInfo, NameAndSpan};
2122
use syntax::codemap;
2223
use syntax::ext::base::ExtCtxt;
2324
use syntax::fold;
25+
use syntax::opt_vec;
2426
use syntax::print::pprust;
2527
use syntax::{ast, ast_util};
26-
use syntax::attr::AttrMetaMethods;
2728

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

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

385386
fn path_node(ids: ~[ast::ident]) -> ast::Path {
386-
ast::Path { span: dummy_sp(),
387-
global: false,
388-
idents: ids,
389-
rp: None,
390-
types: ~[] }
387+
ast::Path {
388+
span: dummy_sp(),
389+
global: false,
390+
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
391+
identifier: identifier,
392+
lifetime: None,
393+
types: opt_vec::Empty,
394+
}).collect()
395+
}
391396
}
392397

393398
fn path_node_global(ids: ~[ast::ident]) -> ast::Path {
394-
ast::Path { span: dummy_sp(),
395-
global: true,
396-
idents: ids,
397-
rp: None,
398-
types: ~[] }
399+
ast::Path {
400+
span: dummy_sp(),
401+
global: true,
402+
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
403+
identifier: identifier,
404+
lifetime: None,
405+
types: opt_vec::Empty,
406+
}).collect()
407+
}
399408
}
400409

401410
#[cfg(stage0)]

src/librustc/metadata/encoder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
988988
encode_name(ecx, ebml_w, item.ident);
989989
encode_attributes(ebml_w, item.attrs);
990990
match ty.node {
991-
ast::ty_path(ref path, ref bounds, _) if path.idents.len() == 1 => {
991+
ast::ty_path(ref path, ref bounds, _) if path.segments
992+
.len() == 1 => {
992993
assert!(bounds.is_none());
993994
encode_impl_type_basename(ecx, ebml_w,
994995
ast_util::path_to_ident(path));

src/librustc/metadata/tydecode.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,20 @@ fn parse_path(st: &mut PState) -> @ast::Path {
138138
':' => { next(st); next(st); }
139139
c => {
140140
if c == '(' {
141-
return @ast::Path { span: dummy_sp(),
142-
global: false,
143-
idents: idents,
144-
rp: None,
145-
types: ~[] };
146-
} else { idents.push(parse_ident_(st, is_last)); }
141+
return @ast::Path {
142+
span: dummy_sp(),
143+
global: false,
144+
segments: idents.consume_iter().transform(|identifier| {
145+
ast::PathSegment {
146+
identifier: identifier,
147+
lifetime: None,
148+
types: opt_vec::Empty,
149+
}
150+
}).collect()
151+
};
152+
} else {
153+
idents.push(parse_ident_(st, is_last));
154+
}
147155
}
148156
}
149157
};

src/librustc/middle/check_const.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
141141
// to handle on-demand instantiation of functions via
142142
// foo::<bar> in a const. Currently that is only done on
143143
// a path in trans::callee that only works in block contexts.
144-
if pth.types.len() != 0 {
144+
if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
145145
sess.span_err(
146146
e.span, "paths in constants may only refer to \
147147
items without type parameters");

src/librustc/middle/privacy.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -251,21 +251,29 @@ impl PrivacyVisitor {
251251
match def {
252252
def_static_method(method_id, _, _) => {
253253
debug!("found static method def, checking it");
254-
self.check_method_common(span, method_id, path.idents.last())
254+
self.check_method_common(span,
255+
method_id,
256+
&path.segments.last().identifier)
255257
}
256258
def_fn(def_id, _) => {
257259
if def_id.crate == LOCAL_CRATE {
258260
if self.local_item_is_private(span, def_id.node) &&
259261
!self.privileged_items.iter().any(|x| x == &def_id.node) {
260262
self.tcx.sess.span_err(span,
261263
fmt!("function `%s` is private",
262-
token::ident_to_str(path.idents.last())));
264+
token::ident_to_str(
265+
&path.segments
266+
.last()
267+
.identifier)));
263268
}
264269
} else if csearch::get_item_visibility(self.tcx.sess.cstore,
265270
def_id) != public {
266271
self.tcx.sess.span_err(span,
267272
fmt!("function `%s` is private",
268-
token::ident_to_str(path.idents.last())));
273+
token::ident_to_str(
274+
&path.segments
275+
.last()
276+
.identifier)));
269277
}
270278
}
271279
_ => {}

src/librustc/middle/region.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
827827
Some(&ast::def_trait(did)) |
828828
Some(&ast::def_struct(did)) => {
829829
if did.crate == ast::LOCAL_CRATE {
830-
if cx.region_is_relevant(&path.rp) {
830+
if cx.region_is_relevant(&path.segments.last().lifetime) {
831831
cx.add_dep(did.node);
832832
}
833833
} else {
@@ -837,7 +837,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
837837
Some(variance) => {
838838
debug!("reference to external, rp'd type %s",
839839
pprust::ty_to_str(ty, sess.intr()));
840-
if cx.region_is_relevant(&path.rp) {
840+
if cx.region_is_relevant(&path.segments.last().lifetime) {
841841
let rv = cx.add_variance(variance);
842842
cx.add_rp(cx.item_id, rv)
843843
}
@@ -860,7 +860,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
860860
ast::ty_path(ref path, _, _) => {
861861
// type parameters are---for now, anyway---always invariant
862862
do cx.with_ambient_variance(rv_invariant) {
863-
for tp in path.types.iter() {
863+
for tp in path.segments.iter().flat_map(|s| s.types.iter()) {
864864
visitor.visit_ty(tp, cx);
865865
}
866866
}

0 commit comments

Comments
 (0)