Auto merge of #87413 - JohnTitor:rollup-dht22jk, r=JohnTitor

Rollup of 14 pull requests

Successful merges:

 - #86410 (VecMap::get_value_matching should return just one element)
 - #86790 (Document iteration order of `retain` functions)
 - #87171 (Remove Option from BufWriter)
 - #87175 (Stabilize `into_parts()` and `into_error()`)
 - #87185 (Fix panics on Windows when the build was cancelled)
 - #87191 (Package LLVM libs for the target rather than the build host)
 - #87255 (better support for running libcore tests with Miri)
 - #87266 (Add testcase for 87076)
 - #87283 (Add `--codegen-backends=foo,bar` configure flag)
 - #87322 (fix: clarify suggestion that `&T` must refer to `T: Sync` for `&T: Send`)
 - #87358 (Fix `--dry-run` when download-ci-llvm is set)
 - #87380 (Don't default to `submodules = true` unless the rust repo has a .git directory)
 - #87398 (Add test for fonts used for module items)
 - #87412 (Add missing article)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-07-23 20:26:33 +00:00
commit 67b03007cf
54 changed files with 213 additions and 44 deletions

View file

@ -1,4 +1,5 @@
use std::borrow::Borrow; use std::borrow::Borrow;
use std::fmt::Debug;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::slice::Iter; use std::slice::Iter;
use std::vec::IntoIter; use std::vec::IntoIter;
@ -12,7 +13,8 @@ pub struct VecMap<K, V>(Vec<(K, V)>);
impl<K, V> VecMap<K, V> impl<K, V> VecMap<K, V>
where where
K: PartialEq, K: Debug + PartialEq,
V: Debug,
{ {
pub fn new() -> Self { pub fn new() -> Self {
VecMap(Default::default()) VecMap(Default::default())
@ -37,14 +39,31 @@ where
self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1) self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1)
} }
/// Returns the value corresponding to the supplied predicate filter. /// Returns the any value corresponding to the supplied predicate filter.
/// ///
/// The supplied predicate will be applied to each (key, value) pair and it will return a /// The supplied predicate will be applied to each (key, value) pair and it will return a
/// reference to the values where the predicate returns `true`. /// reference to the values where the predicate returns `true`.
pub fn get_by(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> { pub fn any_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
self.0.iter().find(|kv| predicate(kv)).map(|elem| &elem.1) self.0.iter().find(|kv| predicate(kv)).map(|elem| &elem.1)
} }
/// Returns the value corresponding to the supplied predicate filter. It crashes if there's
/// more than one matching element.
///
/// The supplied predicate will be applied to each (key, value) pair and it will return a
/// reference to the value where the predicate returns `true`.
pub fn get_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
let mut filter = self.0.iter().filter(|kv| predicate(kv));
let (_, value) = filter.next()?;
// This should return just one element, otherwise it's a bug
assert!(
filter.next().is_none(),
"Collection {:?} should have just one matching element",
self
);
Some(value)
}
/// Returns `true` if the map contains a value for the specified key. /// Returns `true` if the map contains a value for the specified key.
/// ///
/// The key may be any borrowed form of the map's key type, /// The key may be any borrowed form of the map's key type,
@ -131,7 +150,7 @@ impl<K, V> IntoIterator for VecMap<K, V> {
} }
} }
impl<K: PartialEq, V> Extend<(K, V)> for VecMap<K, V> { impl<K: PartialEq + Debug, V: Debug> Extend<(K, V)> for VecMap<K, V> {
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
for (k, v) in iter { for (k, v) in iter {
self.insert(k, v); self.insert(k, v);

View file

@ -1857,12 +1857,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
} }
} }
GeneratorInteriorOrUpvar::Upvar(upvar_span) => { GeneratorInteriorOrUpvar::Upvar(upvar_span) => {
let mut span = MultiSpan::from_span(upvar_span); // `Some(ref_ty)` if `target_ty` is `&T` and `T` fails to impl `Sync`
span.push_span_label( let refers_to_non_sync = match target_ty.kind() {
upvar_span, ty::Ref(_, ref_ty, _) => match self.evaluate_obligation(&obligation) {
Ok(eval) if !eval.may_apply() => Some(ref_ty),
_ => None,
},
_ => None,
};
let (span_label, span_note) = match refers_to_non_sync {
// if `target_ty` is `&T` and `T` fails to impl `Sync`,
// include suggestions to make `T: Sync` so that `&T: Send`
Some(ref_ty) => (
format!(
"has type `{}` which {}, because `{}` is not `Sync`",
target_ty, trait_explanation, ref_ty
),
format!(
"captured value {} because `&` references cannot be sent unless their referent is `Sync`",
trait_explanation
),
),
None => (
format!("has type `{}` which {}", target_ty, trait_explanation), format!("has type `{}` which {}", target_ty, trait_explanation),
); format!("captured value {}", trait_explanation),
err.span_note(span, &format!("captured value {}", trait_explanation)); ),
};
let mut span = MultiSpan::from_span(upvar_span);
span.push_span_label(upvar_span, span_label);
err.span_note(span, &span_note);
} }
} }

