@@ -39,11 +39,13 @@ use crate::json::{Json, ToJson};
39
39
use crate :: spec:: abi:: { lookup as lookup_abi, Abi } ;
40
40
use crate :: spec:: crt_objects:: { CrtObjects , CrtObjectsFallback } ;
41
41
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
42
+ use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
42
43
use rustc_span:: symbol:: { sym, Symbol } ;
43
44
use serde_json:: Value ;
44
45
use std:: borrow:: Cow ;
45
46
use std:: collections:: BTreeMap ;
46
47
use std:: convert:: TryFrom ;
48
+ use std:: hash:: { Hash , Hasher } ;
47
49
use std:: iter:: FromIterator ;
48
50
use std:: ops:: { Deref , DerefMut } ;
49
51
use std:: path:: { Path , PathBuf } ;
@@ -2248,7 +2250,7 @@ impl Target {
2248
2250
2249
2251
Err ( format ! ( "Could not find specification for target {:?}" , target_triple) )
2250
2252
}
2251
- TargetTriple :: TargetJson { triple : _ , ref contents } => {
2253
+ TargetTriple :: TargetJson { ref contents, .. } => {
2252
2254
let obj = serde_json:: from_str ( contents) . map_err ( |e| e. to_string ( ) ) ?;
2253
2255
Target :: from_json ( obj)
2254
2256
}
@@ -2419,10 +2421,77 @@ impl ToJson for Target {
2419
2421
}
2420
2422
2421
2423
/// Either a target triple string or a path to a JSON file.
2422
- #[ derive( PartialEq , Clone , Debug , Hash , Encodable , Decodable ) ]
2424
+ #[ derive( Clone , Debug ) ]
2423
2425
pub enum TargetTriple {
2424
2426
TargetTriple ( String ) ,
2425
- TargetJson { triple : String , contents : String } ,
2427
+ TargetJson {
2428
+ /// Warning: This field may only be used by rustdoc. Using it anywhere else will lead to
2429
+ /// inconsistencies as it is discarded during serialization.
2430
+ path_for_rustdoc : PathBuf ,
2431
+ triple : String ,
2432
+ contents : String ,
2433
+ } ,
2434
+ }
2435
+
2436
+ // Use a manual implementation to ignore the path field
2437
+ impl PartialEq for TargetTriple {
2438
+ fn eq ( & self , other : & Self ) -> bool {
2439
+ match ( self , other) {
2440
+ ( Self :: TargetTriple ( l0) , Self :: TargetTriple ( r0) ) => l0 == r0,
2441
+ (
2442
+ Self :: TargetJson { path_for_rustdoc : _, triple : l_triple, contents : l_contents } ,
2443
+ Self :: TargetJson { path_for_rustdoc : _, triple : r_triple, contents : r_contents } ,
2444
+ ) => l_triple == r_triple && l_contents == r_contents,
2445
+ _ => false ,
2446
+ }
2447
+ }
2448
+ }
2449
+
2450
+ // Use a manual implementation to ignore the path field
2451
+ impl Hash for TargetTriple {
2452
+ fn hash < H : Hasher > ( & self , state : & mut H ) -> ( ) {
2453
+ match self {
2454
+ TargetTriple :: TargetTriple ( triple) => {
2455
+ 0u8 . hash ( state) ;
2456
+ triple. hash ( state)
2457
+ }
2458
+ TargetTriple :: TargetJson { path_for_rustdoc : _, triple, contents } => {
2459
+ 1u8 . hash ( state) ;
2460
+ triple. hash ( state) ;
2461
+ contents. hash ( state)
2462
+ }
2463
+ }
2464
+ }
2465
+ }
2466
+
2467
+ // Use a manual implementation to prevent encoding the target json file path in the crate metadata
2468
+ impl < S : Encoder > Encodable < S > for TargetTriple {
2469
+ fn encode ( & self , s : & mut S ) {
2470
+ match self {
2471
+ TargetTriple :: TargetTriple ( triple) => s. emit_enum_variant ( 0 , |s| s. emit_str ( triple) ) ,
2472
+ TargetTriple :: TargetJson { path_for_rustdoc : _, triple, contents } => s
2473
+ . emit_enum_variant ( 1 , |s| {
2474
+ s. emit_str ( triple) ;
2475
+ s. emit_str ( contents)
2476
+ } ) ,
2477
+ }
2478
+ }
2479
+ }
2480
+
2481
+ impl < D : Decoder > Decodable < D > for TargetTriple {
2482
+ fn decode ( d : & mut D ) -> Self {
2483
+ match d. read_usize ( ) {
2484
+ 0 => TargetTriple :: TargetTriple ( d. read_str ( ) . to_owned ( ) ) ,
2485
+ 1 => TargetTriple :: TargetJson {
2486
+ path_for_rustdoc : PathBuf :: new ( ) ,
2487
+ triple : d. read_str ( ) . to_owned ( ) ,
2488
+ contents : d. read_str ( ) . to_owned ( ) ,
2489
+ } ,
2490
+ _ => {
2491
+ panic ! ( "invalid enum variant tag while decoding `TargetTriple`, expected 0..2" ) ;
2492
+ }
2493
+ }
2494
+ }
2426
2495
}
2427
2496
2428
2497
impl TargetTriple {
@@ -2437,7 +2506,7 @@ impl TargetTriple {
2437
2506
let contents = std:: fs:: read_to_string ( & canonicalized_path) . map_err ( |err| {
2438
2507
io:: Error :: new (
2439
2508
io:: ErrorKind :: InvalidInput ,
2440
- format ! ( "Target path {:?} is not a valid file: {}" , canonicalized_path, err) ,
2509
+ format ! ( "target path {:?} is not a valid file: {}" , canonicalized_path, err) ,
2441
2510
)
2442
2511
} ) ?;
2443
2512
let triple = canonicalized_path
@@ -2446,7 +2515,7 @@ impl TargetTriple {
2446
2515
. to_str ( )
2447
2516
. expect ( "target path must be valid unicode" )
2448
2517
. to_owned ( ) ;
2449
- Ok ( TargetTriple :: TargetJson { triple, contents } )
2518
+ Ok ( TargetTriple :: TargetJson { path_for_rustdoc : canonicalized_path , triple, contents } )
2450
2519
}
2451
2520
2452
2521
/// Returns a string triple for this target.
@@ -2455,7 +2524,7 @@ impl TargetTriple {
2455
2524
pub fn triple ( & self ) -> & str {
2456
2525
match * self {
2457
2526
TargetTriple :: TargetTriple ( ref triple)
2458
- | TargetTriple :: TargetJson { ref triple, contents : _ } => triple,
2527
+ | TargetTriple :: TargetJson { ref triple, .. } => triple,
2459
2528
}
2460
2529
}
2461
2530
@@ -2465,11 +2534,10 @@ impl TargetTriple {
2465
2534
/// by `triple()`.
2466
2535
pub fn debug_triple ( & self ) -> String {
2467
2536
use std:: collections:: hash_map:: DefaultHasher ;
2468
- use std:: hash:: { Hash , Hasher } ;
2469
2537
2470
2538
match self {
2471
2539
TargetTriple :: TargetTriple ( triple) => triple. to_owned ( ) ,
2472
- TargetTriple :: TargetJson { triple, contents : content } => {
2540
+ TargetTriple :: TargetJson { path_for_rustdoc : _ , triple, contents : content } => {
2473
2541
let mut hasher = DefaultHasher :: new ( ) ;
2474
2542
content. hash ( & mut hasher) ;
2475
2543
let hash = hasher. finish ( ) ;
0 commit comments