diff --git a/src/classes/Object.pir b/src/classes/Object.pir index d57d3ca460f..defbadc1f08 100644 --- a/src/classes/Object.pir +++ b/src/classes/Object.pir @@ -426,13 +426,12 @@ XXX This had probably best really just tailcall .^CREATE; move this stuff later. attrinit_loop: unless it goto attrinit_done .local string attrname - .local pmc attrhash, itypeclass, type + .local pmc attrhash, itypeclass attrname = shift it $I0 = index attrname, '!' if $I0 < 0 goto attrinit_loop attrhash = attributes[attrname] itypeclass = attrhash['itype'] - type = attrhash['type'] $S0 = substr attrname, 0, 1 unless null itypeclass goto attrinit_itype if $S0 == '@' goto attrinit_array @@ -449,20 +448,6 @@ XXX This had probably best really just tailcall .^CREATE; move this stuff later. .local pmc attr attr = new itypeclass setattribute example, cur_class, attrname, attr - if null type goto type_done - if $S0 == '@' goto pos_type - if $S0 == '%' goto ass_type - setprop attr, 'type', type - goto type_done - ass_type: - $P0 = get_hll_global 'Associative' - goto apply_type - pos_type: - $P0 = get_hll_global 'Positional' - apply_type: - $P0 = $P0.'!select'(type) - 'infix:does'(attr, $P0) - type_done: traits = attrhash['traits'] if null traits goto traits_done $P0 = getprop 'metaclass', cur_class diff --git a/src/parser/actions.pm b/src/parser/actions.pm index 850f4e52548..40cd0904ea5 100644 --- a/src/parser/actions.pm +++ b/src/parser/actions.pm @@ -1807,7 +1807,7 @@ method scope_declarator($/) { if $readtype eq 'rw' { $has.push(PAST::Val.new( :value(1), :named('rw') )); } - if $var { + if $var || $type { # If we have a handles, then we pass that specially. my $handles := has_compiler_trait($var, 'trait_mod:handles'); if $handles { @@ -1818,13 +1818,22 @@ method scope_declarator($/) { # We'll make a block for calling other handles, which'll be # thunked. my $trait_stmts := PAST::Stmts.new(); - emit_traits($var, $trait_stmts, PAST::Op.new( + my $declarand := PAST::Op.new( :pasttype('callmethod'), :name('new'), PAST::Var.new( :name('AttributeDeclarand'), :scope('package'), :namespace(list()) ), PAST::Var.new( :name('$_'), :scope('lexical'), :named('container') ), PAST::Val.new( :value($var.name()), :named('name') ), PAST::Var.new( :name('$how'), :scope('lexical'), :named('how') ) - )); + ); + emit_traits($var, $trait_stmts, $declarand); + if $type { + $trait_stmts.push(PAST::Op.new( + :pasttype('call'), + :name('trait_mod:of'), + $declarand, + $type + )); + } if +@($trait_stmts) > 0 { my $trait_block := PAST::Block.new( :blocktype('declaration'), diff --git a/src/setting/traits.pm b/src/setting/traits.pm index ce12e5a0d36..27a3d653f3e 100644 --- a/src/setting/traits.pm +++ b/src/setting/traits.pm @@ -89,6 +89,10 @@ multi trait_mod:(Code $block, :$default!) { }; } +multi trait_mod:(ContainerDeclarand $c, :$rw!) { + # The default anyway, so nothing to do. +} + multi trait_mod:(Class $class is rw, Object $role) { Q:PIR { .local pmc metaclass, role