@@ -12,6 +12,7 @@ use std::{
12
12
use anyhow:: { Result , anyhow} ;
13
13
use async_trait:: async_trait;
14
14
use auto_hash_map:: AutoSet ;
15
+ use rustc_hash:: FxHashMap ;
15
16
use serde:: { Deserialize , Serialize } ;
16
17
use turbo_rcstr:: RcStr ;
17
18
use turbo_tasks:: {
@@ -154,6 +155,7 @@ pub trait Issue {
154
155
155
156
async fn into_plain (
156
157
self : Vc < Self > ,
158
+ import_trace : Option < ResolvedVc < ImportTrace > > ,
157
159
processing_path : Vc < OptionIssueProcessingPathItems > ,
158
160
) -> Result < Vc < PlainIssue > > {
159
161
let description = match * self . description ( ) . await ? {
@@ -180,21 +182,47 @@ pub trait Issue {
180
182
None
181
183
}
182
184
} ,
185
+ // delete sub_issues?
183
186
sub_issues : self
184
187
. sub_issues ( )
185
188
. await ?
186
189
. iter ( )
187
190
. map ( |i| async move {
188
- anyhow:: Ok ( i. into_plain ( OptionIssueProcessingPathItems :: none ( ) ) . await ?)
191
+ anyhow:: Ok (
192
+ i. into_plain ( None , OptionIssueProcessingPathItems :: none ( ) )
193
+ . await ?,
194
+ )
189
195
} )
190
196
. try_join ( )
191
197
. await ?,
192
198
processing_path : processing_path. into_plain ( ) . await ?,
199
+ import_trace : if let Some ( s) = import_trace {
200
+ Some ( s. await ?)
201
+ } else {
202
+ None
203
+ } ,
193
204
}
194
205
. cell ( ) )
195
206
}
196
207
}
197
208
209
+ // A collectible trait wrapper for `ImportTraceForIssues`
210
+ // To access data simply downcast to `ImportTraceForIssues`
211
+ #[ turbo_tasks:: value_trait]
212
+ pub trait ImportTraceForIssuesTrait { }
213
+
214
+ // An association between an import trace and a collection of issues reported for a given module.
215
+ // Used to augment issue reporting.
216
+ //
217
+ #[ turbo_tasks:: value( shared) ]
218
+ pub struct ImportTraceForIssues {
219
+ pub path : ResolvedVc < ImportTrace > ,
220
+ pub issues : Vec < ResolvedVc < Box < dyn Issue > > > ,
221
+ }
222
+
223
+ #[ turbo_tasks:: value_impl]
224
+ impl ImportTraceForIssuesTrait for ImportTraceForIssues { }
225
+
198
226
#[ turbo_tasks:: value_trait]
199
227
trait IssueProcessingPath {
200
228
fn shortest_path (
@@ -370,6 +398,7 @@ pub struct CapturedIssues {
370
398
issues : AutoSet < ResolvedVc < Box < dyn Issue > > > ,
371
399
#[ cfg( feature = "issue_path" ) ]
372
400
processing_path : ResolvedVc < ItemIssueProcessingPath > ,
401
+ import_trace : AutoSet < ResolvedVc < Box < dyn ImportTraceForIssuesTrait > > > ,
373
402
}
374
403
375
404
#[ turbo_tasks:: value_impl]
@@ -397,38 +426,38 @@ impl CapturedIssues {
397
426
self . issues . iter ( ) . copied ( )
398
427
}
399
428
400
- /// Returns an iterator over the issues with the shortest path from the root
401
- /// issue to each issue.
402
- pub fn iter_with_shortest_path (
403
- & self ,
404
- ) -> impl Iterator <
405
- Item = (
406
- ResolvedVc < Box < dyn Issue > > ,
407
- Vc < OptionIssueProcessingPathItems > ,
408
- ) ,
409
- > + ' _ {
410
- self . issues . iter ( ) . map ( |issue| {
411
- #[ cfg( feature = "issue_path" ) ]
412
- let path = self . processing_path . shortest_path ( * * issue) ;
413
- #[ cfg( not( feature = "issue_path" ) ) ]
414
- let path = OptionIssueProcessingPathItems :: none ( ) ;
415
- ( * issue, path)
416
- } )
417
- }
418
-
429
+ // Returns all the issues as formatted `PlainIssues`.
419
430
pub async fn get_plain_issues ( & self ) -> Result < Vec < ReadRef < PlainIssue > > > {
431
+ let issue_to_trace = self
432
+ . import_trace
433
+ . iter ( )
434
+ . map ( |trace| async move {
435
+ ResolvedVc :: try_downcast_type :: < ImportTraceForIssues > ( * trace)
436
+ . unwrap ( )
437
+ . await
438
+ } )
439
+ . try_join ( )
440
+ . await ?
441
+ . iter ( )
442
+ . flat_map ( |trace| trace. issues . iter ( ) . map ( |issue| ( * issue, * trace. path ) ) )
443
+ . collect :: < FxHashMap < _ , _ > > ( ) ;
444
+
420
445
let mut list = self
421
446
. issues
422
447
. iter ( )
423
- . map ( |& issue| async move {
424
- #[ cfg( feature = "issue_path" ) ]
425
- return issue
426
- . into_plain ( self . processing_path . shortest_path ( * issue) )
427
- . await ;
428
- #[ cfg( not( feature = "issue_path" ) ) ]
429
- return issue
430
- . into_plain ( OptionIssueProcessingPathItems :: none ( ) )
431
- . await ;
448
+ . map ( |& issue| {
449
+ let issue_to_trace = & issue_to_trace;
450
+ async move {
451
+ let import_trace = issue_to_trace. get ( & issue) . cloned ( ) ;
452
+ #[ cfg( feature = "issue_path" ) ]
453
+ return issue
454
+ . into_plain ( import_trace, self . processing_path . shortest_path ( * issue) )
455
+ . await ;
456
+ #[ cfg( not( feature = "issue_path" ) ) ]
457
+ return issue
458
+ . into_plain ( import_trace, OptionIssueProcessingPathItems :: none ( ) )
459
+ . await ;
460
+ }
432
461
} )
433
462
. try_join ( )
434
463
. await ?;
@@ -635,6 +664,9 @@ pub struct OptionIssueSource(Option<IssueSource>);
635
664
#[ turbo_tasks:: value( transparent) ]
636
665
pub struct OptionStyledString ( Option < ResolvedVc < StyledString > > ) ;
637
666
667
+ #[ turbo_tasks:: value( transparent, shared) ]
668
+ pub struct ImportTrace ( pub Vec < RcStr > ) ;
669
+
638
670
#[ turbo_tasks:: value( shared, serialization = "none" ) ]
639
671
#[ derive( Clone , Debug , PartialOrd , Ord , DeterministicHash , Serialize ) ]
640
672
pub enum IssueStage {
@@ -693,6 +725,7 @@ pub struct PlainIssue {
693
725
pub source : Option < PlainIssueSource > ,
694
726
pub sub_issues : Vec < ReadRef < PlainIssue > > ,
695
727
pub processing_path : ReadRef < PlainIssueProcessingPath > ,
728
+ pub import_trace : Option < ReadRef < ImportTrace > > ,
696
729
}
697
730
698
731
fn hash_plain_issue ( issue : & PlainIssue , hasher : & mut Xxh3Hash64Hasher , full : bool ) {
@@ -739,22 +772,6 @@ impl PlainIssue {
739
772
}
740
773
}
741
774
742
- #[ turbo_tasks:: value_impl]
743
- impl PlainIssue {
744
- /// We need deduplicate issues that can come from unique paths, but
745
- /// represent the same underlying problem. Eg, a parse error for a file
746
- /// that is compiled in both client and server contexts.
747
- ///
748
- /// Passing [full] will also hash any sub-issues and processing paths. While
749
- /// useful for generating exact matching hashes, it's possible for the
750
- /// same issue to pass from multiple processing paths, making for overly
751
- /// verbose logging.
752
- #[ turbo_tasks:: function]
753
- pub fn internal_hash ( & self , full : bool ) -> Vc < u64 > {
754
- Vc :: cell ( self . internal_hash_ref ( full) )
755
- }
756
- }
757
-
758
775
#[ turbo_tasks:: value( serialization = "none" ) ]
759
776
#[ derive( Clone , Debug , PartialOrd , Ord ) ]
760
777
pub struct PlainIssueSource {
@@ -961,6 +978,7 @@ where
961
978
None ,
962
979
self . peek_collectibles ( ) ,
963
980
) ) ,
981
+ import_trace : self . peek_collectibles ( ) ,
964
982
} )
965
983
}
966
984
@@ -972,6 +990,7 @@ where
972
990
None ,
973
991
self . take_collectibles ( ) ,
974
992
) ) ,
993
+ import_trace : self . take_collectibles ( ) ,
975
994
} )
976
995
}
977
996
}
0 commit comments