Skip to content

Rollup of 8 pull requests #86588

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jun 24, 2021
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8eb0c0d
Document associativity of iterator folds.
Kmeakin Jun 17, 2021
f265997
Edition 2021 enables disjoint capture
arora-aman Jun 21, 2021
30793c1
Add documentation for various THIR structs
LeSeulArtichaut Jun 14, 2021
faa6461
Update cargo
ehuss Jun 22, 2021
e629381
chore(rustdoc): Remove unused impl block
notriddle Jun 22, 2021
4d1b3a5
Use `use_verbose` for mir::Constant
fee1-dead Jun 23, 2021
6370567
Updated mir pretty print output
fee1-dead Jun 23, 2021
0bb6bc4
Teach rustc to accept lowercase error codes
inquisitivecrystal Jun 22, 2021
d296ea0
Add bstr to rustc-workspace-hack for rustfmt/cargo.
ehuss Jun 23, 2021
23e5ed1
Check if error code is used
GuillaumeGomez Jun 8, 2021
22a702d
Add check on constant to ensure it's up to date
GuillaumeGomez Jun 8, 2021
12b6d32
Remove unused error codes from error_codes.rs and from EXEMPTED_FROM_…
GuillaumeGomez Jun 8, 2021
20f1b1c
Greatly improve code
GuillaumeGomez Jun 23, 2021
0ab9d01
Handle windows paths as well
GuillaumeGomez Jun 23, 2021
55fd13b
Rollup merge of #86137 - GuillaumeGomez:error-code-cleanup, r=Mark-Si…
JohnTitor Jun 24, 2021
469329d
Rollup merge of #86296 - LeSeulArtichaut:thir-doc, r=nikomatsakis
JohnTitor Jun 24, 2021
0fa4f0b
Rollup merge of #86415 - Kmeakin:iterator-associativity-docs, r=dtolnay
JohnTitor Jun 24, 2021
6b618c8
Rollup merge of #86533 - inquisitivecrystal:lower-case-error-explain,…
JohnTitor Jun 24, 2021
3998c03
Rollup merge of #86536 - sexxi-goose:edition, r=nikomatsakis
JohnTitor Jun 24, 2021
60dae7a
Rollup merge of #86560 - ehuss:update-cargo, r=ehuss
JohnTitor Jun 24, 2021
2322097
Rollup merge of #86561 - notriddle:notriddle/cleanup-rustdoc, r=jyn514
JohnTitor Jun 24, 2021
64c9712
Rollup merge of #86566 - fee1-dead:mir-pretty-print, r=oli-obk
JohnTitor Jun 24, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -180,7 +180,7 @@ dependencies = [
"merge",
"num_cpus",
"once_cell",
"opener",
"opener 0.5.0",
"pretty_assertions",
"serde",
"serde_json",
@@ -195,7 +195,9 @@ version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
]

[[package]]
@@ -253,7 +255,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"

