diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2013-06-20 18:23:25 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2013-06-26 18:14:43 -0400 |
| commit | 7b968783d79301af2305c0b1052092f9d31fd622 (patch) | |
| tree | 5249ec3d32b5ecfeb7e20c91c66406246a5b68d2 /src/libsyntax | |
| parent | 12e09afd6d7bb4ca30e572a5214c11284ea1965b (diff) | |
| download | rust-7b968783d79301af2305c0b1052092f9d31fd622.tar.gz rust-7b968783d79301af2305c0b1052092f9d31fd622.zip | |
Infer default static/Owned bounds for unbounded heap fns/traits (#7264)
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/ty.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/pipec.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/proto.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 8 |
11 files changed, 60 insertions, 42 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 90b2f131b00..1a7094acf7e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -771,7 +771,11 @@ pub struct TyClosure { purity: purity, onceness: Onceness, decl: fn_decl, - bounds: OptVec<TyParamBound> + // Optional optvec distinguishes between "fn()" and "fn:()" so we can + // implement issue #7264. None means "fn()", which means infer a default + // bound based on pointer sigil during typeck. Some(Empty) means "fn:()", + // which means use no bounds (e.g., not even Owned on a ~fn()). + bounds: Option<OptVec<TyParamBound>>, } #[deriving(Eq, Encodable, Decodable)] @@ -795,7 +799,7 @@ pub enum ty_ { ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), - ty_path(@Path, @OptVec<TyParamBound>, node_id), + ty_path(@Path, @Option<OptVec<TyParamBound>>, node_id), // for #7264; see above ty_mac(mac), // ty_infer means the type should be inferred instead of it having been // specified. This should only appear at the "top level" of a type and not diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 02d5991e1a7..2c1b4cfc591 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -46,7 +46,7 @@ pub trait AstBuilder { fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt; fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty; - fn ty_path(&self, @ast::Path, @OptVec<ast::TyParamBound>) -> @ast::Ty; + fn ty_path(&self, @ast::Path, @Option<OptVec<ast::TyParamBound>>) -> @ast::Ty; fn ty_ident(&self, span: span, idents: ast::ident) -> @ast::Ty; fn ty_rptr(&self, span: span, @@ -265,7 +265,7 @@ impl AstBuilder for @ExtCtxt { } } - fn ty_path(&self, path: @ast::Path, bounds: @OptVec<ast::TyParamBound>) + fn ty_path(&self, path: @ast::Path, bounds: @Option<OptVec<ast::TyParamBound>>) -> @ast::Ty { self.ty(path.span, ast::ty_path(path, bounds, self.next_id())) @@ -275,7 +275,7 @@ impl AstBuilder for @ExtCtxt { // to generate a bounded existential trait type. fn ty_ident(&self, span: span, ident: ast::ident) -> @ast::Ty { - self.ty_path(self.path_ident(span, ident), @opt_vec::Empty) + self.ty_path(self.path_ident(span, ident), @None) } fn ty_rptr(&self, @@ -306,7 +306,7 @@ impl AstBuilder for @ExtCtxt { ], None, ~[ ty ]), - @opt_vec::Empty) + @None) } fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field { @@ -344,7 +344,7 @@ impl AstBuilder for @ExtCtxt { fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] { opt_vec::take_vec( ty_params.map(|p| self.ty_path( - self.path_global(dummy_sp(), ~[p.ident]), @opt_vec::Empty))) + self.path_global(dummy_sp(), ~[p.ident]), @None))) } fn strip_bounds(&self, generics: &Generics) -> Generics { diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 17bbe7a333e..10d9f878bc4 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -357,7 +357,7 @@ impl<'self> TraitDef<'self> { // Create the type of `self`. let self_type = cx.ty_path(cx.path_all(span, false, ~[ type_ident ], self_lifetime, opt_vec::take_vec(self_ty_params)), - @opt_vec::Empty); + @None); let doc_attr = cx.attribute( span, diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index 9da6bf27ead..2f21eba11d7 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -63,7 +63,7 @@ impl<'self> Path<'self> { self_generics: &Generics) -> @ast::Ty { cx.ty_path(self.to_path(cx, span, - self_ty, self_generics), @opt_vec::Empty) + self_ty, self_generics), @None) } pub fn to_path(&self, cx: @ExtCtxt, @@ -143,7 +143,7 @@ impl<'self> Ty<'self> { Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) } Self => { cx.ty_path(self.to_path(cx, span, self_ty, self_generics), - @opt_vec::Empty) + @None) } Tuple(ref fields) => { let ty = if fields.is_empty() { diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index a75a20a0fa9..2c5ec0909d9 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -59,7 +59,7 @@ impl gen_send for message { let pipe_ty = cx.ty_path( path(~[this.data_name()], span) - .add_tys(cx.ty_vars(&this.generics.ty_params)), @opt_vec::Empty); + .add_tys(cx.ty_vars(&this.generics.ty_params)), @None); let args_ast = vec::append( ~[cx.arg(span, cx.ident_of("pipe"), pipe_ty)], args_ast); @@ -115,7 +115,7 @@ impl gen_send for message { let mut rty = cx.ty_path(path(~[next.data_name()], span) - .add_tys(copy next_state.tys), @opt_vec::Empty); + .add_tys(copy next_state.tys), @None); if try { rty = cx.ty_option(rty); } @@ -144,7 +144,7 @@ impl gen_send for message { cx.ty_path( path(~[this.data_name()], span) .add_tys(cx.ty_vars( - &this.generics.ty_params)), @opt_vec::Empty))], + &this.generics.ty_params)), @None))], args_ast); let message_args = if arg_names.len() == 0 { @@ -190,7 +190,7 @@ impl gen_send for message { fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty { cx.ty_path(path(~[cx.ident_of(self.name())], self.span()) - .add_tys(cx.ty_vars(&self.get_generics().ty_params)), @opt_vec::Empty) + .add_tys(cx.ty_vars(&self.get_generics().ty_params)), @None) } } @@ -224,7 +224,7 @@ impl to_type_decls for state { cx.ty_path( path(~[cx.ident_of(dir), cx.ident_of(next_name)], span) - .add_tys(copy next_state.tys), @opt_vec::Empty)) + .add_tys(copy next_state.tys), @None)) } None => tys }; @@ -277,8 +277,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars( - &self.generics.ty_params)), @opt_vec::Empty)), - @opt_vec::Empty), + &self.generics.ty_params)), @None)), + @None), cx.strip_bounds(&self.generics))); } else { @@ -297,8 +297,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars_global( - &self.generics.ty_params)), @opt_vec::Empty), - self.proto.buffer_ty_path(cx)]), @opt_vec::Empty), + &self.generics.ty_params)), @None), + self.proto.buffer_ty_path(cx)]), @None), cx.strip_bounds(&self.generics))); }; items @@ -383,7 +383,7 @@ impl gen_init for protocol { cx.ty_path(path(~[cx.ident_of("super"), cx.ident_of("__Buffer")], copy self.span) - .add_tys(cx.ty_vars_global(¶ms)), @opt_vec::Empty) + .add_tys(cx.ty_vars_global(¶ms)), @None) } fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item { diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index e86ced847d7..0525c666478 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -13,7 +13,6 @@ use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::pipes::ast_builder::{append_types, path}; -use opt_vec; #[deriving(Eq)] pub enum direction { send, recv } @@ -100,7 +99,7 @@ impl state_ { pub fn to_ty(&self, cx: @ExtCtxt) -> @ast::Ty { cx.ty_path (path(~[cx.ident_of(self.name)],self.span).add_tys( - cx.ty_vars(&self.generics.ty_params)), @opt_vec::Empty) + cx.ty_vars(&self.generics.ty_params)), @None) } /// Iterate over the states that can be reached in one message diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2c7c335a841..2fc111da453 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -651,6 +651,12 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { span: fld.new_span(f.span), } } + fn fold_opt_bounds(b: &Option<OptVec<TyParamBound>>, fld: @ast_fold) + -> Option<OptVec<TyParamBound>> { + do b.map |bounds| { + do bounds.map |bound| { fold_ty_param_bound(bound, fld) } + } + } match *t { ty_nil | ty_bot | ty_infer => copy *t, ty_box(ref mt) => ty_box(fold_mt(mt, fld)), @@ -664,7 +670,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { purity: f.purity, region: f.region, onceness: f.onceness, - bounds: f.bounds.map(|x| fold_ty_param_bound(x, fld)), + bounds: fold_opt_bounds(&f.bounds, fld), decl: fold_fn_decl(&f.decl, fld), lifetimes: copy f.lifetimes, }) @@ -679,8 +685,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { } ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))), ty_path(path, bounds, id) => - ty_path(fld.fold_path(path), - @bounds.map(|x| fold_ty_param_bound(x, fld)), fld.new_id(id)), + ty_path(fld.fold_path(path), @fold_opt_bounds(bounds, fld), fld.new_id(id)), ty_fixed_length_vec(ref mt, e) => { ty_fixed_length_vec( fold_mt(mt, fld), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index d54c64e7ee6..6dd8d4880e3 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -490,7 +490,7 @@ mod test { idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @opt_vec::Empty, 2), + @None, 2), span:sp(4,7)}, pat: @ast::pat{id:1, node: ast::pat_ident(ast::bind_infer, @@ -526,7 +526,7 @@ mod test { idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @opt_vec::Empty, 2), + @None, 2), span:sp(10,13)}, pat: @ast::pat{id:1, // fixme node: ast::pat_ident( diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b10005aeaf1..d67771fc435 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1047,8 +1047,8 @@ impl Parser { // Like the above, but can also parse kind bounds in the case of a // path to be used as a type that might be a trait. - pub fn parse_type_path(&self) -> (@ast::Path, OptVec<TyParamBound>) { - let mut bounds = opt_vec::Empty; + pub fn parse_type_path(&self) -> (@ast::Path, Option<OptVec<TyParamBound>>) { + let mut bounds = None; let path = self.parse_bounded_path_with_tps(false, Some(|| { // Note: this closure might not even get called in the case of a // macro-generated path. But that's the macro parser's job. @@ -2884,9 +2884,13 @@ impl Parser { // matches optbounds = ( ( : ( boundseq )? )? ) // where boundseq = ( bound + boundseq ) | bound // and bound = 'static | ty - fn parse_optional_ty_param_bounds(&self) -> OptVec<TyParamBound> { + // Returns "None" if there's no colon (e.g. "T"); + // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:") + // Returns "Some(stuff)" otherwise (e.g. "T:stuff"). + // NB: The None/Some distinction is important for issue #7264. + fn parse_optional_ty_param_bounds(&self) -> Option<OptVec<TyParamBound>> { if !self.eat(&token::COLON) { - return opt_vec::Empty; + return None; } let mut result = opt_vec::Empty; @@ -2935,13 +2939,15 @@ impl Parser { } } - return result; + return Some(result); } // matches typaram = IDENT optbounds fn parse_ty_param(&self) -> TyParam { let ident = self.parse_ident(); - let bounds = @self.parse_optional_ty_param_bounds(); + let opt_bounds = self.parse_optional_ty_param_bounds(); + // For typarams we don't care about the difference b/w "<T>" and "<T:>". + let bounds = @opt_bounds.get_or_default(opt_vec::Empty); ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds } } @@ -3288,7 +3294,7 @@ impl Parser { let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { - ty_path(path, @opt_vec::Empty, node_id) => { + ty_path(path, @None, node_id) => { Some(@trait_ref { path: path, ref_id: node_id diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 277cc6208fb..0be8c31647f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1488,7 +1488,7 @@ pub fn print_for_decl(s: @ps, loc: @ast::local, coll: @ast::expr) { } fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, - opt_bounds: Option<@OptVec<ast::TyParamBound>>) { + opt_bounds: &Option<OptVec<ast::TyParamBound>>) { maybe_print_comment(s, path.span.lo); if path.global { word(s.s, "::"); } let mut first = true; @@ -1496,7 +1496,7 @@ fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, if first { first = false; } else { word(s.s, "::"); } print_ident(s, *id); } - do opt_bounds.map_consume |bounds| { + do opt_bounds.map |bounds| { print_bounds(s, bounds); }; if path.rp.is_some() || !path.types.is_empty() { @@ -1520,12 +1520,12 @@ fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, } pub fn print_path(s: @ps, path: @ast::Path, colons_before_params: bool) { - print_path_(s, path, colons_before_params, None) + print_path_(s, path, colons_before_params, &None) } pub fn print_bounded_path(s: @ps, path: @ast::Path, - bounds: @OptVec<ast::TyParamBound>) { - print_path_(s, path, false, Some(bounds)) + bounds: &Option<OptVec<ast::TyParamBound>>) { + print_path_(s, path, false, bounds) } pub fn print_irrefutable_pat(s: @ps, pat: @ast::pat) { @@ -1737,7 +1737,7 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) { maybe_print_comment(s, decl.output.span.lo); } -pub fn print_bounds(s: @ps, bounds: @OptVec<ast::TyParamBound>) { +pub fn print_bounds(s: @ps, bounds: &OptVec<ast::TyParamBound>) { if !bounds.is_empty() { word(s.s, ":"); let mut first = true; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9b816ce5e5b..f0a993dbb94 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -246,7 +246,9 @@ pub fn visit_ty<E: Copy>(t: @Ty, (e, v): (E, vt<E>)) { ty_closure(ref f) => { for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } (v.visit_ty)(f.decl.output, (copy e, v)); - visit_ty_param_bounds(&f.bounds, (e, v)); + do f.bounds.map |bounds| { + visit_ty_param_bounds(bounds, (copy e, v)); + }; }, ty_bare_fn(ref f) => { for f.decl.inputs.iter().advance |a| { (v.visit_ty)(a.ty, (copy e, v)); } @@ -254,7 +256,9 @@ pub fn visit_ty<E: Copy>(t: @Ty, (e, v): (E, vt<E>)) { }, ty_path(p, bounds, _) => { visit_path(p, (copy e, v)); - visit_ty_param_bounds(bounds, (e, v)); + do bounds.map |bounds| { + visit_ty_param_bounds(bounds, (copy e, v)); + }; }, ty_fixed_length_vec(ref mt, ex) => { (v.visit_ty)(mt.ty, (copy e, v)); |
