@@ -39,11 +39,13 @@ use crate::json::{Json, ToJson};
3939use crate :: spec:: abi:: { lookup as lookup_abi, Abi } ;
4040use crate :: spec:: crt_objects:: { CrtObjects , CrtObjectsFallback } ;
4141use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
42+ use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
4243use rustc_span:: symbol:: { sym, Symbol } ;
4344use serde_json:: Value ;
4445use std:: borrow:: Cow ;
4546use std:: collections:: BTreeMap ;
4647use std:: convert:: TryFrom ;
48+ use std:: hash:: { Hash , Hasher } ;
4749use std:: iter:: FromIterator ;
4850use std:: ops:: { Deref , DerefMut } ;
4951use std:: path:: { Path , PathBuf } ;
@@ -2248,7 +2250,7 @@ impl Target {
22482250
22492251 Err ( format ! ( "Could not find specification for target {:?}" , target_triple) )
22502252 }
2251- TargetTriple :: TargetJson { triple : _ , ref contents } => {
2253+ TargetTriple :: TargetJson { ref contents, .. } => {
22522254 let obj = serde_json:: from_str ( contents) . map_err ( |e| e. to_string ( ) ) ?;
22532255 Target :: from_json ( obj)
22542256 }
@@ -2419,10 +2421,77 @@ impl ToJson for Target {
24192421}
24202422
24212423/// Either a target triple string or a path to a JSON file.
2422- #[ derive( PartialEq , Clone , Debug , Hash , Encodable , Decodable ) ]
2424+ #[ derive( Clone , Debug ) ]
24232425pub enum TargetTriple {
24242426 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+ }
24262495}
24272496
24282497impl TargetTriple {
@@ -2437,7 +2506,7 @@ impl TargetTriple {
24372506 let contents = std:: fs:: read_to_string ( & canonicalized_path) . map_err ( |err| {
24382507 io:: Error :: new (
24392508 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) ,
24412510 )
24422511 } ) ?;
24432512 let triple = canonicalized_path
@@ -2446,7 +2515,7 @@ impl TargetTriple {
24462515 . to_str ( )
24472516 . expect ( "target path must be valid unicode" )
24482517 . to_owned ( ) ;
2449- Ok ( TargetTriple :: TargetJson { triple, contents } )
2518+ Ok ( TargetTriple :: TargetJson { path_for_rustdoc : canonicalized_path , triple, contents } )
24502519 }
24512520
24522521 /// Returns a string triple for this target.
@@ -2455,7 +2524,7 @@ impl TargetTriple {
24552524 pub fn triple ( & self ) -> & str {
24562525 match * self {
24572526 TargetTriple :: TargetTriple ( ref triple)
2458- | TargetTriple :: TargetJson { ref triple, contents : _ } => triple,
2527+ | TargetTriple :: TargetJson { ref triple, .. } => triple,
24592528 }
24602529 }
24612530
@@ -2465,11 +2534,10 @@ impl TargetTriple {
24652534 /// by `triple()`.
24662535 pub fn debug_triple ( & self ) -> String {
24672536 use std:: collections:: hash_map:: DefaultHasher ;
2468- use std:: hash:: { Hash , Hasher } ;
24692537
24702538 match self {
24712539 TargetTriple :: TargetTriple ( triple) => triple. to_owned ( ) ,
2472- TargetTriple :: TargetJson { triple, contents : content } => {
2540+ TargetTriple :: TargetJson { path_for_rustdoc : _ , triple, contents : content } => {
24732541 let mut hasher = DefaultHasher :: new ( ) ;
24742542 content. hash ( & mut hasher) ;
24752543 let hash = hasher. finish ( ) ;
0 commit comments