@@ -4,6 +4,7 @@ use std::hash::{Hash, Hasher};
4
4
use std:: marker:: PhantomData ;
5
5
use std:: ops:: { Deref , DerefMut } ;
6
6
use std:: panic;
7
+ use std:: path:: PathBuf ;
7
8
use std:: thread:: panicking;
8
9
9
10
use rustc_data_structures:: fx:: FxIndexMap ;
@@ -301,6 +302,7 @@ pub struct DiagInner {
301
302
302
303
pub is_lint : Option < IsLint > ,
303
304
305
+ pub long_ty_path : Option < PathBuf > ,
304
306
/// With `-Ztrack_diagnostics` enabled,
305
307
/// we print where in rustc this error was emitted.
306
308
pub ( crate ) emitted_at : DiagLocation ,
@@ -324,6 +326,7 @@ impl DiagInner {
324
326
args : Default :: default ( ) ,
325
327
sort_span : DUMMY_SP ,
326
328
is_lint : None ,
329
+ long_ty_path : None ,
327
330
emitted_at : DiagLocation :: caller ( ) ,
328
331
}
329
332
}
@@ -1293,9 +1296,37 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
1293
1296
/// `cancel`, etc. Afterwards, `drop` is the only code that will be run on
1294
1297
/// `self`.
1295
1298
fn take_diag ( & mut self ) -> DiagInner {
1299
+ if let Some ( path) = & self . long_ty_path {
1300
+ self . note ( format ! (
1301
+ "the full name for the type has been written to '{}'" ,
1302
+ path. display( )
1303
+ ) ) ;
1304
+ self . note ( "consider using `--verbose` to print the full type name to the console" ) ;
1305
+ }
1296
1306
Box :: into_inner ( self . diag . take ( ) . unwrap ( ) )
1297
1307
}
1298
1308
1309
+ /// This method allows us to access the path of the file where "long types" are written to.
1310
+ ///
1311
+ /// When calling `Diag::emit`, as part of that we will check if a `long_ty_path` has been set,
1312
+ /// and if it has been then we add a note mentioning the file where the "long types" were
1313
+ /// written to.
1314
+ ///
1315
+ /// When calling `tcx.short_string()` after a `Diag` is constructed, the preferred way of doing
1316
+ /// so is `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that
1317
+ /// keeps the existence of a "long type" anywhere in the diagnostic, so the note telling the
1318
+ /// user where we wrote the file to is only printed once at most, *and* it makes it much harder
1319
+ /// to forget to set it.
1320
+ ///
1321
+ /// If the diagnostic hasn't been created before a "short ty string" is created, then you should
1322
+ /// ensure that this method is called to set it `*diag.long_ty_path() = path`.
1323
+ ///
1324
+ /// As a rule of thumb, if you see or add at least one `tcx.short_string()` call anywhere, in a
1325
+ /// scope, `diag.long_ty_path()` should be called once somewhere close by.
1326
+ pub fn long_ty_path ( & mut self ) -> & mut Option < PathBuf > {
1327
+ & mut self . long_ty_path
1328
+ }
1329
+
1299
1330
/// Most `emit_producing_guarantee` functions use this as a starting point.
1300
1331
fn emit_producing_nothing ( mut self ) {
1301
1332
let diag = self . take_diag ( ) ;
0 commit comments