Repository: vercel/next.js
Pull request: Turbopack: correctly apply generate_source_map with scope hoisting

Don't generate source maps if the corresponding merged module specified that (i.e. have different values of `generate_source_map: bool` inside a single AST.

Closes PACK-4942

Changed files:
filename: turbopack/crates/turbopack-ecmascript/src/lib.rs
patch: @@ -1123,7 +1123,8 @@ impl EcmascriptModuleContent {
         let (merged_ast, comments, source_maps, original_source_maps) =
             merge_modules(contents, &entry_points, &globals_merged).await?;
 
-        // Use the options from an arbitrary module, since they should all be the same.
+        // Use the options from an arbitrary module, since they should all be the same with regards
+        // to minify_type and chunking_context.
         let options = module_options.last().unwrap().await?;
 
         let modules_header_width = modules.len().next_power_of_two().trailing_zeros();
@@ -1140,7 +1141,6 @@ impl EcmascriptModuleContent {
             export_contexts: None,
             is_esm: true,
             strict: true,
-            generate_source_map: options.generate_source_map,
             original_source_map: CodeGenResultOriginalSourceMap::ScopeHoisting(
                 original_source_maps,
             ),
@@ -1543,7 +1543,6 @@ struct CodeGenResult {
     export_contexts: Option<FxHashMap<RcStr, Id>>,
     is_esm: bool,
     strict: bool,
-    generate_source_map: bool,
     original_source_map: CodeGenResultOriginalSourceMap,
     minify: MinifyType,
     scope_hoisting_syntax_contexts:
@@ -1715,8 +1714,12 @@ async fn process_parse_result(
 
             Ok(CodeGenResult {
                 program,
-                source_map: CodeGenResultSourceMap::Single {
-                    source_map: source_map.clone(),
+                source_map: if generate_source_map {
+                    CodeGenResultSourceMap::Single {
+                        source_map: source_map.clone(),
+                    }
+                } else {
+                    CodeGenResultSourceMap::None
                 },
                 comments: CodeGenResultComments::Single {
                     comments,
@@ -1726,7 +1729,6 @@ async fn process_parse_result(
                 export_contexts: Some(export_contexts.into_owned()),
                 is_esm,
                 strict,
-                generate_source_map,
                 original_source_map: CodeGenResultOriginalSourceMap::Single(original_source_map),
                 minify,
                 scope_hoisting_syntax_contexts: retain_syntax_context.map(|(_, ctxts, _)| ctxts),
@@ -1757,12 +1759,11 @@ async fn process_parse_result(
                             body,
                             shebang: None,
                         }),
-                        source_map: CodeGenResultSourceMap::default(),
+                        source_map: CodeGenResultSourceMap::None,
                         comments: CodeGenResultComments::Empty,
                         export_contexts: None,
                         is_esm: false,
                         strict: false,
-                        generate_source_map: false,
                         original_source_map: CodeGenResultOriginalSourceMap::Single(None),
                         minify: MinifyType::NoMinify,
                         scope_hoisting_syntax_contexts: None,
@@ -1785,12 +1786,11 @@ async fn process_parse_result(
                             body,
                             shebang: None,
                         }),
-                        source_map: CodeGenResultSourceMap::default(),
+                        source_map: CodeGenResultSourceMap::None,
                         comments: CodeGenResultComments::Empty,
                         export_contexts: None,
                         is_esm: false,
                         strict: false,
-                        generate_source_map: false,
                         original_source_map: CodeGenResultOriginalSourceMap::Single(None),
                         minify: MinifyType::NoMinify,
                         scope_hoisting_syntax_contexts: None,
@@ -1881,13 +1881,14 @@ async fn emit_content(
         comments,
         is_esm,
         strict,
-        generate_source_map,
         original_source_map,
         minify,
         export_contexts: _,
         scope_hoisting_syntax_contexts: _,
     } = content;
 
+    let generate_source_map = source_map.is_some();
+
     let mut bytes: Vec<u8> = vec![];
     // TODO: Insert this as a sourceless segment so that sourcemaps aren't affected.
     // = format!("/* {} */\n", self.module.path().to_string().await?).into_bytes();
@@ -2056,7 +2057,11 @@ fn hygiene_rename_only(
     )
 }
 
+#[derive(Default)]
 enum CodeGenResultSourceMap {
+    #[default]
+    /// No source map should be generated for this module
+    None,
     Single {
         source_map: Arc<SourceMap>,
     },
@@ -2068,9 +2073,20 @@ enum CodeGenResultSourceMap {
     },
 }
 
+impl CodeGenResultSourceMap {
+    fn is_some(&self) -> bool {
+        match self {
+            CodeGenResultSourceMap::None => false,
+            CodeGenResultSourceMap::Single { .. }
+            | CodeGenResultSourceMap::ScopeHoisting { .. } => true,
+        }
+    }
+}
+
 impl Debug for CodeGenResultSourceMap {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
+            CodeGenResultSourceMap::None => write!(f, "CodeGenResultSourceMap::None"),
             CodeGenResultSourceMap::Single { source_map } => {
                 write!(
                     f,
@@ -2090,20 +2106,13 @@ impl Debug for CodeGenResultSourceMap {
     }
 }
 
-impl Default for CodeGenResultSourceMap {
-    fn default() -> Self {
-        CodeGenResultSourceMap::Single {
-            source_map: Arc::new(SourceMap::default()),
-        }
-    }
-}
-
 impl Files for CodeGenResultSourceMap {
     fn try_lookup_source_file(
         &self,
         pos: BytePos,
     ) -> Result<Option<Arc<SourceFile>>, SourceMapLookupError> {
         match self {
+            CodeGenResultSourceMap::None => Ok(None),
             CodeGenResultSourceMap::Single { source_map } => source_map.try_lookup_source_file(pos),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2118,6 +2127,7 @@ impl Files for CodeGenResultSourceMap {
 
     fn is_in_file(&self, f: &Arc<SourceFile>, raw_pos: BytePos) -> bool {
         match self {
+            CodeGenResultSourceMap::None => false,
             CodeGenResultSourceMap::Single { .. } => f.start_pos <= raw_pos && raw_pos < f.end_pos,
             CodeGenResultSourceMap::ScopeHoisting { .. } => {
                 // let (module, pos) = CodeGenResultComments::decode_bytepos(*modules_header_width,
@@ -2132,6 +2142,7 @@ impl Files for CodeGenResultSourceMap {
 
     fn map_raw_pos(&self, pos: BytePos) -> BytePos {
         match self {
+            CodeGenResultSourceMap::None => BytePos::DUMMY,
             CodeGenResultSourceMap::Single { .. } => pos,
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2144,6 +2155,9 @@ impl Files for CodeGenResultSourceMap {
 impl SourceMapper for CodeGenResultSourceMap {
     fn lookup_char_pos(&self, pos: BytePos) -> Loc {
         match self {
+            CodeGenResultSourceMap::None => {
+                panic!("CodeGenResultSourceMap::None cannot lookup_char_pos")
+            }
             CodeGenResultSourceMap::Single { source_map } => source_map.lookup_char_pos(pos),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2157,6 +2171,9 @@ impl SourceMapper for CodeGenResultSourceMap {
     }
     fn span_to_lines(&self, sp: Span) -> FileLinesResult {
         match self {
+            CodeGenResultSourceMap::None => {
+                panic!("CodeGenResultSourceMap::None cannot span_to_lines")
+            }
             CodeGenResultSourceMap::Single { source_map } => source_map.span_to_lines(sp),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2173,6 +2190,9 @@ impl SourceMapper for CodeGenResultSourceMap {
     }
     fn span_to_string(&self, sp: Span) -> String {
         match self {
+            CodeGenResultSourceMap::None => {
+                panic!("CodeGenResultSourceMap::None cannot span_to_string")
+            }
             CodeGenResultSourceMap::Single { source_map } => source_map.span_to_string(sp),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2189,6 +2209,9 @@ impl SourceMapper for CodeGenResultSourceMap {
     }
     fn span_to_filename(&self, sp: Span) -> Arc<FileName> {
         match self {
+            CodeGenResultSourceMap::None => {
+                panic!("CodeGenResultSourceMap::None cannot span_to_filename")
+            }
             CodeGenResultSourceMap::Single { source_map } => source_map.span_to_filename(sp),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2205,6 +2228,9 @@ impl SourceMapper for CodeGenResultSourceMap {
     }
     fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span> {
         match self {
+            CodeGenResultSourceMap::None => {
+                panic!("CodeGenResultSourceMap::None cannot merge_spans")
+            }
             CodeGenResultSourceMap::Single { source_map } => source_map.merge_spans(sp_lhs, sp_rhs),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2234,6 +2260,9 @@ impl SourceMapper for CodeGenResultSourceMap {
     }
     fn call_span_if_macro(&self, sp: Span) -> Span {
         match self {
+            CodeGenResultSourceMap::None => {
+                panic!("CodeGenResultSourceMap::None cannot call_span_if_macro")
+            }
             CodeGenResultSourceMap::Single { source_map } => source_map.call_span_if_macro(sp),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,
@@ -2253,6 +2282,9 @@ impl SourceMapper for CodeGenResultSourceMap {
     }
     fn span_to_snippet(&self, sp: Span) -> Result<String, Box<SpanSnippetError>> {
         match self {
+            CodeGenResultSourceMap::None => {
+                panic!("CodeGenResultSourceMap::None cannot span_to_snippet")
+            }
             CodeGenResultSourceMap::Single { source_map } => source_map.span_to_snippet(sp),
             CodeGenResultSourceMap::ScopeHoisting {
                 modules_header_width,