Preserve the path of the target spec json file for usage by rustdoc · rust-lang/rust@b4b536d (original) (raw)
`@@ -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 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 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();
`