Auto merge of #66121 - pietroalbini:rollup-8zrwe7l, r=pietroalbini
Rollup of 8 pull requests Successful merges: - #65948 (Improve MaybeUninit::get_{ref,mut} documentation) - #65953 (Allow specifying LLVM's MCTargetOptions::ABIName in target specification files) - #66012 (De-querify `trivial_dropck_outlives`.) - #66025 (`Span` cannot represent `span.hi < span.lo`) - #66047 (Don't double-count `simd_shuffle` promotion candidates) - #66053 (when Miri tests are not passing, do not add Miri component) - #66082 (clean highlightSourceLines code) - #66091 (Implemented the home_dir for VxWorks) Failed merges: r? @ghost
This commit is contained in:
commit
1423bec54c
@ -208,6 +208,7 @@ name = "build-manifest"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
]
|
||||
|
||||
|
@ -509,32 +509,183 @@ impl<T> MaybeUninit<T> {
|
||||
self.as_ptr().read()
|
||||
}
|
||||
|
||||
/// Gets a reference to the contained value.
|
||||
/// Gets a shared reference to the contained value.
|
||||
///
|
||||
/// This can be useful when we want to access a `MaybeUninit` that has been
|
||||
/// initialized but don't have ownership of the `MaybeUninit` (preventing the use
|
||||
/// of `.assume_init()`).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
|
||||
/// state. Calling this when the content is not yet fully initialized causes undefined
|
||||
/// behavior.
|
||||
/// Calling this when the content is not yet fully initialized causes undefined
|
||||
/// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
|
||||
/// is in an initialized state.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ### Correct usage of this method:
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(maybe_uninit_ref)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
|
||||
/// // Initialize `x`:
|
||||
/// unsafe { x.as_mut_ptr().write(vec![1, 2, 3]); }
|
||||
/// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
|
||||
/// // create a shared reference to it:
|
||||
/// let x: &Vec<u32> = unsafe {
|
||||
/// // Safety: `x` has been initialized.
|
||||
/// x.get_ref()
|
||||
/// };
|
||||
/// assert_eq!(x, &vec![1, 2, 3]);
|
||||
/// ```
|
||||
///
|
||||
/// ### *Incorrect* usages of this method:
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// #![feature(maybe_uninit_ref)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let x = MaybeUninit::<Vec<u32>>::uninit();
|
||||
/// let x_vec: &Vec<u32> = unsafe { x.get_ref() };
|
||||
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
|
||||
/// ```
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// #![feature(maybe_uninit_ref)]
|
||||
/// use std::{cell::Cell, mem::MaybeUninit};
|
||||
///
|
||||
/// let b = MaybeUninit::<Cell<bool>>::uninit();
|
||||
/// // Initialize the `MaybeUninit` using `Cell::set`:
|
||||
/// unsafe {
|
||||
/// b.get_ref().set(true);
|
||||
/// // ^^^^^^^^^^^
|
||||
/// // Reference to an uninitialized `Cell<bool>`: UB!
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_ref", issue = "63568")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn get_ref(&self) -> &T {
|
||||
intrinsics::panic_if_uninhabited::<T>();
|
||||
&*self.value
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the contained value.
|
||||
/// Gets a mutable (unique) reference to the contained value.
|
||||
///
|
||||
/// This can be useful when we want to access a `MaybeUninit` that has been
|
||||
/// initialized but don't have ownership of the `MaybeUninit` (preventing the use
|
||||
/// of `.assume_init()`).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
|
||||
/// state. Calling this when the content is not yet fully initialized causes undefined
|
||||
/// behavior.
|
||||
/// Calling this when the content is not yet fully initialized causes undefined
|
||||
/// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
|
||||
/// is in an initialized state. For instance, `.get_mut()` cannot be used to
|
||||
/// initialize a `MaybeUninit`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ### Correct usage of this method:
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(maybe_uninit_ref)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// # unsafe extern "C" fn initialize_buffer(buf: *mut [u8; 2048]) { *buf = [0; 2048] }
|
||||
/// # #[cfg(FALSE)]
|
||||
/// extern "C" {
|
||||
/// /// Initializes *all* the bytes of the input buffer.
|
||||
/// fn initialize_buffer(buf: *mut [u8; 2048]);
|
||||
/// }
|
||||
///
|
||||
/// let mut buf = MaybeUninit::<[u8; 2048]>::uninit();
|
||||
///
|
||||
/// // Initialize `buf`:
|
||||
/// unsafe { initialize_buffer(buf.as_mut_ptr()); }
|
||||
/// // Now we know that `buf` has been initialized, so we could `.assume_init()` it.
|
||||
/// // However, using `.assume_init()` may trigger a `memcpy` of the 2048 bytes.
|
||||
/// // To assert our buffer has been initialized without copying it, we upgrade
|
||||
/// // the `&mut MaybeUninit<[u8; 2048]>` to a `&mut [u8; 2048]`:
|
||||
/// let buf: &mut [u8; 2048] = unsafe {
|
||||
/// // Safety: `buf` has been initialized.
|
||||
/// buf.get_mut()
|
||||
/// };
|
||||
///
|
||||
/// // Now we can use `buf` as a normal slice:
|
||||
/// buf.sort_unstable();
|
||||
/// assert!(
|
||||
/// buf.chunks(2).all(|chunk| chunk[0] <= chunk[1]),
|
||||
/// "buffer is sorted",
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// ### *Incorrect* usages of this method:
|
||||
///
|
||||
/// You cannot use `.get_mut()` to initialize a value:
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// #![feature(maybe_uninit_ref)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut b = MaybeUninit::<bool>::uninit();
|
||||
/// unsafe {
|
||||
/// *b.get_mut() = true;
|
||||
/// // We have created a (mutable) reference to an uninitialized `bool`!
|
||||
/// // This is undefined behavior.
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// For instance, you cannot [`Read`] into an uninitialized buffer:
|
||||
///
|
||||
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// #![feature(maybe_uninit_ref)]
|
||||
/// use std::{io, mem::MaybeUninit};
|
||||
///
|
||||
/// fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]>
|
||||
/// {
|
||||
/// let mut buffer = MaybeUninit::<[u8; 64]>::uninit();
|
||||
/// reader.read_exact(unsafe { buffer.get_mut() })?;
|
||||
/// // ^^^^^^^^^^^^^^^^
|
||||
/// // (mutable) reference to uninitialized memory!
|
||||
/// // This is undefined behavior.
|
||||
/// Ok(unsafe { buffer.assume_init() })
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Nor can you use direct field access to do field-by-field gradual initialization:
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// #![feature(maybe_uninit_ref)]
|
||||
/// use std::{mem::MaybeUninit, ptr};
|
||||
///
|
||||
/// struct Foo {
|
||||
/// a: u32,
|
||||
/// b: u8,
|
||||
/// }
|
||||
///
|
||||
/// let foo: Foo = unsafe {
|
||||
/// let mut foo = MaybeUninit::<Foo>::uninit();
|
||||
/// ptr::write(&mut foo.get_mut().a as *mut u32, 1337);
|
||||
/// // ^^^^^^^^^^^^^
|
||||
/// // (mutable) reference to uninitialized memory!
|
||||
/// // This is undefined behavior.
|
||||
/// ptr::write(&mut foo.get_mut().b as *mut u8, 42);
|
||||
/// // ^^^^^^^^^^^^^
|
||||
/// // (mutable) reference to uninitialized memory!
|
||||
/// // This is undefined behavior.
|
||||
/// foo.assume_init()
|
||||
/// };
|
||||
/// ```
|
||||
// FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
|
||||
// to uninitialized data (e.g., in `libcore/fmt/float.rs`). We should make
|
||||
// a final decision about the rules before stabilization.
|
||||
#[unstable(feature = "maybe_uninit_ref", issue = "63568")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn get_mut(&mut self) -> &mut T {
|
||||
intrinsics::panic_if_uninhabited::<T>();
|
||||
&mut *self.value
|
||||
}
|
||||
|
||||
|
@ -309,11 +309,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
|
||||
// position that belongs to it, as opposed to hashing the first
|
||||
// position past it.
|
||||
let span = self.data();
|
||||
|
||||
if span.hi < span.lo {
|
||||
return std_hash::Hash::hash(&TAG_INVALID_SPAN, hasher);
|
||||
}
|
||||
|
||||
let (file_lo, line_lo, col_lo) = match hcx.source_map()
|
||||
.byte_pos_to_line_and_col(span.lo) {
|
||||
Some(pos) => pos,
|
||||
|
@ -228,12 +228,6 @@ rustc_queries! {
|
||||
cycle_delay_bug
|
||||
}
|
||||
|
||||
query trivial_dropck_outlives(ty: Ty<'tcx>) -> bool {
|
||||
anon
|
||||
no_force
|
||||
desc { "checking if `{:?}` has trivial dropck", ty }
|
||||
}
|
||||
|
||||
query adt_dtorck_constraint(
|
||||
_: DefId
|
||||
) -> Result<DtorckConstraint<'tcx>, NoSolution> {}
|
||||
|
@ -5,7 +5,6 @@ use std::iter::FromIterator;
|
||||
use syntax::source_map::Span;
|
||||
use crate::ty::subst::GenericArg;
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
use crate::ty::query::Providers;
|
||||
|
||||
impl<'cx, 'tcx> At<'cx, 'tcx> {
|
||||
/// Given a type `ty` of some value being dropped, computes a set
|
||||
@ -34,7 +33,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> {
|
||||
// Quick check: there are a number of cases that we know do not require
|
||||
// any destructor.
|
||||
let tcx = self.infcx.tcx;
|
||||
if tcx.trivial_dropck_outlives(ty) {
|
||||
if trivial_dropck_outlives(tcx, ty) {
|
||||
return InferOk {
|
||||
value: vec![],
|
||||
obligations: vec![],
|
||||
@ -208,15 +207,15 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
| ty::Error => true,
|
||||
|
||||
// [T; N] and [T] have same properties as T.
|
||||
ty::Array(ty, _) | ty::Slice(ty) => tcx.trivial_dropck_outlives(ty),
|
||||
ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty),
|
||||
|
||||
// (T1..Tn) and closures have same properties as T1..Tn --
|
||||
// check if *any* of those are trivial.
|
||||
ty::Tuple(ref tys) => tys.iter().all(|t| tcx.trivial_dropck_outlives(t.expect_ty())),
|
||||
ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())),
|
||||
ty::Closure(def_id, ref substs) => substs
|
||||
.as_closure()
|
||||
.upvar_tys(def_id, tcx)
|
||||
.all(|t| tcx.trivial_dropck_outlives(t)),
|
||||
.all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
|
||||
ty::Adt(def, _) => {
|
||||
if Some(def.did) == tcx.lang_items().manually_drop() {
|
||||
@ -244,10 +243,3 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
|
||||
}
|
||||
}
|
||||
|
||||
crate fn provide(p: &mut Providers<'_>) {
|
||||
*p = Providers {
|
||||
trivial_dropck_outlives,
|
||||
..*p
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
|
||||
use crate::traits::query::dropck_outlives::DropckOutlivesResult;
|
||||
use crate::traits::query::dropck_outlives::{DropckOutlivesResult, trivial_dropck_outlives};
|
||||
use crate::traits::query::Fallible;
|
||||
use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
|
||||
|
||||
@ -21,7 +21,7 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: &ParamEnvAnd<'tcx, Self>,
|
||||
) -> Option<Self::QueryResponse> {
|
||||
if tcx.trivial_dropck_outlives(key.value.dropped_ty) {
|
||||
if trivial_dropck_outlives(tcx, key.value.dropped_ty) {
|
||||
Some(DropckOutlivesResult::default())
|
||||
} else {
|
||||
None
|
||||
|
@ -3407,7 +3407,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
|
||||
layout::provide(providers);
|
||||
util::provide(providers);
|
||||
constness::provide(providers);
|
||||
crate::traits::query::dropck_outlives::provide(providers);
|
||||
*providers = ty::query::Providers {
|
||||
asyncness,
|
||||
associated_item,
|
||||
|
@ -796,11 +796,6 @@ where
|
||||
}
|
||||
|
||||
let span_data = span.data();
|
||||
|
||||
if span_data.hi < span_data.lo {
|
||||
return TAG_INVALID_SPAN.encode(self);
|
||||
}
|
||||
|
||||
let (file_lo, line_lo, col_lo) = match self.source_map
|
||||
.byte_pos_to_line_and_col(span_data.lo) {
|
||||
Some(pos) => pos,
|
||||
|
@ -161,6 +161,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
|
||||
let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
|
||||
let features = features.join(",");
|
||||
let features = CString::new(features).unwrap();
|
||||
let abi = SmallCStr::new(&sess.target.target.options.llvm_abiname);
|
||||
let is_pie_binary = !find_features && is_pie_binary(sess);
|
||||
let trap_unreachable = sess.target.target.options.trap_unreachable;
|
||||
let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
|
||||
@ -170,7 +171,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
|
||||
Arc::new(move || {
|
||||
let tm = unsafe {
|
||||
llvm::LLVMRustCreateTargetMachine(
|
||||
triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
|
||||
triple.as_ptr(), cpu.as_ptr(), features.as_ptr(), abi.as_ptr(),
|
||||
code_model,
|
||||
reloc_model,
|
||||
opt_level,
|
||||
|
@ -1684,6 +1684,7 @@ extern "C" {
|
||||
pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
|
||||
CPU: *const c_char,
|
||||
Features: *const c_char,
|
||||
Abi: *const c_char,
|
||||
Model: CodeModel,
|
||||
Reloc: RelocMode,
|
||||
Level: CodeGenOptLevel,
|
||||
|
@ -199,6 +199,8 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
||||
bb: location.block,
|
||||
index: 2,
|
||||
});
|
||||
|
||||
return; // Don't double count `simd_shuffle` candidates
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -793,7 +793,10 @@ pub struct TargetOptions {
|
||||
pub merge_functions: MergeFunctions,
|
||||
|
||||
/// Use platform dependent mcount function
|
||||
pub target_mcount: String
|
||||
pub target_mcount: String,
|
||||
|
||||
/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
|
||||
pub llvm_abiname: String,
|
||||
}
|
||||
|
||||
impl Default for TargetOptions {
|
||||
@ -880,6 +883,7 @@ impl Default for TargetOptions {
|
||||
override_export_symbols: None,
|
||||
merge_functions: MergeFunctions::Aliases,
|
||||
target_mcount: "mcount".to_string(),
|
||||
llvm_abiname: "".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1196,6 +1200,7 @@ impl Target {
|
||||
key!(override_export_symbols, opt_list);
|
||||
key!(merge_functions, MergeFunctions)?;
|
||||
key!(target_mcount);
|
||||
key!(llvm_abiname);
|
||||
|
||||
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
|
||||
for name in array.iter().filter_map(|abi| abi.as_string()) {
|
||||
@ -1414,6 +1419,7 @@ impl ToJson for Target {
|
||||
target_option_val!(override_export_symbols);
|
||||
target_option_val!(merge_functions);
|
||||
target_option_val!(target_mcount);
|
||||
target_option_val!(llvm_abiname);
|
||||
|
||||
if default.abi_blacklist != self.options.abi_blacklist {
|
||||
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
|
||||
|
@ -1,6 +1,7 @@
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc::traits::query::dropck_outlives::{DropckOutlivesResult, DtorckConstraint};
|
||||
use rustc::traits::query::dropck_outlives::trivial_dropck_outlives;
|
||||
use rustc::traits::query::{CanonicalTyGoal, NoSolution};
|
||||
use rustc::traits::{TraitEngine, Normalized, ObligationCause, TraitEngineExt};
|
||||
use rustc::ty::query::Providers;
|
||||
@ -172,7 +173,7 @@ fn dtorck_constraint_for_ty<'tcx>(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if tcx.trivial_dropck_outlives(ty) {
|
||||
if trivial_dropck_outlives(tcx, ty) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -163,59 +163,71 @@ function getSearchElement() {
|
||||
|
||||
var main = document.getElementById("main");
|
||||
|
||||
function highlightSourceLines(ev) {
|
||||
// If we're in mobile mode, we should add the sidebar in any case.
|
||||
function onHashChange(ev) {
|
||||
// If we're in mobile mode, we should hide the sidebar in any case.
|
||||
hideSidebar();
|
||||
var elem;
|
||||
var search = getSearchElement();
|
||||
var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
|
||||
var match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
|
||||
if (match) {
|
||||
from = parseInt(match[1], 10);
|
||||
to = from;
|
||||
if (typeof match[2] !== "undefined") {
|
||||
to = parseInt(match[2], 10);
|
||||
}
|
||||
if (to < from) {
|
||||
var tmp = to;
|
||||
to = from;
|
||||
from = tmp;
|
||||
}
|
||||
elem = document.getElementById(from);
|
||||
if (!elem) {
|
||||
return;
|
||||
}
|
||||
if (ev === null) {
|
||||
var x = document.getElementById(from);
|
||||
if (x) {
|
||||
x.scrollIntoView();
|
||||
}
|
||||
}
|
||||
onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
|
||||
onEachLazy(e.getElementsByTagName("span"), function(i_e) {
|
||||
removeClass(i_e, "line-highlighted");
|
||||
});
|
||||
});
|
||||
for (i = from; i <= to; ++i) {
|
||||
elem = document.getElementById(i);
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
addClass(elem, "line-highlighted");
|
||||
}
|
||||
} else if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
|
||||
return highlightSourceLines(match, ev);
|
||||
}
|
||||
var search = getSearchElement();
|
||||
if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
|
||||
addClass(search, "hidden");
|
||||
removeClass(main, "hidden");
|
||||
var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
|
||||
if (browserSupportsHistoryApi()) {
|
||||
history.replaceState(hash, "", "?search=#" + hash);
|
||||
}
|
||||
elem = document.getElementById(hash);
|
||||
var elem = document.getElementById(hash);
|
||||
if (elem) {
|
||||
elem.scrollIntoView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function highlightSourceLines(match, ev) {
|
||||
if (typeof match === "undefined") {
|
||||
// If we're in mobile mode, we should hide the sidebar in any case.
|
||||
hideSidebar();
|
||||
match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
|
||||
}
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
var from = parseInt(match[1], 10);
|
||||
var to = from;
|
||||
if (typeof match[2] !== "undefined") {
|
||||
to = parseInt(match[2], 10);
|
||||
}
|
||||
if (to < from) {
|
||||
var tmp = to;
|
||||
to = from;
|
||||
from = tmp;
|
||||
}
|
||||
var elem = document.getElementById(from);
|
||||
if (!elem) {
|
||||
return;
|
||||
}
|
||||
if (!ev) {
|
||||
var x = document.getElementById(from);
|
||||
if (x) {
|
||||
x.scrollIntoView();
|
||||
}
|
||||
}
|
||||
onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
|
||||
onEachLazy(e.getElementsByTagName("span"), function(i_e) {
|
||||
removeClass(i_e, "line-highlighted");
|
||||
});
|
||||
});
|
||||
for (var i = from; i <= to; ++i) {
|
||||
elem = document.getElementById(i);
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
addClass(elem, "line-highlighted");
|
||||
}
|
||||
}
|
||||
|
||||
function expandSection(id) {
|
||||
var elem = document.getElementById(id);
|
||||
if (elem && isHidden(elem)) {
|
||||
@ -234,8 +246,8 @@ function getSearchElement() {
|
||||
}
|
||||
}
|
||||
|
||||
highlightSourceLines(null);
|
||||
window.onhashchange = highlightSourceLines;
|
||||
highlightSourceLines();
|
||||
window.onhashchange = onHashChange;
|
||||
|
||||
// Gets the human-readable string for the virtual-key code of the
|
||||
// given KeyboardEvent, ev.
|
||||
@ -358,7 +370,7 @@ function getSearchElement() {
|
||||
var set_fragment = function(name) {
|
||||
if (browserSupportsHistoryApi()) {
|
||||
history.replaceState(null, null, "#" + name);
|
||||
highlightSourceLines(null);
|
||||
highlightSourceLines();
|
||||
} else {
|
||||
location.replace("#" + name);
|
||||
}
|
||||
|
@ -287,7 +287,8 @@ pub fn temp_dir() -> PathBuf {
|
||||
}
|
||||
|
||||
pub fn home_dir() -> Option<PathBuf> {
|
||||
None
|
||||
crate::env::var_os("HOME").or_else(|| None
|
||||
).map(PathBuf::from)
|
||||
}
|
||||
|
||||
pub fn exit(code: i32) -> ! {
|
||||
|
@ -68,7 +68,7 @@ impl<'a> StringReader<'a> {
|
||||
let end = sess.source_map().lookup_byte_offset(span.hi());
|
||||
|
||||
// Make the range zero-length if the span is invalid.
|
||||
if span.lo() > span.hi() || begin.sf.start_pos != end.sf.start_pos {
|
||||
if begin.sf.start_pos != end.sf.start_pos {
|
||||
span = span.shrink_to_lo();
|
||||
}
|
||||
|
||||
|
@ -498,10 +498,6 @@ impl SourceMap {
|
||||
pub fn span_to_lines(&self, sp: Span) -> FileLinesResult {
|
||||
debug!("span_to_lines(sp={:?})", sp);
|
||||
|
||||
if sp.lo() > sp.hi() {
|
||||
return Err(SpanLinesError::IllFormedSpan(sp));
|
||||
}
|
||||
|
||||
let lo = self.lookup_char_pos(sp.lo());
|
||||
debug!("span_to_lines: lo={:?}", lo);
|
||||
let hi = self.lookup_char_pos(sp.hi());
|
||||
@ -549,10 +545,6 @@ impl SourceMap {
|
||||
fn span_to_source<F>(&self, sp: Span, extract_source: F) -> Result<String, SpanSnippetError>
|
||||
where F: Fn(&str, usize, usize) -> Result<String, SpanSnippetError>
|
||||
{
|
||||
if sp.lo() > sp.hi() {
|
||||
return Err(SpanSnippetError::IllFormedSpan(sp));
|
||||
}
|
||||
|
||||
let local_begin = self.lookup_byte_offset(sp.lo());
|
||||
let local_end = self.lookup_byte_offset(sp.hi());
|
||||
|
||||
@ -762,14 +754,14 @@ impl SourceMap {
|
||||
|
||||
/// Finds the width of a character, either before or after the provided span.
|
||||
fn find_width_of_character_at_span(&self, sp: Span, forwards: bool) -> u32 {
|
||||
// Disregard malformed spans and assume a one-byte wide character.
|
||||
if sp.lo() >= sp.hi() {
|
||||
debug!("find_width_of_character_at_span: early return malformed span");
|
||||
let sp = sp.data();
|
||||
if sp.lo == sp.hi {
|
||||
debug!("find_width_of_character_at_span: early return empty span");
|
||||
return 1;
|
||||
}
|
||||
|
||||
let local_begin = self.lookup_byte_offset(sp.lo());
|
||||
let local_end = self.lookup_byte_offset(sp.hi());
|
||||
let local_begin = self.lookup_byte_offset(sp.lo);
|
||||
let local_end = self.lookup_byte_offset(sp.hi);
|
||||
debug!("find_width_of_character_at_span: local_begin=`{:?}`, local_end=`{:?}`",
|
||||
local_begin, local_end);
|
||||
|
||||
|
@ -1512,7 +1512,6 @@ pub type FileLinesResult = Result<FileLines, SpanLinesError>;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum SpanLinesError {
|
||||
IllFormedSpan(Span),
|
||||
DistinctSources(DistinctSources),
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
|
||||
|
||||
extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
const char *TripleStr, const char *CPU, const char *Feature,
|
||||
LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
|
||||
const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
|
||||
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
|
||||
bool PositionIndependentExecutable, bool FunctionSections,
|
||||
bool DataSections,
|
||||
@ -374,6 +374,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
Options.FunctionSections = FunctionSections;
|
||||
Options.MCOptions.AsmVerbose = AsmComments;
|
||||
Options.MCOptions.PreserveAsmComments = AsmComments;
|
||||
Options.MCOptions.ABIName = ABIStr;
|
||||
|
||||
if (TrapUnreachable) {
|
||||
// Tell LLVM to codegen `unreachable` into an explicit trap instruction.
|
||||
|
@ -7,3 +7,4 @@ edition = "2018"
|
||||
[dependencies]
|
||||
toml = "0.5"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
@ -11,10 +11,11 @@ use serde::Serialize;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::collections::HashMap;
|
||||
|
||||
static HOSTS: &[&str] = &[
|
||||
"aarch64-unknown-linux-gnu",
|
||||
@ -366,6 +367,7 @@ impl Builder {
|
||||
self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
|
||||
self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
|
||||
|
||||
self.check_toolstate();
|
||||
self.digest_and_sign();
|
||||
let manifest = self.build_manifest();
|
||||
self.write_channel_files(&self.rust_release, &manifest);
|
||||
@ -375,6 +377,25 @@ impl Builder {
|
||||
}
|
||||
}
|
||||
|
||||
/// If a tool does not pass its tests, don't ship it.
|
||||
/// Right now, we do this only for Miri.
|
||||
fn check_toolstate(&mut self) {
|
||||
let toolstates: Option<HashMap<String, String>> =
|
||||
File::open(self.input.join("toolstates-linux.json")).ok()
|
||||
.and_then(|f| serde_json::from_reader(&f).ok());
|
||||
let toolstates = toolstates.unwrap_or_else(|| {
|
||||
println!("WARNING: `toolstates-linux.json` missing/malformed; \
|
||||
assuming all tools failed");
|
||||
HashMap::default() // Use empty map if anything went wrong.
|
||||
});
|
||||
// Mark some tools as missing based on toolstate.
|
||||
if toolstates.get("miri").map(|s| &*s as &str) != Some("test-pass") {
|
||||
println!("Miri tests are not passing, removing component");
|
||||
self.miri_version = None;
|
||||
self.miri_git_commit_hash = None;
|
||||
}
|
||||
}
|
||||
|
||||
/// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
|
||||
fn digest_and_sign(&mut self) {
|
||||
for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user