Skip to content

Commit b0ed151

Browse files
committed
Cleanup how we handle proto in types, remove unsound subtyping
Fixes #1896 which was never truly fixed, just masked. The given tests would have failed had they used `~fn()` and not `@fn()`. They now result in compilation errors. Fixes #2978. Necessary first step for #2202, #2263.
1 parent 53ec6c3 commit b0ed151

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+947
-1002
lines changed

src/libsyntax/ast.rs

+31-14
Original file line numberDiff line numberDiff line change
@@ -410,18 +410,24 @@ impl mutability : cmp::Eq {
410410

411411
#[auto_serialize]
412412
#[auto_deserialize]
413-
enum proto {
414-
proto_bare, // foreign fn
415-
proto_uniq, // fn~
416-
proto_box, // fn@
417-
proto_block, // fn&
413+
pub enum Proto {
414+
ProtoBare, // bare functions (deprecated)
415+
ProtoUniq, // ~fn
416+
ProtoBox, // @fn
417+
ProtoBorrowed, // &fn
418418
}
419419

420-
impl proto : cmp::Eq {
421-
pure fn eq(other: &proto) -> bool {
420+
impl Proto : cmp::Eq {
421+
pure fn eq(other: &Proto) -> bool {
422422
(self as uint) == ((*other) as uint)
423423
}
424-
pure fn ne(other: &proto) -> bool { !self.eq(other) }
424+
pure fn ne(other: &Proto) -> bool { !self.eq(other) }
425+
}
426+
427+
impl Proto : to_bytes::IterBytes {
428+
pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
429+
(self as uint).iter_bytes(lsb0, f);
430+
}
425431
}
426432

427433
#[auto_serialize]
@@ -444,10 +450,10 @@ enum expr_vstore {
444450
expr_vstore_slice // &[1,2,3,4]
445451
}
446452

447-
pure fn is_blockish(p: ast::proto) -> bool {
453+
pure fn is_blockish(p: ast::Proto) -> bool {
448454
match p {
449-
proto_block => true,
450-
proto_bare | proto_uniq | proto_box => false
455+
ProtoBorrowed => true,
456+
ProtoBare | ProtoUniq | ProtoBox => false
451457
}
452458
}
453459

@@ -678,7 +684,7 @@ enum expr_ {
678684
(implicit) condition is always true. */
679685
expr_loop(blk, Option<ident>),
680686
expr_match(@expr, ~[arm]),
681-
expr_fn(proto, fn_decl, blk, capture_clause),
687+
expr_fn(Proto, fn_decl, blk, capture_clause),
682688
expr_fn_block(fn_decl, blk, capture_clause),
683689
// Inner expr is always an expr_fn_block. We need the wrapping node to
684690
// easily type this (a function returning nil on the inside but bool on
@@ -1078,6 +1084,17 @@ impl Onceness : cmp::Eq {
10781084
}
10791085
}
10801086

1087+
#[auto_serialize]
1088+
#[auto_deserialize]
1089+
struct TyFn {
1090+
proto: Proto,
1091+
region: Option<@region>,
1092+
purity: purity,
1093+
onceness: Onceness,
1094+
bounds: @~[ty_param_bound],
1095+
decl: fn_decl
1096+
}
1097+
10811098
#[auto_serialize]
10821099
#[auto_deserialize]
10831100
enum ty_ {
@@ -1086,13 +1103,13 @@ enum ty_ {
10861103
ty_box(mt),
10871104
ty_uniq(mt),
10881105
ty_vec(mt),
1106+
ty_fixed_length_vec(mt, uint),
10891107
ty_ptr(mt),
10901108
ty_rptr(@region, mt),
10911109
ty_rec(~[ty_field]),
1092-
ty_fn(proto, purity, Onceness, @~[ty_param_bound], fn_decl),
1110+
ty_fn(@TyFn),
10931111
ty_tup(~[@Ty]),
10941112
ty_path(@path, node_id),
1095-
ty_fixed_length(@Ty, Option<uint>),
10961113
ty_mac(mac),
10971114
// ty_infer means the type should be inferred instead of it having been
10981115
// specified. This should only appear at the "top level" of a type and not

src/libsyntax/fold.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -524,15 +524,19 @@ fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ {
524524
ty_ptr(mt) => ty_ptr(fold_mt(mt, fld)),
525525
ty_rptr(region, mt) => ty_rptr(region, fold_mt(mt, fld)),
526526
ty_rec(fields) => ty_rec(vec::map(fields, |f| fold_field(*f, fld))),
527-
ty_fn(proto, purity, onceness, bounds, decl) =>
528-
ty_fn(proto,
529-
purity,
530-
onceness,
531-
@vec::map(*bounds, |x| fold_ty_param_bound(*x, fld)),
532-
fold_fn_decl(decl, fld)),
527+
ty_fn(f) =>
528+
ty_fn(@TyFn {
529+
proto: f.proto,
530+
purity: f.purity,
531+
region: f.region,
532+
onceness: f.onceness,
533+
bounds: @vec::map(*f.bounds, |x| fold_ty_param_bound(*x, fld)),
534+
decl: fold_fn_decl(f.decl, fld)
535+
}),
533536
ty_tup(tys) => ty_tup(vec::map(tys, |ty| fld.fold_ty(*ty))),
534537
ty_path(path, id) => ty_path(fld.fold_path(path), fld.new_id(id)),
535-
ty_fixed_length(t, vs) => ty_fixed_length(fld.fold_ty(t), vs),
538+
ty_fixed_length_vec(mt, vs) =>
539+
ty_fixed_length_vec(fold_mt(mt, fld), vs),
536540
ty_mac(mac) => ty_mac(fold_mac(mac))
537541
}
538542
}

src/libsyntax/parse/obsolete.rs

-66
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ pub enum ObsoleteSyntax {
2424
ObsoletePrivSection,
2525
ObsoleteModeInFnType,
2626
ObsoleteByMutRefMode,
27-
ObsoleteFixedLengthVec,
2827
ObsoleteMoveInit,
2928
ObsoleteBinaryMove
3029
}
@@ -102,11 +101,6 @@ impl Parser : ObsoleteReporter {
102101
"by-mutable-reference mode",
103102
"Declare an argument of type &mut T instead"
104103
),
105-
ObsoleteFixedLengthVec => (
106-
"fixed-length vector",
107-
"Fixed-length types are now written `[T * N]`, and instances \
108-
are type-inferred"
109-
),
110104
ObsoleteMoveInit => (
111105
"initializer-by-move",
112106
"Write `let foo = move bar` instead"
@@ -200,65 +194,5 @@ impl Parser : ObsoleteReporter {
200194
}
201195
}
202196

203-
fn try_parse_obsolete_fixed_vstore() -> Option<Option<uint>> {
204-
if self.token == token::BINOP(token::SLASH) {
205-
self.bump();
206-
match copy self.token {
207-
token::UNDERSCORE => {
208-
self.obsolete(copy self.last_span,
209-
ObsoleteFixedLengthVec);
210-
self.bump(); Some(None)
211-
}
212-
token::LIT_INT_UNSUFFIXED(i) if i >= 0i64 => {
213-
self.obsolete(copy self.last_span,
214-
ObsoleteFixedLengthVec);
215-
self.bump(); Some(Some(i as uint))
216-
}
217-
_ => None
218-
}
219-
} else {
220-
None
221-
}
222-
}
223-
224-
fn try_convert_ty_to_obsolete_fixed_length_vstore(sp: span, t: ast::ty_)
225-
-> ast::ty_ {
226-
match self.try_parse_obsolete_fixed_vstore() {
227-
// Consider a fixed length vstore suffix (/N or /_)
228-
None => t,
229-
Some(v) => {
230-
ast::ty_fixed_length(
231-
@{id: self.get_id(), node: t, span: sp}, v)
232-
}
233-
}
234-
}
235-
236-
fn try_convert_expr_to_obsolete_fixed_length_vstore(
237-
lo: uint, hi: uint, ex: ast::expr_
238-
) -> (uint, ast::expr_) {
239-
240-
let mut hi = hi;
241-
let mut ex = ex;
242-
243-
// Vstore is legal following expr_lit(lit_str(...)) and expr_vec(...)
244-
// only.
245-
match ex {
246-
ast::expr_lit(@{node: ast::lit_str(_), span: _}) |
247-
ast::expr_vec(_, _) => {
248-
match self.try_parse_obsolete_fixed_vstore() {
249-
None => (),
250-
Some(v) => {
251-
hi = self.span.hi;
252-
ex = ast::expr_vstore(self.mk_expr(lo, hi, ex),
253-
ast::expr_vstore_fixed(v));
254-
}
255-
}
256-
}
257-
_ => ()
258-
}
259-
260-
return (hi, ex);
261-
}
262-
263197
}
264198

0 commit comments

Comments
 (0)