@@ -273,14 +273,13 @@ impl Compiler {
273273 let cellvar_cache = table
274274 . symbols
275275 . iter ( )
276- . filter ( |( _, s) | matches ! ( s. scope, SymbolScope :: Cell ) )
276+ . filter ( |( _, s) | s. scope == SymbolScope :: Cell )
277277 . map ( |( var, _) | var. clone ( ) )
278278 . collect ( ) ;
279279 let freevar_cache = table
280280 . symbols
281281 . iter ( )
282- // TODO: check if Free or FREE_CLASS symbol
283- . filter ( |( _, s) | matches ! ( s. scope, SymbolScope :: Free ) )
282+ . filter ( |( _, s) | s. scope == SymbolScope :: Free || s. is_free_class )
284283 . map ( |( var, _) | var. clone ( ) )
285284 . collect ( ) ;
286285
@@ -336,6 +335,11 @@ impl Compiler {
336335 let doc = self . name ( "__doc__" ) ;
337336 self . emit ( Instruction :: StoreGlobal ( doc) )
338337 }
338+
339+ if self . find_ann ( statements) {
340+ self . emit ( Instruction :: SetupAnnotation ) ;
341+ }
342+
339343 self . compile_statements ( statements) ?;
340344
341345 assert_eq ! ( self . code_stack. len( ) , size_before) ;
@@ -433,9 +437,12 @@ impl Compiler {
433437 cache = & mut info. varname_cache ;
434438 NameOpType :: Fast
435439 }
436- SymbolScope :: GlobalImplicit if self . ctx . in_func ( ) => NameOpType :: Global ,
437- SymbolScope :: Local | SymbolScope :: GlobalImplicit => NameOpType :: Local ,
438440 SymbolScope :: GlobalExplicit => NameOpType :: Global ,
441+ SymbolScope :: GlobalImplicit | SymbolScope :: Unknown if self . ctx . in_func ( ) => {
442+ NameOpType :: Global
443+ }
444+ SymbolScope :: GlobalImplicit | SymbolScope :: Unknown => NameOpType :: Local ,
445+ SymbolScope :: Local => NameOpType :: Local ,
439446 SymbolScope :: Free => {
440447 cache = & mut info. freevar_cache ;
441448 NameOpType :: Deref
@@ -444,8 +451,8 @@ impl Compiler {
444451 cache = & mut info. cellvar_cache ;
445452 NameOpType :: Deref
446453 }
447- // TODO: is this right?
448- SymbolScope :: Unknown => NameOpType :: Global ,
454+ // // TODO: is this right?
455+ // SymbolScope::Unknown => NameOpType::Global,
449456 } ;
450457 let mut idx = cache
451458 . get_index_of ( name)
@@ -527,6 +534,10 @@ impl Compiler {
527534 let module_idx = module. as_ref ( ) . map ( |s| self . name ( s) ) ;
528535
529536 if import_star {
537+ if self . ctx . in_func ( ) {
538+ return Err ( self
539+ . error_loc ( CompileErrorType :: FunctionImportStar , statement. location ) ) ;
540+ }
530541 let star = self . name ( "*" ) ;
531542 // from .... import *
532543 self . emit ( Instruction :: Import {
@@ -1069,6 +1080,8 @@ impl Compiler {
10691080 }
10701081
10711082 let mut code = self . pop_code_object ( ) ;
1083+ self . current_qualified_path = old_qualified_path;
1084+ self . ctx = prev_ctx;
10721085
10731086 // Prepare type annotations:
10741087 let mut num_annotations = 0 ;
@@ -1138,9 +1151,6 @@ impl Compiler {
11381151 let doc = self . name ( "__doc__" ) ;
11391152 self . emit ( Instruction :: StoreAttr { idx : doc } ) ;
11401153
1141- self . current_qualified_path = old_qualified_path;
1142- self . ctx = prev_ctx;
1143-
11441154 self . apply_decorators ( decorator_list) ;
11451155
11461156 self . store_name ( name) ;
@@ -1151,12 +1161,17 @@ impl Compiler {
11511161 fn build_closure ( & mut self , code : & CodeObject ) {
11521162 if !code. freevars . is_empty ( ) {
11531163 for var in & code. freevars {
1154- let symbol = self . symbol_table_stack . last ( ) . unwrap ( ) . lookup ( var) . unwrap ( ) ;
1164+ let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
1165+ let symbol = table. lookup ( var) . unwrap ( ) ;
11551166 let parent_code = self . code_stack . last ( ) . unwrap ( ) ;
11561167 let vars = match symbol. scope {
11571168 SymbolScope :: Free => & parent_code. freevar_cache ,
11581169 SymbolScope :: Cell => & parent_code. cellvar_cache ,
1159- _ => unreachable ! ( ) ,
1170+ _ if symbol. is_free_class => & parent_code. freevar_cache ,
1171+ x => unreachable ! (
1172+ "var {} in a {:?} should be free or cell but it's {:?}" ,
1173+ var, table. typ, x
1174+ ) ,
11601175 } ;
11611176 let mut idx = vars. get_index_of ( var) . unwrap ( ) ;
11621177 if let SymbolScope :: Free = symbol. scope {
@@ -1236,6 +1251,8 @@ impl Compiler {
12361251 keywords : & [ ast:: Keyword ] ,
12371252 decorator_list : & [ ast:: Expression ] ,
12381253 ) -> CompileResult < ( ) > {
1254+ self . prepare_decorators ( decorator_list) ?;
1255+
12391256 let prev_ctx = self . ctx ;
12401257 self . ctx = CompileContext {
12411258 func : FunctionContext :: NoFunction ,
@@ -1247,7 +1264,6 @@ impl Compiler {
12471264 let old_qualified_path = self . current_qualified_path . take ( ) ;
12481265 self . current_qualified_path = Some ( qualified_name. clone ( ) ) ;
12491266
1250- self . prepare_decorators ( decorator_list) ?;
12511267 self . emit ( Instruction :: LoadBuildClass ) ;
12521268 let line_number = self . get_source_line_number ( ) ;
12531269 self . push_output ( CodeObject :: new (
@@ -1301,6 +1317,9 @@ impl Compiler {
13011317
13021318 let code = self . pop_code_object ( ) ;
13031319
1320+ self . current_qualified_path = old_qualified_path;
1321+ self . ctx = prev_ctx;
1322+
13041323 self . build_closure ( & code) ;
13051324
13061325 self . emit_constant ( bytecode:: ConstantData :: Code {
@@ -1350,8 +1369,6 @@ impl Compiler {
13501369 self . apply_decorators ( decorator_list) ;
13511370
13521371 self . store_name ( name) ;
1353- self . current_qualified_path = old_qualified_path;
1354- self . ctx = prev_ctx;
13551372 Ok ( ( ) )
13561373 }
13571374
@@ -1579,18 +1596,17 @@ impl Compiler {
15791596
15801597 if let ast:: ExpressionType :: Identifier { name } = & target. node {
15811598 // Store as dict entry in __annotations__ dict:
1582- if !self . ctx . in_func ( ) {
1583- let annotations = self . name ( "__annotations__" ) ;
1584- self . emit ( Instruction :: LoadNameAny ( annotations) ) ;
1585- self . emit_constant ( bytecode:: ConstantData :: Str {
1586- value : name. to_owned ( ) ,
1587- } ) ;
1588- self . emit ( Instruction :: StoreSubscript ) ;
1589- }
1599+ let annotations = self . name ( "__annotations__" ) ;
1600+ self . emit ( Instruction :: LoadNameAny ( annotations) ) ;
1601+ self . emit_constant ( bytecode:: ConstantData :: Str {
1602+ value : name. to_owned ( ) ,
1603+ } ) ;
1604+ self . emit ( Instruction :: StoreSubscript ) ;
15901605 } else {
15911606 // Drop annotation if not assigned to simple identifier.
15921607 self . emit ( Instruction :: Pop ) ;
15931608 }
1609+
15941610 Ok ( ( ) )
15951611 }
15961612
@@ -2187,7 +2203,7 @@ impl Compiler {
21872203 let line_number = self . get_source_line_number ( ) ;
21882204 // Create magnificent function <listcomp>:
21892205 self . push_output ( CodeObject :: new (
2190- Default :: default ( ) ,
2206+ bytecode :: CodeFlags :: NEW_LOCALS | bytecode :: CodeFlags :: IS_OPTIMIZED ,
21912207 1 ,
21922208 1 ,
21932209 0 ,
0 commit comments