Skip to content

Commit 46d4bbb

Browse files
committed
Simplify the AST representation of ty param bounds
Change ast::ty_param_bound so that all ty param bounds are represented as traits, with no special cases for Copy/Send/Owned/Const. typeck::collect generates the special cases. A consequence of this is that code using the #[no_core] attribute can't use the Copy kind/trait. Probably not a big deal? As a side effect, any user-defined traits that happen to be called Copy, etc. in the same module override the built-in Copy trait. r=nmatsakis Closes #2284
1 parent 42c05fe commit 46d4bbb

File tree

10 files changed

+57
-65
lines changed

10 files changed

+57
-65
lines changed

src/libsyntax/ast.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,11 @@ const crate_node_id: node_id = 0;
123123

124124
#[auto_serialize]
125125
#[auto_deserialize]
126-
enum ty_param_bound {
127-
bound_copy,
128-
bound_send,
129-
bound_const,
130-
bound_owned,
131-
bound_trait(@Ty),
132-
}
126+
// The AST represents all type param bounds as types.
127+
// typeck::collect::compute_bounds matches these against
128+
// the "special" built-in traits (see middle::lang_items) and
129+
// detects Copy, Send, Owned, and Const.
130+
enum ty_param_bound = @Ty;
133131

134132
#[auto_serialize]
135133
#[auto_deserialize]

