diff --git a/Cargo.lock b/Cargo.lock
index 26a9e64b85af4..fc8659b2ec0a9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1848,9 +1848,9 @@ dependencies = [
[[package]]
name = "mdbook"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+/~https://github.com/rust-lang/crates.io-index"
-checksum = "b75e31ae4eaa0e45e17ee2b6b9e3ed969c3c6ff12bb4c2e352c42493f4ebb706"
+checksum = "29be448fcafb00c5a8966c4020c2a5ffbbc333e5b96d0bb5ef54b5bd0524d9ff"
dependencies = [
"ammonia",
"anyhow",
diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
index 9d48e233de655..ccd294d92b2f4 100644
--- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
@@ -5,9 +5,9 @@ use rustc_span::Span;
use rustc_target::abi::call::FnAbi;
pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
- /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
- /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
- /// add them to librustc_codegen_llvm/context.rs
+ /// Remember to add all intrinsics here, in `compiler/rustc_typeck/src/check/mod.rs`,
+ /// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics,
+ /// add them to `compiler/rustc_codegen_llvm/src/context.rs`.
fn codegen_intrinsic_call(
&mut self,
instance: ty::Instance<'tcx>,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md
index e289534bf7abd..496174b28efac 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0092.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0092.md
@@ -12,8 +12,8 @@ extern "rust-intrinsic" {
```
Please check you didn't make a mistake in the function's name. All intrinsic
-functions are defined in `librustc_codegen_llvm/intrinsic.rs` and in
-`libcore/intrinsics.rs` in the Rust source code. Example:
+functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
+`library/core/src/intrinsics.rs` in the Rust source code. Example:
```
#![feature(intrinsics)]
diff --git a/compiler/rustc_error_codes/src/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md
index 8e7de1a9d37b3..6d58e50ec8813 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0093.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0093.md
@@ -17,8 +17,8 @@ fn main() {
```
Please check you didn't make a mistake in the function's name. All intrinsic
-functions are defined in `librustc_codegen_llvm/intrinsic.rs` and in
-`libcore/intrinsics.rs` in the Rust source code. Example:
+functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
+`library/core/src/intrinsics.rs` in the Rust source code. Example:
```
#![feature(intrinsics)]
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index a554c80cdaa1a..1dd6d590d908f 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -28,7 +28,6 @@ pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, Selecti
pub type CanonicalChalkEnvironmentAndGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
-pub use self::ImplSource::*;
pub use self::ObligationCauseCode::*;
pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner};
@@ -418,10 +417,10 @@ pub type SelectionResult<'tcx, T> = Result, SelectionError<'tcx>>;
///
/// // Case B: ImplSource must be provided by caller. This applies when
/// // type is a type parameter.
-/// param.clone(); // ImplSourceParam
+/// param.clone(); // ImplSource::Param
///
/// // Case C: A mix of cases A and B.
-/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam])
+/// mixed.clone(); // ImplSource(Impl_1, [ImplSource::Param])
/// }
/// ```
///
@@ -431,72 +430,72 @@ pub type SelectionResult<'tcx, T> = Result , SelectionError<'tcx>>;
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
pub enum ImplSource<'tcx, N> {
/// ImplSource identifying a particular impl.
- ImplSourceUserDefined(ImplSourceUserDefinedData<'tcx, N>),
+ UserDefined(ImplSourceUserDefinedData<'tcx, N>),
/// ImplSource for auto trait implementations.
/// This carries the information and nested obligations with regards
/// to an auto implementation for a trait `Trait`. The nested obligations
/// ensure the trait implementation holds for all the constituent types.
- ImplSourceAutoImpl(ImplSourceAutoImplData),
+ AutoImpl(ImplSourceAutoImplData),
/// Successful resolution to an obligation provided by the caller
/// for some type parameter. The `Vec` represents the
/// obligations incurred from normalizing the where-clause (if
/// any).
- ImplSourceParam(Vec),
+ Param(Vec),
/// Virtual calls through an object.
- ImplSourceObject(ImplSourceObjectData<'tcx, N>),
+ Object(ImplSourceObjectData<'tcx, N>),
/// Successful resolution for a builtin trait.
- ImplSourceBuiltin(ImplSourceBuiltinData),
+ Builtin(ImplSourceBuiltinData),
/// ImplSource automatically generated for a closure. The `DefId` is the ID
- /// of the closure expression. This is a `ImplSourceUserDefined` in spirit, but the
+ /// of the closure expression. This is a `ImplSource::UserDefined` in spirit, but the
/// impl is generated by the compiler and does not appear in the source.
- ImplSourceClosure(ImplSourceClosureData<'tcx, N>),
+ Closure(ImplSourceClosureData<'tcx, N>),
/// Same as above, but for a function pointer type with the given signature.
- ImplSourceFnPointer(ImplSourceFnPointerData<'tcx, N>),
+ FnPointer(ImplSourceFnPointerData<'tcx, N>),
/// ImplSource for a builtin `DeterminantKind` trait implementation.
- ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData),
+ DiscriminantKind(ImplSourceDiscriminantKindData),
/// ImplSource automatically generated for a generator.
- ImplSourceGenerator(ImplSourceGeneratorData<'tcx, N>),
+ Generator(ImplSourceGeneratorData<'tcx, N>),
/// ImplSource for a trait alias.
- ImplSourceTraitAlias(ImplSourceTraitAliasData<'tcx, N>),
+ TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
}
impl<'tcx, N> ImplSource<'tcx, N> {
pub fn nested_obligations(self) -> Vec {
match self {
- ImplSourceUserDefined(i) => i.nested,
- ImplSourceParam(n) => n,
- ImplSourceBuiltin(i) => i.nested,
- ImplSourceAutoImpl(d) => d.nested,
- ImplSourceClosure(c) => c.nested,
- ImplSourceGenerator(c) => c.nested,
- ImplSourceObject(d) => d.nested,
- ImplSourceFnPointer(d) => d.nested,
- ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => Vec::new(),
- ImplSourceTraitAlias(d) => d.nested,
+ ImplSource::UserDefined(i) => i.nested,
+ ImplSource::Param(n) => n,
+ ImplSource::Builtin(i) => i.nested,
+ ImplSource::AutoImpl(d) => d.nested,
+ ImplSource::Closure(c) => c.nested,
+ ImplSource::Generator(c) => c.nested,
+ ImplSource::Object(d) => d.nested,
+ ImplSource::FnPointer(d) => d.nested,
+ ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => Vec::new(),
+ ImplSource::TraitAlias(d) => d.nested,
}
}
pub fn borrow_nested_obligations(&self) -> &[N] {
match &self {
- ImplSourceUserDefined(i) => &i.nested[..],
- ImplSourceParam(n) => &n[..],
- ImplSourceBuiltin(i) => &i.nested[..],
- ImplSourceAutoImpl(d) => &d.nested[..],
- ImplSourceClosure(c) => &c.nested[..],
- ImplSourceGenerator(c) => &c.nested[..],
- ImplSourceObject(d) => &d.nested[..],
- ImplSourceFnPointer(d) => &d.nested[..],
- ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => &[],
- ImplSourceTraitAlias(d) => &d.nested[..],
+ ImplSource::UserDefined(i) => &i.nested[..],
+ ImplSource::Param(n) => &n[..],
+ ImplSource::Builtin(i) => &i.nested[..],
+ ImplSource::AutoImpl(d) => &d.nested[..],
+ ImplSource::Closure(c) => &c.nested[..],
+ ImplSource::Generator(c) => &c.nested[..],
+ ImplSource::Object(d) => &d.nested[..],
+ ImplSource::FnPointer(d) => &d.nested[..],
+ ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => &[],
+ ImplSource::TraitAlias(d) => &d.nested[..],
}
}
@@ -505,42 +504,42 @@ impl<'tcx, N> ImplSource<'tcx, N> {
F: FnMut(N) -> M,
{
match self {
- ImplSourceUserDefined(i) => ImplSourceUserDefined(ImplSourceUserDefinedData {
+ ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData {
impl_def_id: i.impl_def_id,
substs: i.substs,
nested: i.nested.into_iter().map(f).collect(),
}),
- ImplSourceParam(n) => ImplSourceParam(n.into_iter().map(f).collect()),
- ImplSourceBuiltin(i) => ImplSourceBuiltin(ImplSourceBuiltinData {
+ ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()),
+ ImplSource::Builtin(i) => ImplSource::Builtin(ImplSourceBuiltinData {
nested: i.nested.into_iter().map(f).collect(),
}),
- ImplSourceObject(o) => ImplSourceObject(ImplSourceObjectData {
+ ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
upcast_trait_ref: o.upcast_trait_ref,
vtable_base: o.vtable_base,
nested: o.nested.into_iter().map(f).collect(),
}),
- ImplSourceAutoImpl(d) => ImplSourceAutoImpl(ImplSourceAutoImplData {
+ ImplSource::AutoImpl(d) => ImplSource::AutoImpl(ImplSourceAutoImplData {
trait_def_id: d.trait_def_id,
nested: d.nested.into_iter().map(f).collect(),
}),
- ImplSourceClosure(c) => ImplSourceClosure(ImplSourceClosureData {
+ ImplSource::Closure(c) => ImplSource::Closure(ImplSourceClosureData {
closure_def_id: c.closure_def_id,
substs: c.substs,
nested: c.nested.into_iter().map(f).collect(),
}),
- ImplSourceGenerator(c) => ImplSourceGenerator(ImplSourceGeneratorData {
+ ImplSource::Generator(c) => ImplSource::Generator(ImplSourceGeneratorData {
generator_def_id: c.generator_def_id,
substs: c.substs,
nested: c.nested.into_iter().map(f).collect(),
}),
- ImplSourceFnPointer(p) => ImplSourceFnPointer(ImplSourceFnPointerData {
+ ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData {
fn_ty: p.fn_ty,
nested: p.nested.into_iter().map(f).collect(),
}),
- ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => {
- ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData)
+ ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => {
+ ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
}
- ImplSourceTraitAlias(d) => ImplSourceTraitAlias(ImplSourceTraitAliasData {
+ ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
alias_def_id: d.alias_def_id,
substs: d.substs,
nested: d.nested.into_iter().map(f).collect(),
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index d73fc628ceb70..b8f6675b8e219 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -7,25 +7,25 @@ use std::fmt;
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
- super::ImplSourceUserDefined(ref v) => write!(f, "{:?}", v),
+ super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v),
- super::ImplSourceAutoImpl(ref t) => write!(f, "{:?}", t),
+ super::ImplSource::AutoImpl(ref t) => write!(f, "{:?}", t),
- super::ImplSourceClosure(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::Closure(ref d) => write!(f, "{:?}", d),
- super::ImplSourceGenerator(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::Generator(ref d) => write!(f, "{:?}", d),
- super::ImplSourceFnPointer(ref d) => write!(f, "ImplSourceFnPointer({:?})", d),
+ super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
- super::ImplSourceDiscriminantKind(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::DiscriminantKind(ref d) => write!(f, "{:?}", d),
- super::ImplSourceObject(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
- super::ImplSourceParam(ref n) => write!(f, "ImplSourceParam({:?})", n),
+ super::ImplSource::Param(ref n) => write!(f, "ImplSourceParamData({:?})", n),
- super::ImplSourceBuiltin(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
- super::ImplSourceTraitAlias(ref d) => write!(f, "{:?}", d),
+ super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),
}
}
}
@@ -96,7 +96,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx,
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
- "ImplSourceTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})",
+ "ImplSourceTraitAliasData(alias_def_id={:?}, substs={:?}, nested={:?})",
self.alias_def_id, self.substs, self.nested
)
}
diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs
index 0664f25e409dc..d3b6d706337ed 100644
--- a/compiler/rustc_mir/src/interpret/intrinsics.rs
+++ b/compiler/rustc_mir/src/interpret/intrinsics.rs
@@ -435,6 +435,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// These just return their argument
self.copy_op(args[0], dest)?;
}
+ sym::assume => {
+ let cond = self.read_scalar(args[0])?.check_init()?.to_bool()?;
+ if !cond {
+ throw_ub_format!("`assume` intrinsic called with `false`");
+ }
+ }
_ => return Ok(false),
}
diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs
index b789cb76e9f85..9f200ca62b8c6 100644
--- a/compiler/rustc_mir/src/interpret/terminator.rs
+++ b/compiler/rustc_mir/src/interpret/terminator.rs
@@ -390,9 +390,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::InstanceDef::Virtual(_, idx) => {
let mut args = args.to_vec();
// We have to implement all "object safe receivers". Currently we
- // support built-in pointers (&, &mut, Box) as well as unsized-self. We do
+ // support built-in pointers `(&, &mut, Box)` as well as unsized-self. We do
// not yet support custom self types.
- // Also see librustc_codegen_llvm/abi.rs and librustc_codegen_llvm/mir/block.rs.
+ // Also see `compiler/rustc_codegen_llvm/src/abi.rs` and `compiler/rustc_codegen_ssa/src/mir/block.rs`.
let receiver_place = match args[0].layout.ty.builtin_deref(true) {
Some(_) => {
// Built-in pointer.
diff --git a/compiler/rustc_mir/src/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs
index edafa00a03ad0..d2586f0f84dff 100644
--- a/compiler/rustc_mir/src/monomorphize/mod.rs
+++ b/compiler/rustc_mir/src/monomorphize/mod.rs
@@ -21,7 +21,7 @@ pub fn custom_coerce_unsize_info<'tcx>(
});
match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
- Ok(traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData {
+ Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
impl_def_id,
..
})) => tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap(),
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 6b87bc4f34ad4..35bfeff10b4aa 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -96,7 +96,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
));
match result {
- Ok(Some(ImplSource::ImplSourceUserDefined(_))) => {
+ Ok(Some(ImplSource::UserDefined(_))) => {
debug!(
"find_auto_trait_generics({:?}): \
manual impl found, bailing out",
@@ -315,9 +315,8 @@ impl AutoTraitFinder<'tcx> {
// If we see an explicit negative impl (e.g., `impl !Send for MyStruct`),
// we immediately bail out, since it's impossible for us to continue.
- if let ImplSource::ImplSourceUserDefined(ImplSourceUserDefinedData {
- impl_def_id,
- ..
+ if let ImplSource::UserDefined(ImplSourceUserDefinedData {
+ impl_def_id, ..
}) = impl_source
{
// Blame 'tidy' for the weird bracket placement.
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index d37f819f376d3..ef8f7b69b5d60 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1000,15 +1000,15 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
};
let eligible = match &impl_source {
- super::ImplSourceClosure(_)
- | super::ImplSourceGenerator(_)
- | super::ImplSourceFnPointer(_)
- | super::ImplSourceObject(_)
- | super::ImplSourceTraitAlias(_) => {
+ super::ImplSource::Closure(_)
+ | super::ImplSource::Generator(_)
+ | super::ImplSource::FnPointer(_)
+ | super::ImplSource::Object(_)
+ | super::ImplSource::TraitAlias(_) => {
debug!("assemble_candidates_from_impls: impl_source={:?}", impl_source);
true
}
- super::ImplSourceUserDefined(impl_data) => {
+ super::ImplSource::UserDefined(impl_data) => {
// We have to be careful when projecting out of an
// impl because of specialization. If we are not in
// codegen (i.e., projection mode is not "any"), and the
@@ -1060,7 +1060,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
}
}
}
- super::ImplSourceDiscriminantKind(..) => {
+ super::ImplSource::DiscriminantKind(..) => {
// While `DiscriminantKind` is automatically implemented for every type,
// the concrete discriminant may not be known yet.
//
@@ -1100,7 +1100,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Error(_) => false,
}
}
- super::ImplSourceParam(..) => {
+ super::ImplSource::Param(..) => {
// This case tell us nothing about the value of an
// associated type. Consider:
//
@@ -1128,7 +1128,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// in `assemble_candidates_from_param_env`.
false
}
- super::ImplSourceAutoImpl(..) | super::ImplSourceBuiltin(..) => {
+ super::ImplSource::AutoImpl(..) | super::ImplSource::Builtin(..) => {
// These traits have no associated types.
selcx.tcx().sess.delay_span_bug(
obligation.cause.span,
@@ -1186,20 +1186,20 @@ fn confirm_select_candidate<'cx, 'tcx>(
impl_source: Selection<'tcx>,
) -> Progress<'tcx> {
match impl_source {
- super::ImplSourceUserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
- super::ImplSourceGenerator(data) => confirm_generator_candidate(selcx, obligation, data),
- super::ImplSourceClosure(data) => confirm_closure_candidate(selcx, obligation, data),
- super::ImplSourceFnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
- super::ImplSourceDiscriminantKind(data) => {
+ super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
+ super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data),
+ super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
+ super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
+ super::ImplSource::DiscriminantKind(data) => {
confirm_discriminant_kind_candidate(selcx, obligation, data)
}
- super::ImplSourceObject(_) => {
+ super::ImplSource::Object(_) => {
confirm_object_candidate(selcx, obligation, obligation_trait_ref)
}
- super::ImplSourceAutoImpl(..)
- | super::ImplSourceParam(..)
- | super::ImplSourceBuiltin(..)
- | super::ImplSourceTraitAlias(..) =>
+ super::ImplSource::AutoImpl(..)
+ | super::ImplSource::Param(..)
+ | super::ImplSource::Builtin(..)
+ | super::ImplSource::TraitAlias(..) =>
// we don't create Select candidates with this kind of resolution
{
span_bug!(
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 9906c1f325f3d..88b656ce68082 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -19,16 +19,12 @@ use crate::traits::project::{self, normalize_with_depth};
use crate::traits::select::TraitObligationExt;
use crate::traits::util;
use crate::traits::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
+use crate::traits::ImplSource;
use crate::traits::Normalized;
use crate::traits::OutputTypeParameterMismatch;
use crate::traits::Selection;
use crate::traits::TraitNotObjectSafe;
use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
-use crate::traits::{
- ImplSourceAutoImpl, ImplSourceBuiltin, ImplSourceClosure, ImplSourceDiscriminantKind,
- ImplSourceFnPointer, ImplSourceGenerator, ImplSourceObject, ImplSourceParam,
- ImplSourceTraitAlias, ImplSourceUserDefined,
-};
use crate::traits::{
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
ImplSourceDiscriminantKindData, ImplSourceFnPointerData, ImplSourceGeneratorData,
@@ -55,67 +51,67 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
match candidate {
BuiltinCandidate { has_nested } => {
let data = self.confirm_builtin_candidate(obligation, has_nested);
- Ok(ImplSourceBuiltin(data))
+ Ok(ImplSource::Builtin(data))
}
ParamCandidate(param) => {
let obligations = self.confirm_param_candidate(obligation, param);
- Ok(ImplSourceParam(obligations))
+ Ok(ImplSource::Param(obligations))
}
ImplCandidate(impl_def_id) => {
- Ok(ImplSourceUserDefined(self.confirm_impl_candidate(obligation, impl_def_id)))
+ Ok(ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id)))
}
AutoImplCandidate(trait_def_id) => {
let data = self.confirm_auto_impl_candidate(obligation, trait_def_id);
- Ok(ImplSourceAutoImpl(data))
+ Ok(ImplSource::AutoImpl(data))
}
ProjectionCandidate => {
self.confirm_projection_candidate(obligation);
- Ok(ImplSourceParam(Vec::new()))
+ Ok(ImplSource::Param(Vec::new()))
}
ClosureCandidate => {
let vtable_closure = self.confirm_closure_candidate(obligation)?;
- Ok(ImplSourceClosure(vtable_closure))
+ Ok(ImplSource::Closure(vtable_closure))
}
GeneratorCandidate => {
let vtable_generator = self.confirm_generator_candidate(obligation)?;
- Ok(ImplSourceGenerator(vtable_generator))
+ Ok(ImplSource::Generator(vtable_generator))
}
FnPointerCandidate => {
let data = self.confirm_fn_pointer_candidate(obligation)?;
- Ok(ImplSourceFnPointer(data))
+ Ok(ImplSource::FnPointer(data))
}
DiscriminantKindCandidate => {
- Ok(ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData))
+ Ok(ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData))
}
TraitAliasCandidate(alias_def_id) => {
let data = self.confirm_trait_alias_candidate(obligation, alias_def_id);
- Ok(ImplSourceTraitAlias(data))
+ Ok(ImplSource::TraitAlias(data))
}
ObjectCandidate => {
let data = self.confirm_object_candidate(obligation);
- Ok(ImplSourceObject(data))
+ Ok(ImplSource::Object(data))
}
BuiltinObjectCandidate => {
// This indicates something like `Trait + Send: Send`. In this case, we know that
// this holds because that's what the object type is telling us, and there's really
// no additional obligations to prove and no types in particular to unify, etc.
- Ok(ImplSourceParam(Vec::new()))
+ Ok(ImplSource::Param(Vec::new()))
}
BuiltinUnsizeCandidate => {
let data = self.confirm_builtin_unsize_candidate(obligation)?;
- Ok(ImplSourceBuiltin(data))
+ Ok(ImplSource::Builtin(data))
}
}
}
diff --git a/compiler/rustc_ty/src/instance.rs b/compiler/rustc_ty/src/instance.rs
index 75bf8ea0bb816..220f4cec742f1 100644
--- a/compiler/rustc_ty/src/instance.rs
+++ b/compiler/rustc_ty/src/instance.rs
@@ -119,9 +119,9 @@ fn resolve_associated_item<'tcx>(
// Now that we know which impl is being used, we can dispatch to
// the actual function:
Ok(match vtbl {
- traits::ImplSourceUserDefined(impl_data) => {
+ traits::ImplSource::UserDefined(impl_data) => {
debug!(
- "resolving ImplSourceUserDefined: {:?}, {:?}, {:?}, {:?}",
+ "resolving ImplSource::UserDefined: {:?}, {:?}, {:?}, {:?}",
param_env, trait_item, rcvr_substs, impl_data
);
assert!(!rcvr_substs.needs_infer());
@@ -216,13 +216,13 @@ fn resolve_associated_item<'tcx>(
Some(ty::Instance::new(leaf_def.item.def_id, substs))
}
- traits::ImplSourceGenerator(generator_data) => Some(Instance {
+ traits::ImplSource::Generator(generator_data) => Some(Instance {
def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
generator_data.generator_def_id,
)),
substs: generator_data.substs,
}),
- traits::ImplSourceClosure(closure_data) => {
+ traits::ImplSource::Closure(closure_data) => {
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
Some(Instance::resolve_closure(
tcx,
@@ -231,18 +231,18 @@ fn resolve_associated_item<'tcx>(
trait_closure_kind,
))
}
- traits::ImplSourceFnPointer(ref data) => match data.fn_ty.kind() {
+ traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
substs: rcvr_substs,
}),
_ => None,
},
- traits::ImplSourceObject(ref data) => {
+ traits::ImplSource::Object(ref data) => {
let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
}
- traits::ImplSourceBuiltin(..) => {
+ traits::ImplSource::Builtin(..) => {
if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() {
// FIXME(eddyb) use lang items for methods instead of names.
let name = tcx.item_name(def_id);
@@ -271,10 +271,10 @@ fn resolve_associated_item<'tcx>(
None
}
}
- traits::ImplSourceAutoImpl(..)
- | traits::ImplSourceParam(..)
- | traits::ImplSourceTraitAlias(..)
- | traits::ImplSourceDiscriminantKind(..) => None,
+ traits::ImplSource::AutoImpl(..)
+ | traits::ImplSource::Param(..)
+ | traits::ImplSource::TraitAlias(..)
+ | traits::ImplSource::DiscriminantKind(..) => None,
})
}
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index b8230f524446a..2ee867c2dd648 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -106,8 +106,8 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
}
}
-/// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs,
-/// and in libcore/intrinsics.rs
+/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
+/// and in `library/core/src/intrinsics.rs`.
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id();
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 8a62031ec887c..c1ba29284da16 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -1306,7 +1306,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
.at(&ObligationCause::dummy(), self.param_env)
.sup(candidate.xform_self_ty, self_ty);
match self.select_trait_candidate(trait_ref) {
- Ok(Some(traits::ImplSource::ImplSourceUserDefined(ref impl_data))) => {
+ Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => {
// If only a single impl matches, make the error message point
// to that impl.
ImplSource(impl_data.impl_def_id)
diff --git a/config.toml.example b/config.toml.example
index fb62e1b4726bc..c5efb8ed5e51c 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -36,8 +36,8 @@ changelog-seen = 1
# toolchain or changing LLVM locally, you probably want to set this to true.
#
# It's currently false by default due to being newly added; please file bugs if
-# enabling this did not work for you on Linux (macOS and Windows support is
-# coming soon).
+# enabling this did not work for you on x86_64-unknown-linux-gnu.
+# Other target triples are currently not supported; see #77084.
#
# We also currently only support this when building LLVM for the build triple.
#
@@ -380,7 +380,7 @@ changelog-seen = 1
# Whether or not to leave debug! and trace! calls in the rust binary.
# Overrides the `debug-assertions` option, if defined.
-#
+#
# Defaults to rust.debug-assertions value
#debug-logging = debug-assertions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index bcbb760021ee4..243fc7bfaa51f 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1,7 +1,7 @@
//! Compiler intrinsics.
//!
-//! The corresponding definitions are in `librustc_codegen_llvm/intrinsic.rs`.
-//! The corresponding const implementations are in `librustc_mir/interpret/intrinsics.rs`
+//! The corresponding definitions are in `compiler/rustc_codegen_llvm/src/intrinsic.rs`.
+//! The corresponding const implementations are in `compiler/rustc_mir/src/interpret/intrinsics.rs`
//!
//! # Const intrinsics
//!
@@ -10,7 +10,7 @@
//!
//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
//! from /~https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to
-//! `librustc_mir/interpret/intrinsics.rs` and add a
+//! `compiler/rustc_mir/src/interpret/intrinsics.rs` and add a
//! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic.
//!
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
@@ -733,6 +733,7 @@ extern "rust-intrinsic" {
/// own, or if it does not enable any significant optimizations.
///
/// This intrinsic does not have a stable counterpart.
+ #[rustc_const_unstable(feature = "const_assume", issue = "76972")]
pub fn assume(b: bool);
/// Hints to the compiler that branch condition is likely to be true.
@@ -904,7 +905,7 @@ extern "rust-intrinsic" {
/// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
///
/// let num = unsafe {
- /// std::mem::transmute::<[u8; 4], u32>(raw_bytes);
+ /// std::mem::transmute::<[u8; 4], u32>(raw_bytes)
/// };
///
/// // use `u32::from_ne_bytes` instead
diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs
index fed7c4a5bf399..de163a60c98f4 100644
--- a/library/core/tests/intrinsics.rs
+++ b/library/core/tests/intrinsics.rs
@@ -1,4 +1,5 @@
use core::any::TypeId;
+use core::intrinsics::assume;
#[test]
fn test_typeid_sized_types() {
@@ -20,3 +21,17 @@ fn test_typeid_unsized_types() {
assert_eq!(TypeId::of::(), TypeId::of::());
assert!(TypeId::of::() != TypeId::of::());
}
+
+// Check that `const_assume` feature allow `assume` intrinsic
+// to be used in const contexts.
+#[test]
+fn test_assume_can_be_in_const_contexts() {
+ const unsafe fn foo(x: usize, y: usize) -> usize {
+ // SAFETY: the entire function is not safe,
+ // but it is just an example not used elsewhere.
+ unsafe { assume(y != 0) };
+ x / y
+ }
+ let rs = unsafe { foo(42, 97) };
+ assert_eq!(rs, 0);
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index d8b36beb3e085..8d86349244b09 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -8,6 +8,8 @@
#![feature(bound_cloned)]
#![feature(box_syntax)]
#![feature(cell_update)]
+#![feature(const_assume)]
+#![feature(core_intrinsics)]
#![feature(core_private_bignum)]
#![feature(core_private_diy_float)]
#![feature(debug_non_exhaustive)]
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index eca169373f39f..5597bbb93d236 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -175,7 +175,7 @@ pub struct _TypeDescriptor {
// to be able to catch Rust panics by simply declaring a `struct rust_panic`.
//
// When modifying, make sure that the type name string exactly matches
-// the one used in src/librustc_codegen_llvm/intrinsic.rs.
+// the one used in `compiler/rustc_codegen_llvm/src/intrinsic.rs`.
const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index eddf00d3979f5..166e28435f0a0 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -75,6 +75,13 @@ pub use crate::sys_common::os_str_bytes as os_str;
#[cfg(not(test))]
pub fn init() {
+ // The standard streams might be closed on application startup. To prevent
+ // std::io::{stdin, stdout,stderr} objects from using other unrelated file
+ // resources opened later, we reopen standards streams when they are closed.
+ unsafe {
+ sanitize_standard_fds();
+ }
+
// By default, some platforms will send a *signal* when an EPIPE error
// would otherwise be delivered. This runtime doesn't install a SIGPIPE
// handler, causing it to kill the program, which isn't exactly what we
@@ -86,6 +93,56 @@ pub fn init() {
reset_sigpipe();
}
+ // In the case when all file descriptors are open, the poll has been
+ // observed to perform better than fcntl (on GNU/Linux).
+ #[cfg(not(any(
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ // The poll on Darwin doesn't set POLLNVAL for closed fds.
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "redox",
+ )))]
+ unsafe fn sanitize_standard_fds() {
+ use crate::sys::os::errno;
+ let pfds: &mut [_] = &mut [
+ libc::pollfd { fd: 0, events: 0, revents: 0 },
+ libc::pollfd { fd: 1, events: 0, revents: 0 },
+ libc::pollfd { fd: 2, events: 0, revents: 0 },
+ ];
+ while libc::poll(pfds.as_mut_ptr(), 3, 0) == -1 {
+ if errno() == libc::EINTR {
+ continue;
+ }
+ libc::abort();
+ }
+ for pfd in pfds {
+ if pfd.revents & libc::POLLNVAL == 0 {
+ continue;
+ }
+ if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
+ // If the stream is closed but we failed to reopen it, abort the
+ // process. Otherwise we wouldn't preserve the safety of
+ // operations on the corresponding Rust object Stdin, Stdout, or
+ // Stderr.
+ libc::abort();
+ }
+ }
+ }
+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "redox"))]
+ unsafe fn sanitize_standard_fds() {
+ use crate::sys::os::errno;
+ for fd in 0..3 {
+ if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
+ if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
+ libc::abort();
+ }
+ }
+ }
+ }
+ #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))]
+ unsafe fn sanitize_standard_fds() {}
+
#[cfg(not(any(target_os = "emscripten", target_os = "fuchsia")))]
unsafe fn reset_sigpipe() {
assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md
index 5fcaafab959e9..dfb39c54c1723 100644
--- a/src/bootstrap/CHANGELOG.md
+++ b/src/bootstrap/CHANGELOG.md
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Non-breaking changes since the last major version]
+- Add `x.py setup` [#76631](/~https://github.com/rust-lang/rust/pull/76631)
- Add a changelog for x.py [#76626](/~https://github.com/rust-lang/rust/pull/76626)
- Optionally, download LLVM from CI on Linux and NixOS
+ [#76439](/~https://github.com/rust-lang/rust/pull/76349)
@@ -15,6 +16,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Make the default stage for x.py configurable [#76625](/~https://github.com/rust-lang/rust/pull/76625)
- Add a dedicated debug-logging option [#76588](/~https://github.com/rust-lang/rust/pull/76588)
- Add sample defaults for x.py [#76628](/~https://github.com/rust-lang/rust/pull/76628)
+- Add `--keep-stage-std`, which behaves like `keep-stage` but allows the stage
+ 0 compiler artifacts (i.e., stage1/bin/rustc) to be rebuilt if changed
+ [#77120](/~https://github.com/rust-lang/rust/pull/77120).
+
## [Version 0] - 2020-09-11
diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index f7512aa9fcebd..637083e08d510 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -7,21 +7,34 @@
use std::env;
-use bootstrap::{Build, Config};
+use bootstrap::{Build, Config, Subcommand};
fn main() {
let args = env::args().skip(1).collect::>();
let config = Config::parse(&args);
let changelog_suggestion = check_version(&config);
- if let Some(suggestion) = &changelog_suggestion {
+
+ // NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the
+ // changelog warning, not the `x.py setup` message.
+ let suggest_setup = !config.config.exists() && !matches!(config.cmd, Subcommand::Setup { .. });
+ if suggest_setup {
+ println!("warning: you have not made a `config.toml`");
+ println!("help: consider running `x.py setup` or copying `config.toml.example`");
+ } else if let Some(suggestion) = &changelog_suggestion {
println!("{}", suggestion);
}
Build::new(config).build();
- if let Some(suggestion) = changelog_suggestion {
+ if suggest_setup {
+ println!("warning: you have not made a `config.toml`");
+ println!("help: consider running `x.py setup` or copying `config.toml.example`");
+ } else if let Some(suggestion) = &changelog_suggestion {
println!("{}", suggestion);
+ }
+
+ if suggest_setup || changelog_suggestion.is_some() {
println!("note: this message was printed twice to make it more likely to be seen");
}
}
@@ -40,7 +53,7 @@ fn check_version(config: &Config) -> Option {
}
} else {
msg.push_str("warning: x.py has made several changes recently you may want to look at\n");
- format!("add `changelog-seen = {}` to `config.toml`", VERSION)
+ format!("add `changelog-seen = {}` at the top of `config.toml`", VERSION)
};
msg.push_str("help: consider looking at the changes in `src/bootstrap/CHANGELOG.md`\n");
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 1f0b55a78698d..5c9184f450687 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -424,8 +424,19 @@ def download_stage0(self):
rustfmt_stamp.write(self.date + self.rustfmt_channel)
if self.downloading_llvm():
- llvm_sha = subprocess.check_output(["git", "log", "--author=bors",
- "--format=%H", "-n1"]).decode(sys.getdefaultencoding()).strip()
+ # We want the most recent LLVM submodule update to avoid downloading
+ # LLVM more often than necessary.
+ #
+ # This git command finds that commit SHA, looking for bors-authored
+ # merges that modified src/llvm-project.
+ #
+ # This works even in a repository that has not yet initialized
+ # submodules.
+ llvm_sha = subprocess.check_output([
+ "git", "log", "--author=bors", "--format=%H", "-n1",
+ "-m", "--first-parent",
+ "--", "src/llvm-project"
+ ]).decode(sys.getdefaultencoding()).strip()
llvm_assertions = self.get_toml('assertions', 'llvm') == 'true'
if self.program_out_of_date(self.llvm_stamp(), llvm_sha + str(llvm_assertions)):
self._download_ci_llvm(llvm_sha, llvm_assertions)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index d2537d65e67f5..4aaaeb8a93bda 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -549,7 +549,9 @@ impl<'a> Builder<'a> {
Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
Subcommand::Run { ref paths } => (Kind::Run, &paths[..]),
- Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(),
+ Subcommand::Format { .. } | Subcommand::Clean { .. } | Subcommand::Setup { .. } => {
+ panic!()
+ }
};
Self::new_internal(build, kind, paths.to_owned())
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 08907edef1d1e..40bf6c48296b2 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -59,7 +59,9 @@ impl Step for Std {
let target = self.target;
let compiler = self.compiler;
- if builder.config.keep_stage.contains(&compiler.stage) {
+ if builder.config.keep_stage.contains(&compiler.stage)
+ || builder.config.keep_stage_std.contains(&compiler.stage)
+ {
builder.info("Warning: Using a potentially old libstd. This may not behave well.");
builder.ensure(StdLink { compiler, target_compiler: compiler, target });
return;
@@ -472,6 +474,7 @@ impl Step for Rustc {
if builder.config.keep_stage.contains(&compiler.stage) {
builder.info("Warning: Using a potentially old librustc. This may not behave well.");
+ builder.info("Warning: Use `--keep-stage-std` if you want to rebuild the compiler when it changes");
builder.ensure(RustcLink { compiler, target_compiler: compiler, target });
return;
}
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index c74501979f0ec..b14746dabb93a 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -71,7 +71,10 @@ pub struct Config {
pub on_fail: Option,
pub stage: u32,
pub keep_stage: Vec,
+ pub keep_stage_std: Vec,
pub src: PathBuf,
+ // defaults to `config.toml`
+ pub config: PathBuf,
pub jobs: Option,
pub cmd: Subcommand,
pub incremental: bool,
@@ -512,6 +515,7 @@ impl Config {
config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
config.deny_warnings = true;
config.missing_tools = false;
+ config.config = PathBuf::from("config.toml");
// set by bootstrap.py
config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
@@ -539,6 +543,7 @@ impl Config {
config.incremental = flags.incremental;
config.dry_run = flags.dry_run;
config.keep_stage = flags.keep_stage;
+ config.keep_stage_std = flags.keep_stage_std;
config.bindir = "bin".into(); // default
if let Some(value) = flags.deny_warnings {
config.deny_warnings = value;
@@ -556,7 +561,7 @@ impl Config {
let get_toml = |file: PathBuf| {
use std::process;
- let contents = t!(fs::read_to_string(&file), "configuration file did not exist");
+ let contents = t!(fs::read_to_string(&file), "`include` config not found");
match toml::from_str(&contents) {
Ok(table) => table,
Err(err) => {
@@ -642,6 +647,7 @@ impl Config {
| Subcommand::Clippy { .. }
| Subcommand::Fix { .. }
| Subcommand::Run { .. }
+ | Subcommand::Setup { .. }
| Subcommand::Format { .. } => flags.stage.unwrap_or(0),
};
@@ -666,6 +672,7 @@ impl Config {
| Subcommand::Clippy { .. }
| Subcommand::Fix { .. }
| Subcommand::Run { .. }
+ | Subcommand::Setup { .. }
| Subcommand::Format { .. } => {}
}
}
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index c119ae38fc391..f1202c82ba690 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1033,7 +1033,7 @@ impl Step for Src {
copy_src_dirs(
builder,
&builder.src,
- &["library"],
+ &["library", "src/llvm-project/libunwind"],
&[
// not needed and contains symlinks which rustup currently
// chokes on when unpacking.
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 842c84a3e5cd6..a12fc50afad58 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -7,6 +7,7 @@ use std::env;
use std::path::PathBuf;
use std::process;
+use build_helper::t;
use getopts::Options;
use crate::builder::Builder;
@@ -19,6 +20,7 @@ pub struct Flags {
pub on_fail: Option,
pub stage: Option,
pub keep_stage: Vec,
+ pub keep_stage_std: Vec,
pub host: Option>,
pub target: Option>,
@@ -88,6 +90,9 @@ pub enum Subcommand {
Run {
paths: Vec,
},
+ Setup {
+ path: String,
+ },
}
impl Default for Subcommand {
@@ -144,6 +149,13 @@ To learn more about a subcommand, run `./x.py -h`",
(pass multiple times to keep e.g., both stages 0 and 1)",
"N",
);
+ opts.optmulti(
+ "",
+ "keep-stage-std",
+ "stage(s) of the standard library to keep without recompiling \
+ (pass multiple times to keep e.g., both stages 0 and 1)",
+ "N",
+ );
opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
let j_msg = format!(
"number of jobs to run in parallel; \
@@ -191,6 +203,7 @@ To learn more about a subcommand, run `./x.py -h`",
|| (s == "install")
|| (s == "run")
|| (s == "r")
+ || (s == "setup")
});
let subcommand = match subcommand {
Some(s) => s,
@@ -445,10 +458,21 @@ Arguments:
At least a tool needs to be called.",
);
}
+ "setup" => {
+ subcommand_help.push_str(
+ "\n
+Arguments:
+ This subcommand accepts a 'profile' to use for builds. For example:
+
+ ./x.py setup library
+
+ The profile is optional and you will be prompted interactively if it is not given.",
+ );
+ }
_ => {}
};
// Get any optional paths which occur after the subcommand
- let paths = matches.free[1..].iter().map(|p| p.into()).collect::>();
+ let mut paths = matches.free[1..].iter().map(|p| p.into()).collect::>();
let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from);
let verbose = matches.opt_present("verbose");
@@ -500,6 +524,20 @@ Arguments:
}
Subcommand::Run { paths }
}
+ "setup" => {
+ let path = if paths.len() > 1 {
+ println!("\nat most one profile can be passed to setup\n");
+ usage(1, &opts, verbose, &subcommand_help)
+ } else if let Some(path) = paths.pop() {
+ t!(path.into_os_string().into_string().map_err(|path| format!(
+ "{} is not a valid UTF8 string",
+ path.to_string_lossy()
+ )))
+ } else {
+ t!(crate::setup::interactive_path())
+ };
+ Subcommand::Setup { path }
+ }
_ => {
usage(1, &opts, verbose, &subcommand_help);
}
@@ -510,7 +548,9 @@ Arguments:
println!("--stage not supported for x.py check, always treated as stage 0");
process::exit(1);
}
- if matches.opt_str("keep-stage").is_some() {
+ if matches.opt_str("keep-stage").is_some()
+ || matches.opt_str("keep-stage-std").is_some()
+ {
println!("--keep-stage not supported for x.py check, only one stage available");
process::exit(1);
}
@@ -528,6 +568,11 @@ Arguments:
.into_iter()
.map(|j| j.parse().expect("`keep-stage` should be a number"))
.collect(),
+ keep_stage_std: matches
+ .opt_strs("keep-stage-std")
+ .into_iter()
+ .map(|j| j.parse().expect("`keep-stage-std` should be a number"))
+ .collect(),
host: if matches.opt_present("host") {
Some(
split(&matches.opt_strs("host"))
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 3f7aeae0ed495..4cc72f5f39c97 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -141,6 +141,7 @@ mod metadata;
mod native;
mod run;
mod sanity;
+mod setup;
mod test;
mod tool;
mod toolstate;
@@ -165,7 +166,7 @@ mod job {
use crate::cache::{Interned, INTERNER};
pub use crate::config::Config;
-use crate::flags::Subcommand;
+pub use crate::flags::Subcommand;
const LLVM_TOOLS: &[&str] = &[
"llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility
@@ -470,6 +471,10 @@ impl Build {
return clean::clean(self, all);
}
+ if let Subcommand::Setup { path: include_name } = &self.config.cmd {
+ return setup::setup(&self.config.src, include_name);
+ }
+
{
let builder = builder::Builder::new(&self);
if let Some(path) = builder.paths.get(0) {
diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs
index 900534714277c..ba593cadbad81 100644
--- a/src/bootstrap/run.rs
+++ b/src/bootstrap/run.rs
@@ -10,7 +10,7 @@ impl Step for ExpandYamlAnchors {
/// Runs the `expand-yaml_anchors` tool.
///
- /// This tool in `src/tools` read the CI configuration files written in YAML and expands the
+ /// This tool in `src/tools` reads the CI configuration files written in YAML and expands the
/// anchors in them, since GitHub Actions doesn't support them.
fn run(self, builder: &Builder<'_>) {
builder.info("Expanding YAML anchors in the GitHub Actions configuration");
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
new file mode 100644
index 0000000000000..9d3a889aa008e
--- /dev/null
+++ b/src/bootstrap/setup.rs
@@ -0,0 +1,88 @@
+use crate::t;
+use std::path::{Path, PathBuf};
+use std::{
+ env, fs,
+ io::{self, Write},
+};
+
+pub fn setup(src_path: &Path, include_name: &str) {
+ let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from);
+
+ if cfg_file.as_ref().map_or(false, |f| f.exists()) {
+ let file = cfg_file.unwrap();
+ println!(
+ "error: you asked `x.py` to setup a new config file, but one already exists at `{}`",
+ file.display()
+ );
+ println!(
+ "help: try adding `profile = \"{}\"` at the top of {}",
+ include_name,
+ file.display()
+ );
+ println!(
+ "note: this will use the configuration in {}/src/bootstrap/defaults/config.toml.{}",
+ src_path.display(),
+ include_name
+ );
+ std::process::exit(1);
+ }
+
+ let path = cfg_file.unwrap_or_else(|| src_path.join("config.toml"));
+ let settings = format!(
+ "# Includes one of the default files in src/bootstrap/defaults\n\
+ profile = \"{}\"\n",
+ include_name
+ );
+ t!(fs::write(path, settings));
+
+ let include_path =
+ format!("{}/src/bootstrap/defaults/config.toml.{}", src_path.display(), include_name);
+ println!("`x.py` will now use the configuration at {}", include_path);
+
+ let suggestions = match include_name {
+ "codegen" | "compiler" => &["check", "build", "test"][..],
+ "library" => &["check", "build", "test library/std", "doc"],
+ "user" => &["dist", "build"],
+ _ => return,
+ };
+
+ println!("To get started, try one of the following commands:");
+ for cmd in suggestions {
+ println!("- `x.py {}`", cmd);
+ }
+
+ if include_name != "user" {
+ println!(
+ "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
+ );
+ }
+}
+
+// Used to get the path for `Subcommand::Setup`
+pub fn interactive_path() -> io::Result {
+ let mut input = String::new();
+ println!(
+ "Welcome to the Rust project! What do you want to do with x.py?
+a) Contribute to the standard library
+b) Contribute to the compiler
+c) Contribute to the compiler, and also modify LLVM or codegen
+d) Install Rust from source"
+ );
+ let template = loop {
+ print!("Please choose one (a/b/c/d): ");
+ io::stdout().flush()?;
+ io::stdin().read_line(&mut input)?;
+ break match input.trim().to_lowercase().as_str() {
+ "a" | "lib" | "library" => "library",
+ "b" | "compiler" => "compiler",
+ "c" | "llvm" => "llvm",
+ "d" | "user" | "maintainer" => "maintainer",
+ _ => {
+ println!("error: unrecognized option '{}'", input.trim());
+ println!("note: press Ctrl+C to exit");
+ continue;
+ }
+ };
+ };
+ Ok(template.to_owned())
+}
diff --git a/src/test/ui/closed-std-fds.rs b/src/test/ui/closed-std-fds.rs
new file mode 100644
index 0000000000000..906da94433455
--- /dev/null
+++ b/src/test/ui/closed-std-fds.rs
@@ -0,0 +1,69 @@
+// Verifies that std provides replacement for the standard file descriptors when they are missing.
+//
+// run-pass
+// ignore-windows unix specific test
+// ignore-cloudabi no processes
+// ignore-emscripten no processes
+// ignore-sgx no processes
+
+#![feature(rustc_private)]
+extern crate libc;
+
+use std::io::{self, Read};
+use std::os::unix::process::CommandExt;
+use std::process::Command;
+
+fn main() {
+ let mut args = std::env::args();
+ let argv0 = args.next().expect("argv0");
+ match args.next().as_deref() {
+ Some("child") => child(),
+ None => parent(&argv0),
+ _ => unreachable!(),
+ }
+}
+
+fn parent(argv0: &str) {
+ let status = unsafe { Command::new(argv0)
+ .arg("child")
+ .pre_exec(close_std_fds_on_exec)
+ .status()
+ .expect("failed to execute child process")
+ };
+ if !status.success() {
+ panic!("child failed with {}", status);
+ }
+}
+
+fn close_std_fds_on_exec() -> io::Result<()> {
+ for fd in 0..3 {
+ if unsafe { libc::fcntl(fd, libc::F_SETFD, libc::FD_CLOEXEC) == -1 } {
+ return Err(io::Error::last_os_error())
+ }
+ }
+ Ok(())
+}
+
+fn child() {
+ // Standard file descriptors should be valid.
+ assert_fd_is_valid(0);
+ assert_fd_is_valid(1);
+ assert_fd_is_valid(2);
+
+ // Writing to stdout & stderr should not panic.
+ println!("a");
+ println!("b");
+ eprintln!("c");
+ eprintln!("d");
+
+ // Stdin should be at EOF.
+ let mut buffer = Vec::new();
+ let n = io::stdin().read_to_end(&mut buffer).unwrap();
+ assert_eq!(n, 0);
+}
+
+fn assert_fd_is_valid(fd: libc::c_int) {
+ if unsafe { libc::fcntl(fd, libc::F_GETFD) == -1 } {
+ panic!("file descriptor {} is not valid {}", fd, io::Error::last_os_error());
+ }
+}
diff --git a/src/tools/miri b/src/tools/miri
index 02a33d411d8e3..2f84bfc57dd0e 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 02a33d411d8e385942776760a99535d69826349b
+Subproject commit 2f84bfc57dd0ef22269bb84dae10f71e5e23e85d
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index f0a6ce2fa06c2..f5e5c0867b48a 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -9,6 +9,6 @@ edition = "2018"
clap = "2.25.0"
[dependencies.mdbook]
-version = "0.4.0"
+version = "0.4.3"
default-features = false
features = ["search"]