[[package]]
name = "cargo"
version = "0.55.0"
version = "0.56.0"
dependencies = [
"anyhow",
"atty",
@@ -288,11 +290,10 @@ dependencies = [
"log",
"memchr",
"num_cpus",
"opener",
"opener 0.5.0",
"openssl",
"percent-encoding 2.1.0",
"pretty_env_logger",
"rand 0.8.3",
"rustc-workspace-hack",
"rustfix 0.6.0",
"semver 1.0.3",
@@ -375,10 +376,12 @@ dependencies = [
"flate2",
"git2",
"glob",
"itertools 0.10.0",
"lazy_static",
"remove_dir_all",
"serde_json",
"tar",
"termcolor",
"toml",
"url 2.2.2",
]
@@ -575,7 +578,7 @@ dependencies = [
"bytecount",
"clap",
"itertools 0.9.0",
"opener",
"opener 0.4.1",
"regex",
"shell-escape",
"walkdir",
@@ -2418,6 +2421,16 @@ dependencies = [
"winapi 0.3.9",
]

[[package]]
name = "opener"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea3ebcd72a54701f56345f16785a6d3ac2df7e986d273eb4395c0b01db17952"
dependencies = [
"bstr",
"winapi 0.3.9",
]

[[package]]
name = "openssl"
version = "0.10.33"
@@ -3558,6 +3571,7 @@ dependencies = [
name = "rustc-workspace-hack"
version = "1.0.0"
dependencies = [
"bstr",
"byteorder",
"crossbeam-utils 0.8.3",
"libc",
@@ -5158,9 +5172,9 @@ dependencies = [

[[package]]
name = "termcolor"
version = "1.1.0"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
8 changes: 6 additions & 2 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
@@ -528,8 +528,12 @@ fn stderr_isatty() -> bool {
}

fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
let normalised =
if code.starts_with('E') { code.to_string() } else { format!("E{0:0>4}", code) };
let upper_cased_code = code.to_ascii_uppercase();
let normalised = if upper_cased_code.starts_with('E') {
upper_cased_code
} else {
format!("E{0:0>4}", code)
};
match registry.try_find_description(&normalised) {
Ok(Some(description)) => {
let mut is_in_code_block = false;
9 changes: 4 additions & 5 deletions compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
@@ -609,7 +609,7 @@ E0783: include_str!("./error_codes/E0783.md"),
// E0540, // multiple rustc_deprecated attributes
E0544, // multiple stability levels
// E0548, // replaced with a generic attribute input check
E0553, // multiple rustc_const_unstable attributes
// E0553, // multiple rustc_const_unstable attributes
// E0555, // replaced with a generic attribute input check
// E0558, // replaced with a generic attribute input check
// E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
@@ -620,10 +620,9 @@ E0783: include_str!("./error_codes/E0783.md"),
// E0612, // merged into E0609
// E0613, // Removed (merged with E0609)
E0625, // thread-local statics cannot be accessed at compile-time
E0629, // missing 'feature' (rustc_const_unstable)
// rustc_const_unstable attribute must be paired with stable/unstable
// attribute
E0630,
// E0629, // missing 'feature' (rustc_const_unstable)
// E0630, // rustc_const_unstable attribute must be paired with stable/unstable
// attribute
E0632, // cannot provide explicit generic arguments when `impl Trait` is
// used in argument position
E0640, // infer outlives requirements
144 changes: 109 additions & 35 deletions compiler/rustc_middle/src/thir.rs

Large diffs are not rendered by default.

46 changes: 19 additions & 27 deletions compiler/rustc_mir/src/util/pretty.rs
Original file line number Diff line number Diff line change
@@ -426,14 +426,14 @@ impl ExtraComments<'tcx> {
}
}

fn use_verbose(ty: &&TyS<'tcx>) -> bool {
fn use_verbose(ty: &&TyS<'tcx>, fn_def: bool) -> bool {
match ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) => false,
// Unit type
ty::Tuple(g_args) if g_args.is_empty() => false,
ty::Tuple(g_args) => g_args.iter().any(|g_arg| use_verbose(&g_arg.expect_ty())),
ty::Array(ty, _) => use_verbose(ty),
ty::FnDef(..) => false,
ty::Tuple(g_args) => g_args.iter().any(|g_arg| use_verbose(&g_arg.expect_ty(), fn_def)),
ty::Array(ty, _) => use_verbose(ty, fn_def),
ty::FnDef(..) => fn_def,
_ => true,
}
}
@@ -442,28 +442,20 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
let Constant { span, user_ty, literal } = constant;
match literal.ty().kind() {
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char => {}
// Unit type
ty::Tuple(tys) if tys.is_empty() => {}
_ => {
self.push("mir::Constant");
self.push(&format!(
"+ span: {}",
self.tcx.sess.source_map().span_to_embeddable_string(*span)
));
if let Some(user_ty) = user_ty {
self.push(&format!("+ user_ty: {:?}", user_ty));
}
match literal {
ConstantKind::Ty(literal) => self.push(&format!("+ literal: {:?}", literal)),
ConstantKind::Val(val, ty) => {
// To keep the diffs small, we render this almost like we render ty::Const
self.push(&format!(
"+ literal: Const {{ ty: {}, val: Value({:?}) }}",
ty, val
))
}
if use_verbose(&literal.ty(), true) {
self.push("mir::Constant");
self.push(&format!(
"+ span: {}",
self.tcx.sess.source_map().span_to_embeddable_string(*span)
));
if let Some(user_ty) = user_ty {
self.push(&format!("+ user_ty: {:?}", user_ty));
}
match literal {
ConstantKind::Ty(literal) => self.push(&format!("+ literal: {:?}", literal)),
ConstantKind::Val(val, ty) => {
// To keep the diffs small, we render this almost like we render ty::Const
self.push(&format!("+ literal: Const {{ ty: {}, val: Value({:?}) }}", ty, val))
}
}
}
@@ -472,7 +464,7 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
self.super_const(constant);
let ty::Const { ty, val, .. } = constant;
if use_verbose(ty) {
if use_verbose(ty, false) {
self.push("ty::Const");
self.push(&format!("+ ty: {:?}", ty));
let val = match val {
14 changes: 12 additions & 2 deletions compiler/rustc_typeck/src/check/upvar.rs
Original file line number Diff line number Diff line change
@@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// We now fake capture information for all variables that are mentioned within the closure
// We do this after handling migrations so that min_captures computes before
if !self.tcx.features().capture_disjoint_fields {
if !enable_precise_capture(self.tcx, span) {
let mut capture_information: InferredCaptureInformation<'tcx> = Default::default();

if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
@@ -212,7 +212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// If we have an origin, store it.
if let Some(origin) = delegate.current_origin.clone() {
let origin = if self.tcx.features().capture_disjoint_fields {
let origin = if enable_precise_capture(self.tcx, span) {
(origin.0, restrict_capture_precision(origin.1))
} else {
(origin.0, Place { projections: vec![], ..origin.1 })
@@ -1924,3 +1924,13 @@ fn determine_place_ancestry_relation(
PlaceAncestryRelation::Divergent
}
}

/// Precise capture is enabled if the feature gate `capture_disjoint_fields` is enabled or if
/// user is using Rust Edition 2021 or higher.
///
/// `span` is the span of the closure.
fn enable_precise_capture(tcx: TyCtxt<'_>, span: Span) -> bool {
// We use span here to ensure that if the closure was generated by a macro with a different
// edition.
tcx.features().capture_disjoint_fields || span.rust_2021()
}
9 changes: 8 additions & 1 deletion library/core/src/iter/traits/double_ended.rs
Original file line number Diff line number Diff line change
@@ -248,6 +248,11 @@ pub trait DoubleEndedIterator: Iterator {
/// Folding is useful whenever you have a collection of something, and want
/// to produce a single value from it.
///
/// Note: `rfold()` combines elements in a *right-associative* fashion. For associative
/// operators like `+`, the order the elements are combined in is not important, but for non-associative
/// operators like `-` the order will affect the final result.
/// For a *left-associative* version of `rfold()`, see [`Iterator::fold()`].
///
/// # Examples
///
/// Basic usage:
@@ -262,7 +267,8 @@ pub trait DoubleEndedIterator: Iterator {
/// assert_eq!(sum, 6);
/// ```
///
/// This example builds a string, starting with an initial value
/// This example demonstrates the right-associative nature of `rfold()`:
/// it builds a string, starting with an initial value
/// and continuing with each element from the back until the front:
///
/// ```
@@ -276,6 +282,7 @@ pub trait DoubleEndedIterator: Iterator {
///
/// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
/// ```
#[doc(alias = "foldr")]
#[inline]
#[stable(feature = "iter_rfold", since = "1.27.0")]
fn rfold<B, F>(mut self, init: B, mut f: F) -> B
22 changes: 21 additions & 1 deletion library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
@@ -2083,6 +2083,11 @@ pub trait Iterator {
/// Note: [`reduce()`] can be used to use the first element as the initial
/// value, if the accumulator type and item type is the same.
///
/// Note: `fold()` combines elements in a *left-associative* fashion. For associative
/// operators like `+`, the order the elements are combined in is not important, but for non-associative
/// operators like `-` the order will affect the final result.
/// For a *right-associative* version of `fold()`, see [`DoubleEndedIterator::rfold()`].
///
/// # Note to Implementors
///
/// Several of the other (forward) methods have default implementations in
@@ -2116,6 +2121,21 @@ pub trait Iterator {
///
/// And so, our final result, `6`.
///
/// This example demonstrates the left-associative nature of `fold()`:
/// it builds a string, starting with an initial value
/// and continuing with each element from the front until the back:
///
/// ```
/// let numbers = [1, 2, 3, 4, 5];
///
/// let zero = "0".to_string();
///
/// let result = numbers.iter().fold(zero, |acc, &x| {
/// format!("({} + {})", acc, x)
/// });
///
/// assert_eq!(result, "(((((0 + 1) + 2) + 3) + 4) + 5)");
/// ```
/// It's common for people who haven't used iterators a lot to
/// use a `for` loop with a list of things to build up a result. Those
/// can be turned into `fold()`s:
@@ -2140,7 +2160,7 @@ pub trait Iterator {
/// ```
///
/// [`reduce()`]: Iterator::reduce
#[doc(alias = "inject")]
#[doc(alias = "inject", alias = "foldl")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn fold<B, F>(mut self, init: B, mut f: F) -> B
2 changes: 1 addition & 1 deletion src/bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ toml = "0.5"
lazy_static = "1.3.0"
time = "0.1"
ignore = "0.4.10"
opener = "0.4"
opener = "0.5"
merge = "0.1.0"
once_cell = "1.7.2"

22 changes: 0 additions & 22 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
@@ -101,28 +101,6 @@ crate struct RenderType {
generics: Option<Vec<Generic>>,
}

impl Serialize for RenderType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if let Some(name) = &self.name {
let mut seq = serializer.serialize_seq(None)?;
if let Some(id) = self.idx {
seq.serialize_element(&id)?;
} else {
seq.serialize_element(&name)?;
}
if let Some(generics) = &self.generics {
seq.serialize_element(&generics)?;
}
seq.end()
} else {
serializer.serialize_none()
}
}
}

/// A type used for the search index.
#[derive(Debug)]
crate struct Generic {
3 changes: 0 additions & 3 deletions src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
Original file line number Diff line number Diff line change
@@ -14,9 +14,6 @@
- _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:5:18: 5:23
+ _2 = const (2_u32, false); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
+ // mir::Constant
+ // + span: $DIR/checked_add.rs:5:18: 5:23
+ // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [2, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:5:18: 5:23
}

3 changes: 0 additions & 3 deletions src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
Original file line number Diff line number Diff line change
@@ -18,9 +18,6 @@
- assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:5:13: 5:29
+ _2 = const 2_u8; // scope 0 at $DIR/indirect.rs:5:13: 5:25
+ _3 = const (3_u8, false); // scope 0 at $DIR/indirect.rs:5:13: 5:29
+ // mir::Constant
+ // + span: $DIR/indirect.rs:5:13: 5:29
+ // + literal: Const { ty: (u8, bool), val: Value(ByRef { alloc: Allocation { bytes: [3, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u8, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:5:13: 5:29
}

3 changes: 0 additions & 3 deletions src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
Original file line number Diff line number Diff line change
@@ -15,9 +15,6 @@
(_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:11:11: 11:17
- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
+ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
+ // mir::Constant
+ // + span: $DIR/issue-67019.rs:11:10: 11:19
+ // + literal: Const { ty: (u8, u8), val: Value(ByRef { alloc: Allocation { bytes: [1, 2], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:11:18: 11:19
_1 = test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:11:5: 11:20
// mir::Constant
Original file line number Diff line number Diff line change
@@ -20,9 +20,6 @@
StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:9: 7:10
- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
+ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
+ // mir::Constant
+ // + span: $DIR/mutable_variable_aggregate.rs:7:13: 7:14
+ // + literal: Const { ty: (i32, i32), val: Value(ByRef { alloc: Allocation { bytes: [42, 0, 0, 0, 99, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
nop; // scope 0 at $DIR/mutable_variable_aggregate.rs:4:11: 8:2
StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:8:1: 8:2
StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:8:1: 8:2
Original file line number Diff line number Diff line change
@@ -27,9 +27,6 @@
- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // mir::Constant
+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
}

Original file line number Diff line number Diff line change
@@ -27,9 +27,6 @@
- _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
- assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ _2 = const (4_i32, false); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // mir::Constant
+ // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
+ // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
}

3 changes: 0 additions & 3 deletions src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
Original file line number Diff line number Diff line change
@@ -9,9 +9,6 @@
- _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:6:5: 6:10
- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:6:5: 6:10
+ _1 = const (4_u32, false); // scope 0 at $DIR/return_place.rs:6:5: 6:10
+ // mir::Constant
+ // + span: $DIR/return_place.rs:6:5: 6:10
+ // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
+ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:6:5: 6:10
}

Original file line number Diff line number Diff line change
@@ -18,9 +18,6 @@
StorageLive(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
- _3 = _1; // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
+ _3 = const (1_u32, 2_u32); // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
+ // mir::Constant
+ // + span: $DIR/tuple_literal_propagation.rs:5:13: 5:14
+ // + literal: Const { ty: (u32, u32), val: Value(ByRef { alloc: Allocation { bytes: [1, 0, 0, 0, 2, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
_2 = consume(move _3) -> bb1; // scope 1 at $DIR/tuple_literal_propagation.rs:5:5: 5:15
// mir::Constant
// + span: $DIR/tuple_literal_propagation.rs:5:5: 5:12
3 changes: 0 additions & 3 deletions src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff
Original file line number Diff line number Diff line change
@@ -12,9 +12,6 @@
- _0 = Baz { x: move _2, y: const 0f32, z: const false }; // scope 0 at $DIR/deaggregator_test.rs:9:5: 9:35
+ (_0.0: usize) = move _2; // scope 0 at $DIR/deaggregator_test.rs:9:5: 9:35
+ (_0.1: f32) = const 0f32; // scope 0 at $DIR/deaggregator_test.rs:9:5: 9:35
// mir::Constant
// + span: $DIR/deaggregator_test.rs:9:20: 9:23
// + literal: Const { ty: f32, val: Value(Scalar(0x00000000)) }
+ (_0.2: bool) = const false; // scope 0 at $DIR/deaggregator_test.rs:9:5: 9:35
StorageDead(_2); // scope 0 at $DIR/deaggregator_test.rs:9:34: 9:35
return; // scope 0 at $DIR/deaggregator_test.rs:10:2: 10:2
Original file line number Diff line number Diff line change
@@ -12,9 +12,6 @@
StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:53:8: 53:9
_3 = _1; // scope 0 at $DIR/if-condition-int.rs:53:8: 53:9
_2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if-condition-int.rs:53:8: 53:18
// mir::Constant
// + span: $DIR/if-condition-int.rs:53:13: 53:18
// + literal: Const { ty: f32, val: Value(Scalar(0xc2280000)) }
StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:53:17: 53:18
switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:53:5: 53:35
}
Original file line number Diff line number Diff line change
@@ -38,9 +38,6 @@
// mir::Constant
// + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12
// + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(Scalar(<ZST>)) }
// mir::Constant
// + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
// + literal: Const { ty: ((), ()), val: Value(Scalar(<ZST>)) }
}

bb1: {
23 changes: 23 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/run_pass/edition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// edition:2021
// run-pass

// Test that edition 2021 enables disjoint capture by default.

struct Point {
x: i32,
y: i32,
}

fn main() {
let mut p = Point { x: 10, y: 10 };

let c = || {
println!("{}", p.x);
};

// `c` should only capture `p.x`, therefore mutating `p.y` is allowed.
let py = &mut p.y;

c();
*py = 20;
}
2 changes: 1 addition & 1 deletion src/tools/cargo
Submodule cargo updated 56 files
+89 −1 CHANGELOG.md
+2 −3 Cargo.toml
+2 −0 crates/cargo-test-support/Cargo.toml
+583 −0 crates/cargo-test-support/src/compare.rs
+174 −0 crates/cargo-test-support/src/diff.rs
+113 −693 crates/cargo-test-support/src/lib.rs
+7 −7 crates/cargo-test-support/src/paths.rs
+2 −11 crates/cargo-test-support/src/publish.rs
+33 −26 crates/cargo-util/src/process_builder.rs
+12 −32 src/bin/cargo/commands/report.rs
+3 −0 src/cargo/core/compiler/build_config.rs
+6 −1 src/cargo/core/compiler/compilation.rs
+23 −5 src/cargo/core/compiler/context/mod.rs
+13 −7 src/cargo/core/compiler/custom_build.rs
+259 −7 src/cargo/core/compiler/future_incompat.rs
+114 −100 src/cargo/core/compiler/job_queue.rs
+6 −1 src/cargo/core/compiler/mod.rs
+1 −1 src/cargo/core/compiler/output_depinfo.rs
+4 −4 src/cargo/core/features.rs
+4 −5 src/cargo/core/resolver/dep_cache.rs
+4 −0 src/cargo/core/resolver/errors.rs
+9 −26 src/cargo/core/resolver/features.rs
+18 −2 src/cargo/core/shell.rs
+3 −26 src/cargo/core/summary.rs
+3 −15 src/cargo/core/workspace.rs
+1 −5 src/cargo/ops/cargo_compile.rs
+12 −4 src/cargo/ops/cargo_install.rs
+12 −3 src/cargo/ops/cargo_read_manifest.rs
+3 −1 src/cargo/ops/common_for_install_and_uninstall.rs
+33 −7 src/cargo/ops/fix.rs
+7 −8 src/cargo/ops/tree/graph.rs
+19 −5 src/cargo/util/important_paths.rs
+1 −1 src/cargo/util/toml/mod.rs
+4 −4 src/doc/contrib/src/tests/writing.md
+4 −4 tests/testsuite/bad_config.rs
+4 −4 tests/testsuite/bench.rs
+46 −7 tests/testsuite/build.rs
+11 −39 tests/testsuite/build_script.rs
+126 −9 tests/testsuite/build_script_extra_link_arg.rs
+2 −4 tests/testsuite/cargo_command.rs
+4 −4 tests/testsuite/cargo_config.rs
+28 −0 tests/testsuite/cargo_env_config.rs
+2 −2 tests/testsuite/clean.rs
+6 −38 tests/testsuite/config.rs
+38 −0 tests/testsuite/dep_info.rs
+14 −9 tests/testsuite/doc.rs
+8 −90 tests/testsuite/features_namespaced.rs
+46 −0 tests/testsuite/fix.rs
+213 −37 tests/testsuite/future_incompat_report.rs
+40 −1 tests/testsuite/install.rs
+9 −21 tests/testsuite/locate_project.rs
+10 −18 tests/testsuite/lockfile_compat.rs
+1 −1 tests/testsuite/metabuild.rs
+29 −7 tests/testsuite/publish.rs
+1 −1 tests/testsuite/verify_project.rs
+51 −33 tests/testsuite/weak_dep_features.rs
1 change: 1 addition & 0 deletions src/tools/rustc-workspace-hack/Cargo.toml
Original file line number Diff line number Diff line change
@@ -61,6 +61,7 @@ features = [
]

[dependencies]
bstr = { version = "0.2.13", features = ["default"] }
byteorder = { version = "1", features = ['default', 'std'] }
curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
crossbeam-utils = { version = "0.8.0", features = ["nightly"] }
114 changes: 93 additions & 21 deletions src/tools/tidy/src/error_codes_check.rs
Original file line number Diff line number Diff line change
@@ -6,20 +6,33 @@ use std::ffi::OsStr;
use std::fs::read_to_string;
use std::path::Path;

use regex::Regex;

// A few of those error codes can't be tested but all the others can and *should* be tested!
const EXEMPTED_FROM_TEST: &[&str] = &[
"E0227", "E0279", "E0280", "E0313", "E0314", "E0315", "E0377", "E0461", "E0462", "E0464",
"E0465", "E0473", "E0474", "E0475", "E0476", "E0479", "E0480", "E0481", "E0482", "E0483",
"E0484", "E0485", "E0486", "E0487", "E0488", "E0489", "E0514", "E0519", "E0523", "E0553",
"E0554", "E0570", "E0629", "E0630", "E0640", "E0717", "E0729",
"E0227", "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0464", "E0465", "E0476",
"E0482", "E0514", "E0519", "E0523", "E0554", "E0570", "E0640", "E0717", "E0729",
];

// Some error codes don't have any tests apparently...
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0729"];

// If the file path contains any of these, we don't want to try to extract error codes from it.
//
// We need to declare each path in the windows version (with backslash).
const PATHS_TO_IGNORE_FOR_EXTRACTION: &[&str] =
&["src/test/", "src\\test\\", "src/doc/", "src\\doc\\", "src/tools/", "src\\tools\\"];

#[derive(Default, Debug)]
struct ErrorCodeStatus {
has_test: bool,
has_explanation: bool,
is_used: bool,
}

fn check_error_code_explanation(
f: &str,
error_codes: &mut HashMap<String, bool>,
error_codes: &mut HashMap<String, ErrorCodeStatus>,
err_code: String,
) -> bool {
let mut invalid_compile_fail_format = false;
@@ -30,15 +43,15 @@ fn check_error_code_explanation(
if s.starts_with("```") {
if s.contains("compile_fail") && s.contains('E') {
if !found_error_code {
error_codes.insert(err_code.clone(), true);
error_codes.get_mut(&err_code).map(|x| x.has_test = true);
found_error_code = true;
}
} else if s.contains("compile-fail") {
invalid_compile_fail_format = true;
}
} else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
if !found_error_code {
error_codes.get_mut(&err_code).map(|x| *x = true);
error_codes.get_mut(&err_code).map(|x| x.has_test = true);
found_error_code = true;
}
}
@@ -77,7 +90,7 @@ macro_rules! some_or_continue {

fn extract_error_codes(
f: &str,
error_codes: &mut HashMap<String, bool>,
error_codes: &mut HashMap<String, ErrorCodeStatus>,
path: &Path,
errors: &mut Vec<String>,
) {
@@ -90,15 +103,16 @@ fn extract_error_codes(
.split_once(':')
.expect(
format!(
"Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} without a `:` delimiter",
"Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} \
without a `:` delimiter",
s,
).as_str()
)
.as_str(),
)
.0
.to_owned();
if !error_codes.contains_key(&err_code) {
error_codes.insert(err_code.clone(), false);
}
error_codes.entry(err_code.clone()).or_default().has_explanation = true;

// Now we extract the tests from the markdown file!
let md_file_name = match s.split_once("include_str!(\"") {
None => continue,
@@ -145,15 +159,15 @@ fn extract_error_codes(
.to_string();
if !error_codes.contains_key(&err_code) {
// this check should *never* fail!
error_codes.insert(err_code, false);
error_codes.insert(err_code, ErrorCodeStatus::default());
}
} else if s == ";" {
reached_no_explanation = true;
}
}
}

fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, bool>) {
fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, ErrorCodeStatus>) {
for line in f.lines() {
let s = line.trim();
if s.starts_with("error[E") || s.starts_with("warning[E") {
@@ -164,8 +178,24 @@ fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, boo
Some((_, err_code)) => err_code,
},
};
let nb = error_codes.entry(err_code.to_owned()).or_insert(false);
*nb = true;
error_codes.entry(err_code.to_owned()).or_default().has_test = true;
}
}
}

fn extract_error_codes_from_source(
f: &str,
error_codes: &mut HashMap<String, ErrorCodeStatus>,
regex: &Regex,
) {
for line in f.lines() {
if line.trim_start().starts_with("//") {
continue;
}
for cap in regex.captures_iter(line) {
if let Some(error_code) = cap.get(1) {
error_codes.entry(error_code.as_str().to_owned()).or_default().is_used = true;
}
}
}
}
@@ -174,8 +204,17 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
let mut errors = Vec::new();
let mut found_explanations = 0;
let mut found_tests = 0;
let mut error_codes: HashMap<String, ErrorCodeStatus> = HashMap::new();
// We want error codes which match the following cases:
//
// * foo(a, E0111, a)
// * foo(a, E0111)
// * foo(E0111, a)
// * #[error = "E0111"]
let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap();

println!("Checking which error codes lack tests...");
let mut error_codes: HashMap<String, bool> = HashMap::new();

for path in paths {
super::walk(path, &mut |path| super::filter_dirs(path), &mut |entry, contents| {
let file_name = entry.file_name();
@@ -185,6 +224,11 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
} else if entry.path().extension() == Some(OsStr::new("stderr")) {
extract_error_codes_from_tests(contents, &mut error_codes);
found_tests += 1;
} else if entry.path().extension() == Some(OsStr::new("rs")) {
let path = entry.path().to_string_lossy();
if PATHS_TO_IGNORE_FOR_EXTRACTION.iter().all(|c| !path.contains(c)) {
extract_error_codes_from_source(contents, &mut error_codes, &regex);
}
}
});
}
@@ -199,15 +243,43 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
if errors.is_empty() {
println!("Found {} error codes", error_codes.len());

for (err_code, nb) in &error_codes {
if !*nb && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
for (err_code, error_status) in &error_codes {
if !error_status.has_test && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
errors.push(format!("Error code {} needs to have at least one UI test!", err_code));
} else if *nb && EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
} else if error_status.has_test && EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
errors.push(format!(
"Error code {} has a UI test, it shouldn't be listed into EXEMPTED_FROM_TEST!",
err_code
));
}
if !error_status.is_used && !error_status.has_explanation {
errors.push(format!(
"Error code {} isn't used and doesn't have an error explanation, it should be \
commented in error_codes.rs file",
err_code
));
}
}
}
if errors.is_empty() {
// Checking if local constants need to be cleaned.
for err_code in EXEMPTED_FROM_TEST {
match error_codes.get(err_code.to_owned()) {
Some(status) => {
if status.has_test {
errors.push(format!(
"{} error code has a test and therefore should be \
removed from the `EXEMPTED_FROM_TEST` constant",
err_code
));
}
}
None => errors.push(format!(
"{} error code isn't used anymore and therefore should be removed \
from `EXEMPTED_FROM_TEST` constant",
err_code
)),
}
}
}
errors.sort();