src/libsyntax/ext/auto_serialize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ priv impl ext_ctxt {
227227
path: @ast::path,
228228
bounds: @~[ast::ty_param_bound]
229229
) -> ast::ty_param {
230-
let bound = ast::bound_trait(@{
230+
let bound = ast::ty_param_bound(@{
231231
id: self.next_id(),
232232
node: ast::ty_path(path, self.next_id()),
233233
span: span,
@@ -366,7 +366,7 @@ fn mk_impl(
366366
let mut trait_tps = vec::append(
367367
~[ty_param],
368368
do tps.map |tp| {
369-
let t_bound = ast::bound_trait(@{
369+
let t_bound = ast::ty_param_bound(@{
370370
id: cx.next_id(),
371371
node: ast::ty_path(path, cx.next_id()),
372372
span: span,

src/libsyntax/fold.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,7 @@ fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl {
131131
}
132132

133133
fn fold_ty_param_bound(tpb: ty_param_bound, fld: ast_fold) -> ty_param_bound {
134-
match tpb {
135-
bound_copy | bound_send | bound_const | bound_owned => tpb,
136-
bound_trait(ty) => bound_trait(fld.fold_ty(ty))
137-
}
134+
ty_param_bound(fld.fold_ty(*tpb))
138135
}
139136

140137
fn fold_ty_param(tp: ty_param, fld: ast_fold) -> ty_param {

src/libsyntax/parse/parser.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ use obsolete::{
2424
};
2525
use ast::{_mod, add, arg, arm, attribute,
2626
bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
27-
bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
28-
bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
27+
bitand, bitor, bitxor, blk, blk_check_mode, box, by_copy,
2928
by_move, by_ref, by_val, capture_clause,
3029
capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
3130
class_immutable, class_mutable,
@@ -2295,19 +2294,20 @@ impl Parser {
22952294
return spanned(lo, hi, bloc);
22962295
}
22972296

2297+
fn mk_ty_path(i: ident) -> @Ty {
2298+
@{id: self.get_id(), node: ty_path(
2299+
ident_to_path(copy self.last_span, i),
2300+
self.get_id()), span: self.last_span}
2301+
}
2302+
22982303
fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] {
22992304
let mut bounds = ~[];
23002305
if self.eat(token::COLON) {
23012306
while is_ident(self.token) {
23022307
if is_ident(self.token) {
2303-
// XXX: temporary until kinds become traits
23042308
let maybe_bound = match self.token {
23052309
token::IDENT(copy sid, _) => {
23062310
match *self.id_to_str(sid) {
2307-
~"Send" => Some(bound_send),
2308-
~"Copy" => Some(bound_copy),
2309-
~"Const" => Some(bound_const),
2310-
~"Owned" => Some(bound_owned),
23112311

23122312
~"send"
23132313
| ~"copy"
@@ -2317,7 +2317,7 @@ impl Parser {
23172317
ObsoleteLowerCaseKindBounds);
23182318
// Bogus value, but doesn't matter, since
23192319
// is an error
2320-
Some(bound_send)
2320+
Some(ty_param_bound(self.mk_ty_path(sid)))
23212321
}
23222322

23232323
_ => None
@@ -2332,11 +2332,11 @@ impl Parser {
23322332
bounds.push(bound);
23332333
}
23342334
None => {
2335-
bounds.push(bound_trait(self.parse_ty(false)));
2335+
bounds.push(ty_param_bound(self.parse_ty(false)));
23362336
}
23372337
}
23382338
} else {
2339-
bounds.push(bound_trait(self.parse_ty(false)));
2339+
bounds.push(ty_param_bound(self.parse_ty(false)));
23402340
}
23412341
}
23422342
}

src/libsyntax/print/pprust.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,17 +1704,11 @@ fn print_arg_mode(s: ps, m: ast::mode) {
17041704
}
17051705

17061706
fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) {
1707-
if vec::len(*bounds) > 0u {
1707+
if bounds.is_not_empty() {
17081708
word(s.s, ~":");
17091709
for vec::each(*bounds) |bound| {
17101710
nbsp(s);
1711-
match *bound {
1712-
ast::bound_copy => word(s.s, ~"Copy"),
1713-
ast::bound_send => word(s.s, ~"Send"),
1714-
ast::bound_const => word(s.s, ~"Const"),
1715-
ast::bound_owned => word(s.s, ~"Owned"),
1716-
ast::bound_trait(t) => print_type(s, t)
1717-
}
1711+
print_type(s, **bound);
17181712
}
17191713
}
17201714
}

src/libsyntax/visit.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,7 @@ fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {
264264

265265
fn visit_ty_param_bounds<E>(bounds: @~[ty_param_bound], e: E, v: vt<E>) {
266266
for vec::each(*bounds) |bound| {
267-
match *bound {
268-
bound_trait(t) => v.visit_ty(t, e, v),
269-
bound_copy | bound_send | bound_const | bound_owned => ()
270-
}
267+
v.visit_ty(**bound, e, v)
271268
}
272269
}
273270

src/rustc/middle/resolve.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use middle::pat_util::{pat_bindings};
99
use syntax::ast::{_mod, add, arm};
1010
use syntax::ast::{bind_by_ref, bind_by_implicit_ref, bind_by_value};
1111
use syntax::ast::{bitand, bitor, bitxor};
12-
use syntax::ast::{blk, bound_const, bound_copy, bound_owned, bound_send};
13-
use syntax::ast::{bound_trait, binding_mode, capture_clause, class_ctor};
14-
use syntax::ast::{class_dtor, crate, crate_num, decl_item};
12+
use syntax::ast::{binding_mode, blk,
13+
capture_clause, class_ctor, class_dtor};
14+
use syntax::ast::{crate, crate_num, decl_item};
1515
use syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn};
1616
use syntax::ast::{def_foreign_mod, def_id, def_label, def_local, def_mod};
1717
use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
@@ -39,6 +39,7 @@ use syntax::ast::{trait_ref, tuple_variant_kind, Ty, ty_bool, ty_char};
3939
use syntax::ast::{ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16, ty_i32};
4040
use syntax::ast::{ty_i64, ty_i8, ty_int, ty_param, ty_path, ty_str, ty_u};
4141
use syntax::ast::{ty_u16, ty_u32, ty_u64, ty_u8, ty_uint, type_value_ns};
42+
use syntax::ast::{ty_param_bound};
4243
use syntax::ast::{variant, view_item, view_item_export, view_item_import};
4344
use syntax::ast::{view_item_use, view_path_glob, view_path_list};
4445
use syntax::ast::{view_path_simple, visibility, anonymous, named};
@@ -3764,14 +3765,7 @@ impl Resolver {
37643765
visitor: ResolveVisitor) {
37653766
for type_parameters.each |type_parameter| {
37663767
for type_parameter.bounds.each |bound| {
3767-
match *bound {
3768-
bound_copy | bound_send | bound_const | bound_owned => {
3769-
// Nothing to do.
3770-
}
3771-
bound_trait(trait_type) => {
3772-
self.resolve_type(trait_type, visitor);
3773-
}
3774-
}
3768+
self.resolve_type(**bound, visitor);
37753769
}
37763770
}
37773771
}
@@ -4088,7 +4082,7 @@ impl Resolver {
40884082
let mut result_def = None;
40894083

40904084
// First, check to see whether the name is a primitive type.
4091-
if path.idents.len() == 1u {
4085+
if path.idents.len() == 1 {
40924086
let name = path.idents.last();
40934087

40944088
match self.primitive_type_table

src/rustc/middle/typeck/collect.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -707,28 +707,41 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
707707
}
708708
}
709709

710+
// Translate the AST's notion of ty param bounds (which are just newtyped Tys)
711+
// to ty's notion of ty param bounds, which can either be user-defined traits,
712+
// or one of the four built-in traits (formerly known as kinds): Const, Copy,
713+
// Owned, and Send.
710714
fn compute_bounds(ccx: @crate_ctxt,
711715
ast_bounds: @~[ast::ty_param_bound]) -> ty::param_bounds {
712716
@do vec::flat_map(*ast_bounds) |b| {
713-
match *b {
714-
ast::bound_send => ~[ty::bound_send],
715-
ast::bound_copy => ~[ty::bound_copy],
716-
ast::bound_const => ~[ty::bound_const],
717-
ast::bound_owned => ~[ty::bound_owned],
718-
ast::bound_trait(t) => {
719-
let ity = ast_ty_to_ty(ccx, empty_rscope, t);
720-
match ty::get(ity).sty {
721-
ty::ty_trait(*) => {
722-
~[ty::bound_trait(ity)]
723-
}
724-
_ => {
717+
let li = &ccx.tcx.lang_items;
718+
let ity = ast_ty_to_ty(ccx, empty_rscope, **b);
719+
match ty::get(ity).sty {
720+
ty::ty_trait(did, _, _) => {
721+
let d = Some(did);
722+
if d == li.send_trait {
723+
~[ty::bound_send]
724+
}
725+
else if d == li.copy_trait {
726+
~[ty::bound_copy]
727+
}
728+
else if d == li.const_trait {
729+
~[ty::bound_const]
730+
}
731+
else if d == li.owned_trait {
732+
~[ty::bound_owned]
733+
}
734+
else {
735+
// Must be a user-defined trait
736+
~[ty::bound_trait(ity)]
737+
}
738+
}
739+
_ => {
725740
ccx.tcx.sess.span_err(
726-
t.span, ~"type parameter bounds must be \
727-
trait types");
741+
(*b).span, ~"type parameter bounds must be \
742+
trait types");
728743
~[]
729-
}
730744
}
731-
}
732745
}
733746
}
734747
}

src/test/compile-fail/tag-that-dare-not-speak-its-name.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
extern mod core;
77

8-
fn last<T: Copy>(v: ~[const T]) -> core::Option<T> {
8+
fn last<T>(v: ~[const &T]) -> core::Option<T> {
99
fail;
1010
}
1111

src/test/run-pass/issue-2284.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// xfail-test
21
trait Send {
32
fn f();
43
}

0 commit comments

Comments
 (0)