Skip to content

Commit

Permalink
Auto merge of #76265 - Dylan-DPC:rollup-j3i509l, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 12 pull requests

Successful merges:

 - #75150 (Add a note for Ipv4Addr::to_ipv6_compatible)
 - #76120 (Add `[T; N]::as_[mut_]slice`)
 - #76142 (Make all methods of `std::net::Ipv4Addr` const)
 - #76164 (Link to slice pattern in array docs)
 - #76167 (Replace MinGW library hack with heuristic controlling link mode)
 - #76204 (Rename and expose LoopState as ControlFlow)
 - #76238 (Move to intra-doc links for library/core/src/iter/traits/iterator.rs)
 - #76242 (Read: adjust a FIXME reference)
 - #76243 (Fix typos in vec try_reserve(_exact) docs)
 - #76245 (inliner: Avoid query cycles when optimizing generators)
 - #76255 (Update books)
 - #76261 (Use intra-doc links in `core::marker`)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Sep 3, 2020
2 parents 51f79b6 + af331a2 commit 4f66117
Show file tree
Hide file tree
Showing 25 changed files with 365 additions and 304 deletions.
117 changes: 25 additions & 92 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,86 +1014,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
}
}

// Because windows-gnu target is meant to be self-contained for pure Rust code it bundles
// own mingw-w64 libraries. These libraries are usually not compatible with mingw-w64
// installed in the system. This breaks many cases where Rust is mixed with other languages
// (e.g. *-sys crates).
// We prefer system mingw-w64 libraries if they are available to avoid this issue.
fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
fn find_exe_in_path<P>(exe_name: P) -> Option<PathBuf>
where
P: AsRef<Path>,
{
for dir in env::split_paths(&env::var_os("PATH")?) {
let full_path = dir.join(&exe_name);
if full_path.is_file() {
return Some(fix_windows_verbatim_for_gcc(&full_path));
}
}
None
}

fn probe(sess: &Session) -> Option<PathBuf> {
if let (linker, LinkerFlavor::Gcc) = linker_and_flavor(&sess) {
let linker_path = if cfg!(windows) && linker.extension().is_none() {
linker.with_extension("exe")
} else {
linker
};
if let Some(linker_path) = find_exe_in_path(linker_path) {
let mingw_arch = match &sess.target.target.arch {
x if x == "x86" => "i686",
x => x,
};
let mingw_bits = &sess.target.target.target_pointer_width;
let mingw_dir = format!("{}-w64-mingw32", mingw_arch);
// Here we have path/bin/gcc but we need path/
let mut path = linker_path;
path.pop();
path.pop();
// Loosely based on Clang MinGW driver
let probe_paths = vec![
path.join(&mingw_dir).join("lib"), // Typical path
path.join(&mingw_dir).join("sys-root/mingw/lib"), // Rare path
path.join(format!(
"lib/mingw/tools/install/mingw{}/{}/lib",
&mingw_bits, &mingw_dir
)), // Chocolatey is creative
];
for probe_path in probe_paths {
if probe_path.join("crt2.o").exists() {
return Some(probe_path);
};
}
};
};
None
}

let mut system_library_path = sess.system_library_path.borrow_mut();
match &*system_library_path {
Some(Some(compiler_libs_path)) => Some(compiler_libs_path.clone()),
Some(None) => None,
None => {
let path = probe(sess);
*system_library_path = Some(path.clone());
path
}
}
}

fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf {
// prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details
if sess.opts.cg.link_self_contained.is_none()
&& sess.target.target.llvm_target.contains("windows-gnu")
{
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
let file_path = compiler_libs_path.join(name);
if file_path.exists() {
return file_path;
}
}
}
let fs = sess.target_filesearch(PathKind::Native);
let file_path = fs.get_lib_path().join(name);
if file_path.exists() {
Expand Down Expand Up @@ -1286,6 +1207,28 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
}
}

// Returns true if linker is located within sysroot
fn detect_self_contained_mingw(sess: &Session) -> bool {
let (linker, _) = linker_and_flavor(&sess);
// Assume `-C linker=rust-lld` as self-contained mode
if linker == Path::new("rust-lld") {
return true;
}
let linker_with_extension = if cfg!(windows) && linker.extension().is_none() {
linker.with_extension("exe")
} else {
linker
};
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
let full_path = dir.join(&linker_with_extension);
// If linker comes from sysroot assume self-contained mode
if full_path.is_file() && !full_path.starts_with(&sess.sysroot) {
return false;
}
}
true
}

