@@ -1222,6 +1222,13 @@ def expr_variable(tree, location, scope):
12221222 if in_dev_tree :
12231223 e = in_dev_tree
12241224 if e is None :
1225+ # TODO/HACK: The discard ref is exposed like this to allow it to be as
1226+ # keyword-like as possible while still allowing it to be shadowed.
1227+ # Once we remove support for discard_ref_shadowing the discard ref
1228+ # should become a proper keyword and its codegen be done via dedicated
1229+ # dispatch
1230+ if name == '_' and tree .site .dml_version () != (1 , 2 ):
1231+ return mkDiscardRef (tree .site )
12251232 raise EIDENT (tree .site , name )
12261233 return e
12271234
@@ -2331,14 +2338,26 @@ def try_codegen_invocation(site, init_ast, outargs, location, scope):
23312338 else :
23322339 return common_inline (site , meth_node , indices , inargs , outargs )
23332340
2341+ def codegen_init_for_untyped_target (site , tgt , src_ast , location , scope ):
2342+ if not tgt .writable :
2343+ raise EASSIGN (site , tgt )
2344+ if src_ast .kind != 'initializer_scalar' :
2345+ raise EDATAINIT (tgt .site ,
2346+ f'{ tgt } can only be used as the target '
2347+ + 'of an assignment if its initializer is a '
2348+ + 'simple expression or a return value of a '
2349+ + 'method call' )
2350+ return ExpressionInitializer (
2351+ codegen_expression (src_ast .args [0 ], location , scope ))
2352+
23342353@statement_dispatcher
23352354def stmt_assign (stmt , location , scope ):
23362355 (_ , site , tgt_ast , src_asts ) = stmt
23372356 assert tgt_ast .kind in {'assign_target_chain' , 'assign_target_tuple' }
2338- tgts = [codegen_expression (ast , location , scope )
2357+ tgts = [codegen_expression_maybe_nonvalue (ast , location , scope )
23392358 for ast in tgt_ast .args [0 ]]
23402359 for tgt in tgts :
2341- if deep_const (tgt .ctype ()):
2360+ if not isinstance ( tgt , NonValue ) and deep_const (tgt .ctype ()):
23422361 raise ECONST (tgt .site )
23432362 if tgt_ast .kind == 'assign_target_chain' :
23442363 method_tgts = [tgts [0 ]]
@@ -2360,14 +2379,23 @@ def stmt_assign(stmt, location, scope):
23602379 + f'initializer: Expected { src_asts } , got 1' ))
23612380 return []
23622381
2363- lscope = Symtab (scope )
2364- init_typ = tgts [- 1 ].ctype ()
2365- init = eval_initializer (
2366- tgts [- 1 ].site , init_typ , src_asts [0 ], location , scope , False )
2382+ if isinstance (tgts [- 1 ], NonValue ):
2383+ if len (tgts ) != 1 :
2384+ raise tgts [- 1 ].exc ()
2385+ init_typ = tgts [- 1 ].type if tgts [- 1 ].explicit_type else None
2386+ else :
2387+ init_typ = tgts [- 1 ].ctype ()
2388+
2389+ init = (eval_initializer (tgts [- 1 ].site , init_typ , src_asts [0 ],
2390+ location , scope , False )
2391+ if init_typ is not None else
2392+ codegen_init_for_untyped_target (site , tgts [0 ], src_asts [0 ],
2393+ location , scope ))
23672394
23682395 if len (tgts ) == 1 :
23692396 return [mkAssignStatement (tgts [0 ].site , tgts [0 ], init )]
23702397
2398+ lscope = Symtab (scope )
23712399 sym = lscope .add_variable (
23722400 'tmp' , type = init_typ , site = init .site , init = init ,
23732401 stmt = True )
@@ -2396,22 +2424,31 @@ def stmt_assign(stmt, location, scope):
23962424
23972425 stmts = []
23982426 lscope = Symtab (scope )
2399- syms = []
2427+ stmt_pairs = []
24002428 for (i , (tgt , src_ast )) in enumerate (zip (tgts , src_asts )):
2401- init = eval_initializer (site , tgt .ctype (), src_ast , location ,
2402- scope , False )
2403- name = 'tmp%d' % (i ,)
2404- sym = lscope .add_variable (
2405- name , type = tgt .ctype (), site = tgt .site , init = init ,
2406- stmt = True )
2407- syms .append (sym )
2408-
2409- stmts .extend (sym_declaration (sym ) for sym in syms )
2410- stmts .extend (
2411- AssignStatement (
2412- tgt .site , tgt ,
2413- ExpressionInitializer (mkLocalVariable (tgt .site , sym )))
2414- for (tgt , sym ) in zip (tgts , syms ))
2429+ if isinstance (tgt , NonValue ):
2430+ init = (eval_initializer (site , tgt .type , src_ast , location ,
2431+ scope , False )
2432+ if tgt .explicit_type else
2433+ codegen_init_for_untyped_target (site , tgt , src_ast ,
2434+ location , scope ))
2435+ stmt_pairs .append ((mkAssignStatement (tgt .site , tgt , init ),
2436+ None ))
2437+ else :
2438+ init = eval_initializer (site , tgt .ctype (), src_ast , location ,
2439+ scope , False )
2440+ name = 'tmp%d' % (i ,)
2441+ sym = lscope .add_variable (
2442+ name , type = tgt .ctype (), site = tgt .site , init = init ,
2443+ stmt = True )
2444+ write = AssignStatement (
2445+ tgt .site , tgt ,
2446+ ExpressionInitializer (mkLocalVariable (tgt .site , sym )))
2447+ stmt_pairs .append ((sym_declaration (sym ), write ))
2448+
2449+ stmts .extend (first for (first , _ ) in stmt_pairs )
2450+ stmts .extend (second for (_ , second ) in stmt_pairs
2451+ if second is not None )
24152452 return [mkCompound (site , stmts )]
24162453
24172454@statement_dispatcher
@@ -3633,7 +3670,7 @@ def codegen_inline(site, meth_node, indices, inargs, outargs,
36333670 parmtype if parmtype else arg .ctype (),
36343671 meth_node .name )
36353672 for (arg , var , (parmname , parmtype )) in zip (
3636- outargs , outvars , meth_node .outp )]
3673+ outargs , outvars , meth_node .outp )]
36373674 exit_handler = GotoExit_dml12 ()
36383675 with exit_handler :
36393676 code = [codegen_statement (meth_node .astcode ,
@@ -4063,15 +4100,20 @@ def copy_outarg(arg, var, parmname, parmtype, method_name):
40634100 an exception. We would be able to skip the proxy variable for
40644101 calls to non-throwing methods when arg.ctype() and parmtype are
40654102 equivalent types, but we don't do this today.'''
4066- argtype = arg .ctype ()
4067-
4068- if not argtype :
4069- raise ICE (arg .site , "unknown expression type" )
4103+ if isinstance (arg , NonValue ):
4104+ if not arg .writable :
4105+ raise arg .exc ()
40704106 else :
4071- ok , trunc , constviol = realtype (parmtype ).canstore (realtype (argtype ))
4072- if not ok :
4073- raise EARGT (arg .site , 'call' , method_name ,
4074- arg .ctype (), parmname , parmtype , 'output' )
4107+ argtype = arg .ctype ()
4108+
4109+ if not argtype :
4110+ raise ICE (arg .site , "unknown expression type" )
4111+ else :
4112+ ok , trunc , constviol = realtype (parmtype ).canstore (
4113+ realtype (argtype ))
4114+ if not ok :
4115+ raise EARGT (arg .site , 'call' , method_name ,
4116+ arg .ctype (), parmname , parmtype , 'output' )
40754117
40764118 return mkCopyData (var .site , var , arg )
40774119
0 commit comments