View file

@ -364,7 +364,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
let concrete_ty = tcx let concrete_ty = tcx
.mir_borrowck(owner.expect_local()) .mir_borrowck(owner.expect_local())
.concrete_opaque_types .concrete_opaque_types
.get_by(|(key, _)| key.def_id == def_id.to_def_id()) .get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
.map(|concrete_ty| *concrete_ty) .map(|concrete_ty| *concrete_ty)
.unwrap_or_else(|| { .unwrap_or_else(|| {
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
@ -512,8 +512,15 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
struct ConstraintLocator<'tcx> { struct ConstraintLocator<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
/// def_id of the opaque type whose defining uses are being checked
def_id: DefId, def_id: DefId,
// (first found type span, actual type)
/// as we walk the defining uses, we are checking that all of them
/// define the same hidden type. This variable is set to `Some`
/// with the first type that we find, and then later types are
/// checked against it (we also carry the span of that first
/// type).
found: Option<(Span, Ty<'tcx>)>, found: Option<(Span, Ty<'tcx>)>,
} }
@ -531,7 +538,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
.tcx .tcx
.typeck(def_id) .typeck(def_id)
.concrete_opaque_types .concrete_opaque_types
.get_by(|(key, _)| key.def_id == self.def_id) .any_value_matching(|(key, _)| key.def_id == self.def_id)
.is_none() .is_none()
{ {
debug!("no constraints in typeck results"); debug!("no constraints in typeck results");

View file

@ -38,7 +38,7 @@ changelog-seen = 2
# This is false by default so that distributions don't unexpectedly download # This is false by default so that distributions don't unexpectedly download
# LLVM from the internet. # LLVM from the internet.
# #
# All tier 1 targets are currently supported; set this to `"if-supported"` if # All tier 1 targets are currently supported; set this to `"if-available"` if
# you are not sure whether you're on a tier 1 target. # you are not sure whether you're on a tier 1 target.
# #
# We also currently only support this when building LLVM for the build triple. # We also currently only support this when building LLVM for the build triple.

View file

@ -935,6 +935,7 @@ impl<K, V> BTreeMap<K, V> {
/// Retains only the elements specified by the predicate. /// Retains only the elements specified by the predicate.
/// ///
/// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
/// The elements are visited in ascending key order.
/// ///
/// # Examples /// # Examples
/// ///

View file

@ -846,6 +846,7 @@ impl<T> BTreeSet<T> {
/// Retains only the elements specified by the predicate. /// Retains only the elements specified by the predicate.
/// ///
/// In other words, remove all elements `e` such that `f(&e)` returns `false`. /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
/// The elements are visited in ascending order.
/// ///
/// # Examples /// # Examples
/// ///

View file

@ -56,6 +56,10 @@
//! [`Rc`]: rc //! [`Rc`]: rc
//! [`RefCell`]: core::cell //! [`RefCell`]: core::cell
// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
// rustc itself never sets the feature, so this line has no affect there.
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
#![allow(unused_attributes)] #![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")] #![stable(feature = "alloc", since = "1.36.0")]
#![doc( #![doc(

View file

@ -49,6 +49,10 @@
// //
// This cfg won't affect doc tests. // This cfg won't affect doc tests.
#![cfg(not(test))] #![cfg(not(test))]
// To run libcore tests without x.py without ending up with two copies of libcore, Miri needs to be
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
// rustc itself never sets the feature, so this line has no affect there.
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
#![stable(feature = "core", since = "1.6.0")] #![stable(feature = "core", since = "1.6.0")]
#![doc( #![doc(
html_playground_url = "https://play.rust-lang.org/", html_playground_url = "https://play.rust-lang.org/",

View file

@ -934,6 +934,7 @@ where
/// Retains only the elements specified by the predicate. /// Retains only the elements specified by the predicate.
/// ///
/// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
/// The elements are visited in unsorted (and unspecified) order.
/// ///
/// # Examples /// # Examples
/// ///

View file

@ -912,6 +912,7 @@ where
/// Retains only the elements specified by the predicate. /// Retains only the elements specified by the predicate.
/// ///
/// In other words, remove all elements `e` such that `f(&e)` returns `false`. /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
/// The elements are visited in unsorted (and unspecified) order.
/// ///
/// # Examples /// # Examples
/// ///

View file

@ -68,7 +68,7 @@ use crate::ptr;
/// [`flush`]: BufWriter::flush /// [`flush`]: BufWriter::flush
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct BufWriter<W: Write> { pub struct BufWriter<W: Write> {
inner: Option<W>, inner: W,
// The buffer. Avoid using this like a normal `Vec` in common code paths. // The buffer. Avoid using this like a normal `Vec` in common code paths.
// That is, don't use `buf.push`, `buf.extend_from_slice`, or any other // That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
// methods that require bounds checking or the like. This makes an enormous // methods that require bounds checking or the like. This makes an enormous
@ -112,7 +112,7 @@ impl<W: Write> BufWriter<W> {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> { pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
BufWriter { inner: Some(inner), buf: Vec::with_capacity(capacity), panicked: false } BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
} }
/// Send data in our local buffer into the inner writer, looping as /// Send data in our local buffer into the inner writer, looping as
@ -161,10 +161,9 @@ impl<W: Write> BufWriter<W> {
} }
let mut guard = BufGuard::new(&mut self.buf); let mut guard = BufGuard::new(&mut self.buf);
let inner = self.inner.as_mut().unwrap();
while !guard.done() { while !guard.done() {
self.panicked = true; self.panicked = true;
let r = inner.write(guard.remaining()); let r = self.inner.write(guard.remaining());
self.panicked = false; self.panicked = false;
match r { match r {
@ -212,7 +211,7 @@ impl<W: Write> BufWriter<W> {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn get_ref(&self) -> &W { pub fn get_ref(&self) -> &W {
self.inner.as_ref().unwrap() &self.inner
} }
/// Gets a mutable reference to the underlying writer. /// Gets a mutable reference to the underlying writer.
@ -232,7 +231,7 @@ impl<W: Write> BufWriter<W> {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self) -> &mut W { pub fn get_mut(&mut self) -> &mut W {
self.inner.as_mut().unwrap() &mut self.inner
} }
/// Returns a reference to the internally buffered data. /// Returns a reference to the internally buffered data.
@ -308,7 +307,7 @@ impl<W: Write> BufWriter<W> {
pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> { pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
match self.flush_buf() { match self.flush_buf() {
Err(e) => Err(IntoInnerError::new(self, e)), Err(e) => Err(IntoInnerError::new(self, e)),
Ok(()) => Ok(self.inner.take().unwrap()), Ok(()) => Ok(self.into_raw_parts().0),
} }
} }
@ -339,7 +338,12 @@ impl<W: Write> BufWriter<W> {
pub fn into_raw_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) { pub fn into_raw_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
let buf = mem::take(&mut self.buf); let buf = mem::take(&mut self.buf);
let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) }; let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
(self.inner.take().unwrap(), buf)
// SAFETY: forget(self) prevents double dropping inner
let inner = unsafe { ptr::read(&mut self.inner) };
mem::forget(self);
(inner, buf)
} }
// Ensure this function does not get inlined into `write`, so that it // Ensure this function does not get inlined into `write`, so that it
@ -643,7 +647,7 @@ where
{ {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("BufWriter") fmt.debug_struct("BufWriter")
.field("writer", &self.inner.as_ref().unwrap()) .field("writer", &self.inner)
.field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity())) .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
.finish() .finish()
} }
@ -663,7 +667,7 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write> Drop for BufWriter<W> { impl<W: Write> Drop for BufWriter<W> {
fn drop(&mut self) { fn drop(&mut self) {
if self.inner.is_some() && !self.panicked { if !self.panicked {
// dtors should not panic, so we ignore a failed flush // dtors should not panic, so we ignore a failed flush
let _r = self.flush_buf(); let _r = self.flush_buf();
} }

View file

@ -133,7 +133,6 @@ impl<W> IntoInnerError<W> {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// #![feature(io_into_inner_error_parts)]
/// use std::io::{BufWriter, ErrorKind, Write}; /// use std::io::{BufWriter, ErrorKind, Write};
/// ///
/// let mut not_enough_space = [0u8; 10]; /// let mut not_enough_space = [0u8; 10];
@ -143,7 +142,7 @@ impl<W> IntoInnerError<W> {
/// let err = into_inner_err.into_error(); /// let err = into_inner_err.into_error();
/// assert_eq!(err.kind(), ErrorKind::WriteZero); /// assert_eq!(err.kind(), ErrorKind::WriteZero);
/// ``` /// ```
#[unstable(feature = "io_into_inner_error_parts", issue = "79704")] #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
pub fn into_error(self) -> Error { pub fn into_error(self) -> Error {
self.1 self.1
} }
@ -156,7 +155,6 @@ impl<W> IntoInnerError<W> {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// #![feature(io_into_inner_error_parts)]
/// use std::io::{BufWriter, ErrorKind, Write}; /// use std::io::{BufWriter, ErrorKind, Write};
/// ///
/// let mut not_enough_space = [0u8; 10]; /// let mut not_enough_space = [0u8; 10];
@ -167,7 +165,7 @@ impl<W> IntoInnerError<W> {
/// assert_eq!(err.kind(), ErrorKind::WriteZero); /// assert_eq!(err.kind(), ErrorKind::WriteZero);
/// assert_eq!(recovered_writer.buffer(), b"t be actually written"); /// assert_eq!(recovered_writer.buffer(), b"t be actually written");
/// ``` /// ```
#[unstable(feature = "io_into_inner_error_parts", issue = "79704")] #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
pub fn into_parts(self) -> (Error, W) { pub fn into_parts(self) -> (Error, W) {
(self.1, self.0) (self.1, self.0)
} }

View file

@ -3,7 +3,7 @@
//! //!
//! This module contains some of the real meat in the rustbuild build system //! This module contains some of the real meat in the rustbuild build system
//! which is where Cargo is used to compile the standard library, libtest, and //! which is where Cargo is used to compile the standard library, libtest, and
//! compiler. This module is also responsible for assembling the sysroot as it //! the compiler. This module is also responsible for assembling the sysroot as it
//! goes along from the output of the previous stage. //! goes along from the output of the previous stage.
use std::borrow::Cow; use std::borrow::Cow;

View file

@ -13,6 +13,7 @@ use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use crate::cache::{Interned, INTERNER}; use crate::cache::{Interned, INTERNER};
use crate::channel::GitInfo;
pub use crate::flags::Subcommand; pub use crate::flags::Subcommand;
use crate::flags::{Color, Flags}; use crate::flags::{Color, Flags};
use crate::util::exe; use crate::util::exe;
@ -48,7 +49,7 @@ pub struct Config {
/// Call Build::ninja() instead of this. /// Call Build::ninja() instead of this.
pub ninja_in_file: bool, pub ninja_in_file: bool,
pub verbose: usize, pub verbose: usize,
pub submodules: bool, pub submodules: Option<bool>,
pub fast_submodules: bool, pub fast_submodules: bool,
pub compiler_docs: bool, pub compiler_docs: bool,
pub docs_minification: bool, pub docs_minification: bool,
@ -552,7 +553,7 @@ impl Config {
config.backtrace = true; config.backtrace = true;
config.rust_optimize = true; config.rust_optimize = true;
config.rust_optimize_tests = true; config.rust_optimize_tests = true;
config.submodules = true; config.submodules = None;
config.fast_submodules = true; config.fast_submodules = true;
config.docs = true; config.docs = true;
config.docs_minification = true; config.docs_minification = true;
@ -658,11 +659,11 @@ impl Config {
config.npm = build.npm.map(PathBuf::from); config.npm = build.npm.map(PathBuf::from);
config.gdb = build.gdb.map(PathBuf::from); config.gdb = build.gdb.map(PathBuf::from);
config.python = build.python.map(PathBuf::from); config.python = build.python.map(PathBuf::from);
config.submodules = build.submodules;
set(&mut config.low_priority, build.low_priority); set(&mut config.low_priority, build.low_priority);
set(&mut config.compiler_docs, build.compiler_docs); set(&mut config.compiler_docs, build.compiler_docs);
set(&mut config.docs_minification, build.docs_minification); set(&mut config.docs_minification, build.docs_minification);
set(&mut config.docs, build.docs); set(&mut config.docs, build.docs);
set(&mut config.submodules, build.submodules);
set(&mut config.fast_submodules, build.fast_submodules); set(&mut config.fast_submodules, build.fast_submodules);
set(&mut config.locked_deps, build.locked_deps); set(&mut config.locked_deps, build.locked_deps);
set(&mut config.vendor, build.vendor); set(&mut config.vendor, build.vendor);
@ -792,8 +793,16 @@ impl Config {
// CI-built LLVM can be either dynamic or static. // CI-built LLVM can be either dynamic or static.
let ci_llvm = config.out.join(&*config.build.triple).join("ci-llvm"); let ci_llvm = config.out.join(&*config.build.triple).join("ci-llvm");
let link_type = t!(std::fs::read_to_string(ci_llvm.join("link-type.txt"))); config.llvm_link_shared = if config.dry_run {
config.llvm_link_shared = link_type == "dynamic"; // just assume dynamic for now
true
} else {
let link_type = t!(
std::fs::read_to_string(ci_llvm.join("link-type.txt")),
format!("CI llvm missing: {}", ci_llvm.display())
);
link_type == "dynamic"
};
} }
if config.llvm_thin_lto { if config.llvm_thin_lto {
@ -1075,6 +1084,10 @@ impl Config {
pub fn llvm_enabled(&self) -> bool { pub fn llvm_enabled(&self) -> bool {
self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
} }
pub fn submodules(&self, rust_info: &GitInfo) -> bool {
self.submodules.unwrap_or(rust_info.is_git())
}
} }
fn set<T>(field: &mut T, val: Option<T>) { fn set<T>(field: &mut T, val: Option<T>) {

View file

@ -160,6 +160,7 @@ o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of tw
o("extended", "build.extended", "build an extended rust tool set") o("extended", "build.extended", "build an extended rust tool set")
v("tools", None, "List of extended tools will be installed") v("tools", None, "List of extended tools will be installed")
v("codegen-backends", None, "List of codegen backends to build")
v("build", "build.build", "GNUs ./configure syntax LLVM build triple") v("build", "build.build", "GNUs ./configure syntax LLVM build triple")
v("host", None, "GNUs ./configure syntax LLVM host triples") v("host", None, "GNUs ./configure syntax LLVM host triples")
v("target", None, "GNUs ./configure syntax LLVM target triples") v("target", None, "GNUs ./configure syntax LLVM target triples")
@ -339,6 +340,8 @@ for key in known_args:
set('target.{}.llvm-filecheck'.format(build()), value) set('target.{}.llvm-filecheck'.format(build()), value)
elif option.name == 'tools': elif option.name == 'tools':
set('build.tools', value.split(',')) set('build.tools', value.split(','))
elif option.name == 'codegen-backends':
set('rust.codegen-backends', value.split(','))
elif option.name == 'host': elif option.name == 'host':
set('build.host', value.split(',')) set('build.host', value.split(','))
elif option.name == 'target': elif option.name == 'target':

View file

@ -1955,8 +1955,16 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir
cmd.arg("--libfiles"); cmd.arg("--libfiles");
builder.verbose(&format!("running {:?}", cmd)); builder.verbose(&format!("running {:?}", cmd));
let files = output(&mut cmd); let files = output(&mut cmd);
let build_llvm_out = &builder.llvm_out(builder.config.build);
let target_llvm_out = &builder.llvm_out(target);
for file in files.trim_end().split(' ') { for file in files.trim_end().split(' ') {
builder.install(Path::new(file), dst_libdir, 0o644); // If we're not using a custom LLVM, make sure we package for the target.
let file = if let Ok(relative_path) = Path::new(file).strip_prefix(build_llvm_out) {
target_llvm_out.join(relative_path)
} else {
PathBuf::from(file)
};
builder.install(&file, dst_libdir, 0o644);
} }
!builder.config.dry_run !builder.config.dry_run
} else { } else {

View file

@ -103,12 +103,20 @@ pub unsafe fn setup(build: &mut Build) {
}; };
let parent = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid.parse().unwrap()); let parent = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid.parse().unwrap());
assert!(
!parent.is_null(), // If we get a null parent pointer here, it is possible that either
"PID `{}` doesn't seem to exist: {}", // we have got an invalid pid or the parent process has been closed.
pid, // Since the first case rarely happens
io::Error::last_os_error() // (only when wrongly setting the environmental variable),
); // so it might be better to improve the experience of the second case
// when users have interrupted the parent process and we don't finish
// duplicating the handle yet.
// We just need close the job object if that occurs.
if parent.is_null() {
CloseHandle(job);
return;
}
let mut parent_handle = ptr::null_mut(); let mut parent_handle = ptr::null_mut();
let r = DuplicateHandle( let r = DuplicateHandle(
GetCurrentProcess(), GetCurrentProcess(),

View file

@ -486,7 +486,7 @@ impl Build {
t!(std::fs::read_dir(dir)).next().is_none() t!(std::fs::read_dir(dir)).next().is_none()
} }
if !self.config.submodules { if !self.config.submodules(&self.rust_info) {
return; return;
} }
@ -562,7 +562,7 @@ impl Build {
"library/stdarch", "library/stdarch",
]; ];
// Avoid running git when there isn't a git checkout. // Avoid running git when there isn't a git checkout.
if !self.config.submodules { if !self.config.submodules(&self.rust_info) {
return; return;
} }
let output = output( let output = output(

View file

@ -0,0 +1,4 @@
// This test checks that the correct font is used on module items (in index.html pages).
goto: file://|DOC_PATH|/test_docs/index.html
assert-css: (".item-table .module-item a", {"font-family": '"Fira Sans", Arial, sans-serif'}, ALL)
assert-css: (".item-table .docblock-short", {"font-family": '"Source Serif 4", "Noto Sans KR", serif'}, ALL)

View file

@ -0,0 +1,25 @@
// edition:2018
use ::core::pin::Pin;
use ::core::future::Future;
use ::core::marker::Send;
trait Foo {
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'me: 'async_trait;
}
impl Foo for () {
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'me:'async_trait {
Box::pin( //~ ERROR future cannot be sent between threads safely
async move {
let x = x;
}
)
}
}
fn main() { }

View file

@ -0,0 +1,23 @@
error: future cannot be sent between threads safely
--> $DIR/issue-86507.rs:17:13
|
LL | / Box::pin(
LL | | async move {
LL | | let x = x;
LL | | }
LL | | )
| |_____________^ future created by async block is not `Send`
|
note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
--> $DIR/issue-86507.rs:19:29
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
= note: required for the cast to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting type parameter `T`
|
LL | where 'me:'async_trait, T: std::marker::Sync {
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View file

@ -0,0 +1,20 @@
// build-pass
#![feature(const_generics)]
#![allow(incomplete_features)]
#[derive(PartialEq, Eq)]
pub struct UnitDims {
pub time: u8,
pub length: u8,
}
pub struct UnitValue<const DIMS: UnitDims>;
impl<const DIMS: UnitDims> UnitValue<DIMS> {
fn crash() {}
}
fn main() {
UnitValue::<{ UnitDims { time: 1, length: 2 } }>::crash();
}

View file

@ -55,11 +55,11 @@ note: captured value is not `Send`
LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool { LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
| ^^ has type `std::rc::Rc<[u8]>` which is not `Send` | ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
note: captured value is not `Send` note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
--> $DIR/future_not_send.rs:20:40 --> $DIR/future_not_send.rs:20:40
| |
LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool { LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
| ^^^^ has type `&std::cell::Cell<usize>` which is not `Send` | ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
= note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync` = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
error: future cannot be sent between threads safely error: future cannot be sent between threads safely