/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
/// We only provide such support for a very limited number of targets.
fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
Expand All @@ -1298,10 +1241,10 @@ fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
// based on host and linker path, for example.
// (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)),
// FIXME: Find some heuristic for "native mingw toolchain is available",
// likely based on `get_crt_libs_path` (https://github.com/rust-lang/rust/pull/67429).
Some(CrtObjectsFallback::Mingw) => {
sess.host == sess.target.target && sess.target.target.target_vendor != "uwp"
sess.host == sess.target.target
&& sess.target.target.target_vendor != "uwp"
&& detect_self_contained_mingw(&sess)
}
// FIXME: Figure out cases in which WASM needs to link with a native toolchain.
Some(CrtObjectsFallback::Wasm) => true,
Expand Down Expand Up @@ -1498,16 +1441,6 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<'

/// Add sysroot and other globally set directories to the directory search list.
fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: bool) {
// Prefer system mingw-w64 libs, see get_crt_libs_path comment for more details.
if sess.opts.cg.link_self_contained.is_none()
&& cfg!(windows)
&& sess.target.target.llvm_target.contains("windows-gnu")
{
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
cmd.include_path(&compiler_libs_path);
}
}

// The default library location, we need this to find the runtime.
// The location of crates will be determined as needed.
let lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,14 @@ impl Inliner<'tcx> {
// Avoid a cycle here by only using `optimized_mir` only if we have
// a lower `HirId` than the callee. This ensures that the callee will
// not inline us. This trick only works without incremental compilation.
// So don't do it if that is enabled.
if !self.tcx.dep_graph.is_fully_enabled() && self_hir_id < callee_hir_id {
// So don't do it if that is enabled. Also avoid inlining into generators,
// since their `optimized_mir` is used for layout computation, which can
// create a cycle, even when no attempt is made to inline the function
// in the other direction.
if !self.tcx.dep_graph.is_fully_enabled()
&& self_hir_id < callee_hir_id
&& caller_body.generator_kind.is_none()
{
self.tcx.optimized_mir(callsite.callee)
} else {
continue;
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/collections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ impl<T> VecDeque<T> {
}

/// Tries to reserve the minimum capacity for exactly `additional` more elements to
/// be inserted in the given `VecDeque<T>`. After calling `reserve_exact`,
/// be inserted in the given `VecDeque<T>`. After calling `try_reserve_exact`,
/// capacity will be greater than or equal to `self.len() + additional`.
/// Does nothing if the capacity is already sufficient.
///
Expand Down Expand Up @@ -727,7 +727,7 @@ impl<T> VecDeque<T> {

/// Tries to reserve capacity for at least `additional` more elements to be inserted
/// in the given `VecDeque<T>`. The collection may reserve more space to avoid
/// frequent reallocations. After calling `reserve`, capacity will be
/// frequent reallocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional`. Does nothing if
/// capacity is already sufficient.
///
Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ impl<T> Vec<T> {

/// Tries to reserve capacity for at least `additional` more elements to be inserted
/// in the given `Vec<T>`. The collection may reserve more space to avoid
/// frequent reallocations. After calling `reserve`, capacity will be
/// frequent reallocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional`. Does nothing if
/// capacity is already sufficient.
///
Expand Down Expand Up @@ -559,7 +559,7 @@ impl<T> Vec<T> {
}

/// Tries to reserves the minimum capacity for exactly `additional` more elements to
/// be inserted in the given `Vec<T>`. After calling `reserve_exact`,
/// be inserted in the given `Vec<T>`. After calling `try_reserve_exact`,
/// capacity will be greater than or equal to `self.len() + additional`.
/// Does nothing if the capacity is already sufficient.
///
Expand All @@ -582,7 +582,7 @@ impl<T> Vec<T> {
/// let mut output = Vec::new();
///
/// // Pre-reserve the memory, exiting if we can't
/// output.try_reserve(data.len())?;
/// output.try_reserve_exact(data.len())?;
///
/// // Now we know this can't OOM in the middle of our complex work
/// output.extend(data.iter().map(|&val| {
Expand Down
13 changes: 13 additions & 0 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,4 +422,17 @@ impl<T, const N: usize> [T; N] {
// and we just need to cast it to the correct type.
unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) }
}

/// Returns a slice containing the entire array. Equivalent to `&s[..]`.
#[unstable(feature = "array_methods", issue = "76118")]
pub fn as_slice(&self) -> &[T] {
self
}

/// Returns a mutable slice containing the entire array. Equivalent to
/// `&mut s[..]`.
#[unstable(feature = "array_methods", issue = "76118")]
pub fn as_mut_slice(&mut self) -> &mut [T] {
self
}
}
38 changes: 19 additions & 19 deletions library/core/src/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::cmp;
use crate::fmt;
use crate::intrinsics;
use crate::ops::{Add, AddAssign, Try};
use crate::ops::{Add, AddAssign, ControlFlow, Try};

use super::{from_fn, LoopState};
use super::from_fn;
use super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};

mod chain;
Expand Down Expand Up @@ -1164,10 +1164,10 @@ where
#[inline]
fn find<T, B>(
f: &mut impl FnMut(T) -> Option<B>,
) -> impl FnMut((), T) -> LoopState<(), B> + '_ {
) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ {
move |(), x| match f(x) {
Some(x) => LoopState::Break(x),
None => LoopState::Continue(()),
Some(x) => ControlFlow::Break(x),
None => ControlFlow::Continue(()),
}
}

