From c5e77709116581d6175349f03699a84f65e940ae Mon Sep 17 00:00:00 2001 From: Teakowa <27560638+Teakowa@users.noreply.github.com> Date: Mon, 12 Oct 2026 05:01:33 +0800 Subject: [PATCH] fix(driver): drop the unreachable retained-source validation fallback workshop-rs 1.13's set_file_source prunes provenance spans that do not resolve in the attached document, and the only source-dependent validate check runs on spans pruning already removed; a remaining validate() failure is source-independent, so the unretained re-parse could only re-surface the same error. The fallback, the retained_source flag, and the source-map-span-overflow warning are removed; validation errors now return directly. The span-pruning regression test keeps its assert and gains the new issue reference. Fixes #626 --- crates/wright-driver/src/session.rs | 60 ++++--------------- crates/wright-driver/tests/source_provider.rs | 9 ++- 2 files changed, 15 insertions(+), 54 deletions(-) diff --git a/crates/wright-driver/src/session.rs b/crates/wright-driver/src/session.rs index 809f5721..a4a752f4 100644 --- a/crates/wright-driver/src/session.rs +++ b/crates/wright-driver/src/session.rs @@ -569,7 +569,6 @@ impl CompilerSession { .map_err(|error| workshop_diag_for_provider_artifact(error, resolved, &[]))?; let mut provenance = Provenance::Unmapped; let mut source_files = vec![resolved.display.clone()]; - let mut retained_source = false; if let Some(map) = &source_map { match map.apply(&mut program) { Ok(()) => { @@ -591,7 +590,7 @@ impl CompilerSession { }; match std::fs::read_to_string(&member_path) { Ok(text) => { - retained_source |= program.set_file_source( + program.set_file_source( workshop_rs::source::FileId::from_index(index), text, ); @@ -621,54 +620,17 @@ impl CompilerSession { } } self.progress(ProgressEvent::new(ProgressPhase::Validation)); - if let Err(error) = program.validate() { - if !retained_source { - return Err(workshop_diag_for_provider_artifact( - error, - resolved, - if provenance == Provenance::Mapped { - &source_files - } else { - &[] - }, - )); - } - // A provider map may carry spans that do not resolve inside the - // retained authored source (e.g. positions recorded against an - // expansion rather than the authored line). Retained-source - // validation is a freshness audit, not a load gate: re-parse the - // artifact without retained text so the run still serves — - // mapped positions survive, authored extents degrade (#583). - let mut unretained = workshop_rs::parser::parse_with_context( - &workshop_text, - &self.catalog, - &locale, - &*self.catalog, + program.validate().map_err(|error| { + workshop_diag_for_provider_artifact( + error, + resolved, + if provenance == Provenance::Mapped { + &source_files + } else { + &[] + }, ) - .map_err(|error| workshop_diag_for_provider_artifact(error, resolved, &[]))?; - if let Some(map) = &source_map { - map.apply(&mut unretained).map_err(|apply_error| { - Diagnostic::error( - "source-map-mismatch", - Stage::Frontend, - format!( - "the provider source map does not match its Workshop artifact ({apply_error})" - ), - ) - })?; - } - unretained.validate().map_err(|error| { - workshop_diag_for_provider_artifact(error, resolved, &source_files) - })?; - program = unretained; - self.diagnostics.push(Diagnostic::warning( - "source-map-span-overflow", - Stage::Frontend, - format!( - "the provider source map carries spans outside its members' retained sources ({error}); authored source extents are unavailable" - ), - )); - } + })?; if self.config.profile != wright_transform::Profile::Off { self.progress(ProgressEvent::new(ProgressPhase::Lowering)); } diff --git a/crates/wright-driver/tests/source_provider.rs b/crates/wright-driver/tests/source_provider.rs index 266f84a7..65815220 100644 --- a/crates/wright-driver/tests/source_provider.rs +++ b/crates/wright-driver/tests/source_provider.rs @@ -494,11 +494,10 @@ fn mapped_provider_project_reports_its_source_file_count() { /// A provider map may carry a span that does not resolve inside the /// retained authored source (e.g. a position recorded against an expanded -/// spelling rather than the authored line). Retained-source validation is a -/// freshness audit, not a load gate: the run still serves and mapped -/// positions survive instead of failing the load (#583). `workshop-rs` prunes -/// spans that do not resolve in the attached source (1.13), so the load no -/// longer needs its `source-map-span-overflow` fallback for this input. +/// spelling rather than the authored line). `workshop-rs` prunes spans +/// that do not resolve in the attached source (1.13), so the run still +/// serves and mapped positions survive instead of failing the load +/// (#583, #626). #[test] fn mapped_span_outside_retained_source_degrades_extents_not_the_load() { let (dir, entry) = temp_entry();