From 0643df28a33f122af9cfbdf49970ab55ae08f106 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 4 Mar 2013 15:33:05 -0800 Subject: [PATCH 1/3] libsyntax: Implement `#[deriving_clone]` --- src/libsyntax/ext/base.rs | 3 + src/libsyntax/ext/deriving.rs | 301 +++++++++++++++++- src/test/run-pass/deriving-clone-enum.rs | 9 + .../run-pass/deriving-clone-generic-enum.rs | 9 + .../run-pass/deriving-clone-generic-struct.rs | 9 + .../deriving-clone-generic-tuple-struct.rs | 5 + src/test/run-pass/deriving-clone-struct.rs | 8 + .../run-pass/deriving-clone-tuple-struct.rs | 5 + 8 files changed, 333 insertions(+), 16 deletions(-) create mode 100644 src/test/run-pass/deriving-clone-enum.rs create mode 100644 src/test/run-pass/deriving-clone-generic-enum.rs create mode 100644 src/test/run-pass/deriving-clone-generic-struct.rs create mode 100644 src/test/run-pass/deriving-clone-generic-tuple-struct.rs create mode 100644 src/test/run-pass/deriving-clone-struct.rs create mode 100644 src/test/run-pass/deriving-clone-tuple-struct.rs diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b3d3358e5861e..01439fb40fb37 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -155,6 +155,9 @@ pub fn syntax_expander_table() -> SyntaxEnv { syntax_expanders.insert(@~"deriving_iter_bytes", @SE(ItemDecorator( ext::deriving::expand_deriving_iter_bytes))); + syntax_expanders.insert(@~"deriving_clone", + @SE(ItemDecorator( + ext::deriving::expand_deriving_clone))); // Quasi-quoting expanders syntax_expanders.insert(@~"quote_tokens", diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index 50047d2ce4166..f5dbf26913834 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -15,7 +15,7 @@ use core::prelude::*; use ast; use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def}; -use ast::{enum_variant_kind, expr, expr_match, ident, item, item_}; +use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; @@ -84,6 +84,18 @@ pub fn expand_deriving_iter_bytes(cx: ext_ctxt, expand_deriving_iter_bytes_enum_def) } +pub fn expand_deriving_clone(cx: ext_ctxt, + span: span, + _: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + expand_deriving(cx, + span, + in_items, + expand_deriving_clone_struct_def, + expand_deriving_clone_enum_def) +} + fn expand_deriving(cx: ext_ctxt, span: span, in_items: ~[@item], @@ -303,6 +315,21 @@ fn create_derived_iter_bytes_impl(cx: ext_ctxt, create_derived_impl(cx, span, type_ident, generics, methods, trait_path) } +fn create_derived_clone_impl(cx: ext_ctxt, + span: span, + type_ident: ident, + generics: &Generics, + method: @method) + -> @item { + let methods = [ method ]; + let trait_path = [ + cx.ident_of(~"core"), + cx.ident_of(~"clone"), + cx.ident_of(~"Clone"), + ]; + create_derived_impl(cx, span, type_ident, generics, methods, trait_path) +} + // Creates a method from the given set of statements conforming to the // signature of the `iter_bytes` method. fn create_iter_bytes_method(cx: ext_ctxt, @@ -352,6 +379,58 @@ fn create_iter_bytes_method(cx: ext_ctxt, } } +// Creates a method from the given expression conforming to the signature of +// the `clone` method. +fn create_clone_method(cx: ext_ctxt, + span: span, + +type_ident: ast::ident, + generics: &Generics, + expr: @ast::expr) + -> @method { + // Create the type parameters of the return value. + let mut output_ty_params = ~[]; + for generics.ty_params.each |ty_param| { + let path = build::mk_ty_path(cx, span, ~[ ty_param.ident ]); + output_ty_params.push(path); + } + + // Create the type of the return value. + let output_type_path = build::mk_raw_path_(span, + ~[ type_ident ], + output_ty_params); + let output_type = ast::ty_path(output_type_path, cx.next_id()); + let output_type = @ast::Ty { + id: cx.next_id(), + node: output_type, + span: span + }; + + // Create the function declaration. + let fn_decl = build::mk_fn_decl(~[], output_type); + + // Create the body block. + let body_block = build::mk_simple_block(cx, span, expr); + + // Create the self type and method identifier. + let self_ty = spanned { node: sty_region(m_imm), span: span }; + let method_ident = cx.ident_of(~"clone"); + + // Create the method. + @ast::method { + ident: method_ident, + attrs: ~[], + generics: ast_util::empty_generics(), + self_ty: self_ty, + purity: impure_fn, + decl: fn_decl, + body: body_block, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: public, + } +} + fn create_subpatterns(cx: ext_ctxt, span: span, prefix: ~str, @@ -372,6 +451,15 @@ fn create_subpatterns(cx: ext_ctxt, return dvec::unwrap(subpats); } +fn is_struct_tuple(struct_def: &struct_def) -> bool { + struct_def.fields.len() > 0 && struct_def.fields.all(|f| { + match f.node.kind { + named_field(*) => false, + unnamed_field => true + } + }) +} + fn create_enum_variant_pattern(cx: ext_ctxt, span: span, variant: &variant, @@ -488,6 +576,16 @@ fn call_substructure_iter_bytes_method(cx: ext_ctxt, build::mk_stmt(cx, span, self_call) } +fn call_substructure_clone_method(cx: ext_ctxt, + span: span, + self_field: @expr) + -> @expr { + // Call the substructure method. + let clone_ident = cx.ident_of(~"clone"); + let self_method = build::mk_access_(cx, span, self_field, clone_ident); + build::mk_call_(cx, span, self_method, ~[]) +} + fn variant_arg_count(cx: ext_ctxt, span: span, variant: &variant) -> uint { match variant.node.kind { tuple_variant_kind(ref args) => args.len(), @@ -508,21 +606,12 @@ fn expand_deriving_eq_struct_def(cx: ext_ctxt, let eq_ident = cx.ident_of(~"eq"); let ne_ident = cx.ident_of(~"ne"); - let is_struct_tuple = - struct_def.fields.len() > 0 && struct_def.fields.all(|f| { - match f.node.kind { - named_field(*) => false, - unnamed_field => true - } - }); - - let derive_struct_fn = if is_struct_tuple { + let derive_struct_fn = if is_struct_tuple(struct_def) { expand_deriving_eq_struct_tuple_method } else { expand_deriving_eq_struct_method }; - let eq_method = derive_struct_fn(cx, span, struct_def, @@ -618,6 +707,48 @@ fn expand_deriving_iter_bytes_enum_def(cx: ext_ctxt, method); } +fn expand_deriving_clone_struct_def(cx: ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the method. + let method = if !is_struct_tuple(struct_def) { + expand_deriving_clone_struct_method(cx, + span, + struct_def, + type_ident, + generics) + } else { + expand_deriving_clone_tuple_struct_method(cx, + span, + struct_def, + type_ident, + generics) + }; + + // Create the implementation. + create_derived_clone_impl(cx, span, type_ident, generics, method) +} + +fn expand_deriving_clone_enum_def(cx: ext_ctxt, + span: span, + enum_definition: &enum_def, + type_ident: ident, + generics: &Generics) + -> @item { + // Create the method. + let method = expand_deriving_clone_enum_method(cx, + span, + enum_definition, + type_ident, + generics); + + // Create the implementation. + create_derived_clone_impl(cx, span, type_ident, generics, method) +} + fn expand_deriving_eq_struct_method(cx: ext_ctxt, span: span, struct_def: &struct_def, @@ -709,6 +840,93 @@ fn expand_deriving_iter_bytes_struct_method(cx: ext_ctxt, return create_iter_bytes_method(cx, span, statements); } +fn expand_deriving_clone_struct_method(cx: ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @method { + let self_ident = cx.ident_of(~"self"); + + // Create the new fields. + let mut fields = ~[]; + for struct_def.fields.each |struct_field| { + match struct_field.node.kind { + named_field(ident, _, _) => { + // Create the accessor for this field. + let self_field = build::mk_access(cx, + span, + ~[ self_ident ], + ident); + + // Call the substructure method. + let call = call_substructure_clone_method(cx, + span, + self_field); + + let field = build::Field { ident: ident, ex: call }; + fields.push(field); + } + unnamed_field => { + cx.span_bug(span, + ~"unnamed fields in \ + expand_deriving_clone_struct_method"); + } + } + } + + // Create the struct literal. + let struct_literal = build::mk_struct_e(cx, + span, + ~[ type_ident ], + fields); + create_clone_method(cx, span, type_ident, generics, struct_literal) +} + +fn expand_deriving_clone_tuple_struct_method(cx: ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + generics: &Generics) + -> @method { + // Create the pattern for the match. + let matching_path = build::mk_raw_path(span, ~[ type_ident ]); + let field_count = struct_def.fields.len(); + let subpats = create_subpatterns(cx, span, ~"__self", field_count); + let pat = build::mk_pat_enum(cx, span, matching_path, subpats); + + // Create the new fields. + let mut subcalls = ~[]; + for uint::range(0, struct_def.fields.len()) |i| { + // Create the expression for this field. + let field_ident = cx.ident_of(~"__self" + i.to_str()); + let field = build::mk_path(cx, span, ~[ field_ident ]); + + // Call the substructure method. + let subcall = call_substructure_clone_method(cx, span, field); + subcalls.push(subcall); + } + + // Create the call to the struct constructor. + let call = build::mk_call(cx, span, ~[ type_ident ], subcalls); + + // Create the pattern body. + let match_body_block = build::mk_simple_block(cx, span, call); + + // Create the arm. + let arm = ast::arm { + pats: ~[ pat ], + guard: None, + body: match_body_block + }; + + // Create the method body. + let self_match_expr = expand_enum_or_struct_match(cx, span, ~[ arm ]); + + // Create the method. + create_clone_method(cx, span, type_ident, generics, self_match_expr) +} + fn expand_deriving_eq_enum_method(cx: ext_ctxt, span: span, enum_definition: &enum_def, @@ -904,6 +1122,17 @@ fn expand_deriving_eq_struct_tuple_method(cx: ext_ctxt, type_ident, generics, self_match_expr) } +fn expand_enum_or_struct_match(cx: ext_ctxt, + span: span, + arms: ~[ ast::arm ]) + -> @expr { + let self_ident = cx.ident_of(~"self"); + let self_expr = build::mk_path(cx, span, ~[ self_ident ]); + let self_expr = build::mk_unary(cx, span, deref, self_expr); + let self_match_expr = expr_match(self_expr, arms); + build::mk_expr(cx, span, self_match_expr) +} + fn expand_deriving_iter_bytes_enum_method(cx: ext_ctxt, span: span, enum_definition: &enum_def) @@ -953,14 +1182,54 @@ fn expand_deriving_iter_bytes_enum_method(cx: ext_ctxt, }; // Create the method body. - let self_ident = cx.ident_of(~"self"); - let self_expr = build::mk_path(cx, span, ~[ self_ident ]); - let self_expr = build::mk_unary(cx, span, deref, self_expr); - let self_match_expr = expr_match(self_expr, arms); - let self_match_expr = build::mk_expr(cx, span, self_match_expr); + let self_match_expr = expand_enum_or_struct_match(cx, span, arms); let self_match_stmt = build::mk_stmt(cx, span, self_match_expr); // Create the method. create_iter_bytes_method(cx, span, ~[ self_match_stmt ]) } +fn expand_deriving_clone_enum_method(cx: ext_ctxt, + span: span, + enum_definition: &enum_def, + type_ident: ident, + generics: &Generics) + -> @method { + // Create the arms of the match in the method body. + let arms = do enum_definition.variants.map |variant| { + // Create the matching pattern. + let pat = create_enum_variant_pattern(cx, span, variant, ~"__self"); + + // Iterate over the variant arguments, creating the subcalls. + let mut subcalls = ~[]; + for uint::range(0, variant_arg_count(cx, span, variant)) |j| { + // Create the expression for this field. + let field_ident = cx.ident_of(~"__self" + j.to_str()); + let field = build::mk_path(cx, span, ~[ field_ident ]); + + // Call the substructure method. + let subcall = call_substructure_clone_method(cx, span, field); + subcalls.push(subcall); + } + + // Create the call to the enum variant (if necessary). + let call = if subcalls.len() > 0 { + build::mk_call(cx, span, ~[ variant.node.name ], subcalls) + } else { + build::mk_path(cx, span, ~[ variant.node.name ]) + }; + + // Create the pattern body. + let match_body_block = build::mk_simple_block(cx, span, call); + + // Create the arm. + ast::arm { pats: ~[ pat ], guard: None, body: match_body_block } + }; + + // Create the method body. + let self_match_expr = expand_enum_or_struct_match(cx, span, arms); + + // Create the method. + create_clone_method(cx, span, type_ident, generics, self_match_expr) +} + diff --git a/src/test/run-pass/deriving-clone-enum.rs b/src/test/run-pass/deriving-clone-enum.rs new file mode 100644 index 0000000000000..bad83f41bac65 --- /dev/null +++ b/src/test/run-pass/deriving-clone-enum.rs @@ -0,0 +1,9 @@ +#[deriving_clone] +enum E { + A, + B(()), + C +} + +fn main() {} + diff --git a/src/test/run-pass/deriving-clone-generic-enum.rs b/src/test/run-pass/deriving-clone-generic-enum.rs new file mode 100644 index 0000000000000..c70e644e2a860 --- /dev/null +++ b/src/test/run-pass/deriving-clone-generic-enum.rs @@ -0,0 +1,9 @@ +#[deriving_clone] +enum E { + A(T), + B(T,U), + C +} + +fn main() {} + diff --git a/src/test/run-pass/deriving-clone-generic-struct.rs b/src/test/run-pass/deriving-clone-generic-struct.rs new file mode 100644 index 0000000000000..73fb3ad8d6477 --- /dev/null +++ b/src/test/run-pass/deriving-clone-generic-struct.rs @@ -0,0 +1,9 @@ +#[deriving_clone] +struct S { + foo: (), + bar: (), + baz: T, +} + +fn main() {} + diff --git a/src/test/run-pass/deriving-clone-generic-tuple-struct.rs b/src/test/run-pass/deriving-clone-generic-tuple-struct.rs new file mode 100644 index 0000000000000..d7b15d63280d0 --- /dev/null +++ b/src/test/run-pass/deriving-clone-generic-tuple-struct.rs @@ -0,0 +1,5 @@ +#[deriving_clone] +struct S(T, ()); + +fn main() {} + diff --git a/src/test/run-pass/deriving-clone-struct.rs b/src/test/run-pass/deriving-clone-struct.rs new file mode 100644 index 0000000000000..2f371c8920be5 --- /dev/null +++ b/src/test/run-pass/deriving-clone-struct.rs @@ -0,0 +1,8 @@ +#[deriving_clone] +struct S { + foo: (), + bar: () +} + +fn main() {} + diff --git a/src/test/run-pass/deriving-clone-tuple-struct.rs b/src/test/run-pass/deriving-clone-tuple-struct.rs new file mode 100644 index 0000000000000..a1a79613d401f --- /dev/null +++ b/src/test/run-pass/deriving-clone-tuple-struct.rs @@ -0,0 +1,5 @@ +#[deriving_clone] +struct S((), ()); + +fn main() {} + From 1fef1828ade7a259c1f0c120db16be267f7ef0a6 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 4 Mar 2013 16:11:30 -0800 Subject: [PATCH 2/3] libsyntax: Separate multiple inherited traits with `+` --- src/libsyntax/parse/parser.rs | 2 +- .../auxiliary/trait_inheritance_auto_xc_aux.rs | 2 +- .../auxiliary/trait_inheritance_overloading_xc.rs | 2 +- src/test/compile-fail/issue-3953.rs | 15 +++++++++------ src/test/run-pass/trait-inheritance-auto-xc-2.rs | 2 +- src/test/run-pass/trait-inheritance-auto.rs | 2 +- src/test/run-pass/trait-inheritance-diamond.rs | 2 +- src/test/run-pass/trait-inheritance-num.rs | 4 ++-- src/test/run-pass/trait-inheritance-num0.rs | 2 +- src/test/run-pass/trait-inheritance-num1.rs | 2 +- src/test/run-pass/trait-inheritance-num2.rs | 4 ++-- src/test/run-pass/trait-inheritance-num3.rs | 2 +- src/test/run-pass/trait-inheritance-num5.rs | 2 +- .../run-pass/trait-inheritance-overloading.rs | 2 +- src/test/run-pass/trait-inheritance-static2.rs | 2 +- src/test/run-pass/trait-inheritance2.rs | 2 +- 16 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 0d0d23e0cd0a9..9f83d9ca955cb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3119,7 +3119,7 @@ pub impl Parser { fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[@trait_ref] { self.parse_seq_to_before_end( ket, - seq_sep_none(), + seq_sep_trailing_disallowed(token::BINOP(token::PLUS)), |p| p.parse_trait_ref() ) } diff --git a/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs b/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs index 3e26a09fb8f0d..ecd43686b773a 100644 --- a/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs +++ b/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs @@ -12,6 +12,6 @@ trait Foo { fn f() -> int; } trait Bar { fn g() -> int; } trait Baz { fn h() -> int; } -trait Quux: Foo Bar Baz { } +trait Quux: Foo + Bar + Baz { } impl Quux for T { } diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/auxiliary/trait_inheritance_overloading_xc.rs index 10a7238a3f7d0..e86f7cfd26ad5 100644 --- a/src/test/auxiliary/trait_inheritance_overloading_xc.rs +++ b/src/test/auxiliary/trait_inheritance_overloading_xc.rs @@ -10,7 +10,7 @@ use core::cmp::Eq; -pub trait MyNum : Add Sub Mul Eq { +pub trait MyNum : Add + Sub + Mul + Eq { } pub struct MyInt { diff --git a/src/test/compile-fail/issue-3953.rs b/src/test/compile-fail/issue-3953.rs index c88a94ef62969..afd8cf892333f 100644 --- a/src/test/compile-fail/issue-3953.rs +++ b/src/test/compile-fail/issue-3953.rs @@ -10,12 +10,15 @@ use core::cmp::Eq; -trait Hahaha: Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq //~ ERROR Duplicate supertrait in trait declaration - Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq - Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq - Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq - Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq - Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq {} +trait Hahaha: Eq + Eq + Eq + Eq + Eq + //~ ERROR Duplicate supertrait + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + + Eq {} enum Lol = int; diff --git a/src/test/run-pass/trait-inheritance-auto-xc-2.rs b/src/test/run-pass/trait-inheritance-auto-xc-2.rs index c3333fa10ab17..6b8dd43d58b57 100644 --- a/src/test/run-pass/trait-inheritance-auto-xc-2.rs +++ b/src/test/run-pass/trait-inheritance-auto-xc-2.rs @@ -17,7 +17,7 @@ extern mod aux(name = "trait_inheritance_auto_xc_2_aux"); use aux::{Foo, Bar, Baz, A}; // We want to extend all Foo, Bar, Bazes to Quuxes -pub trait Quux: Foo Bar Baz { } +pub trait Quux: Foo + Bar + Baz { } impl Quux for T { } fn f(a: &T) { diff --git a/src/test/run-pass/trait-inheritance-auto.rs b/src/test/run-pass/trait-inheritance-auto.rs index 5d576193880e5..7ebbc8e83cb65 100644 --- a/src/test/run-pass/trait-inheritance-auto.rs +++ b/src/test/run-pass/trait-inheritance-auto.rs @@ -16,7 +16,7 @@ trait Foo { fn f() -> int; } trait Bar { fn g() -> int; } trait Baz { fn h() -> int; } -trait Quux: Foo Bar Baz { } +trait Quux: Foo + Bar + Baz { } struct A { x: int } diff --git a/src/test/run-pass/trait-inheritance-diamond.rs b/src/test/run-pass/trait-inheritance-diamond.rs index 1d6e482309178..a4a3991f9e8f9 100644 --- a/src/test/run-pass/trait-inheritance-diamond.rs +++ b/src/test/run-pass/trait-inheritance-diamond.rs @@ -13,7 +13,7 @@ trait A { fn a(&self) -> int; } trait B: A { fn b(&self) -> int; } trait C: A { fn c(&self) -> int; } -trait D: B C { fn d(&self) -> int; } +trait D: B + C { fn d(&self) -> int; } struct S { bogus: () } diff --git a/src/test/run-pass/trait-inheritance-num.rs b/src/test/run-pass/trait-inheritance-num.rs index 36b1e6cd4de40..92cb25b8d2be7 100644 --- a/src/test/run-pass/trait-inheritance-num.rs +++ b/src/test/run-pass/trait-inheritance-num.rs @@ -16,9 +16,9 @@ use core::num::NumCast::from; extern mod std; use std::cmp::FuzzyEq; -pub trait NumExt: NumCast Eq Ord {} +pub trait NumExt: NumCast + Eq + Ord {} -pub trait FloatExt: NumExt FuzzyEq {} +pub trait FloatExt: NumExt + FuzzyEq {} fn greater_than_one(n: &T) -> bool { *n > from(1) } fn greater_than_one_float(n: &T) -> bool { *n > from(1) } diff --git a/src/test/run-pass/trait-inheritance-num0.rs b/src/test/run-pass/trait-inheritance-num0.rs index 70eed496db3f5..7f0d4d77b6264 100644 --- a/src/test/run-pass/trait-inheritance-num0.rs +++ b/src/test/run-pass/trait-inheritance-num0.rs @@ -19,7 +19,7 @@ trait Num { fn gt(&self, other: &Self) -> bool; } -pub trait NumExt: Num NumCast { } +pub trait NumExt: Num + NumCast { } fn greater_than_one(n: &T) -> bool { n.gt(&from(1)) diff --git a/src/test/run-pass/trait-inheritance-num1.rs b/src/test/run-pass/trait-inheritance-num1.rs index 44b4bd60f1de0..07b9772af2970 100644 --- a/src/test/run-pass/trait-inheritance-num1.rs +++ b/src/test/run-pass/trait-inheritance-num1.rs @@ -11,7 +11,7 @@ use core::cmp::Ord; use core::num::NumCast::from; -pub trait NumExt: NumCast Ord { } +pub trait NumExt: NumCast + Ord { } fn greater_than_one(n: &T) -> bool { *n > from(1) diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index 5c9d9e6a13b5f..8f8b83c3d7614 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -38,7 +38,7 @@ impl TypeExt for f64 {} impl TypeExt for float {} -pub trait NumExt: TypeExt Eq Ord NumCast {} +pub trait NumExt: TypeExt + Eq + Ord + NumCast {} impl NumExt for u8 {} impl NumExt for u16 {} @@ -94,7 +94,7 @@ impl IntegerExt for i64 {} impl IntegerExt for int {} -pub trait FloatExt: NumExt FuzzyEq {} +pub trait FloatExt: NumExt + FuzzyEq {} impl FloatExt for f32 {} impl FloatExt for f64 {} diff --git a/src/test/run-pass/trait-inheritance-num3.rs b/src/test/run-pass/trait-inheritance-num3.rs index c2cd56ad1078e..67861709e76f2 100644 --- a/src/test/run-pass/trait-inheritance-num3.rs +++ b/src/test/run-pass/trait-inheritance-num3.rs @@ -11,7 +11,7 @@ use core::cmp::{Eq, Ord}; use core::num::NumCast::from; -pub trait NumExt: Eq Ord NumCast {} +pub trait NumExt: Eq + Ord + NumCast {} impl NumExt for f32 {} diff --git a/src/test/run-pass/trait-inheritance-num5.rs b/src/test/run-pass/trait-inheritance-num5.rs index ac8d80359d874..2efe5b23eb57b 100644 --- a/src/test/run-pass/trait-inheritance-num5.rs +++ b/src/test/run-pass/trait-inheritance-num5.rs @@ -11,7 +11,7 @@ use core::cmp::{Eq, Ord}; use core::num::NumCast::from; -pub trait NumExt: Eq NumCast {} +pub trait NumExt: Eq + NumCast {} impl NumExt for f32 {} impl NumExt for int {} diff --git a/src/test/run-pass/trait-inheritance-overloading.rs b/src/test/run-pass/trait-inheritance-overloading.rs index 54a9ea9ad1e32..a4d7e33891f49 100644 --- a/src/test/run-pass/trait-inheritance-overloading.rs +++ b/src/test/run-pass/trait-inheritance-overloading.rs @@ -10,7 +10,7 @@ use core::cmp::Eq; -trait MyNum : Add Sub Mul Eq { } +trait MyNum : Add + Sub + Mul + Eq { } struct MyInt { val: int } diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs index 6f706ad0be746..ccc7f1fc4c07f 100644 --- a/src/test/run-pass/trait-inheritance-static2.rs +++ b/src/test/run-pass/trait-inheritance-static2.rs @@ -14,7 +14,7 @@ trait MyNum { static fn from_int(int) -> Self; } -pub trait NumExt: MyEq MyNum { } +pub trait NumExt: MyEq + MyNum { } struct S { v: int } diff --git a/src/test/run-pass/trait-inheritance2.rs b/src/test/run-pass/trait-inheritance2.rs index 55a63e9099a93..5925888650d80 100644 --- a/src/test/run-pass/trait-inheritance2.rs +++ b/src/test/run-pass/trait-inheritance2.rs @@ -12,7 +12,7 @@ trait Foo { fn f() -> int; } trait Bar { fn g() -> int; } trait Baz { fn h() -> int; } -trait Quux: Foo Bar Baz { } +trait Quux: Foo + Bar + Baz { } struct A { x: int } From 94474f80a666826da616af6728e22a8879d033f2 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 4 Mar 2013 17:05:42 -0800 Subject: [PATCH 3/3] librustc: Fix silly bug in AST conversion for const vstores. rs=bugfix Means that we'll need another snapshot to rid the language of `[const T]`. --- src/librustc/middle/typeck/astconv.rs | 2 +- src/test/run-pass/const-vec-syntax.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/const-vec-syntax.rs diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 5c05723bb3f04..d03cc67b5ab50 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -218,7 +218,7 @@ pub fn ast_ty_to_ty( let mut mt = ast_mt_to_mt(self, rscope, mt); if a_seq_ty.mutbl == ast::m_mutbl || a_seq_ty.mutbl == ast::m_const { - mt = ty::mt { ty: mt.ty, mutbl: ast::m_mutbl }; + mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl }; } return ty::mk_evec(tcx, mt, vst); } diff --git a/src/test/run-pass/const-vec-syntax.rs b/src/test/run-pass/const-vec-syntax.rs new file mode 100644 index 0000000000000..ec8e04e41ef58 --- /dev/null +++ b/src/test/run-pass/const-vec-syntax.rs @@ -0,0 +1,7 @@ +fn f(_: &const [int]) {} + +fn main() { + let v = [ 1, 2, 3 ]; + f(v); +} +