Expand Down Expand Up @@ -1864,13 +1864,13 @@ where
flag: &'a mut bool,
p: &'a mut impl FnMut(&T) -> bool,
mut fold: impl FnMut(Acc, T) -> R + 'a,
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
move |acc, x| {
if p(&x) {
LoopState::from_try(fold(acc, x))
ControlFlow::from_try(fold(acc, x))
} else {
*flag = true;
LoopState::Break(Try::from_ok(acc))
ControlFlow::Break(Try::from_ok(acc))
}
}
}
Expand Down Expand Up @@ -1963,8 +1963,8 @@ where
{
let Self { iter, predicate } = self;
iter.try_fold(init, |acc, x| match predicate(x) {
Some(item) => LoopState::from_try(fold(acc, item)),
None => LoopState::Break(Try::from_ok(acc)),
Some(item) => ControlFlow::from_try(fold(acc, item)),
None => ControlFlow::Break(Try::from_ok(acc)),
})
.into_try()
}
Expand Down Expand Up @@ -2135,11 +2135,11 @@ where
fn check<T, Acc, R: Try<Ok = Acc>>(
mut n: usize,
mut fold: impl FnMut(Acc, T) -> R,
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> {
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> {
move |acc, x| {
n -= 1;
let r = fold(acc, x);
if n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
}
}

Expand Down Expand Up @@ -2246,11 +2246,11 @@ where
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
n: &'a mut usize,
mut fold: impl FnMut(Acc, T) -> R + 'a,
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
move |acc, x| {
*n -= 1;
let r = fold(acc, x);
if *n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) }
if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
}
}

Expand Down Expand Up @@ -2414,10 +2414,10 @@ where
state: &'a mut St,
f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
mut fold: impl FnMut(Acc, B) -> R + 'a,
) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
move |acc, x| match f(state, x) {
None => LoopState::Break(Try::from_ok(acc)),
Some(x) => LoopState::from_try(fold(acc, x)),
None => ControlFlow::Break(Try::from_ok(acc)),
Some(x) => ControlFlow::from_try(fold(acc, x)),
}
}

Expand Down Expand Up @@ -2638,10 +2638,10 @@ where
let error = &mut *self.error;
self.iter
.try_fold(init, |acc, x| match x {
Ok(x) => LoopState::from_try(f(acc, x)),
Ok(x) => ControlFlow::from_try(f(acc, x)),
Err(e) => {
*error = Err(e);
LoopState::Break(Try::from_ok(acc))
ControlFlow::Break(Try::from_ok(acc))
}
})
.into_try()
Expand Down
Loading

0 comments on commit 4f66117

Please sign in to comment.