Skip to content

Commit 0a7a873

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 9406339 commit 0a7a873

25 files changed

+694
-390
lines changed

src/librustc/front/std_inject.rs

Lines changed: 12 additions & 5 deletions
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

Lines changed: 20 additions & 11 deletions
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

@@ -340,19 +341,27 @@ fn nospan<T>(t: T) -> codemap::spanned<T> {
340341
}
341342

342343
fn path_node(ids: ~[ast::ident]) -> ast::Path {
343-
ast::Path { span: dummy_sp(),
344-
global: false,
345-
idents: ids,
346-
rp: None,
347-
types: ~[] }
344+
ast::Path {
345+
span: dummy_sp(),
346+
global: false,
347+
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
348+
identifier: identifier,
349+
lifetime: None,
350+
types: opt_vec::Empty,
351+
}).collect()
352+
}
348353
}
349354

350355
fn path_node_global(ids: ~[ast::ident]) -> ast::Path {
351-
ast::Path { span: dummy_sp(),
352-
global: true,
353-
idents: ids,
354-
rp: None,
355-
types: ~[] }
356+
ast::Path {
357+
span: dummy_sp(),
358+
global: true,
359+
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
360+
identifier: identifier,
361+
lifetime: None,
362+
types: opt_vec::Empty,
363+
}).collect()
364+
}
356365
}
357366

358367
fn mk_tests(cx: &TestCtxt) -> @ast::item {

src/librustc/metadata/encoder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
996996
encode_name(ecx, ebml_w, item.ident);
997997
encode_attributes(ebml_w, item.attrs);
998998
match ty.node {
999-
ast::ty_path(ref path, ref bounds, _) if path.idents.len() == 1 => {
999+
ast::ty_path(ref path, ref bounds, _) if path.segments
1000+
.len() == 1 => {
10001001
assert!(bounds.is_none());
10011002
encode_impl_type_basename(ecx, ebml_w,
10021003
ast_util::path_to_ident(path));

src/librustc/metadata/tydecode.rs

Lines changed: 14 additions & 6 deletions
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub fn check_expr(sess: Session,
117117
// to handle on-demand instantiation of functions via
118118
// foo::<bar> in a const. Currently that is only done on
119119
// a path in trans::callee that only works in block contexts.
120-
if pth.types.len() != 0 {
120+
if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
121121
sess.span_err(
122122
e.span, "paths in constants may only refer to \
123123
items without type parameters");

src/librustc/middle/privacy.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ use syntax::ast_util::{Private, Public, is_local};
3333
use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy};
3434
use syntax::attr;
3535
use syntax::codemap::span;
36-
use syntax::parse::token;
3736
use syntax::oldvisit;
37+
use syntax::parse::token;
3838

3939
pub fn check_crate<'mm>(tcx: ty::ctxt,
4040
method_map: &'mm method_map,
@@ -255,21 +255,29 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
255255
match def {
256256
def_static_method(method_id, _, _) => {
257257
debug!("found static method def, checking it");
258-
check_method_common(span, method_id, path.idents.last())
258+
check_method_common(span,
259+
method_id,
260+
&path.segments.last().identifier)
259261
}
260262
def_fn(def_id, _) => {
261263
if def_id.crate == LOCAL_CRATE {
262264
if local_item_is_private(span, def_id.node) &&
263265
!privileged_items.iter().any(|x| x == &def_id.node) {
264266
tcx.sess.span_err(span,
265267
fmt!("function `%s` is private",
266-
token::ident_to_str(path.idents.last())));
268+
token::ident_to_str(
269+
&path.segments
270+
.last()
271+
.identifier)));
267272
}
268273
} else if csearch::get_item_visibility(tcx.sess.cstore,
269274
def_id) != public {
270275
tcx.sess.span_err(span,
271276
fmt!("function `%s` is private",
272-
token::ident_to_str(path.idents.last())));
277+
token::ident_to_str(
278+
&path.segments
279+
.last()
280+
.identifier)));
273281
}
274282
}
275283
_ => {}

src/librustc/middle/region.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ fn determine_rp_in_ty(ty: &ast::Ty,
797797
Some(&ast::def_trait(did)) |
798798
Some(&ast::def_struct(did)) => {
799799
if did.crate == ast::LOCAL_CRATE {
800-
if cx.region_is_relevant(&path.rp) {
800+
if cx.region_is_relevant(&path.segments.last().lifetime) {
801801
cx.add_dep(did.node);
802802
}
803803
} else {
@@ -807,7 +807,7 @@ fn determine_rp_in_ty(ty: &ast::Ty,
807807
Some(variance) => {
808808
debug!("reference to external, rp'd type %s",
809809
pprust::ty_to_str(ty, sess.intr()));
810-
if cx.region_is_relevant(&path.rp) {
810+
if cx.region_is_relevant(&path.segments.last().lifetime) {
811811
let rv = cx.add_variance(variance);
812812
cx.add_rp(cx.item_id, rv)
813813
}
@@ -830,7 +830,7 @@ fn determine_rp_in_ty(ty: &ast::Ty,
830830
ast::ty_path(ref path, _, _) => {
831831
// type parameters are---for now, anyway---always invariant
832832
do cx.with_ambient_variance(rv_invariant) {
833-
for tp in path.types.iter() {
833+
for tp in path.segments.iter().flat_map_(|s| s.types.iter()) {
834834
(visitor.visit_ty)(tp, (cx, visitor));
835835
}
836836
}

0 commit comments

Comments
 (0)