@@ -29,6 +29,7 @@ struct Compiler<O: OutputStream = BasicOutputStream> {
2929 source_path : Option < String > ,
3030 current_source_location : ast:: Location ,
3131 current_qualified_path : Option < String > ,
32+ done_with_future_stmts : bool ,
3233 ctx : CompileContext ,
3334 opts : CompileOpts ,
3435}
@@ -166,6 +167,7 @@ impl<O: OutputStream> Compiler<O> {
166167 source_path : None ,
167168 current_source_location : ast:: Location :: default ( ) ,
168169 current_qualified_path : None ,
170+ done_with_future_stmts : false ,
169171 ctx : CompileContext {
170172 in_loop : false ,
171173 func : FunctionContext :: NoFunction ,
@@ -334,6 +336,16 @@ impl<O: OutputStream> Compiler<O> {
334336 self . set_source_location ( statement. location ) ;
335337 use ast:: StatementType :: * ;
336338
339+ match & statement. node {
340+ // we do this here because `from __future__` still executes that `from` statement at runtime,
341+ // we still need to compile the ImportFrom down below
342+ ImportFrom { module, names, .. } if module. as_deref ( ) == Some ( "__future__" ) => {
343+ self . compile_future_features ( & names) ?
344+ }
345+ // if we find any other statement, stop accepting future statements
346+ _ => self . done_with_future_stmts = true ,
347+ }
348+
337349 match & statement. node {
338350 Import { names } => {
339351 // import a, b, c as d
@@ -2132,6 +2144,38 @@ impl<O: OutputStream> Compiler<O> {
21322144 Ok ( ( ) )
21332145 }
21342146
2147+ fn compile_future_features (
2148+ & mut self ,
2149+ features : & [ ast:: ImportSymbol ] ,
2150+ ) -> Result < ( ) , CompileError > {
2151+ if self . done_with_future_stmts {
2152+ return Err ( CompileError {
2153+ error : CompileErrorType :: InvalidFuturePlacement ,
2154+ location : self . current_source_location . clone ( ) ,
2155+ source_path : self . source_path . clone ( ) ,
2156+ statement : None ,
2157+ } ) ;
2158+ }
2159+ for feature in features {
2160+ match & * feature. symbol {
2161+ // Python 3 features; we've already implemented them by default
2162+ "nested_scopes" | "generators" | "division" | "absolute_import"
2163+ | "with_statement" | "print_function" | "unicode_literals" => { }
2164+ // "generator_stop" => {}
2165+ // "annotations" => {}
2166+ other => {
2167+ return Err ( CompileError {
2168+ error : CompileErrorType :: InvalidFutureFeature ( other. to_owned ( ) ) ,
2169+ location : self . current_source_location . clone ( ) ,
2170+ source_path : self . source_path . clone ( ) ,
2171+ statement : None ,
2172+ } )
2173+ }
2174+ }
2175+ }
2176+ Ok ( ( ) )
2177+ }
2178+
21352179 // Scope helpers:
21362180 fn enter_scope ( & mut self ) {
21372181 // println!("Enter scope {:?}", self.symbol_table_stack);
0 commit comments