From ea1460773f1be2d0d717f6ab7609727e52ffa226 Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Mon, 26 Oct 2020 19:04:29 +0530 Subject: make MIR graphviz generation use gsgdt gsgdt [https://crates.io/crates/gsgdt] is a crate which provides an interface for stringly typed graphs. It also provides generation of graphviz dot format from said graph. --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 057b0884e28..3aeb0b8c5b3 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -104,6 +104,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "getopts", "getrandom", "gimli", + "gsgdt", "hashbrown", "hermit-abi", "humantime", -- cgit 1.4.1-3-g733a5 From 3ac1df8b99341fa781aead2f3eeef955309a12f3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 18 Oct 2020 13:53:54 +0200 Subject: consider assignments of union field of ManuallyDrop type safe --- compiler/rustc_middle/src/mir/query.rs | 6 +-- compiler/rustc_mir/src/transform/check_unsafety.rs | 53 ++++++++++++---------- src/test/ui/union/union-unsafe.rs | 6 +-- src/test/ui/union/union-unsafe.stderr | 26 +---------- 4 files changed, 35 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index db0056e482b..03faef4d9fa 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -46,7 +46,7 @@ pub enum UnsafetyViolationDetails { UseOfMutableStatic, UseOfExternStatic, DerefOfRawPointer, - AssignToNonCopyUnionField, + AssignToDroppingUnionField, AccessToUnionField, MutationOfLayoutConstrainedField, BorrowOfLayoutConstrainedField, @@ -94,8 +94,8 @@ impl UnsafetyViolationDetails { "raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules \ and cause data races: all of these are undefined behavior", ), - AssignToNonCopyUnionField => ( - "assignment to non-`Copy` union field", + AssignToDroppingUnionField => ( + "assignment to union field that needs dropping", "the previous content of the field will be dropped, which causes undefined \ behavior if the field was not properly initialized", ), diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index acec3e8f82f..fdc033f9eb3 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -235,37 +235,40 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationDetails::DerefOfRawPointer, ), - ty::Adt(adt, _) => { - if adt.is_union() { - if context == PlaceContext::MutatingUse(MutatingUseContext::Store) - || context == PlaceContext::MutatingUse(MutatingUseContext::Drop) - || context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) - { - let elem_ty = match elem { - ProjectionElem::Field(_, ty) => ty, - _ => span_bug!( - self.source_info.span, - "non-field projection {:?} from union?", - place - ), - }; - if !elem_ty.is_copy_modulo_regions( + ty::Adt(adt, _) if adt.is_union() => { + if context == PlaceContext::MutatingUse(MutatingUseContext::Store) + || context == PlaceContext::MutatingUse(MutatingUseContext::Drop) + || context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) + { + let elem_ty = match elem { + ProjectionElem::Field(_, ty) => ty, + _ => span_bug!( + self.source_info.span, + "non-field projection {:?} from union?", + place + ), + }; + let manually_drop = elem_ty + .ty_adt_def() + .map_or(false, |adt_def| adt_def.is_manually_drop()); + let nodrop = manually_drop + || elem_ty.is_copy_modulo_regions( self.tcx.at(self.source_info.span), self.param_env, - ) { - self.require_unsafe( - UnsafetyViolationKind::GeneralAndConstFn, - UnsafetyViolationDetails::AssignToNonCopyUnionField, - ) - } else { - // write to non-move union, safe - } - } else { + ); + if !nodrop { self.require_unsafe( UnsafetyViolationKind::GeneralAndConstFn, - UnsafetyViolationDetails::AccessToUnionField, + UnsafetyViolationDetails::AssignToDroppingUnionField, ) + } else { + // write to non-drop union field, safe } + } else { + self.require_unsafe( + UnsafetyViolationKind::GeneralAndConstFn, + UnsafetyViolationDetails::AccessToUnionField, + ) } } _ => {} diff --git a/src/test/ui/union/union-unsafe.rs b/src/test/ui/union/union-unsafe.rs index 10f0c467560..9810ed75d59 100644 --- a/src/test/ui/union/union-unsafe.rs +++ b/src/test/ui/union/union-unsafe.rs @@ -18,7 +18,7 @@ union U4 { fn generic_noncopy() { let mut u3 = U3 { a: ManuallyDrop::new(T::default()) }; - u3.a = ManuallyDrop::new(T::default()); //~ ERROR assignment to non-`Copy` union field is unsafe + u3.a = ManuallyDrop::new(T::default()); // OK (assignment does not drop) *u3.a = T::default(); //~ ERROR access to union field is unsafe } @@ -41,7 +41,7 @@ fn main() { // let U1 { .. } = u1; // OK let mut u2 = U2 { a: ManuallyDrop::new(String::from("old")) }; // OK - u2.a = ManuallyDrop::new(String::from("new")); //~ ERROR assignment to non-`Copy` union + u2.a = ManuallyDrop::new(String::from("new")); // OK (assignment does not drop) *u2.a = String::from("new"); //~ ERROR access to union field is unsafe let mut u3 = U3 { a: ManuallyDrop::new(0) }; // OK @@ -49,6 +49,6 @@ fn main() { *u3.a = 1; //~ ERROR access to union field is unsafe let mut u3 = U3 { a: ManuallyDrop::new(String::from("old")) }; // OK - u3.a = ManuallyDrop::new(String::from("new")); //~ ERROR assignment to non-`Copy` union + u3.a = ManuallyDrop::new(String::from("new")); // OK (assignment does not drop) *u3.a = String::from("new"); //~ ERROR access to union field is unsafe } diff --git a/src/test/ui/union/union-unsafe.stderr b/src/test/ui/union/union-unsafe.stderr index b50d9e17506..5b3a58814a9 100644 --- a/src/test/ui/union/union-unsafe.stderr +++ b/src/test/ui/union/union-unsafe.stderr @@ -1,11 +1,3 @@ -error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:21:5 - | -LL | u3.a = ManuallyDrop::new(T::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field - | - = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized - error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/union-unsafe.rs:22:6 | @@ -46,14 +38,6 @@ LL | if let U1 { a: 12 } = u1 {} | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:44:5 - | -LL | u2.a = ManuallyDrop::new(String::from("new")); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field - | - = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized - error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/union-unsafe.rs:45:6 | @@ -70,14 +54,6 @@ LL | *u3.a = 1; | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:52:5 - | -LL | u3.a = ManuallyDrop::new(String::from("new")); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field - | - = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized - error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/union-unsafe.rs:53:6 | @@ -86,6 +62,6 @@ LL | *u3.a = String::from("new"); | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 11 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0133`. -- cgit 1.4.1-3-g733a5 From 64856e29c1c780117348c196e05902476251bc92 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 24 Oct 2020 21:12:32 +0200 Subject: adjust union access unsafety check logic to take into account Deref and the actual type of the assignment --- compiler/rustc_mir/src/transform/check_unsafety.rs | 35 ++++++++++-------- src/test/ui/union/union-unsafe.rs | 21 +++++++++++ src/test/ui/union/union-unsafe.stderr | 42 +++++++++++++++++----- 3 files changed, 74 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index fdc033f9eb3..e78f8d4c901 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -190,7 +190,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } } - for (i, elem) in place.projection.iter().enumerate() { + for (i, _elem) in place.projection.iter().enumerate() { let proj_base = &place.projection[..i]; if context.is_borrow() { if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { @@ -236,23 +236,28 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { UnsafetyViolationDetails::DerefOfRawPointer, ), ty::Adt(adt, _) if adt.is_union() => { - if context == PlaceContext::MutatingUse(MutatingUseContext::Store) + let assign_to_field = context + == PlaceContext::MutatingUse(MutatingUseContext::Store) || context == PlaceContext::MutatingUse(MutatingUseContext::Drop) - || context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) - { - let elem_ty = match elem { - ProjectionElem::Field(_, ty) => ty, - _ => span_bug!( - self.source_info.span, - "non-field projection {:?} from union?", - place - ), - }; - let manually_drop = elem_ty + || context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput); + // If there is a `Deref` further along the projection chain, this is *not* an + // assignment to a union field. In that case the union field is just read to + // obtain the pointer/reference. + let assign_to_field = assign_to_field + && !place.projection[i..] + .iter() + .any(|elem| matches!(elem, ProjectionElem::Deref)); + // If this is just an assignment, determine if the assigned type needs dropping. + if assign_to_field { + // We have to check the actual type of the assignment, as that determines if the + // old value is being dropped. + let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty; + // To avoid semver hazard, we only consider `Copy` and `ManuallyDrop` non-dropping. + let manually_drop = assigned_ty .ty_adt_def() .map_or(false, |adt_def| adt_def.is_manually_drop()); let nodrop = manually_drop - || elem_ty.is_copy_modulo_regions( + || assigned_ty.is_copy_modulo_regions( self.tcx.at(self.source_info.span), self.param_env, ); @@ -260,7 +265,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.require_unsafe( UnsafetyViolationKind::GeneralAndConstFn, UnsafetyViolationDetails::AssignToDroppingUnionField, - ) + ); } else { // write to non-drop union field, safe } diff --git a/src/test/ui/union/union-unsafe.rs b/src/test/ui/union/union-unsafe.rs index 9810ed75d59..9c7ed1f7bfc 100644 --- a/src/test/ui/union/union-unsafe.rs +++ b/src/test/ui/union/union-unsafe.rs @@ -1,4 +1,6 @@ +#![feature(untagged_unions)] use std::mem::ManuallyDrop; +use std::cell::RefCell; union U1 { a: u8 @@ -16,6 +18,25 @@ union U4 { a: T } +union URef { + p: &'static mut i32, +} + +union URefCell { // field that does not drop but is not `Copy`, either + a: (RefCell, i32), +} + +fn deref_union_field(mut u: URef) { + // Not an assignment but an access to the union field! + *(u.p) = 13; //~ ERROR access to union field is unsafe +} + +fn assign_noncopy_union_field(mut u: URefCell) { + u.a = (RefCell::new(0), 1); //~ ERROR assignment to union field that needs dropping + u.a.0 = RefCell::new(0); //~ ERROR assignment to union field that needs dropping + u.a.1 = 1; // OK +} + fn generic_noncopy() { let mut u3 = U3 { a: ManuallyDrop::new(T::default()) }; u3.a = ManuallyDrop::new(T::default()); // OK (assignment does not drop) diff --git a/src/test/ui/union/union-unsafe.stderr b/src/test/ui/union/union-unsafe.stderr index 5b3a58814a9..f80d4394f84 100644 --- a/src/test/ui/union/union-unsafe.stderr +++ b/src/test/ui/union/union-unsafe.stderr @@ -1,5 +1,29 @@ error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:22:6 + --> $DIR/union-unsafe.rs:31:5 + | +LL | *(u.p) = 13; + | ^^^^^^^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: assignment to union field that needs dropping is unsafe and requires unsafe function or block + --> $DIR/union-unsafe.rs:35:5 + | +LL | u.a = (RefCell::new(0), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that needs dropping + | + = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized + +error[E0133]: assignment to union field that needs dropping is unsafe and requires unsafe function or block + --> $DIR/union-unsafe.rs:36:5 + | +LL | u.a.0 = RefCell::new(0); + | ^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that needs dropping + | + = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-unsafe.rs:43:6 | LL | *u3.a = T::default(); | ^^^^ access to union field @@ -7,7 +31,7 @@ LL | *u3.a = T::default(); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:28:6 + --> $DIR/union-unsafe.rs:49:6 | LL | *u3.a = T::default(); | ^^^^ access to union field @@ -15,7 +39,7 @@ LL | *u3.a = T::default(); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:36:13 + --> $DIR/union-unsafe.rs:57:13 | LL | let a = u1.a; | ^^^^ access to union field @@ -23,7 +47,7 @@ LL | let a = u1.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:39:14 + --> $DIR/union-unsafe.rs:60:14 | LL | let U1 { a } = u1; | ^ access to union field @@ -31,7 +55,7 @@ LL | let U1 { a } = u1; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:40:20 + --> $DIR/union-unsafe.rs:61:20 | LL | if let U1 { a: 12 } = u1 {} | ^^ access to union field @@ -39,7 +63,7 @@ LL | if let U1 { a: 12 } = u1 {} = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:45:6 + --> $DIR/union-unsafe.rs:66:6 | LL | *u2.a = String::from("new"); | ^^^^ access to union field @@ -47,7 +71,7 @@ LL | *u2.a = String::from("new"); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:49:6 + --> $DIR/union-unsafe.rs:70:6 | LL | *u3.a = 1; | ^^^^ access to union field @@ -55,13 +79,13 @@ LL | *u3.a = 1; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:53:6 + --> $DIR/union-unsafe.rs:74:6 | LL | *u3.a = String::from("new"); | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 8 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0133`. -- cgit 1.4.1-3-g733a5 From af309cc2d93ce1e8e57cedffbfc35f9df040376a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 Oct 2020 08:57:57 +0100 Subject: needs -> might need --- compiler/rustc_middle/src/mir/query.rs | 2 +- src/test/ui/union/union-unsafe.rs | 4 ++-- src/test/ui/union/union-unsafe.stderr | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 03faef4d9fa..89a93096f1c 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -95,7 +95,7 @@ impl UnsafetyViolationDetails { and cause data races: all of these are undefined behavior", ), AssignToDroppingUnionField => ( - "assignment to union field that needs dropping", + "assignment to union field that might need dropping", "the previous content of the field will be dropped, which causes undefined \ behavior if the field was not properly initialized", ), diff --git a/src/test/ui/union/union-unsafe.rs b/src/test/ui/union/union-unsafe.rs index 9c7ed1f7bfc..6adf0ac59b9 100644 --- a/src/test/ui/union/union-unsafe.rs +++ b/src/test/ui/union/union-unsafe.rs @@ -32,8 +32,8 @@ fn deref_union_field(mut u: URef) { } fn assign_noncopy_union_field(mut u: URefCell) { - u.a = (RefCell::new(0), 1); //~ ERROR assignment to union field that needs dropping - u.a.0 = RefCell::new(0); //~ ERROR assignment to union field that needs dropping + u.a = (RefCell::new(0), 1); //~ ERROR assignment to union field that might need dropping + u.a.0 = RefCell::new(0); //~ ERROR assignment to union field that might need dropping u.a.1 = 1; // OK } diff --git a/src/test/ui/union/union-unsafe.stderr b/src/test/ui/union/union-unsafe.stderr index f80d4394f84..a25c09144f7 100644 --- a/src/test/ui/union/union-unsafe.stderr +++ b/src/test/ui/union/union-unsafe.stderr @@ -6,19 +6,19 @@ LL | *(u.p) = 13; | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error[E0133]: assignment to union field that needs dropping is unsafe and requires unsafe function or block +error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block --> $DIR/union-unsafe.rs:35:5 | LL | u.a = (RefCell::new(0), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that needs dropping + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping | = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized -error[E0133]: assignment to union field that needs dropping is unsafe and requires unsafe function or block +error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block --> $DIR/union-unsafe.rs:36:5 | LL | u.a.0 = RefCell::new(0); - | ^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that needs dropping + | ^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping | = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized -- cgit 1.4.1-3-g733a5 From 3d11e96569861f2df3254af65bd8065dc70474bf Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Mon, 23 Nov 2020 15:51:01 +0100 Subject: Fix order of diff when rustdoc tests fail --- src/tools/compiletest/src/runtest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 4ca0b2aba0a..57926fedfd4 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2436,7 +2436,7 @@ impl<'test> TestCx<'test> { }) }; let mut diff = Command::new("diff"); - diff.args(&["-u", "-r"]).args(&[out_dir, &compare_dir]); + diff.args(&["-u", "-r"]).args(&[&compare_dir, out_dir]); let output = if let Some(pager) = pager { let diff_pid = diff.stdout(Stdio::piped()).spawn().expect("failed to run `diff`"); -- cgit 1.4.1-3-g733a5 From d93f1d6c04fab017a24d868dd766a290321e636c Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Mon, 23 Nov 2020 13:22:56 +0100 Subject: Apply `doc(cfg)` from parent items while collecting trait impls Because trait impls bypass the standard `clean` hierarchy they do not participate in the `propagate_doc_cfg` pass, so instead we need to pre-collect all possible `doc(cfg)` attributes that will apply to them when cleaning. --- src/librustdoc/clean/inline.rs | 10 +++---- src/librustdoc/passes/collect_trait_impls.rs | 28 ++++++++++++++++++- src/test/rustdoc/doc-cfg.rs | 3 +- src/test/rustdoc/issue-79201.rs | 41 ++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 src/test/rustdoc/issue-79201.rs (limited to 'src') diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cc3e8707e52..17963e44a01 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -339,9 +339,6 @@ crate fn build_impl( return; } - let attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs); - debug!("merged_attrs={:?}", attrs); - let tcx = cx.tcx; let associated_trait = tcx.impl_trait_ref(did); @@ -435,7 +432,7 @@ crate fn build_impl( debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id()); - ret.push(clean::Item::from_def_id_and_parts( + let mut item = clean::Item::from_def_id_and_parts( did, None, clean::ImplItem(clean::Impl { @@ -450,7 +447,10 @@ crate fn build_impl( blanket_impl: None, }), cx, - )); + ); + item.attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs); + debug!("merged_attrs={:?}", item.attrs); + ret.push(item); } fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) -> clean::Module { diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 2946db1f462..62eb7d4d11f 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -5,6 +5,7 @@ use crate::fold::DocFolder; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_middle::ty::DefIdTree; use rustc_span::symbol::sym; crate const COLLECT_TRAIT_IMPLS: Pass = Pass { @@ -90,7 +91,32 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { for &impl_node in cx.tcx.hir().trait_impls(trait_did) { let impl_did = cx.tcx.hir().local_def_id(impl_node); cx.tcx.sess.time("build_local_trait_impl", || { - inline::build_impl(cx, None, impl_did.to_def_id(), None, &mut new_items); + let mut extra_attrs = Vec::new(); + let mut parent = cx.tcx.parent(impl_did.to_def_id()); + while let Some(did) = parent { + extra_attrs.extend( + cx.tcx + .get_attrs(did) + .iter() + .filter(|attr| attr.has_name(sym::doc)) + .filter(|attr| { + if let Some([attr]) = attr.meta_item_list().as_deref() { + attr.has_name(sym::cfg) + } else { + false + } + }) + .cloned(), + ); + parent = cx.tcx.parent(did); + } + inline::build_impl( + cx, + None, + impl_did.to_def_id(), + Some(&extra_attrs), + &mut new_items, + ); }); } } diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs index d7041ee2f1a..471dd3a9d18 100644 --- a/src/test/rustdoc/doc-cfg.rs +++ b/src/test/rustdoc/doc-cfg.rs @@ -25,12 +25,13 @@ pub mod unix_only { // @has doc_cfg/unix_only/trait.ArmOnly.html \ // '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ // 'This is supported on Unix and ARM only.' - // @count - '//*[@class="stab portability"]' 2 + // @count - '//*[@class="stab portability"]' 1 #[doc(cfg(target_arch = "arm"))] pub trait ArmOnly { fn unix_and_arm_only_function(); } + #[doc(cfg(target_arch = "arm"))] impl ArmOnly for super::Portable { fn unix_and_arm_only_function() {} } diff --git a/src/test/rustdoc/issue-79201.rs b/src/test/rustdoc/issue-79201.rs new file mode 100644 index 00000000000..f95d79cd493 --- /dev/null +++ b/src/test/rustdoc/issue-79201.rs @@ -0,0 +1,41 @@ +#![feature(doc_cfg)] + +// @has 'issue_79201/trait.Foo.html' +// @count - '//*[@class="stab portability"]' 6 +// @matches - '//*[@class="stab portability"]' 'crate feature foo-root' +// @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod' +// @matches - '//*[@class="stab portability"]' 'crate feature foo-private-mod' +// @matches - '//*[@class="stab portability"]' 'crate feature foo-fn' +// @matches - '//*[@class="stab portability"]' 'crate feature foo-method' + +pub trait Foo {} + +#[doc(cfg(feature = "foo-root"))] +impl crate::Foo for usize {} + +#[doc(cfg(feature = "foo-public-mod"))] +pub mod public { + impl crate::Foo for u8 {} +} + +#[doc(cfg(feature = "foo-private-mod"))] +mod private { + impl crate::Foo for u16 {} +} + +#[doc(cfg(feature = "foo-const"))] +const _: () = { + impl crate::Foo for u32 {} +}; + +#[doc(cfg(feature = "foo-fn"))] +fn __() { + impl crate::Foo for u64 {} +} + +#[doc(cfg(feature = "foo-method"))] +impl dyn Foo { + fn __() { + impl crate::Foo for u128 {} + } +} -- cgit 1.4.1-3-g733a5 From 9b09dc05794faf13f580bc7cc57788dfa32e28de Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 24 Nov 2020 14:13:04 +0100 Subject: Show hidden elements by default when JS is disabled --- src/librustdoc/html/static/noscript.css | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/librustdoc/html/static/noscript.css b/src/librustdoc/html/static/noscript.css index 832bd9ba2d6..ffa1a7639ab 100644 --- a/src/librustdoc/html/static/noscript.css +++ b/src/librustdoc/html/static/noscript.css @@ -1,3 +1,9 @@ +/* +This whole CSS file is used only in case rustdoc is rendered with javascript disabled. Since a lot +of content is hidden by default (depending on the settings too), we have to overwrite some of the +rules. +*/ + #main > h2 + div, #main > h2 + h3, #main > h3 + div { display: block; } @@ -13,3 +19,7 @@ #main > h2 + h3 { display: flex; } + +#main .impl-items .hidden { + display: block !important; +} -- cgit 1.4.1-3-g733a5 From 0387981f2b5e41c982ec4a1b102f0c54997361ff Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Sat, 17 Oct 2020 19:48:40 +0200 Subject: Add --no-deps command-line argument --- clippy_workspace_tests/path_dep/Cargo.toml | 3 ++ clippy_workspace_tests/path_dep/src/lib.rs | 6 +++ clippy_workspace_tests/subcrate/Cargo.toml | 3 ++ src/driver.rs | 37 +++++++++------- tests/dogfood.rs | 71 +++++++++++++++++++++++++++++- 5 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 clippy_workspace_tests/path_dep/Cargo.toml create mode 100644 clippy_workspace_tests/path_dep/src/lib.rs (limited to 'src') diff --git a/clippy_workspace_tests/path_dep/Cargo.toml b/clippy_workspace_tests/path_dep/Cargo.toml new file mode 100644 index 00000000000..85a91cd2dec --- /dev/null +++ b/clippy_workspace_tests/path_dep/Cargo.toml @@ -0,0 +1,3 @@ +[package] +name = "path_dep" +version = "0.1.0" diff --git a/clippy_workspace_tests/path_dep/src/lib.rs b/clippy_workspace_tests/path_dep/src/lib.rs new file mode 100644 index 00000000000..35ce524f2b1 --- /dev/null +++ b/clippy_workspace_tests/path_dep/src/lib.rs @@ -0,0 +1,6 @@ +#![deny(clippy::empty_loop)] + +#[cfg(feature = "primary_package_test")] +pub fn lint_me() { + loop {} +} diff --git a/clippy_workspace_tests/subcrate/Cargo.toml b/clippy_workspace_tests/subcrate/Cargo.toml index 83ea5868160..45362c11b85 100644 --- a/clippy_workspace_tests/subcrate/Cargo.toml +++ b/clippy_workspace_tests/subcrate/Cargo.toml @@ -1,3 +1,6 @@ [package] name = "subcrate" version = "0.1.0" + +[dependencies] +path_dep = { path = "../path_dep" } diff --git a/src/driver.rs b/src/driver.rs index ef31c72481a..bbe9ce73936 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -277,27 +277,34 @@ pub fn main() { args.extend(vec!["--sysroot".into(), sys_root]); }; + let mut no_deps = false; + let clippy_args = env::var("CLIPPY_ARGS") + .unwrap_or_default() + .split("__CLIPPY_HACKERY__") + .filter_map(|s| match s { + "" => None, + "--no-deps" => { + no_deps = true; + None + }, + _ => Some(s.to_string()), + }) + .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]) + .collect::>(); + // this check ensures that dependencies are built but not linted and the final // crate is linted but not built - let clippy_enabled = env::var("CLIPPY_TESTS").map_or(false, |val| val == "true") - || arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_none(); - - if clippy_enabled { - args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]); - if let Ok(extra_args) = env::var("CLIPPY_ARGS") { - args.extend(extra_args.split("__CLIPPY_HACKERY__").filter_map(|s| { - if s.is_empty() { - None - } else { - Some(s.to_string()) - } - })); - } + let clippy_disabled = env::var("CLIPPY_TESTS").map_or(false, |val| val != "true") + || arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some() + || no_deps && env::var("CARGO_PRIMARY_PACKAGE").is_err(); + + if !clippy_disabled { + args.extend(clippy_args); } let mut clippy = ClippyCallbacks; let mut default = DefaultCallbacks; let callbacks: &mut (dyn rustc_driver::Callbacks + Send) = - if clippy_enabled { &mut clippy } else { &mut default }; + if clippy_disabled { &mut default } else { &mut clippy }; rustc_driver::RunCompiler::new(&args, callbacks).run() })) } diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 48e0478f169..b166a6b7c1f 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -3,7 +3,7 @@ #![feature(once_cell)] use std::lazy::SyncLazy; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; mod cargo; @@ -41,12 +41,77 @@ fn dogfood_clippy() { #[test] fn dogfood_subprojects() { + fn test_no_deps_ignores_path_deps_in_workspaces() { + fn clean(cwd: &Path, target_dir: &Path) { + Command::new("cargo") + .current_dir(cwd) + .env("CARGO_TARGET_DIR", target_dir) + .arg("clean") + .args(&["-p", "subcrate"]) + .args(&["-p", "path_dep"]) + .output() + .unwrap(); + } + + if cargo::is_rustc_test_suite() { + return; + } + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let target_dir = root.join("target").join("dogfood"); + let cwd = root.join("clippy_workspace_tests"); + + // Make sure we start with a clean state + clean(&cwd, &target_dir); + + // `path_dep` is a path dependency of `subcrate` that would trigger a denied lint. + // Make sure that with the `--no-deps` argument Clippy does not run on `path_dep`. + let output = Command::new(&*CLIPPY_PATH) + .current_dir(&cwd) + .env("CLIPPY_DOGFOOD", "1") + .env("CARGO_INCREMENTAL", "0") + .arg("clippy") + .args(&["-p", "subcrate"]) + .arg("--") + .arg("--no-deps") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .args(&["--cfg", r#"feature="primary_package_test""#]) + .output() + .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + + assert!(output.status.success()); + + // Make sure we start with a clean state + clean(&cwd, &target_dir); + + // Test that without the `--no-deps` argument, `path_dep` is linted. + let output = Command::new(&*CLIPPY_PATH) + .current_dir(&cwd) + .env("CLIPPY_DOGFOOD", "1") + .env("CARGO_INCREMENTAL", "0") + .arg("clippy") + .args(&["-p", "subcrate"]) + .arg("--") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .args(&["--cfg", r#"feature="primary_package_test""#]) + .output() + .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + + assert!(!output.status.success()); + } + // run clippy on remaining subprojects and fail the test if lint warnings are reported if cargo::is_rustc_test_suite() { return; } let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + // NOTE: `path_dep` crate is omitted on purpose here for d in &[ "clippy_workspace_tests", "clippy_workspace_tests/src", @@ -72,4 +137,8 @@ fn dogfood_subprojects() { assert!(output.status.success()); } + + // NOTE: Since tests run in parallel we can't run cargo commands on the same workspace at the + // same time, so we test this immediately after the dogfood for workspaces. + test_no_deps_ignores_path_deps_in_workspaces(); } -- cgit 1.4.1-3-g733a5 From 7eda421e9629a717d31ec03d12b4befd03f5fb50 Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Wed, 25 Nov 2020 15:02:47 +0100 Subject: Apply suggestion regarding clippy_enabled bool --- src/driver.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/driver.rs b/src/driver.rs index bbe9ce73936..03381106de1 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -182,6 +182,7 @@ fn toolchain_path(home: Option, toolchain: Option) -> Option Date: Fri, 27 Nov 2020 16:53:30 +0100 Subject: Make --fix imply --no-deps --- src/main.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 6739a4cf224..ea06743394d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,7 +62,7 @@ struct ClippyCmd { unstable_options: bool, cargo_subcommand: &'static str, args: Vec, - clippy_args: String, + clippy_args: Vec, } impl ClippyCmd { @@ -99,7 +99,10 @@ impl ClippyCmd { args.insert(0, "+nightly".to_string()); } - let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect(); + let mut clippy_args: Vec = old_args.collect(); + if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") { + clippy_args.push("--no-deps".into()); + } ClippyCmd { unstable_options, @@ -147,10 +150,15 @@ impl ClippyCmd { fn into_std_cmd(self) -> Command { let mut cmd = Command::new("cargo"); + let clippy_args: String = self + .clippy_args + .iter() + .map(|arg| format!("{}__CLIPPY_HACKERY__", arg)) + .collect(); cmd.env(self.path_env(), Self::path()) .envs(ClippyCmd::target_dir()) - .env("CLIPPY_ARGS", self.clippy_args) + .env("CLIPPY_ARGS", clippy_args) .arg(self.cargo_subcommand) .args(&self.args); @@ -201,6 +209,24 @@ mod tests { assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options"))); } + #[test] + fn fix_implies_no_deps() { + let args = "cargo clippy --fix -Zunstable-options" + .split_whitespace() + .map(ToString::to_string); + let cmd = ClippyCmd::new(args); + assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps")); + } + + #[test] + fn no_deps_not_duplicated_with_fix() { + let args = "cargo clippy --fix -Zunstable-options -- --no-deps" + .split_whitespace() + .map(ToString::to_string); + let cmd = ClippyCmd::new(args); + assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1); + } + #[test] fn check() { let args = "cargo clippy".split_whitespace().map(ToString::to_string); -- cgit 1.4.1-3-g733a5 From 952b731fb9134e44e4c99bae46e6a917c944e77e Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Fri, 27 Nov 2020 18:04:30 +0100 Subject: Reword bitrotten comment --- src/driver.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/driver.rs b/src/driver.rs index 03381106de1..e490ee54c0b 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -293,8 +293,11 @@ pub fn main() { .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]) .collect::>(); - // this check ensures that dependencies are built but not linted and the final - // crate is linted but not built + // We enable Clippy if one of the following conditions is met + // - IF Clippy is run on its test suite OR + // - IF Clippy is run on the main crate, not on deps (`!cap_lints_allow`) THEN + // - IF `--no-deps` is not set (`!no_deps`) OR + // - IF `--no-deps` is set and Clippy is run on the specified primary package let clippy_tests_set = env::var("CLIPPY_TESTS").map_or(false, |val| val == "true"); let cap_lints_allow = arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some(); let in_primary_package = env::var("CARGO_PRIMARY_PACKAGE").is_ok(); -- cgit 1.4.1-3-g733a5 From 75eb72cc9c23d31f10bd7b4ec6331dd8383cf829 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 15 Nov 2020 13:03:30 +0000 Subject: passes: prohibit attrs on generic params This commit modifies the `check_attr` pass so that attribute placement on generic parameters is checked for validity. Signed-off-by: David Wood --- compiler/rustc_hir/src/target.rs | 23 ++++++++ compiler/rustc_passes/src/check_attr.rs | 12 ++++ src/test/ui/issues/issue-78957.rs | 30 ++++++++++ src/test/ui/issues/issue-78957.stderr | 69 ++++++++++++++++++++++ src/test/ui/proc-macro/ambiguous-builtin-attrs.rs | 4 +- .../ui/proc-macro/ambiguous-builtin-attrs.stderr | 14 +++-- 6 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/issues/issue-78957.rs create mode 100644 src/test/ui/issues/issue-78957.stderr (limited to 'src') diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index b870e4c6ead..2774cc9c08e 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -9,6 +9,13 @@ use crate::{Item, ItemKind, TraitItem, TraitItemKind}; use std::fmt::{self, Display}; +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum GenericParamKind { + Type, + Lifetime, + Const, +} + #[derive(Copy, Clone, PartialEq, Debug)] pub enum MethodKind { Trait { body: bool }, @@ -43,6 +50,7 @@ pub enum Target { ForeignFn, ForeignStatic, ForeignTy, + GenericParam(GenericParamKind), } impl Display for Target { @@ -77,6 +85,11 @@ impl Display for Target { Target::ForeignFn => "foreign function", Target::ForeignStatic => "foreign static item", Target::ForeignTy => "foreign type", + Target::GenericParam(kind) => match kind { + GenericParamKind::Type => "type parameter", + GenericParamKind::Lifetime => "lifetime parameter", + GenericParamKind::Const => "const parameter", + }, } ) } @@ -124,4 +137,14 @@ impl Target { hir::ForeignItemKind::Type => Target::ForeignTy, } } + + pub fn from_generic_param(generic_param: &hir::GenericParam<'_>) -> Target { + match generic_param.kind { + hir::GenericParamKind::Type { .. } => Target::GenericParam(GenericParamKind::Type), + hir::GenericParamKind::Lifetime { .. } => { + Target::GenericParam(GenericParamKind::Lifetime) + } + hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const), + } + } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9c0234953bb..e0babd1885b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -814,6 +814,18 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { intravisit::walk_item(self, item) } + fn visit_generic_param(&mut self, generic_param: &'tcx hir::GenericParam<'tcx>) { + let target = Target::from_generic_param(generic_param); + self.check_attributes( + generic_param.hir_id, + generic_param.attrs, + &generic_param.span, + target, + None, + ); + intravisit::walk_generic_param(self, generic_param) + } + fn visit_trait_item(&mut self, trait_item: &'tcx TraitItem<'tcx>) { let target = Target::from_trait_item(trait_item); self.check_attributes(trait_item.hir_id, &trait_item.attrs, &trait_item.span, target, None); diff --git a/src/test/ui/issues/issue-78957.rs b/src/test/ui/issues/issue-78957.rs new file mode 100644 index 00000000000..263c69bbc0b --- /dev/null +++ b/src/test/ui/issues/issue-78957.rs @@ -0,0 +1,30 @@ +#![deny(unused_attributes)] +#![feature(min_const_generics)] + +use std::marker::PhantomData; + +pub struct Foo<#[inline] const N: usize>; +//~^ ERROR attribute should be applied to function or closure +pub struct Bar<#[cold] const N: usize>; +//~^ ERROR attribute should be applied to a function +//~| WARN this was previously accepted +pub struct Baz<#[repr(C)] const N: usize>; +//~^ ERROR attribute should be applied to a struct, enum, or union +// +pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); +//~^ ERROR attribute should be applied to function or closure +pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); +//~^ ERROR attribute should be applied to a function +//~| WARN this was previously accepted +pub struct Baz2<#[repr(C)] 'a>(PhantomData<&'a ()>); +//~^ ERROR attribute should be applied to a struct, enum, or union +// +pub struct Foo3<#[inline] T>(PhantomData); +//~^ ERROR attribute should be applied to function or closure +pub struct Bar3<#[cold] T>(PhantomData); +//~^ ERROR attribute should be applied to a function +//~| WARN this was previously accepted +pub struct Baz3<#[repr(C)] T>(PhantomData); +//~^ ERROR attribute should be applied to a struct, enum, or union + +fn main() {} diff --git a/src/test/ui/issues/issue-78957.stderr b/src/test/ui/issues/issue-78957.stderr new file mode 100644 index 00000000000..26437ee4bef --- /dev/null +++ b/src/test/ui/issues/issue-78957.stderr @@ -0,0 +1,69 @@ +error[E0518]: attribute should be applied to function or closure + --> $DIR/issue-78957.rs:6:16 + | +LL | pub struct Foo<#[inline] const N: usize>; + | ^^^^^^^^^ - not a function or closure + +error: attribute should be applied to a function + --> $DIR/issue-78957.rs:8:16 + | +LL | pub struct Bar<#[cold] const N: usize>; + | ^^^^^^^ - not a function + | +note: the lint level is defined here + --> $DIR/issue-78957.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error[E0517]: attribute should be applied to a struct, enum, or union + --> $DIR/issue-78957.rs:11:23 + | +LL | pub struct Baz<#[repr(C)] const N: usize>; + | ^ - not a struct, enum, or union + +error[E0518]: attribute should be applied to function or closure + --> $DIR/issue-78957.rs:14:17 + | +LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); + | ^^^^^^^^^ -- not a function or closure + +error: attribute should be applied to a function + --> $DIR/issue-78957.rs:16:17 + | +LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); + | ^^^^^^^ -- not a function + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error[E0517]: attribute should be applied to a struct, enum, or union + --> $DIR/issue-78957.rs:19:24 + | +LL | pub struct Baz2<#[repr(C)] 'a>(PhantomData<&'a ()>); + | ^ -- not a struct, enum, or union + +error[E0518]: attribute should be applied to function or closure + --> $DIR/issue-78957.rs:22:17 + | +LL | pub struct Foo3<#[inline] T>(PhantomData); + | ^^^^^^^^^ - not a function or closure + +error: attribute should be applied to a function + --> $DIR/issue-78957.rs:24:17 + | +LL | pub struct Bar3<#[cold] T>(PhantomData); + | ^^^^^^^ - not a function + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error[E0517]: attribute should be applied to a struct, enum, or union + --> $DIR/issue-78957.rs:27:24 + | +LL | pub struct Baz3<#[repr(C)] T>(PhantomData); + | ^ - not a struct, enum, or union + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0517, E0518. +For more information about an error, try `rustc --explain E0517`. diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs index 9f4f0abf324..142efb3c6cd 100644 --- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -17,7 +17,9 @@ fn test() {} #[bench] // OK, shadowed fn bench() {} -fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous +fn non_macro_expanded_location<#[repr(C)] T>() { + //~^ ERROR `repr` is ambiguous + //~| ERROR attribute should be applied to a struct, enum, or union match 0u8 { #[repr(C)] //~ ERROR `repr` is ambiguous _ => {} diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr index 23310f6c6f5..276ee1cfd35 100644 --- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `NonExistent` in this scope - --> $DIR/ambiguous-builtin-attrs.rs:30:5 + --> $DIR/ambiguous-builtin-attrs.rs:32:5 | LL | NonExistent; | ^^^^^^^^^^^ not found in this scope @@ -47,7 +47,7 @@ LL | use builtin_attrs::*; = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous (built-in attribute vs any other name) - --> $DIR/ambiguous-builtin-attrs.rs:22:11 + --> $DIR/ambiguous-builtin-attrs.rs:24:11 | LL | #[repr(C)] | ^^^^ ambiguous name @@ -74,7 +74,13 @@ LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ = help: use `crate::feature` to refer to this attribute macro unambiguously -error: aborting due to 6 previous errors +error[E0517]: attribute should be applied to a struct, enum, or union + --> $DIR/ambiguous-builtin-attrs.rs:20:39 + | +LL | fn non_macro_expanded_location<#[repr(C)] T>() { + | ^ - not a struct, enum, or union + +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0425, E0659. +Some errors have detailed explanations: E0425, E0517, E0659. For more information about an error, try `rustc --explain E0425`. -- cgit 1.4.1-3-g733a5 From 06ca6bba8dd21fe3330b2212a34c6bf244300486 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 22 Nov 2020 21:58:41 +0000 Subject: Add tests --- .../integer-ranges/overlapping_range_endpoints.rs | 6 ++++++ .../integer-ranges/overlapping_range_endpoints.stderr | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs index af720a05693..2463d5cf4dc 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs @@ -33,6 +33,12 @@ fn main() { m!(0u8, 25, 20..=30); m!(0u8, 30, 20..=30); //~ ERROR multiple patterns covering the same range + match 0u8 { + 0..=10 => {} + 20..=30 => {} + 10..=20 => {} //~ ERROR multiple patterns covering the same range + _ => {} + } match (0u8, true) { (0..=10, true) => {} (10..20, true) => {} // not detected diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index 7bb747cdf6f..5351a7e61c2 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -61,7 +61,17 @@ LL | m!(0u8, 30, 20..=30); | this range overlaps on `30_u8` error: multiple patterns covering the same range - --> $DIR/overlapping_range_endpoints.rs:44:16 + --> $DIR/overlapping_range_endpoints.rs:39:9 + | +LL | 0..=10 => {} + | ------ this range overlaps on `10_u8` +LL | 20..=30 => {} + | ------- this range overlaps on `20_u8` +LL | 10..=20 => {} + | ^^^^^^^ overlapping patterns + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:50:16 | LL | (true, 0..=10) => {} | ------ this range overlaps on `10_u8` @@ -69,12 +79,12 @@ LL | (true, 10..20) => {} | ^^^^^^ overlapping patterns error: multiple patterns covering the same range - --> $DIR/overlapping_range_endpoints.rs:50:14 + --> $DIR/overlapping_range_endpoints.rs:56:14 | LL | Some(0..=10) => {} | ------ this range overlaps on `10_u8` LL | Some(10..20) => {} | ^^^^^^ overlapping patterns -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors -- cgit 1.4.1-3-g733a5 From d1a50ffb7c332677f3c613540d507114c83e0f86 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 22 Oct 2020 18:34:00 +0100 Subject: Rename the `overlapping_patterns` lint to `overlapping_range_endpoints` --- compiler/rustc_lint/src/lib.rs | 3 +- compiler/rustc_lint_defs/src/builtin.rs | 17 ++++----- .../src/thir/pattern/deconstruct_pat.rs | 13 ++++--- src/test/ui/issues/issue-21475.rs | 2 +- src/test/ui/issues/issue-26251.rs | 2 +- .../integer-ranges/overlapping_range_endpoints.rs | 22 +++++------ .../overlapping_range_endpoints.stderr | 44 +++++++++++----------- 7 files changed, 52 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 81549be4b09..d5e77843b92 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -283,7 +283,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { UNUSED_MUT, UNREACHABLE_CODE, UNREACHABLE_PATTERNS, - OVERLAPPING_PATTERNS, + OVERLAPPING_RANGE_ENDPOINTS, UNUSED_MUST_USE, UNUSED_UNSAFE, PATH_STATEMENTS, @@ -335,6 +335,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { store.register_renamed("exceeding_bitshifts", "arithmetic_overflow"); store.register_renamed("redundant_semicolon", "redundant_semicolons"); store.register_renamed("intra_doc_link_resolution_failure", "broken_intra_doc_links"); + store.register_renamed("overlapping_patterns", "overlapping_range_endpoints"); store.register_removed("unknown_features", "replaced by an error"); store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate"); store.register_removed("negate_unsigned", "cast a signed value instead"); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index fa82dce0ae2..20ea7377e3f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -588,8 +588,8 @@ declare_lint! { } declare_lint! { - /// The `overlapping_patterns` lint detects `match` arms that have - /// [range patterns] that overlap. + /// The `overlapping_range_endpoints` lint detects `match` arms that have [range patterns] that + /// overlap on their endpoints. /// /// [range patterns]: https://doc.rust-lang.org/nightly/reference/patterns.html#range-patterns /// @@ -607,13 +607,12 @@ declare_lint! { /// /// ### Explanation /// - /// It is likely a mistake to have range patterns in a match expression - /// that overlap. Check that the beginning and end values are what you - /// expect, and keep in mind that with `..=` the left and right bounds are - /// inclusive. - pub OVERLAPPING_PATTERNS, + /// It is likely a mistake to have range patterns in a match expression that overlap in this + /// way. Check that the beginning and end values are what you expect, and keep in mind that + /// with `..=` the left and right bounds are inclusive. + pub OVERLAPPING_RANGE_ENDPOINTS, Warn, - "detects overlapping patterns" + "detects range patterns with overlapping endpoints" } declare_lint! { @@ -2765,7 +2764,7 @@ declare_lint_pass! { DEAD_CODE, UNREACHABLE_CODE, UNREACHABLE_PATTERNS, - OVERLAPPING_PATTERNS, + OVERLAPPING_RANGE_ENDPOINTS, BINDINGS_WITH_VARIANT_NAME, UNUSED_MACROS, WARNINGS, diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 3b2eef5a905..34cb9ff1cc5 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -273,7 +273,7 @@ impl IntRange { let mut borders: Vec<_> = row_borders.chain(self_borders).collect(); borders.sort_unstable(); - self.lint_overlapping_patterns(pcx, hir_id, overlaps); + self.lint_overlapping_range_endpoints(pcx, hir_id, overlaps); // We're going to iterate through every adjacent pair of borders, making sure that // each represents an interval of nonnegative length, and convert each such @@ -296,7 +296,7 @@ impl IntRange { .collect() } - fn lint_overlapping_patterns( + fn lint_overlapping_range_endpoints( &self, pcx: PatCtxt<'_, '_, '_>, hir_id: Option, @@ -304,22 +304,23 @@ impl IntRange { ) { if let (true, Some(hir_id)) = (!overlaps.is_empty(), hir_id) { pcx.cx.tcx.struct_span_lint_hir( - lint::builtin::OVERLAPPING_PATTERNS, + lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, hir_id, pcx.span, |lint| { - let mut err = lint.build("multiple patterns covering the same range"); - err.span_label(pcx.span, "overlapping patterns"); + let mut err = lint.build("multiple patterns overlap on their endpoints"); + err.span_label(pcx.span, "overlapping range endpoints"); for (int_range, span) in overlaps { // Use the real type for user display of the ranges: err.span_label( span, &format!( "this range overlaps on `{}`", - int_range.to_pat(pcx.cx.tcx, pcx.ty), + int_range.to_pat(pcx.cx.tcx, pcx.ty) ), ); } + // FIXME: add note err.emit(); }, ); diff --git a/src/test/ui/issues/issue-21475.rs b/src/test/ui/issues/issue-21475.rs index ab0a1886963..b028fcae077 100644 --- a/src/test/ui/issues/issue-21475.rs +++ b/src/test/ui/issues/issue-21475.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(unused_imports, overlapping_patterns)] +#![allow(unused_imports, overlapping_range_endpoints)] // pretty-expanded FIXME #23616 use m::{START, END}; diff --git a/src/test/ui/issues/issue-26251.rs b/src/test/ui/issues/issue-26251.rs index edb06fea8ad..a3e26a41232 100644 --- a/src/test/ui/issues/issue-26251.rs +++ b/src/test/ui/issues/issue-26251.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(overlapping_patterns)] +#![allow(overlapping_range_endpoints)] fn main() { let x = 'a'; diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs index 2463d5cf4dc..6ad87d873ee 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs @@ -1,5 +1,5 @@ #![feature(exclusive_range_pattern)] -#![deny(overlapping_patterns)] +#![deny(overlapping_range_endpoints)] macro_rules! m { ($s:expr, $t1:pat, $t2:pat) => { @@ -12,31 +12,31 @@ macro_rules! m { } fn main() { - m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns covering the same range - m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns covering the same range + m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns overlap on their endpoints + m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns overlap on their endpoints m!(0u8, 20..=30, 31..=40); m!(0u8, 20..=30, 29..=40); - m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns covering the same range + m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns overlap on their endpoints m!(0u8, 20.. 30, 28..=40); m!(0u8, 20.. 30, 30..=40); m!(0u8, 20..=30, 30..=30); - m!(0u8, 20..=30, 30..=31); //~ ERROR multiple patterns covering the same range + m!(0u8, 20..=30, 30..=31); //~ ERROR multiple patterns overlap on their endpoints m!(0u8, 20..=30, 29..=30); m!(0u8, 20..=30, 20..=20); m!(0u8, 20..=30, 20..=21); - m!(0u8, 20..=30, 19..=20); //~ ERROR multiple patterns covering the same range + m!(0u8, 20..=30, 19..=20); //~ ERROR multiple patterns overlap on their endpoints m!(0u8, 20..=30, 20); m!(0u8, 20..=30, 25); m!(0u8, 20..=30, 30); m!(0u8, 20.. 30, 29); - m!(0u8, 20, 20..=30); //~ ERROR multiple patterns covering the same range + m!(0u8, 20, 20..=30); //~ ERROR multiple patterns overlap on their endpoints m!(0u8, 25, 20..=30); - m!(0u8, 30, 20..=30); //~ ERROR multiple patterns covering the same range + m!(0u8, 30, 20..=30); //~ ERROR multiple patterns overlap on their endpoints match 0u8 { 0..=10 => {} 20..=30 => {} - 10..=20 => {} //~ ERROR multiple patterns covering the same range + 10..=20 => {} //~ ERROR multiple patterns overlap on their endpoints _ => {} } match (0u8, true) { @@ -47,13 +47,13 @@ fn main() { } match (true, 0u8) { (true, 0..=10) => {} - (true, 10..20) => {} //~ ERROR multiple patterns covering the same range + (true, 10..20) => {} //~ ERROR multiple patterns overlap on their endpoints (false, 10..20) => {} _ => {} } match Some(0u8) { Some(0..=10) => {} - Some(10..20) => {} //~ ERROR multiple patterns covering the same range + Some(10..20) => {} //~ ERROR multiple patterns overlap on their endpoints _ => {} } } diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index 5351a7e61c2..56995421f2b 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -1,66 +1,66 @@ -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:15:22 | LL | m!(0u8, 20..=30, 30..=40); - | ------- ^^^^^^^ overlapping patterns + | ------- ^^^^^^^ overlapping range endpoints | | | this range overlaps on `30_u8` | note: the lint level is defined here --> $DIR/overlapping_range_endpoints.rs:2:9 | -LL | #![deny(overlapping_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(overlapping_range_endpoints)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:16:22 | LL | m!(0u8, 30..=40, 20..=30); - | ------- ^^^^^^^ overlapping patterns + | ------- ^^^^^^^ overlapping range endpoints | | | this range overlaps on `30_u8` -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:19:22 | LL | m!(0u8, 20.. 30, 29..=40); - | ------- ^^^^^^^ overlapping patterns + | ------- ^^^^^^^ overlapping range endpoints | | | this range overlaps on `29_u8` -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:23:22 | LL | m!(0u8, 20..=30, 30..=31); - | ------- ^^^^^^^ overlapping patterns + | ------- ^^^^^^^ overlapping range endpoints | | | this range overlaps on `30_u8` -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:27:22 | LL | m!(0u8, 20..=30, 19..=20); - | ------- ^^^^^^^ overlapping patterns + | ------- ^^^^^^^ overlapping range endpoints | | | this range overlaps on `20_u8` -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:32:17 | LL | m!(0u8, 20, 20..=30); - | -- ^^^^^^^ overlapping patterns + | -- ^^^^^^^ overlapping range endpoints | | | this range overlaps on `20_u8` -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:34:17 | LL | m!(0u8, 30, 20..=30); - | -- ^^^^^^^ overlapping patterns + | -- ^^^^^^^ overlapping range endpoints | | | this range overlaps on `30_u8` -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:39:9 | LL | 0..=10 => {} @@ -68,23 +68,23 @@ LL | 0..=10 => {} LL | 20..=30 => {} | ------- this range overlaps on `20_u8` LL | 10..=20 => {} - | ^^^^^^^ overlapping patterns + | ^^^^^^^ overlapping range endpoints -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:50:16 | LL | (true, 0..=10) => {} | ------ this range overlaps on `10_u8` LL | (true, 10..20) => {} - | ^^^^^^ overlapping patterns + | ^^^^^^ overlapping range endpoints -error: multiple patterns covering the same range +error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:56:14 | LL | Some(0..=10) => {} | ------ this range overlaps on `10_u8` LL | Some(10..20) => {} - | ^^^^^^ overlapping patterns + | ^^^^^^ overlapping range endpoints error: aborting due to 10 previous errors -- cgit 1.4.1-3-g733a5 From c89d439bb5c18608054d767e5b472679fa2f01da Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 22 Oct 2020 19:25:55 +0100 Subject: Be consistent about linting singletons --- .../src/thir/pattern/deconstruct_pat.rs | 2 +- .../integer-ranges/overlapping_range_endpoints.rs | 4 ++-- .../integer-ranges/overlapping_range_endpoints.stderr | 18 +----------------- 3 files changed, 4 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 34cb9ff1cc5..7c466ff591c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -161,7 +161,7 @@ impl IntRange { // 2 -------- // 2 ------- let (lo, hi) = self.boundaries(); let (other_lo, other_hi) = other.boundaries(); - lo == other_hi || hi == other_lo + (lo == other_hi || hi == other_lo) && !self.is_singleton() && !other.is_singleton() } fn to_pat<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> { diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs index 6ad87d873ee..5ea92b07081 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs @@ -29,9 +29,9 @@ fn main() { m!(0u8, 20..=30, 25); m!(0u8, 20..=30, 30); m!(0u8, 20.. 30, 29); - m!(0u8, 20, 20..=30); //~ ERROR multiple patterns overlap on their endpoints + m!(0u8, 20, 20..=30); m!(0u8, 25, 20..=30); - m!(0u8, 30, 20..=30); //~ ERROR multiple patterns overlap on their endpoints + m!(0u8, 30, 20..=30); match 0u8 { 0..=10 => {} diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index 56995421f2b..f694e4c9aab 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -44,22 +44,6 @@ LL | m!(0u8, 20..=30, 19..=20); | | | this range overlaps on `20_u8` -error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:32:17 - | -LL | m!(0u8, 20, 20..=30); - | -- ^^^^^^^ overlapping range endpoints - | | - | this range overlaps on `20_u8` - -error: multiple patterns overlap on their endpoints - --> $DIR/overlapping_range_endpoints.rs:34:17 - | -LL | m!(0u8, 30, 20..=30); - | -- ^^^^^^^ overlapping range endpoints - | | - | this range overlaps on `30_u8` - error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:39:9 | @@ -86,5 +70,5 @@ LL | Some(0..=10) => {} LL | Some(10..20) => {} | ^^^^^^ overlapping range endpoints -error: aborting due to 10 previous errors +error: aborting due to 8 previous errors -- cgit 1.4.1-3-g733a5 From 94ad5e167281d212ce3b32868717fde92501d04d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 22 Oct 2020 19:32:46 +0100 Subject: Improve error message --- .../src/thir/pattern/deconstruct_pat.rs | 6 +-- .../overlapping_range_endpoints.stderr | 49 ++++++++++++++-------- 2 files changed, 35 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 7c466ff591c..5b1dbabe9a1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -309,18 +309,18 @@ impl IntRange { pcx.span, |lint| { let mut err = lint.build("multiple patterns overlap on their endpoints"); - err.span_label(pcx.span, "overlapping range endpoints"); + err.span_label(pcx.span, "... with this range"); for (int_range, span) in overlaps { // Use the real type for user display of the ranges: err.span_label( span, &format!( - "this range overlaps on `{}`", + "this range overlaps on `{}`...", int_range.to_pat(pcx.cx.tcx, pcx.ty) ), ); } - // FIXME: add note + err.note("this is likely to be a mistake"); err.emit(); }, ); diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index f694e4c9aab..045c487873a 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -2,73 +2,88 @@ error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:15:22 | LL | m!(0u8, 20..=30, 30..=40); - | ------- ^^^^^^^ overlapping range endpoints + | ------- ^^^^^^^ ... with this range | | - | this range overlaps on `30_u8` + | this range overlaps on `30_u8`... | note: the lint level is defined here --> $DIR/overlapping_range_endpoints.rs:2:9 | LL | #![deny(overlapping_range_endpoints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this is likely to be a mistake error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:16:22 | LL | m!(0u8, 30..=40, 20..=30); - | ------- ^^^^^^^ overlapping range endpoints + | ------- ^^^^^^^ ... with this range | | - | this range overlaps on `30_u8` + | this range overlaps on `30_u8`... + | + = note: this is likely to be a mistake error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:19:22 | LL | m!(0u8, 20.. 30, 29..=40); - | ------- ^^^^^^^ overlapping range endpoints + | ------- ^^^^^^^ ... with this range | | - | this range overlaps on `29_u8` + | this range overlaps on `29_u8`... + | + = note: this is likely to be a mistake error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:23:22 | LL | m!(0u8, 20..=30, 30..=31); - | ------- ^^^^^^^ overlapping range endpoints + | ------- ^^^^^^^ ... with this range | | - | this range overlaps on `30_u8` + | this range overlaps on `30_u8`... + | + = note: this is likely to be a mistake error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:27:22 | LL | m!(0u8, 20..=30, 19..=20); - | ------- ^^^^^^^ overlapping range endpoints + | ------- ^^^^^^^ ... with this range | | - | this range overlaps on `20_u8` + | this range overlaps on `20_u8`... + | + = note: this is likely to be a mistake error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:39:9 | LL | 0..=10 => {} - | ------ this range overlaps on `10_u8` + | ------ this range overlaps on `10_u8`... LL | 20..=30 => {} - | ------- this range overlaps on `20_u8` + | ------- this range overlaps on `20_u8`... LL | 10..=20 => {} - | ^^^^^^^ overlapping range endpoints + | ^^^^^^^ ... with this range + | + = note: this is likely to be a mistake error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:50:16 | LL | (true, 0..=10) => {} - | ------ this range overlaps on `10_u8` + | ------ this range overlaps on `10_u8`... LL | (true, 10..20) => {} - | ^^^^^^ overlapping range endpoints + | ^^^^^^ ... with this range + | + = note: this is likely to be a mistake error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:56:14 | LL | Some(0..=10) => {} - | ------ this range overlaps on `10_u8` + | ------ this range overlaps on `10_u8`... LL | Some(10..20) => {} - | ^^^^^^ overlapping range endpoints + | ^^^^^^ ... with this range + | + = note: this is likely to be a mistake error: aborting due to 8 previous errors -- cgit 1.4.1-3-g733a5 From 5687c162792db8d267f80de7bd56c319e12efead Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 22 Nov 2020 22:21:09 +0000 Subject: `overlapping_range_endpoints` does not belong in the `unused` lint group --- compiler/rustc_lint/src/lib.rs | 1 - .../usefulness/integer-ranges/exhaustiveness.rs | 1 + .../integer-ranges/exhaustiveness.stderr | 24 +++++------ .../usefulness/integer-ranges/reachability.rs | 1 + .../usefulness/integer-ranges/reachability.stderr | 50 +++++++++++----------- 5 files changed, 39 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index d5e77843b92..f87796a95e9 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -283,7 +283,6 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { UNUSED_MUT, UNREACHABLE_CODE, UNREACHABLE_PATTERNS, - OVERLAPPING_RANGE_ENDPOINTS, UNUSED_MUST_USE, UNUSED_UNSAFE, PATH_STATEMENTS, diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs index 5a44dfc28bb..ef573db8210 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs +++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs @@ -1,5 +1,6 @@ #![feature(exclusive_range_pattern)] #![feature(assoc_char_consts)] +#![allow(overlapping_range_endpoints)] #![deny(unreachable_patterns)] macro_rules! m { diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr index 2e0023348e4..b1440375494 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `u8::MAX` not covered - --> $DIR/exhaustiveness.rs:47:8 + --> $DIR/exhaustiveness.rs:48:8 | LL | m!(0u8, 0..255); | ^^^ pattern `u8::MAX` not covered @@ -8,7 +8,7 @@ LL | m!(0u8, 0..255); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: `u8::MAX` not covered - --> $DIR/exhaustiveness.rs:48:8 + --> $DIR/exhaustiveness.rs:49:8 | LL | m!(0u8, 0..=254); | ^^^ pattern `u8::MAX` not covered @@ -17,7 +17,7 @@ LL | m!(0u8, 0..=254); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: `0_u8` not covered - --> $DIR/exhaustiveness.rs:49:8 + --> $DIR/exhaustiveness.rs:50:8 | LL | m!(0u8, 1..=255); | ^^^ pattern `0_u8` not covered @@ -26,7 +26,7 @@ LL | m!(0u8, 1..=255); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: `42_u8` not covered - --> $DIR/exhaustiveness.rs:50:8 + --> $DIR/exhaustiveness.rs:51:8 | LL | m!(0u8, 0..42 | 43..=255); | ^^^ pattern `42_u8` not covered @@ -35,7 +35,7 @@ LL | m!(0u8, 0..42 | 43..=255); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: `i8::MAX` not covered - --> $DIR/exhaustiveness.rs:51:8 + --> $DIR/exhaustiveness.rs:52:8 | LL | m!(0i8, -128..127); | ^^^ pattern `i8::MAX` not covered @@ -44,7 +44,7 @@ LL | m!(0i8, -128..127); = note: the matched value is of type `i8` error[E0004]: non-exhaustive patterns: `i8::MAX` not covered - --> $DIR/exhaustiveness.rs:52:8 + --> $DIR/exhaustiveness.rs:53:8 | LL | m!(0i8, -128..=126); | ^^^ pattern `i8::MAX` not covered @@ -53,7 +53,7 @@ LL | m!(0i8, -128..=126); = note: the matched value is of type `i8` error[E0004]: non-exhaustive patterns: `i8::MIN` not covered - --> $DIR/exhaustiveness.rs:53:8 + --> $DIR/exhaustiveness.rs:54:8 | LL | m!(0i8, -127..=127); | ^^^ pattern `i8::MIN` not covered @@ -62,7 +62,7 @@ LL | m!(0i8, -127..=127); = note: the matched value is of type `i8` error[E0004]: non-exhaustive patterns: `0_i8` not covered - --> $DIR/exhaustiveness.rs:54:11 + --> $DIR/exhaustiveness.rs:55:11 | LL | match 0i8 { | ^^^ pattern `0_i8` not covered @@ -71,7 +71,7 @@ LL | match 0i8 { = note: the matched value is of type `i8` error[E0004]: non-exhaustive patterns: `u128::MAX` not covered - --> $DIR/exhaustiveness.rs:59:8 + --> $DIR/exhaustiveness.rs:60:8 | LL | m!(0u128, 0..=ALMOST_MAX); | ^^^^^ pattern `u128::MAX` not covered @@ -80,7 +80,7 @@ LL | m!(0u128, 0..=ALMOST_MAX); = note: the matched value is of type `u128` error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered - --> $DIR/exhaustiveness.rs:60:8 + --> $DIR/exhaustiveness.rs:61:8 | LL | m!(0u128, 0..=4); | ^^^^^ pattern `5_u128..=u128::MAX` not covered @@ -89,7 +89,7 @@ LL | m!(0u128, 0..=4); = note: the matched value is of type `u128` error[E0004]: non-exhaustive patterns: `0_u128` not covered - --> $DIR/exhaustiveness.rs:61:8 + --> $DIR/exhaustiveness.rs:62:8 | LL | m!(0u128, 1..=u128::MAX); | ^^^^^ pattern `0_u128` not covered @@ -98,7 +98,7 @@ LL | m!(0u128, 1..=u128::MAX); = note: the matched value is of type `u128` error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered - --> $DIR/exhaustiveness.rs:69:11 + --> $DIR/exhaustiveness.rs:70:11 | LL | match (0u8, true) { | ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs index 6516925e939..fb4d59b0578 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs +++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs @@ -1,4 +1,5 @@ #![feature(exclusive_range_pattern)] +#![allow(overlapping_range_endpoints)] #![deny(unreachable_patterns)] macro_rules! m { diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr index e6878d950d6..9a02fac6a75 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr @@ -1,149 +1,149 @@ error: unreachable pattern - --> $DIR/reachability.rs:16:17 + --> $DIR/reachability.rs:17:17 | LL | m!(0u8, 42, 42); | ^^ | note: the lint level is defined here - --> $DIR/reachability.rs:2:9 + --> $DIR/reachability.rs:3:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:20:22 + --> $DIR/reachability.rs:21:22 | LL | m!(0u8, 20..=30, 20); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:21:22 + --> $DIR/reachability.rs:22:22 | LL | m!(0u8, 20..=30, 21); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:22:22 + --> $DIR/reachability.rs:23:22 | LL | m!(0u8, 20..=30, 25); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:23:22 + --> $DIR/reachability.rs:24:22 | LL | m!(0u8, 20..=30, 29); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:24:22 + --> $DIR/reachability.rs:25:22 | LL | m!(0u8, 20..=30, 30); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:27:21 + --> $DIR/reachability.rs:28:21 | LL | m!(0u8, 20..30, 20); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:28:21 + --> $DIR/reachability.rs:29:21 | LL | m!(0u8, 20..30, 21); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:29:21 + --> $DIR/reachability.rs:30:21 | LL | m!(0u8, 20..30, 25); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:30:21 + --> $DIR/reachability.rs:31:21 | LL | m!(0u8, 20..30, 29); | ^^ error: unreachable pattern - --> $DIR/reachability.rs:34:22 + --> $DIR/reachability.rs:35:22 | LL | m!(0u8, 20..=30, 20..=30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:35:22 + --> $DIR/reachability.rs:36:22 | LL | m!(0u8, 20.. 30, 20.. 30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:36:22 + --> $DIR/reachability.rs:37:22 | LL | m!(0u8, 20..=30, 20.. 30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:38:22 + --> $DIR/reachability.rs:39:22 | LL | m!(0u8, 20..=30, 21..=30); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:39:22 + --> $DIR/reachability.rs:40:22 | LL | m!(0u8, 20..=30, 20..=29); | ^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:41:24 + --> $DIR/reachability.rs:42:24 | LL | m!('a', 'A'..='z', 'a'..='z'); | ^^^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:48:9 + --> $DIR/reachability.rs:49:9 | LL | 5..=8 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:54:9 + --> $DIR/reachability.rs:55:9 | LL | 5..15 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:61:9 + --> $DIR/reachability.rs:62:9 | LL | 5..25 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:69:9 + --> $DIR/reachability.rs:70:9 | LL | 5..25 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:75:9 + --> $DIR/reachability.rs:76:9 | LL | 5..15 => {}, | ^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:82:9 + --> $DIR/reachability.rs:83:9 | LL | '\u{D7FF}'..='\u{E000}' => {}, | ^^^^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/reachability.rs:103:9 + --> $DIR/reachability.rs:104:9 | LL | &FOO => {} | ^^^^ error: unreachable pattern - --> $DIR/reachability.rs:104:9 + --> $DIR/reachability.rs:105:9 | LL | BAR => {} | ^^^ -- cgit 1.4.1-3-g733a5 From 50d9b30a3751388e629d246ad4428c3f3f8d2567 Mon Sep 17 00:00:00 2001 From: PankajChaudhary5 Date: Thu, 8 Oct 2020 10:45:34 +0530 Subject: Added better error message for shared borrow treated as unique for purposes of lifetimes --- compiler/rustc_mir/src/util/borrowck_errors.rs | 7 ++++--- src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr | 2 +- src/test/ui/borrowck/mut-borrow-in-loop.stderr | 6 +++--- src/test/ui/borrowck/two-phase-across-loop.stderr | 2 +- src/test/ui/nll/closures-in-loops.stderr | 2 +- src/test/ui/nll/issue-62007-assign-const-index.stderr | 4 ++-- src/test/ui/nll/issue-62007-assign-differing-fields.stderr | 4 ++-- src/test/ui/nll/polonius/assignment-to-differing-field.stderr | 8 ++++---- 8 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/util/borrowck_errors.rs b/compiler/rustc_mir/src/util/borrowck_errors.rs index 83bf7584f2e..56d8045813c 100644 --- a/compiler/rustc_mir/src/util/borrowck_errors.rs +++ b/compiler/rustc_mir/src/util/borrowck_errors.rs @@ -68,9 +68,10 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { err.span_label( new_loan_span, format!( - "mutable borrow starts here in previous \ - iteration of loop{}", - opt_via + "{}{} was mutably borrowed here in the previous iteration of the loop{}", + desc, + via(opt_via), + opt_via, ), ); if let Some(old_load_end_span) = old_load_end_span { diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr index ca1496a6c8d..a4090777939 100644 --- a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr +++ b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr @@ -23,7 +23,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time --> $DIR/borrowck-mut-borrow-linear-errors.rs:12:30 | LL | _ => { addr.push(&mut x); } - | ^^^^^^ mutable borrow starts here in previous iteration of loop + | ^^^^^^ `x` was mutably borrowed here in the previous iteration of the loop error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.stderr b/src/test/ui/borrowck/mut-borrow-in-loop.stderr index 260b9673d74..b621694a548 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop.stderr +++ b/src/test/ui/borrowck/mut-borrow-in-loop.stderr @@ -15,7 +15,7 @@ LL | impl<'a, T : 'a> FuncWrapper<'a, T> { LL | (self.func)(arg) | ------------^^^- | | | - | | mutable borrow starts here in previous iteration of loop + | | `*arg` was mutably borrowed here in the previous iteration of the loop | argument requires that `*arg` is borrowed for `'a` error[E0499]: cannot borrow `*arg` as mutable more than once at a time @@ -27,7 +27,7 @@ LL | impl<'a, T : 'a> FuncWrapper<'a, T> { LL | (self.func)(arg) | ------------^^^- | | | - | | mutable borrow starts here in previous iteration of loop + | | `*arg` was mutably borrowed here in the previous iteration of the loop | argument requires that `*arg` is borrowed for `'a` error[E0499]: cannot borrow `*arg` as mutable more than once at a time @@ -39,7 +39,7 @@ LL | impl<'a, T : 'a> FuncWrapper<'a, T> { LL | (self.func)(arg) | ------------^^^- | | | - | | mutable borrow starts here in previous iteration of loop + | | `*arg` was mutably borrowed here in the previous iteration of the loop | argument requires that `*arg` is borrowed for `'a` error: aborting due to 3 previous errors; 1 warning emitted diff --git a/src/test/ui/borrowck/two-phase-across-loop.stderr b/src/test/ui/borrowck/two-phase-across-loop.stderr index 38993a50bf6..d4e515d12bb 100644 --- a/src/test/ui/borrowck/two-phase-across-loop.stderr +++ b/src/test/ui/borrowck/two-phase-across-loop.stderr @@ -2,7 +2,7 @@ error[E0499]: cannot borrow `foo` as mutable more than once at a time --> $DIR/two-phase-across-loop.rs:17:22 | LL | strings.push(foo.get_string()); - | ^^^ mutable borrow starts here in previous iteration of loop + | ^^^ `foo` was mutably borrowed here in the previous iteration of the loop error: aborting due to previous error diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr index 37638a93d77..2f134f83ced 100644 --- a/src/test/ui/nll/closures-in-loops.stderr +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -15,7 +15,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time LL | v.push(|| x = String::new()); | ^^ - borrows occur due to use of `x` in closure | | - | mutable borrow starts here in previous iteration of loop + | `x` was mutably borrowed here in the previous iteration of the loop error[E0524]: two closures require unique access to `x` at the same time --> $DIR/closures-in-loops.rs:20:16 diff --git a/src/test/ui/nll/issue-62007-assign-const-index.stderr b/src/test/ui/nll/issue-62007-assign-const-index.stderr index 758a14d0177..0db9fe62c38 100644 --- a/src/test/ui/nll/issue-62007-assign-const-index.stderr +++ b/src/test/ui/nll/issue-62007-assign-const-index.stderr @@ -5,7 +5,7 @@ LL | fn to_refs(mut list: [&mut List; 2]) -> Vec<&mut T> { | - let's call the lifetime of this reference `'1` ... LL | result.push(&mut list[0].value); - | ^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop + | ^^^^^^^^^^^^^^^^^^ `list[_].value` was mutably borrowed here in the previous iteration of the loop ... LL | return result; | ------ returning this value requires that `list[_].value` is borrowed for `'1` @@ -19,7 +19,7 @@ LL | fn to_refs(mut list: [&mut List; 2]) -> Vec<&mut T> { LL | if let Some(n) = list[0].next.as_mut() { | ^^^^^^^^^^^^--------- | | - | mutable borrow starts here in previous iteration of loop + | `list[_].next` was mutably borrowed here in the previous iteration of the loop | argument requires that `list[_].next` is borrowed for `'1` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/issue-62007-assign-differing-fields.stderr b/src/test/ui/nll/issue-62007-assign-differing-fields.stderr index f942d7628b5..f1af2e855af 100644 --- a/src/test/ui/nll/issue-62007-assign-differing-fields.stderr +++ b/src/test/ui/nll/issue-62007-assign-differing-fields.stderr @@ -5,7 +5,7 @@ LL | fn to_refs<'a, T>(mut list: (&'a mut List, &'a mut List)) -> Vec<&'a | -- lifetime `'a` defined here ... LL | result.push(&mut (list.0).value); - | ^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop + | ^^^^^^^^^^^^^^^^^^^ `list.0.value` was mutably borrowed here in the previous iteration of the loop ... LL | return result; | ------ returning this value requires that `list.0.value` is borrowed for `'a` @@ -19,7 +19,7 @@ LL | fn to_refs<'a, T>(mut list: (&'a mut List, &'a mut List)) -> Vec<&'a LL | if let Some(n) = (list.0).next.as_mut() { | ^^^^^^^^^^^^^--------- | | - | mutable borrow starts here in previous iteration of loop + | `list.0.next` was mutably borrowed here in the previous iteration of the loop | argument requires that `list.0.next` is borrowed for `'a` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/polonius/assignment-to-differing-field.stderr b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr index 07ca021b53b..2fe6a53a49a 100644 --- a/src/test/ui/nll/polonius/assignment-to-differing-field.stderr +++ b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr @@ -5,7 +5,7 @@ LL | fn assignment_to_field_projection<'a, T>( | -- lifetime `'a` defined here ... LL | result.push(&mut (list.0).value); - | ^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop + | ^^^^^^^^^^^^^^^^^^^ `list.0.value` was mutably borrowed here in the previous iteration of the loop ... LL | return result; | ------ returning this value requires that `list.0.value` is borrowed for `'a` @@ -19,7 +19,7 @@ LL | fn assignment_to_field_projection<'a, T>( LL | if let Some(n) = (list.0).next.as_mut() { | ^^^^^^^^^^^^^--------- | | - | mutable borrow starts here in previous iteration of loop + | `list.0.next` was mutably borrowed here in the previous iteration of the loop | argument requires that `list.0.next` is borrowed for `'a` error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time @@ -29,7 +29,7 @@ LL | fn assignment_through_projection_chain<'a, T>( | -- lifetime `'a` defined here ... LL | result.push(&mut ((((list.0).0).0).0).0.value); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `list.0.0.0.0.0.value` was mutably borrowed here in the previous iteration of the loop ... LL | return result; | ------ returning this value requires that `list.0.0.0.0.0.value` is borrowed for `'a` @@ -43,7 +43,7 @@ LL | fn assignment_through_projection_chain<'a, T>( LL | if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^--------- | | - | mutable borrow starts here in previous iteration of loop + | `list.0.0.0.0.0.next` was mutably borrowed here in the previous iteration of the loop | argument requires that `list.0.0.0.0.0.next` is borrowed for `'a` error: aborting due to 4 previous errors -- cgit 1.4.1-3-g733a5 From 5404deeb64f4449079f5165ace6bfa1e52ca4b33 Mon Sep 17 00:00:00 2001 From: mibac138 <5672750+mibac138@users.noreply.github.com> Date: Wed, 14 Oct 2020 22:27:48 +0200 Subject: Gracefully handle mistyping -> as => in function return type --- compiler/rustc_parse/src/parser/expr.rs | 4 ++-- compiler/rustc_parse/src/parser/item.rs | 4 ++-- compiler/rustc_parse/src/parser/path.rs | 5 +++-- compiler/rustc_parse/src/parser/ty.rs | 21 +++++++++++++++++++++ src/test/ui/fn/fn-fat-arrow-return.fixed | 18 ++++++++++++++++++ src/test/ui/fn/fn-fat-arrow-return.rs | 18 ++++++++++++++++++ src/test/ui/fn/fn-fat-arrow-return.stderr | 8 ++++++++ src/test/ui/fn/fn-fat-arrow-return2.rs | 10 ++++++++++ src/test/ui/fn/fn-fat-arrow-return2.stderr | 14 ++++++++++++++ 9 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/fn/fn-fat-arrow-return.fixed create mode 100644 src/test/ui/fn/fn-fat-arrow-return.rs create mode 100644 src/test/ui/fn/fn-fat-arrow-return.stderr create mode 100644 src/test/ui/fn/fn-fat-arrow-return2.rs create mode 100644 src/test/ui/fn/fn-fat-arrow-return2.stderr (limited to 'src') diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 93be478fc8c..790a0c867af 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1,5 +1,5 @@ use super::pat::{GateOr, PARAM_EXPECTED}; -use super::ty::{AllowPlus, RecoverQPath}; +use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath}; use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType}; use super::{SemiColonMode, SeqSep, TokenExpectType}; use crate::maybe_recover_from_interpolated_ty_qpath; @@ -1647,7 +1647,7 @@ impl<'a> Parser<'a> { self.expect_or()?; args }; - let output = self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes)?; + let output = self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverFatArrow::Yes)?; Ok(P(FnDecl { inputs, output })) } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 5954b370e6d..9e342a0d681 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1,5 +1,5 @@ use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error}; -use super::ty::{AllowPlus, RecoverQPath}; +use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath}; use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; @@ -1648,7 +1648,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P> { Ok(P(FnDecl { inputs: self.parse_fn_params(req_name)?, - output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes)?, + output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, RecoverFatArrow::Yes)?, })) } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 17e5bcf7605..311a4829fcf 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,4 +1,4 @@ -use super::ty::{AllowPlus, RecoverQPath}; +use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath}; use super::{Parser, TokenType}; use crate::maybe_whole; use rustc_ast::ptr::P; @@ -231,7 +231,8 @@ impl<'a> Parser<'a> { // `(T, U) -> R` let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; let span = ident.span.to(self.prev_token.span); - let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No)?; + let output = + self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverFatArrow::No)?; ParenthesizedArgs { inputs, output, span }.into() }; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 7a6ebca4e15..ff19c5cfa85 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -43,6 +43,12 @@ pub(super) enum RecoverQPath { No, } +#[derive(PartialEq)] +pub(super) enum RecoverFatArrow { + Yes, + No, +} + // Is `...` (`CVarArgs`) legal at this level of type parsing? #[derive(PartialEq)] enum AllowCVariadic { @@ -87,11 +93,26 @@ impl<'a> Parser<'a> { &mut self, allow_plus: AllowPlus, recover_qpath: RecoverQPath, + recover_fat_arrow: RecoverFatArrow, ) -> PResult<'a, FnRetTy> { Ok(if self.eat(&token::RArrow) { // FIXME(Centril): Can we unconditionally `allow_plus`? let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?; FnRetTy::Ty(ty) + } else if recover_fat_arrow == RecoverFatArrow::Yes && self.token == token::FatArrow { + // Don't `eat` to prevent `=>` from being added as an expected token which isn't + // actually expected and could only confuse users + self.bump(); + self.struct_span_err(self.prev_token.span, "return types are denoted using `->`") + .span_suggestion_short( + self.prev_token.span, + "use `->` instead", + "->".to_string(), + Applicability::MachineApplicable, + ) + .emit(); + let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?; + FnRetTy::Ty(ty) } else { FnRetTy::Default(self.token.span.shrink_to_lo()) }) diff --git a/src/test/ui/fn/fn-fat-arrow-return.fixed b/src/test/ui/fn/fn-fat-arrow-return.fixed new file mode 100644 index 00000000000..0acca85aa67 --- /dev/null +++ b/src/test/ui/fn/fn-fat-arrow-return.fixed @@ -0,0 +1,18 @@ +// run-rustfix +#![allow(unused)] +fn a() -> usize { 0 } +//~^ ERROR return types are denoted using `->` + +fn bar(_: u32) {} + +fn baz() -> *const dyn Fn(u32) { unimplemented!() } + +fn foo() { + match () { + _ if baz() == &bar as &dyn Fn(u32) => (), + () => (), + } +} + +fn main() { +} diff --git a/src/test/ui/fn/fn-fat-arrow-return.rs b/src/test/ui/fn/fn-fat-arrow-return.rs new file mode 100644 index 00000000000..4bdcd70d7fc --- /dev/null +++ b/src/test/ui/fn/fn-fat-arrow-return.rs @@ -0,0 +1,18 @@ +// run-rustfix +#![allow(unused)] +fn a() => usize { 0 } +//~^ ERROR return types are denoted using `->` + +fn bar(_: u32) {} + +fn baz() -> *const dyn Fn(u32) { unimplemented!() } + +fn foo() { + match () { + _ if baz() == &bar as &dyn Fn(u32) => (), + () => (), + } +} + +fn main() { +} diff --git a/src/test/ui/fn/fn-fat-arrow-return.stderr b/src/test/ui/fn/fn-fat-arrow-return.stderr new file mode 100644 index 00000000000..1fcdb18a514 --- /dev/null +++ b/src/test/ui/fn/fn-fat-arrow-return.stderr @@ -0,0 +1,8 @@ +error: return types are denoted using `->` + --> $DIR/fn-fat-arrow-return.rs:3:8 + | +LL | fn a() => usize { 0 } + | ^^ help: use `->` instead + +error: aborting due to previous error + diff --git a/src/test/ui/fn/fn-fat-arrow-return2.rs b/src/test/ui/fn/fn-fat-arrow-return2.rs new file mode 100644 index 00000000000..316fa2cbf02 --- /dev/null +++ b/src/test/ui/fn/fn-fat-arrow-return2.rs @@ -0,0 +1,10 @@ +fn a() => impl Fn() => bool { + //~^ ERROR return types are denoted using `->` + //~| ERROR expected `;` or `{`, found `=>` + unimplemented!() +} + +fn main() { + let foo = |a: bool| => bool { a }; + dbg!(foo(false)); +} diff --git a/src/test/ui/fn/fn-fat-arrow-return2.stderr b/src/test/ui/fn/fn-fat-arrow-return2.stderr new file mode 100644 index 00000000000..a6f9fe3b573 --- /dev/null +++ b/src/test/ui/fn/fn-fat-arrow-return2.stderr @@ -0,0 +1,14 @@ +error: return types are denoted using `->` + --> $DIR/fn-fat-arrow-return2.rs:1:8 + | +LL | fn a() => impl Fn() => bool { + | ^^ help: use `->` instead + +error: expected `;` or `{`, found `=>` + --> $DIR/fn-fat-arrow-return2.rs:1:21 + | +LL | fn a() => impl Fn() => bool { + | ^^ expected `;` or `{` + +error: aborting due to 2 previous errors + -- cgit 1.4.1-3-g733a5 From 71d75503506880efa89c902465cdcb205d0eb9e5 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 2 Dec 2020 14:33:26 +0100 Subject: const_evaluatable_checked: fix occurs check --- compiler/rustc_infer/src/infer/combine.rs | 16 +++++++++++++++- compiler/rustc_middle/src/ty/relate.rs | 6 +++++- .../const-generics/occurs-check/unused-substs-5.rs | 20 ++++++++++++++++++++ .../occurs-check/unused-substs-5.stderr | 12 ++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-5.rs create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-5.stderr (limited to 'src') diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 6a1715ef818..594e2c6205f 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -543,6 +543,10 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { true } + fn visit_ct_substs(&self) -> bool { + true + } + fn binders( &mut self, a: ty::Binder, @@ -716,7 +720,10 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { let variable_table = &mut inner.const_unification_table(); let var_value = variable_table.probe_value(vid); match var_value.val { - ConstVariableValue::Known { value: u } => self.relate(u, u), + ConstVariableValue::Known { value: u } => { + drop(inner); + self.relate(u, u) + } ConstVariableValue::Unknown { universe } => { if self.for_universe.can_name(universe) { Ok(c) @@ -815,6 +822,10 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { true } + fn visit_ct_substs(&self) -> bool { + true + } + fn relate_with_variance>( &mut self, _variance: ty::Variance, @@ -870,6 +881,9 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } } + ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { + Ok(t) + } _ => relate::super_relate_tys(self, t, t), } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index ef5034e218d..80dc7d89d18 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -33,6 +33,10 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; + fn visit_ct_substs(&self) -> bool { + false + } + fn with_cause(&mut self, _cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -579,7 +583,7 @@ pub fn super_relate_consts>( ( ty::ConstKind::Unevaluated(a_def, a_substs, None), ty::ConstKind::Unevaluated(b_def, b_substs, None), - ) if tcx.features().const_evaluatable_checked => { + ) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => { if tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) { Ok(a.val) } else { diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.rs b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs new file mode 100644 index 00000000000..e5d487d89b9 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs @@ -0,0 +1,20 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +// `N + 1` also depends on `T` here even if it doesn't use it. +fn q(_: T) -> [u8; N + 1] { + todo!() +} + +fn supplier() -> T { + todo!() +} + +fn catch_me() where [u8; N + 1]: Default { + let mut x = supplier(); + x = q::<_, N>(x); //~ ERROR mismatched types +} + +fn main() { + catch_me::<3>(); +} diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr new file mode 100644 index 00000000000..239569dab09 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-5.rs:15:9 + | +LL | x = q::<_, N>(x); + | ^^^^^^^^^^^^ + | | + | cyclic type of infinite size + | help: try using a conversion method: `q::<_, N>(x).to_vec()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 25740fc6823ee3901e5917869b1f1ae1b4373c5e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 2 Dec 2020 18:31:55 +0000 Subject: rustdoc: --default-theme: minor grammar fix to usage message Signed-off-by: Ian Jackson --- src/librustdoc/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 751f2301053..951bb27a9fa 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -275,7 +275,7 @@ fn opts() -> Vec { "default-theme", "Set the default theme. THEME should be the theme name, generally lowercase. \ If an unknown default theme is specified, the builtin default is used. \ - The set of themes, and the rustdoc built-in default is not stable.", + The set of themes, and the rustdoc built-in default, are not stable.", "THEME", ) }), -- cgit 1.4.1-3-g733a5 From 36ee3bde07093ac81f9be113000df69c79c1afca Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 2 Dec 2020 18:32:38 +0000 Subject: rustdoc: stabilise --default-theme As discussed in #77213, this seems like it has bedded in and can be safely and usefully made stable. (rustdoc already has other stable options that interact quite intimately with the rustdoc-supplied CSS, and also an option for supplying entirely different CSS, so exposing the theme names this way seems a very minor step.) Signed-off-by: Ian Jackson --- src/librustdoc/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 951bb27a9fa..83d2c2d894b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -269,7 +269,7 @@ fn opts() -> Vec { "sort modules by where they appear in the program, rather than alphabetically", ) }), - unstable("default-theme", |o| { + stable("default-theme", |o| { o.optopt( "", "default-theme", -- cgit 1.4.1-3-g733a5 From c21b275d35bbc624ad5859d69ae5172464fd66e8 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 3 Dec 2020 00:23:01 +0000 Subject: rustdoc: document --default-theme option in command line doc Signed-off-by: Ian Jackson --- src/doc/rustdoc/src/command-line-arguments.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 31e002810ce..faf22296b5d 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -237,6 +237,26 @@ for a target triple that's different than your host triple. All of the usual caveats of cross-compiling code apply. +## `--default-theme`: set the default theme + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs --default-theme=ayu +``` + +Sets the default theme (for users whose browser has not remembered a +previous theme selection from the on-page theme picker). + +The supplied value should be the lowercase version of the theme name. +The set of available themes can be seen in the theme picker in the +gneerated output. + +Note that the set of available themes - and their appearance - is not +necessarily stable from one rustdoc version to the next. If the +requested theme does not exist, the builtin default (currently +`light`) is used instead. + ## `--markdown-css`: include more CSS files when rendering markdown Using this flag looks like this: -- cgit 1.4.1-3-g733a5 From 63f3876b856e8e995d2b4960ca9f6f617950ce7b Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 3 Dec 2020 10:22:57 +0000 Subject: fix typo in src/doc/rustdoc/src/command-line-arguments.md Co-authored-by: Guillaume Gomez --- src/doc/rustdoc/src/command-line-arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index faf22296b5d..80f7851debf 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -250,7 +250,7 @@ previous theme selection from the on-page theme picker). The supplied value should be the lowercase version of the theme name. The set of available themes can be seen in the theme picker in the -gneerated output. +generated output. Note that the set of available themes - and their appearance - is not necessarily stable from one rustdoc version to the next. If the -- cgit 1.4.1-3-g733a5 From 3548be94c03fd6d1c11afd6af9c884f398a6489e Mon Sep 17 00:00:00 2001 From: mibac138 <5672750+mibac138@users.noreply.github.com> Date: Thu, 15 Oct 2020 21:21:45 +0200 Subject: Gracefully handle confusing -> with : in function return type --- compiler/rustc_parse/src/parser/expr.rs | 5 +- compiler/rustc_parse/src/parser/generics.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 7 ++- compiler/rustc_parse/src/parser/path.rs | 4 +- compiler/rustc_parse/src/parser/ty.rs | 78 +++++++++++++++++++++----- src/test/ui/fn/fn-fat-arrow-return.fixed | 18 ------ src/test/ui/fn/fn-fat-arrow-return.rs | 18 ------ src/test/ui/fn/fn-fat-arrow-return.stderr | 8 --- src/test/ui/fn/fn-fat-arrow-return2.rs | 10 ---- src/test/ui/fn/fn-fat-arrow-return2.stderr | 14 ----- src/test/ui/fn/fn-recover-return-sign.fixed | 28 +++++++++ src/test/ui/fn/fn-recover-return-sign.rs | 28 +++++++++ src/test/ui/fn/fn-recover-return-sign.stderr | 26 +++++++++ src/test/ui/fn/fn-recover-return-sign2.rs | 8 +++ src/test/ui/fn/fn-recover-return-sign2.stderr | 14 +++++ src/test/ui/parser/fn-colon-return-type.rs | 3 +- src/test/ui/parser/fn-colon-return-type.stderr | 4 +- src/test/ui/parser/not-a-pred.rs | 13 ++++- src/test/ui/parser/not-a-pred.stderr | 32 ++++++++++- 19 files changed, 223 insertions(+), 97 deletions(-) delete mode 100644 src/test/ui/fn/fn-fat-arrow-return.fixed delete mode 100644 src/test/ui/fn/fn-fat-arrow-return.rs delete mode 100644 src/test/ui/fn/fn-fat-arrow-return.stderr delete mode 100644 src/test/ui/fn/fn-fat-arrow-return2.rs delete mode 100644 src/test/ui/fn/fn-fat-arrow-return2.stderr create mode 100644 src/test/ui/fn/fn-recover-return-sign.fixed create mode 100644 src/test/ui/fn/fn-recover-return-sign.rs create mode 100644 src/test/ui/fn/fn-recover-return-sign.stderr create mode 100644 src/test/ui/fn/fn-recover-return-sign2.rs create mode 100644 src/test/ui/fn/fn-recover-return-sign2.stderr (limited to 'src') diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 790a0c867af..4d2167442be 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1,5 +1,5 @@ use super::pat::{GateOr, PARAM_EXPECTED}; -use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath}; +use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType}; use super::{SemiColonMode, SeqSep, TokenExpectType}; use crate::maybe_recover_from_interpolated_ty_qpath; @@ -1647,7 +1647,8 @@ impl<'a> Parser<'a> { self.expect_or()?; args }; - let output = self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverFatArrow::Yes)?; + let output = + self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverReturnSign::Yes)?; Ok(P(FnDecl { inputs, output })) } diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index dd99a7587dd..ed8d4f78426 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -240,7 +240,7 @@ impl<'a> Parser<'a> { // Parse type with mandatory colon and (possibly empty) bounds, // or with mandatory equality sign and the second type. - let ty = self.parse_ty()?; + let ty = self.parse_ty_for_where_clause()?; if self.eat(&token::Colon) { let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?; Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 9e342a0d681..ff0323a107a 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1,5 +1,5 @@ use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error}; -use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath}; +use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; @@ -1514,7 +1514,7 @@ impl<'a> Parser<'a> { let header = self.parse_fn_front_matter()?; // `const ... fn` let ident = self.parse_ident()?; // `foo` let mut generics = self.parse_generics()?; // `<'a, T, ...>` - let decl = self.parse_fn_decl(req_name, AllowPlus::Yes)?; // `(p: u8, ...)` + let decl = self.parse_fn_decl(req_name, AllowPlus::Yes, RecoverReturnSign::Yes)?; // `(p: u8, ...)` generics.where_clause = self.parse_where_clause()?; // `where T: Ord` let mut sig_hi = self.prev_token.span; @@ -1645,10 +1645,11 @@ impl<'a> Parser<'a> { &mut self, req_name: ReqName, ret_allow_plus: AllowPlus, + recover_return_sign: RecoverReturnSign, ) -> PResult<'a, P> { Ok(P(FnDecl { inputs: self.parse_fn_params(req_name)?, - output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, RecoverFatArrow::Yes)?, + output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?, })) } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 311a4829fcf..4510e86e034 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,4 +1,4 @@ -use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath}; +use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, TokenType}; use crate::maybe_whole; use rustc_ast::ptr::P; @@ -232,7 +232,7 @@ impl<'a> Parser<'a> { let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; let span = ident.span.to(self.prev_token.span); let output = - self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverFatArrow::No)?; + self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?; ParenthesizedArgs { inputs, output, span }.into() }; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index ff19c5cfa85..ee0dc8f6304 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -43,12 +43,23 @@ pub(super) enum RecoverQPath { No, } -#[derive(PartialEq)] -pub(super) enum RecoverFatArrow { +#[derive(Copy, Clone, PartialEq)] +pub(super) enum RecoverReturnSign { Yes, + OnlyFatArrow, No, } +impl RecoverReturnSign { + fn can_recover(self, token: &TokenKind) -> bool { + match self { + Self::Yes => matches!(token, token::FatArrow | token::Colon), + Self::OnlyFatArrow => matches!(token, token::FatArrow), + Self::No => false, + } + } +} + // Is `...` (`CVarArgs`) legal at this level of type parsing? #[derive(PartialEq)] enum AllowCVariadic { @@ -68,14 +79,24 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { impl<'a> Parser<'a> { /// Parses a type. pub fn parse_ty(&mut self) -> PResult<'a, P> { - self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::No) + self.parse_ty_common( + AllowPlus::Yes, + RecoverQPath::Yes, + AllowCVariadic::No, + RecoverReturnSign::Yes, + ) } /// Parse a type suitable for a function or function pointer parameter. /// The difference from `parse_ty` is that this version allows `...` /// (`CVarArgs`) at the top level of the type. pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P> { - self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::Yes) + self.parse_ty_common( + AllowPlus::Yes, + RecoverQPath::Yes, + AllowCVariadic::Yes, + RecoverReturnSign::Yes, + ) } /// Parses a type in restricted contexts where `+` is not permitted. @@ -85,7 +106,22 @@ impl<'a> Parser<'a> { /// Example 2: `value1 as TYPE + value2` /// `+` is prohibited to avoid interactions with expression grammar. pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P> { - self.parse_ty_common(AllowPlus::No, RecoverQPath::Yes, AllowCVariadic::No) + self.parse_ty_common( + AllowPlus::No, + RecoverQPath::Yes, + AllowCVariadic::No, + RecoverReturnSign::Yes, + ) + } + + /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>` + pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P> { + self.parse_ty_common( + AllowPlus::Yes, + RecoverQPath::Yes, + AllowCVariadic::Yes, + RecoverReturnSign::OnlyFatArrow, + ) } /// Parses an optional return type `[ -> TY ]` in a function declaration. @@ -93,13 +129,18 @@ impl<'a> Parser<'a> { &mut self, allow_plus: AllowPlus, recover_qpath: RecoverQPath, - recover_fat_arrow: RecoverFatArrow, + recover_return_sign: RecoverReturnSign, ) -> PResult<'a, FnRetTy> { Ok(if self.eat(&token::RArrow) { // FIXME(Centril): Can we unconditionally `allow_plus`? - let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?; + let ty = self.parse_ty_common( + allow_plus, + recover_qpath, + AllowCVariadic::No, + recover_return_sign, + )?; FnRetTy::Ty(ty) - } else if recover_fat_arrow == RecoverFatArrow::Yes && self.token == token::FatArrow { + } else if recover_return_sign.can_recover(&self.token.kind) { // Don't `eat` to prevent `=>` from being added as an expected token which isn't // actually expected and could only confuse users self.bump(); @@ -111,7 +152,12 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ) .emit(); - let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?; + let ty = self.parse_ty_common( + allow_plus, + recover_qpath, + AllowCVariadic::No, + recover_return_sign, + )?; FnRetTy::Ty(ty) } else { FnRetTy::Default(self.token.span.shrink_to_lo()) @@ -123,6 +169,7 @@ impl<'a> Parser<'a> { allow_plus: AllowPlus, recover_qpath: RecoverQPath, allow_c_variadic: AllowCVariadic, + recover_return_sign: RecoverReturnSign, ) -> PResult<'a, P> { let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); @@ -150,14 +197,14 @@ impl<'a> Parser<'a> { TyKind::Infer } else if self.check_fn_front_matter() { // Function pointer type - self.parse_ty_bare_fn(lo, Vec::new())? + self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)? } else if self.check_keyword(kw::For) { // Function pointer type or bound list (trait object type) starting with a poly-trait. // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` let lifetime_defs = self.parse_late_bound_lifetime_defs()?; if self.check_fn_front_matter() { - self.parse_ty_bare_fn(lo, lifetime_defs)? + self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)? } else { let path = self.parse_path(PathStyle::Type)?; let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); @@ -359,9 +406,14 @@ impl<'a> Parser<'a> { /// Function Style ABI Parameter types /// ``` /// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers. - fn parse_ty_bare_fn(&mut self, lo: Span, params: Vec) -> PResult<'a, TyKind> { + fn parse_ty_bare_fn( + &mut self, + lo: Span, + params: Vec, + recover_return_sign: RecoverReturnSign, + ) -> PResult<'a, TyKind> { let ast::FnHeader { ext, unsafety, constness, asyncness } = self.parse_fn_front_matter()?; - let decl = self.parse_fn_decl(|_| false, AllowPlus::No)?; + let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?; let whole_span = lo.to(self.prev_token.span); if let ast::Const::Yes(span) = constness { self.error_fn_ptr_bad_qualifier(whole_span, span, "const"); diff --git a/src/test/ui/fn/fn-fat-arrow-return.fixed b/src/test/ui/fn/fn-fat-arrow-return.fixed deleted file mode 100644 index 0acca85aa67..00000000000 --- a/src/test/ui/fn/fn-fat-arrow-return.fixed +++ /dev/null @@ -1,18 +0,0 @@ -// run-rustfix -#![allow(unused)] -fn a() -> usize { 0 } -//~^ ERROR return types are denoted using `->` - -fn bar(_: u32) {} - -fn baz() -> *const dyn Fn(u32) { unimplemented!() } - -fn foo() { - match () { - _ if baz() == &bar as &dyn Fn(u32) => (), - () => (), - } -} - -fn main() { -} diff --git a/src/test/ui/fn/fn-fat-arrow-return.rs b/src/test/ui/fn/fn-fat-arrow-return.rs deleted file mode 100644 index 4bdcd70d7fc..00000000000 --- a/src/test/ui/fn/fn-fat-arrow-return.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-rustfix -#![allow(unused)] -fn a() => usize { 0 } -//~^ ERROR return types are denoted using `->` - -fn bar(_: u32) {} - -fn baz() -> *const dyn Fn(u32) { unimplemented!() } - -fn foo() { - match () { - _ if baz() == &bar as &dyn Fn(u32) => (), - () => (), - } -} - -fn main() { -} diff --git a/src/test/ui/fn/fn-fat-arrow-return.stderr b/src/test/ui/fn/fn-fat-arrow-return.stderr deleted file mode 100644 index 1fcdb18a514..00000000000 --- a/src/test/ui/fn/fn-fat-arrow-return.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: return types are denoted using `->` - --> $DIR/fn-fat-arrow-return.rs:3:8 - | -LL | fn a() => usize { 0 } - | ^^ help: use `->` instead - -error: aborting due to previous error - diff --git a/src/test/ui/fn/fn-fat-arrow-return2.rs b/src/test/ui/fn/fn-fat-arrow-return2.rs deleted file mode 100644 index 316fa2cbf02..00000000000 --- a/src/test/ui/fn/fn-fat-arrow-return2.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn a() => impl Fn() => bool { - //~^ ERROR return types are denoted using `->` - //~| ERROR expected `;` or `{`, found `=>` - unimplemented!() -} - -fn main() { - let foo = |a: bool| => bool { a }; - dbg!(foo(false)); -} diff --git a/src/test/ui/fn/fn-fat-arrow-return2.stderr b/src/test/ui/fn/fn-fat-arrow-return2.stderr deleted file mode 100644 index a6f9fe3b573..00000000000 --- a/src/test/ui/fn/fn-fat-arrow-return2.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: return types are denoted using `->` - --> $DIR/fn-fat-arrow-return2.rs:1:8 - | -LL | fn a() => impl Fn() => bool { - | ^^ help: use `->` instead - -error: expected `;` or `{`, found `=>` - --> $DIR/fn-fat-arrow-return2.rs:1:21 - | -LL | fn a() => impl Fn() => bool { - | ^^ expected `;` or `{` - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/fn/fn-recover-return-sign.fixed b/src/test/ui/fn/fn-recover-return-sign.fixed new file mode 100644 index 00000000000..076be6a35a4 --- /dev/null +++ b/src/test/ui/fn/fn-recover-return-sign.fixed @@ -0,0 +1,28 @@ +// run-rustfix +#![allow(unused)] +fn a() -> usize { 0 } +//~^ ERROR return types are denoted using `->` + +fn b()-> usize { 0 } +//~^ ERROR return types are denoted using `->` + +fn bar(_: u32) {} + +fn baz() -> *const dyn Fn(u32) { unimplemented!() } + +fn foo() { + match () { + _ if baz() == &bar as &dyn Fn(u32) => (), + () => (), + } +} + +fn main() { + let foo = |a: bool| -> bool { a }; + //~^ ERROR return types are denoted using `->` + dbg!(foo(false)); + + let bar = |a: bool|-> bool { a }; + //~^ ERROR return types are denoted using `->` + dbg!(bar(false)); +} diff --git a/src/test/ui/fn/fn-recover-return-sign.rs b/src/test/ui/fn/fn-recover-return-sign.rs new file mode 100644 index 00000000000..0656023c0f8 --- /dev/null +++ b/src/test/ui/fn/fn-recover-return-sign.rs @@ -0,0 +1,28 @@ +// run-rustfix +#![allow(unused)] +fn a() => usize { 0 } +//~^ ERROR return types are denoted using `->` + +fn b(): usize { 0 } +//~^ ERROR return types are denoted using `->` + +fn bar(_: u32) {} + +fn baz() -> *const dyn Fn(u32) { unimplemented!() } + +fn foo() { + match () { + _ if baz() == &bar as &dyn Fn(u32) => (), + () => (), + } +} + +fn main() { + let foo = |a: bool| => bool { a }; + //~^ ERROR return types are denoted using `->` + dbg!(foo(false)); + + let bar = |a: bool|: bool { a }; + //~^ ERROR return types are denoted using `->` + dbg!(bar(false)); +} diff --git a/src/test/ui/fn/fn-recover-return-sign.stderr b/src/test/ui/fn/fn-recover-return-sign.stderr new file mode 100644 index 00000000000..983109730ff --- /dev/null +++ b/src/test/ui/fn/fn-recover-return-sign.stderr @@ -0,0 +1,26 @@ +error: return types are denoted using `->` + --> $DIR/fn-recover-return-sign.rs:3:8 + | +LL | fn a() => usize { 0 } + | ^^ help: use `->` instead + +error: return types are denoted using `->` + --> $DIR/fn-recover-return-sign.rs:6:7 + | +LL | fn b(): usize { 0 } + | ^ help: use `->` instead + +error: return types are denoted using `->` + --> $DIR/fn-recover-return-sign.rs:21:25 + | +LL | let foo = |a: bool| => bool { a }; + | ^^ help: use `->` instead + +error: return types are denoted using `->` + --> $DIR/fn-recover-return-sign.rs:25:24 + | +LL | let bar = |a: bool|: bool { a }; + | ^ help: use `->` instead + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/fn/fn-recover-return-sign2.rs b/src/test/ui/fn/fn-recover-return-sign2.rs new file mode 100644 index 00000000000..b6a6a1ec2a6 --- /dev/null +++ b/src/test/ui/fn/fn-recover-return-sign2.rs @@ -0,0 +1,8 @@ +// Separate test file because `Fn() => bool` isn't getting fixed and rustfix complained that +// even though a fix was applied the code was still incorrect + +fn foo() => impl Fn() => bool { + //~^ ERROR return types are denoted using `->` + //~| ERROR expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>` + unimplemented!() +} diff --git a/src/test/ui/fn/fn-recover-return-sign2.stderr b/src/test/ui/fn/fn-recover-return-sign2.stderr new file mode 100644 index 00000000000..d62cacd4bf5 --- /dev/null +++ b/src/test/ui/fn/fn-recover-return-sign2.stderr @@ -0,0 +1,14 @@ +error: return types are denoted using `->` + --> $DIR/fn-recover-return-sign2.rs:4:10 + | +LL | fn foo() => impl Fn() => bool { + | ^^ help: use `->` instead + +error: expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>` + --> $DIR/fn-recover-return-sign2.rs:4:23 + | +LL | fn foo() => impl Fn() => bool { + | ^^ expected one of `+`, `->`, `::`, `;`, `where`, or `{` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/fn-colon-return-type.rs b/src/test/ui/parser/fn-colon-return-type.rs index c791fb3ae67..0001ef57c99 100644 --- a/src/test/ui/parser/fn-colon-return-type.rs +++ b/src/test/ui/parser/fn-colon-return-type.rs @@ -1,4 +1,5 @@ -fn foo(x: i32): i32 { //~ ERROR expected one of `->`, `;`, `where`, or `{`, found `:` +fn foo(x: i32): i32 { +//~^ ERROR return types are denoted using `->` x } diff --git a/src/test/ui/parser/fn-colon-return-type.stderr b/src/test/ui/parser/fn-colon-return-type.stderr index 92df9bc60bd..1de91878205 100644 --- a/src/test/ui/parser/fn-colon-return-type.stderr +++ b/src/test/ui/parser/fn-colon-return-type.stderr @@ -1,8 +1,8 @@ -error: expected one of `->`, `;`, `where`, or `{`, found `:` +error: return types are denoted using `->` --> $DIR/fn-colon-return-type.rs:1:15 | LL | fn foo(x: i32): i32 { - | ^ expected one of `->`, `;`, `where`, or `{` + | ^ help: use `->` instead error: aborting due to previous error diff --git a/src/test/ui/parser/not-a-pred.rs b/src/test/ui/parser/not-a-pred.rs index 1b3d9bf66bb..5518b554d8e 100644 --- a/src/test/ui/parser/not-a-pred.rs +++ b/src/test/ui/parser/not-a-pred.rs @@ -1,6 +1,15 @@ fn f(a: isize, b: isize) : lt(a, b) { } -//~^ ERROR expected one of `->`, `;`, `where`, or `{`, found `:` +//~^ ERROR return types are denoted using `->` +//~| ERROR expected type, found function `lt` [E0573] +//~| ERROR expected type, found local variable `a` [E0573] +//~| ERROR expected type, found local variable `b` [E0573] fn lt(a: isize, b: isize) { } -fn main() { let a: isize = 10; let b: isize = 23; check (lt(a, b)); f(a, b); } +fn main() { + let a: isize = 10; + let b: isize = 23; + check (lt(a, b)); + //~^ ERROR cannot find function `check` in this scope [E0425] + f(a, b); +} diff --git a/src/test/ui/parser/not-a-pred.stderr b/src/test/ui/parser/not-a-pred.stderr index ec413c5594c..bcc64a687fd 100644 --- a/src/test/ui/parser/not-a-pred.stderr +++ b/src/test/ui/parser/not-a-pred.stderr @@ -1,8 +1,34 @@ -error: expected one of `->`, `;`, `where`, or `{`, found `:` +error: return types are denoted using `->` --> $DIR/not-a-pred.rs:1:26 | LL | fn f(a: isize, b: isize) : lt(a, b) { } - | ^ expected one of `->`, `;`, `where`, or `{` + | ^ help: use `->` instead -error: aborting due to previous error +error[E0573]: expected type, found function `lt` + --> $DIR/not-a-pred.rs:1:28 + | +LL | fn f(a: isize, b: isize) : lt(a, b) { } + | ^^^^^^^^ not a type + +error[E0573]: expected type, found local variable `a` + --> $DIR/not-a-pred.rs:1:31 + | +LL | fn f(a: isize, b: isize) : lt(a, b) { } + | ^ not a type + +error[E0573]: expected type, found local variable `b` + --> $DIR/not-a-pred.rs:1:34 + | +LL | fn f(a: isize, b: isize) : lt(a, b) { } + | ^ not a type + +error[E0425]: cannot find function `check` in this scope + --> $DIR/not-a-pred.rs:12:5 + | +LL | check (lt(a, b)); + | ^^^^^ not found in this scope + +error: aborting due to 5 previous errors +Some errors have detailed explanations: E0425, E0573. +For more information about an error, try `rustc --explain E0425`. -- cgit 1.4.1-3-g733a5 From 87c621690a00c96e9f2874ba318ee46db98b7ab5 Mon Sep 17 00:00:00 2001 From: Daiki Ihara Date: Thu, 3 Dec 2020 00:38:02 +0900 Subject: Update some associated-types ui test suites --- .../associated-types-project-from-hrtb-in-fn.fixed | 2 +- .../associated-types/associated-types-project-from-hrtb-in-fn.rs | 2 +- .../associated-types-project-from-hrtb-in-fn.stderr | 3 ++- .../associated-types-project-from-hrtb-in-struct.rs | 8 ++++---- .../associated-types-project-from-hrtb-in-struct.stderr | 9 +++++---- .../associated-types-project-from-hrtb-in-trait-method.fixed | 4 ++-- .../associated-types-project-from-hrtb-in-trait-method.rs | 4 ++-- .../associated-types-project-from-hrtb-in-trait-method.stderr | 5 +++-- 8 files changed, 20 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed index 760d2b433c8..bca69a97677 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed @@ -11,7 +11,7 @@ pub trait Foo { fn foo2 Foo<&'x isize>>( x: >::A) - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters { // This case is illegal because we have to instantiate `'x`, and // we don't know what region to instantiate it with. diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs index 6eb584ea645..1e23dd8890b 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs @@ -11,7 +11,7 @@ pub trait Foo { fn foo2 Foo<&'x isize>>( x: I::A) - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters { // This case is illegal because we have to instantiate `'x`, and // we don't know what region to instantiate it with. diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr index f2137f68665..989624bdd93 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr @@ -1,4 +1,4 @@ -error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context +error[E0212]: cannot use the associated type of a trait with uninferred generic parameters --> $DIR/associated-types-project-from-hrtb-in-fn.rs:13:8 | LL | x: I::A) @@ -6,3 +6,4 @@ LL | x: I::A) error: aborting due to previous error +For more information about this error, try `rustc --explain E0212`. diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs index 58f186d7775..ed30d86cb5b 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs @@ -9,14 +9,14 @@ pub trait Foo { struct SomeStruct Foo<&'x isize>> { field: I::A - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters } enum SomeEnum<'b, I: for<'a> Foo<&'a isize>> { TupleVariant(I::A), - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters StructVariant { field: I::A }, - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters OkVariant(&'b usize), } @@ -33,7 +33,7 @@ struct YetAnotherStruct<'a, I: for<'x> Foo<&'x isize>> { struct Why<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'aa, I: for<'l, 'm> Foo<&'l &'m isize>> { field: I::A, - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters } pub fn main() {} diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr index e3fd2860ebc..cadc3e9eab1 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr @@ -1,4 +1,4 @@ -error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context +error[E0212]: cannot use the associated type of a trait with uninferred generic parameters --> $DIR/associated-types-project-from-hrtb-in-struct.rs:11:12 | LL | field: I::A @@ -10,7 +10,7 @@ LL | struct SomeStruct<'a, I: for<'x> Foo<&'x isize>> { LL | field: >::A | -error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context +error[E0212]: cannot use the associated type of a trait with uninferred generic parameters --> $DIR/associated-types-project-from-hrtb-in-struct.rs:16:18 | LL | TupleVariant(I::A), @@ -22,7 +22,7 @@ LL | enum SomeEnum<'c, 'b, I: for<'a> Foo<&'a isize>> { LL | TupleVariant(>::A), | -error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context +error[E0212]: cannot use the associated type of a trait with uninferred generic parameters --> $DIR/associated-types-project-from-hrtb-in-struct.rs:18:28 | LL | StructVariant { field: I::A }, @@ -36,7 +36,7 @@ LL | LL | StructVariant { field: >::A }, | -error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context +error[E0212]: cannot use the associated type of a trait with uninferred generic parameters --> $DIR/associated-types-project-from-hrtb-in-struct.rs:35:12 | LL | field: I::A, @@ -51,3 +51,4 @@ LL | field: >::A, error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0212`. diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed index acf32bccbec..66d8613f184 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed @@ -11,7 +11,7 @@ pub trait Foo { trait SomeTrait Foo<&'x isize>> { fn some_method(&self, arg: >::A); - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters } trait AnotherTrait Foo<&'x isize>> { @@ -30,7 +30,7 @@ struct Peach(std::marker::PhantomData); impl Banana<'a>> Peach { fn mango(&self) -> >::Assoc { - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters Default::default() } } diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs index a249f89685e..0a1b29de19e 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs @@ -11,7 +11,7 @@ pub trait Foo { trait SomeTrait Foo<&'x isize>> { fn some_method(&self, arg: I::A); - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters } trait AnotherTrait Foo<&'x isize>> { @@ -30,7 +30,7 @@ struct Peach(std::marker::PhantomData); impl Banana<'a>> Peach { fn mango(&self) -> X::Assoc { - //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters Default::default() } } diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr index a37fec24493..d457f9f8468 100644 --- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr +++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr @@ -1,10 +1,10 @@ -error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context +error[E0212]: cannot use the associated type of a trait with uninferred generic parameters --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:13:32 | LL | fn some_method(&self, arg: I::A); | ^^^^ help: use a fully qualified path with inferred lifetimes: `>::A` -error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context +error[E0212]: cannot use the associated type of a trait with uninferred generic parameters --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:32:24 | LL | fn mango(&self) -> X::Assoc { @@ -12,3 +12,4 @@ LL | fn mango(&self) -> X::Assoc { error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0212`. -- cgit 1.4.1-3-g733a5 From 6fe31e76fb7c3a1d6346977e8edfd06c8f2c405e Mon Sep 17 00:00:00 2001 From: Vishnunarayan K I Date: Sat, 5 Dec 2020 20:21:21 +0530 Subject: fix clippy test --- src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs b/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs index 6d2124c12fe..c57a45dc7aa 100644 --- a/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs +++ b/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs @@ -1,7 +1,6 @@ -#![allow(clippy::useless_attribute)] //issue #2910 +// edition:2018 -#[macro_use] -extern crate serde_derive; +use serde::Deserialize; /// Tests that we do not lint for unused underscores in a `MacroAttribute` /// expansion -- cgit 1.4.1-3-g733a5 From db8ddbf570fa7d8df5d71b19b44a771c80c689ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 5 Dec 2020 17:31:31 +0100 Subject: Move tooltips messages to CSS instead of inside HTML --- src/librustdoc/html/highlight.rs | 15 ++++--- src/librustdoc/html/markdown.rs | 61 +++++++---------------------- src/librustdoc/html/static/rustdoc.css | 24 ++++++++---- src/librustdoc/html/static/themes/ayu.css | 4 +- src/librustdoc/html/static/themes/dark.css | 4 +- src/librustdoc/html/static/themes/light.css | 4 +- 6 files changed, 47 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 1cbfbf50dd7..47d2707e40d 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -11,6 +11,7 @@ use std::fmt::{Display, Write}; use std::iter::Peekable; use rustc_lexer::{LiteralKind, TokenKind}; +use rustc_span::edition::Edition; use rustc_span::symbol::Ident; use rustc_span::with_default_session_globals; @@ -19,16 +20,20 @@ crate fn render_with_highlighting( src: String, class: Option<&str>, playground_button: Option<&str>, - tooltip: Option<(&str, &str)>, + tooltip: Option<(Option, &str)>, ) -> String { debug!("highlighting: ================\n{}\n==============", src); let mut out = String::with_capacity(src.len()); - if let Some((tooltip, class)) = tooltip { + if let Some((edition_info, class)) = tooltip { write!( out, - "
ⓘ{}
", - class, tooltip + "
ⓘ
", + class, + if let Some(edition_info) = edition_info { + format!(" edition=\"{}\"", edition_info) + } else { + String::new() + }, ) .unwrap(); } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 8ce686c6550..6229a479b4d 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -286,60 +286,27 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { }); let tooltip = if ignore != Ignore::None { - Some(("This example is not tested".to_owned(), "ignore")) + Some((None, "ignore")) } else if compile_fail { - Some(("This example deliberately fails to compile".to_owned(), "compile_fail")) + Some((None, "compile_fail")) } else if should_panic { - Some(("This example panics".to_owned(), "should_panic")) + Some((None, "should_panic")) } else if explicit_edition { - Some((format!("This code runs with edition {}", edition), "edition")) + Some((Some(edition), "edition")) } else { None }; - if let Some((s1, s2)) = tooltip { - s.push_str(&highlight::render_with_highlighting( - text, - Some(&format!( - "rust-example-rendered{}", - if ignore != Ignore::None { - " ignore" - } else if compile_fail { - " compile_fail" - } else if should_panic { - " should_panic" - } else if explicit_edition { - " edition " - } else { - "" - } - )), - playground_button.as_deref(), - Some((s1.as_str(), s2)), - )); - Some(Event::Html(s.into())) - } else { - s.push_str(&highlight::render_with_highlighting( - text, - Some(&format!( - "rust-example-rendered{}", - if ignore != Ignore::None { - " ignore" - } else if compile_fail { - " compile_fail" - } else if should_panic { - " should_panic" - } else if explicit_edition { - " edition " - } else { - "" - } - )), - playground_button.as_deref(), - None, - )); - Some(Event::Html(s.into())) - } + s.push_str(&highlight::render_with_highlighting( + text, + Some(&format!( + "rust-example-rendered{}", + if let Some((_, class)) = tooltip { format!(" {}", class) } else { String::new() } + )), + playground_button.as_deref(), + tooltip, + )); + Some(Event::Html(s.into())) } } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 8eef65a231d..afc4308b68f 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1079,20 +1079,29 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { cursor: pointer; } -.tooltip .tooltiptext { - width: 120px; +.tooltip::after { display: none; text-align: center; padding: 5px 3px 3px 3px; border-radius: 6px; margin-left: 5px; - top: -5px; - left: 105%; - z-index: 10; font-size: 16px; } -.tooltip .tooltiptext::after { +.tooltip.ignore::after { + content: "This example is not tested"; +} +.tooltip.compile_fail::after { + content: "This example deliberately fails to compile"; +} +.tooltip.should_panic::after { + content: "This example panics"; +} +.tooltip.edition::after { + content: "This code runs with edition " attr(edition); +} + +.tooltip::before { content: " "; position: absolute; top: 50%; @@ -1100,9 +1109,10 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { margin-top: -5px; border-width: 5px; border-style: solid; + display: none; } -.tooltip:hover .tooltiptext { +.tooltip:hover::before, .tooltip:hover::after { display: inline; } diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index c1f796f09e8..9c71fbb7f03 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -388,13 +388,13 @@ pre.ignore:hover, .information:hover + pre.ignore { color: #39AFD7; } -.tooltip .tooltiptext { +.tooltip::after { background-color: #314559; color: #c5c5c5; border: 1px solid #5c6773; } -.tooltip .tooltiptext::after { +.tooltip::before { border-color: transparent #314559 transparent transparent; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 946ca0a40c9..eb25272ea3b 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -337,13 +337,13 @@ pre.ignore:hover, .information:hover + pre.ignore { color: #0089ff; } -.tooltip .tooltiptext { +.tooltip::after { background-color: #000; color: #fff; border-color: #000; } -.tooltip .tooltiptext::after { +.tooltip::before { border-color: transparent black transparent transparent; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index e0b9a04921a..20e3c0a4092 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -329,12 +329,12 @@ pre.ignore:hover, .information:hover + pre.ignore { color: #0089ff; } -.tooltip .tooltiptext { +.tooltip::after { background-color: #000; color: #fff; } -.tooltip .tooltiptext::after { +.tooltip::before { border-color: transparent black transparent transparent; } -- cgit 1.4.1-3-g733a5 From 9b6293692801f703e694c4c7f61b165b939cea8d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 5 Dec 2020 17:31:39 +0100 Subject: Update tests --- src/test/rustdoc/codeblock-title.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/test/rustdoc/codeblock-title.rs b/src/test/rustdoc/codeblock-title.rs index b59b21111b0..1327fd67d31 100644 --- a/src/test/rustdoc/codeblock-title.rs +++ b/src/test/rustdoc/codeblock-title.rs @@ -1,10 +1,9 @@ #![crate_name = "foo"] -// ignore-tidy-linelength - -// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]/span' "This example deliberately fails to compile" -// @has foo/fn.bar.html '//*[@class="tooltip ignore"]/span' "This example is not tested" -// @has foo/fn.bar.html '//*[@class="tooltip should_panic"]/span' "This example panics" +// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]' "ⓘ" +// @has foo/fn.bar.html '//*[@class="tooltip ignore"]' "ⓘ" +// @has foo/fn.bar.html '//*[@class="tooltip should_panic"]' "ⓘ" +// @has foo/fn.bar.html '//*[@edition="2018"]' "ⓘ" /// foo /// @@ -20,7 +19,7 @@ /// hoo(); /// ``` /// -/// ``` +/// ```edition2018 /// let x = 0; /// ``` pub fn bar() -> usize { 2 } -- cgit 1.4.1-3-g733a5 From 77d80b22f1abe8392f7124fec343fdbbe760340e Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 24 Oct 2020 21:13:54 +0200 Subject: Introduce if-let guards in the HIR --- compiler/rustc_ast_lowering/src/expr.rs | 15 ++++++++++----- compiler/rustc_hir/src/hir.rs | 1 + compiler/rustc_hir/src/intravisit.rs | 4 ++++ compiler/rustc_hir_pretty/src/lib.rs | 9 +++++++++ src/test/ui/rfc-2294-if-let-guard/feature-gate.rs | 1 - src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr | 9 --------- 6 files changed, 24 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index e0e78a4d609..7c95c7f6480 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -505,14 +505,19 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { + let pat = self.lower_pat(&arm.pat); + let guard = arm.guard.as_ref().map(|cond| { + if let ExprKind::Let(ref pat, ref scrutinee) = cond.kind { + hir::Guard::IfLet(self.lower_pat(pat), self.lower_expr(scrutinee)) + } else { + hir::Guard::If(self.lower_expr(cond)) + } + }); hir::Arm { hir_id: self.next_id(), attrs: self.lower_attrs(&arm.attrs), - pat: self.lower_pat(&arm.pat), - guard: match arm.guard { - Some(ref x) => Some(hir::Guard::If(self.lower_expr(x))), - _ => None, - }, + pat, + guard, body: self.lower_expr(&arm.body), span: arm.span, } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 44dc6673564..03cb4b76dc0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1160,6 +1160,7 @@ pub struct Arm<'hir> { #[derive(Debug, HashStable_Generic)] pub enum Guard<'hir> { If(&'hir Expr<'hir>), + IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>), } #[derive(Debug, HashStable_Generic)] diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 3e8fc689acf..ea3f2b7f679 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1228,6 +1228,10 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) { if let Some(ref g) = arm.guard { match g { Guard::If(ref e) => visitor.visit_expr(e), + Guard::IfLet(ref pat, ref e) => { + visitor.visit_pat(pat); + visitor.visit_expr(e); + } } } visitor.visit_expr(&arm.body); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 25b09d76295..6897a349513 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2002,6 +2002,15 @@ impl<'a> State<'a> { self.print_expr(&e); self.s.space(); } + hir::Guard::IfLet(pat, e) => { + self.word_nbsp("if"); + self.word_nbsp("let"); + self.print_pat(&pat); + self.s.space(); + self.word_space("="); + self.print_expr(&e); + self.s.space(); + } } } self.word_space("=>"); diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs index c0a9bbc36b2..311d1afcfc0 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs @@ -6,7 +6,6 @@ fn _if_let_guard() { match () { () if let 0 = 1 => {} //~^ ERROR `if let` guard is not implemented - //~| ERROR `let` expressions are not supported here () if (let 0 = 1) => {} //~^ ERROR `let` expressions in this position are experimental diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr index 5c7f8190dd6..d43096336c5 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr @@ -169,15 +169,6 @@ LL | use_expr!((let 0 = 1)); = note: see issue #53667 for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:7:15 - | -LL | () if let 0 = 1 => {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if`- and `while`-expressions - = note: as well as when nested within `&&` and parenthesis in those conditions - error: `let` expressions are not supported here --> $DIR/feature-gate.rs:11:16 | -- cgit 1.4.1-3-g733a5 From f3d4aa6afbad980da62b20cd4583079be7d62104 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Fri, 13 Nov 2020 18:27:27 +0100 Subject: Implement lowering of if-let guards to MIR --- compiler/rustc_hir/src/hir.rs | 4 +- compiler/rustc_mir_build/src/build/matches/mod.rs | 54 ++++++++++++++++++---- compiler/rustc_mir_build/src/build/scope.rs | 1 + compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- .../src/thir/pattern/check_match.rs | 31 +++++++++++++ compiler/rustc_passes/src/check_const.rs | 2 + src/tools/clippy/clippy_lints/src/utils/author.rs | 1 + 7 files changed, 84 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 03cb4b76dc0..f850295e62f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1722,6 +1722,8 @@ pub enum MatchSource { IfDesugar { contains_else_clause: bool }, /// An `if let _ = _ { .. }` (optionally with `else { .. }`). IfLetDesugar { contains_else_clause: bool }, + /// An `if let _ = _ => { .. }` match guard. + IfLetGuardDesugar, /// A `while _ { .. }` (which was desugared to a `loop { match _ { .. } }`). WhileDesugar, /// A `while let _ = _ { .. }` (which was desugared to a @@ -1740,7 +1742,7 @@ impl MatchSource { use MatchSource::*; match self { Normal => "match", - IfDesugar { .. } | IfLetDesugar { .. } => "if", + IfDesugar { .. } | IfLetDesugar { .. } | IfLetGuardDesugar => "if", WhileDesugar | WhileLetDesugar => "while", ForLoopDesugar => "for", TryDesugar => "?", diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 7ffdb7e33fb..d4715b836ea 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -228,6 +228,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard: Option<&Guard<'tcx>>, fake_borrow_temps: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, + arm_span: Option, arm_scope: Option, ) -> BasicBlock { if candidate.subcandidates.is_empty() { @@ -239,6 +240,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard, fake_borrow_temps, scrutinee_span, + arm_span, true, ) } else { @@ -274,6 +276,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard, &fake_borrow_temps, scrutinee_span, + arm_span, schedule_drops, ); if arm_scope.is_none() { @@ -436,6 +439,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &fake_borrow_temps, irrefutable_pat.span, None, + None, ) .unit() } @@ -817,11 +821,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// For an example of a case where we set `otherwise_block`, even for an /// exhaustive match consider: /// + /// ```rust /// match x { /// (true, true) => (), /// (_, false) => (), /// (false, true) => (), /// } + /// ``` /// /// For this match, we check if `x.0` matches `true` (for the first /// arm). If that's false, we check `x.1`. If it's `true` we check if @@ -935,11 +941,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Link up matched candidates. For example, if we have something like /// this: /// + /// ```rust /// ... /// Some(x) if cond => ... /// Some(x) => ... /// Some(x) if cond => ... /// ... + /// ``` /// /// We generate real edges from: /// * `start_block` to the `prebinding_block` of the first pattern, @@ -1517,7 +1525,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Initializes each of the bindings from the candidate by /// moving/copying/ref'ing the source as appropriate. Tests the guard, if /// any, and then branches to the arm. Returns the block for the case where - /// the guard fails. + /// the guard succeeds. /// /// Note: we do not check earlier that if there is a guard, /// there cannot be move bindings. We avoid a use-after-move by only @@ -1529,6 +1537,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard: Option<&Guard<'tcx>>, fake_borrows: &Vec<(Place<'tcx>, Local)>, scrutinee_span: Span, + arm_span: Option, schedule_drops: bool, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -1659,15 +1668,42 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow); } - // the block to branch to if the guard fails; if there is no - // guard, this block is simply unreachable - let guard = match guard { - Guard::If(e) => self.hir.mirror(e.clone()), + let (guard_span, (post_guard_block, otherwise_post_guard_block)) = match guard { + Guard::If(e) => { + let e = self.hir.mirror(e.clone()); + let source_info = self.source_info(e.span); + (e.span, self.test_bool(block, e, source_info)) + }, + Guard::IfLet(pat, scrutinee) => { + let scrutinee_span = scrutinee.span(); + let scrutinee_place = unpack!(block = self.lower_scrutinee(block, scrutinee.clone(), scrutinee_span)); + let mut guard_candidate = Candidate::new(scrutinee_place, &pat, false); + let wildcard = Pat::wildcard_from_ty(pat.ty); + let mut otherwise_candidate = Candidate::new(scrutinee_place, &wildcard, false); + let fake_borrow_temps = + self.lower_match_tree(block, pat.span, false, &mut [&mut guard_candidate, &mut otherwise_candidate]); + self.declare_bindings( + None, + pat.span.to(arm_span.unwrap()), + pat, + ArmHasGuard(false), + Some((Some(&scrutinee_place), scrutinee.span())), + ); + let post_guard_block = self.bind_pattern( + self.source_info(pat.span), + guard_candidate, + None, + &fake_borrow_temps, + scrutinee.span(), + None, + None, + ); + let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap(); + (scrutinee_span, (post_guard_block, otherwise_post_guard_block)) + } }; - let source_info = self.source_info(guard.span); - let guard_end = self.source_info(tcx.sess.source_map().end_point(guard.span)); - let (post_guard_block, otherwise_post_guard_block) = - self.test_bool(block, guard, source_info); + let source_info = self.source_info(guard_span); + let guard_end = self.source_info(tcx.sess.source_map().end_point(guard_span)); let guard_frame = self.guard_context.pop().unwrap(); debug!("Exiting guard building context with locals: {:?}", guard_frame); diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 468b3484ca5..0f38c30818f 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -1220,6 +1220,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { arm.guard.as_ref(), &fake_borrow_temps, scrutinee_span, + Some(arm.span), Some(arm.scope), ); diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 310673f5efc..aac1e505b65 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -778,7 +778,7 @@ fn convert_arm<'tcx>(cx: &mut Cx<'_, 'tcx>, arm: &'tcx hir::Arm<'tcx>) -> Arm<'t pattern: cx.pattern_from_hir(&arm.pat), guard: arm.guard.as_ref().map(|g| match g { hir::Guard::If(ref e) => Guard::If(e.to_ref()), - hir::Guard::IfLet(ref pat, ref e) => Guard::IfLet(cx.pattern_from_hir(pat), e.to_ref()) + hir::Guard::IfLet(ref pat, ref e) => Guard::IfLet(cx.pattern_from_hir(pat), e.to_ref()), }), body: arm.body.to_ref(), lint_level: LintLevel::Explicit(arm.hir_id), diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 97edbd83b89..29b7e176b0e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -164,10 +164,20 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { for arm in arms { // Check the arm for some things unrelated to exhaustiveness. self.check_patterns(&arm.pat); + if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard { + self.check_patterns(pat); + } } let mut cx = self.new_cx(scrut.hir_id); + for arm in arms { + if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard { + let tpat = self.lower_pattern(&mut cx, pat, &mut false).0; + check_if_let_guard(&mut cx, &tpat, pat.hir_id); + } + } + let mut have_errors = false; let arms: Vec<_> = arms @@ -360,12 +370,28 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, source: hir:: let msg = match source { hir::MatchSource::IfLetDesugar { .. } => "irrefutable if-let pattern", hir::MatchSource::WhileLetDesugar => "irrefutable while-let pattern", + hir::MatchSource::IfLetGuardDesugar => "irrefutable if-let guard", _ => bug!(), }; lint.build(msg).emit() }); } +fn check_if_let_guard<'p, 'tcx>( + cx: &mut MatchCheckCtxt<'p, 'tcx>, + pat: &'p super::Pat<'tcx>, + pat_id: HirId, +) { + let arms = [MatchArm { pat, hir_id: pat_id, has_guard: false }]; + let report = compute_match_usefulness(&cx, &arms, pat_id, pat.ty); + report_arm_reachability(&cx, &report, hir::MatchSource::IfLetGuardDesugar); + + if report.non_exhaustiveness_witnesses.is_empty() { + // The match is exhaustive, i.e. the if let pattern is irrefutable. + irrefutable_let_pattern(cx.tcx, pat.span, pat_id, hir::MatchSource::IfLetGuardDesugar) + } +} + /// Report unreachable arms, if any. fn report_arm_reachability<'p, 'tcx>( cx: &MatchCheckCtxt<'p, 'tcx>, @@ -390,6 +416,11 @@ fn report_arm_reachability<'p, 'tcx>( } } + hir::MatchSource::IfLetGuardDesugar => { + assert_eq!(arm_index, 0); + unreachable_pattern(cx.tcx, arm.pat.span, arm.hir_id, None); + } + hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => { unreachable_pattern(cx.tcx, arm.pat.span, arm.hir_id, catchall); } diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index e37c6418eb8..2d6bbff460d 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -45,6 +45,8 @@ impl NonConstExpr { return None; } + Self::Match(IfLetGuardDesugar) => bug!("if-let guard outside a `match` expression"), + // All other expressions are allowed. Self::Loop(Loop | While | WhileLet) | Self::Match( diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 7250de3a41c..135f289a2b3 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -730,6 +730,7 @@ fn desugaring_name(des: hir::MatchSource) -> String { "MatchSource::IfLetDesugar {{ contains_else_clause: {} }}", contains_else_clause ), + hir::MatchSource::IfLetGuardDesugar => "MatchSource::IfLetGuardDesugar".to_string(), hir::MatchSource::IfDesugar { contains_else_clause } => format!( "MatchSource::IfDesugar {{ contains_else_clause: {} }}", contains_else_clause -- cgit 1.4.1-3-g733a5 From 61e69bc3fc92c0e76bc8a3977c82cfac75efd743 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 15 Nov 2020 22:51:02 +0100 Subject: Handle `Guard::IfLet` in clippy --- src/tools/clippy/clippy_lints/src/shadow.rs | 4 ++++ src/tools/clippy/clippy_lints/src/utils/author.rs | 12 ++++++++++++ src/tools/clippy/clippy_lints/src/utils/hir_utils.rs | 4 +++- src/tools/clippy/clippy_lints/src/utils/inspector.rs | 5 +++++ 4 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 225fe58906f..f8396592678 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -342,6 +342,10 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut if let Some(ref guard) = arm.guard { match guard { Guard::If(if_expr) => check_expr(cx, if_expr, bindings), + Guard::IfLet(guard_pat, guard_expr) => { + check_pat(cx, guard_pat, Some(*guard_expr), guard_pat.span, bindings); + check_expr(cx, guard_expr, bindings); + }, } } check_expr(cx, &arm.body, bindings); diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 135f289a2b3..4249dbb4e65 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -372,6 +372,18 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { self.current = if_expr_pat; self.visit_expr(if_expr); }, + hir::Guard::IfLet(ref if_let_pat, ref if_let_expr) => { + let if_let_pat_pat = self.next("pat"); + let if_let_expr_pat = self.next("expr"); + println!( + " if let Guard::IfLet(ref {}, ref {}) = {};", + if_let_pat_pat, if_let_expr_pat, guard_pat + ); + self.current = if_let_expr_pat; + self.visit_expr(if_let_expr); + self.current = if_let_pat_pat; + self.visit_pat(if_let_pat); + }, } } self.current = format!("{}[{}].pat", arms_pat, i); diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs index e4ad105c351..b0099b4a792 100644 --- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs @@ -169,6 +169,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { fn eq_guard(&mut self, left: &Guard<'_>, right: &Guard<'_>) -> bool { match (left, right) { (Guard::If(l), Guard::If(r)) => self.eq_expr(l, r), + (Guard::IfLet(lp, le), Guard::IfLet(rp, re)) => self.eq_pat(lp, rp) && self.eq_expr(le, re), + _ => false, } } @@ -643,7 +645,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_guard(&mut self, g: &Guard<'_>) { match g { - Guard::If(ref expr) => { + Guard::If(ref expr) | Guard::IfLet(_, ref expr) => { self.hash_expr(expr); }, } diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index 8f0ef9150d4..0c93a12b921 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -560,5 +560,10 @@ fn print_guard(cx: &LateContext<'_>, guard: &hir::Guard<'_>, indent: usize) { println!("{}If", ind); print_expr(cx, expr, indent + 1); }, + hir::Guard::IfLet(pat, expr) => { + println!("{}IfLet", ind); + print_pat(cx, pat, indent + 1); + print_expr(cx, expr, indent + 1); + }, } } -- cgit 1.4.1-3-g733a5 From 09172603685ba72f1cae4f69b6fff63f2dfcd27f Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 15 Nov 2020 23:42:48 +0100 Subject: Add a few basic tests for if-let guards --- src/test/ui/generator/yielding-in-match-guards.rs | 11 ++++ src/test/ui/rfc-2294-if-let-guard/bindings.rs | 10 ++++ src/test/ui/rfc-2294-if-let-guard/bindings.stderr | 15 +++++ .../ui/rfc-2294-if-let-guard/feature-gate.stderr | 70 +++++++++++----------- src/test/ui/rfc-2294-if-let-guard/run-pass.rs | 34 +++++++++++ src/test/ui/rfc-2294-if-let-guard/typeck.rs | 16 +++++ src/test/ui/rfc-2294-if-let-guard/typeck.stderr | 21 +++++++ src/test/ui/rfc-2294-if-let-guard/warns.rs | 22 +++++++ src/test/ui/rfc-2294-if-let-guard/warns.stderr | 26 ++++++++ 9 files changed, 190 insertions(+), 35 deletions(-) create mode 100644 src/test/ui/rfc-2294-if-let-guard/bindings.rs create mode 100644 src/test/ui/rfc-2294-if-let-guard/bindings.stderr create mode 100644 src/test/ui/rfc-2294-if-let-guard/run-pass.rs create mode 100644 src/test/ui/rfc-2294-if-let-guard/typeck.rs create mode 100644 src/test/ui/rfc-2294-if-let-guard/typeck.stderr create mode 100644 src/test/ui/rfc-2294-if-let-guard/warns.rs create mode 100644 src/test/ui/rfc-2294-if-let-guard/warns.stderr (limited to 'src') diff --git a/src/test/ui/generator/yielding-in-match-guards.rs b/src/test/ui/generator/yielding-in-match-guards.rs index c76726414df..5c10a7c7811 100644 --- a/src/test/ui/generator/yielding-in-match-guards.rs +++ b/src/test/ui/generator/yielding-in-match-guards.rs @@ -10,6 +10,9 @@ // Thus, `&'_ u8` should be included in type signature // of the underlying generator. +#![feature(if_let_guard)] +#![allow(incomplete_features)] + async fn f() -> u8 { 1 } async fn foo() -> [bool; 10] { [false; 10] } @@ -36,8 +39,16 @@ async fn i(x: u8) { } } +async fn j(x: u8) { + match x { + y if let (1, 42) = (f().await, y) => (), + _ => (), + } +} + fn main() { let _ = g(10); let _ = h(9); let _ = i(8); + let _ = j(7); } diff --git a/src/test/ui/rfc-2294-if-let-guard/bindings.rs b/src/test/ui/rfc-2294-if-let-guard/bindings.rs new file mode 100644 index 00000000000..4e2d70e3290 --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/bindings.rs @@ -0,0 +1,10 @@ +#![feature(if_let_guard)] +#![allow(incomplete_features)] + +fn main() { + match Some(None) { + Some(x) if let Some(y) = x => (x, y), + _ => y, //~ ERROR cannot find value `y` + } + y //~ ERROR cannot find value `y` +} diff --git a/src/test/ui/rfc-2294-if-let-guard/bindings.stderr b/src/test/ui/rfc-2294-if-let-guard/bindings.stderr new file mode 100644 index 00000000000..9c5d92a33ad --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/bindings.stderr @@ -0,0 +1,15 @@ +error[E0425]: cannot find value `y` in this scope + --> $DIR/bindings.rs:7:14 + | +LL | _ => y, + | ^ not found in this scope + +error[E0425]: cannot find value `y` in this scope + --> $DIR/bindings.rs:9:5 + | +LL | y + | ^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr index d43096336c5..1670078e0d3 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr @@ -1,5 +1,5 @@ error: no rules expected the token `let` - --> $DIR/feature-gate.rs:81:15 + --> $DIR/feature-gate.rs:80:15 | LL | macro_rules! use_expr { | --------------------- when calling this macro @@ -17,7 +17,7 @@ LL | () if let 0 = 1 => {} = help: add `#![feature(if_let_guard)]` to the crate attributes to enable error[E0658]: `if let` guard is not implemented - --> $DIR/feature-gate.rs:77:12 + --> $DIR/feature-gate.rs:76:12 | LL | () if let 0 = 1 => {} | ^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | () if let 0 = 1 => {} = help: add `#![feature(if_let_guard)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:11:16 + --> $DIR/feature-gate.rs:10:16 | LL | () if (let 0 = 1) => {} | ^^^^^^^^^ @@ -35,7 +35,7 @@ LL | () if (let 0 = 1) => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:15:18 + --> $DIR/feature-gate.rs:14:18 | LL | () if (((let 0 = 1))) => {} | ^^^^^^^^^ @@ -44,7 +44,7 @@ LL | () if (((let 0 = 1))) => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:19:23 + --> $DIR/feature-gate.rs:18:23 | LL | () if true && let 0 = 1 => {} | ^^^^^^^^^ @@ -53,7 +53,7 @@ LL | () if true && let 0 = 1 => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:23:15 + --> $DIR/feature-gate.rs:22:15 | LL | () if let 0 = 1 && true => {} | ^^^^^^^^^ @@ -62,7 +62,7 @@ LL | () if let 0 = 1 && true => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:27:16 + --> $DIR/feature-gate.rs:26:16 | LL | () if (let 0 = 1) && true => {} | ^^^^^^^^^ @@ -71,7 +71,7 @@ LL | () if (let 0 = 1) && true => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:31:24 + --> $DIR/feature-gate.rs:30:24 | LL | () if true && (let 0 = 1) => {} | ^^^^^^^^^ @@ -80,7 +80,7 @@ LL | () if true && (let 0 = 1) => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:35:16 + --> $DIR/feature-gate.rs:34:16 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:35:31 + --> $DIR/feature-gate.rs:34:31 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ @@ -98,7 +98,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:41:15 + --> $DIR/feature-gate.rs:40:15 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:41:28 + --> $DIR/feature-gate.rs:40:28 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -116,7 +116,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:41:42 + --> $DIR/feature-gate.rs:40:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -125,7 +125,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:41:55 + --> $DIR/feature-gate.rs:40:55 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -134,7 +134,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:41:68 + --> $DIR/feature-gate.rs:40:68 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -143,7 +143,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:53:15 + --> $DIR/feature-gate.rs:52:15 | LL | () if let Range { start: _, end: _ } = (true..true) && false => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -152,7 +152,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:69:16 + --> $DIR/feature-gate.rs:68:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^ @@ -161,7 +161,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0)); = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are experimental - --> $DIR/feature-gate.rs:72:16 + --> $DIR/feature-gate.rs:71:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ @@ -170,7 +170,7 @@ LL | use_expr!((let 0 = 1)); = help: add `#![feature(let_chains)]` to the crate attributes to enable error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:11:16 + --> $DIR/feature-gate.rs:10:16 | LL | () if (let 0 = 1) => {} | ^^^^^^^^^ @@ -179,7 +179,7 @@ LL | () if (let 0 = 1) => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:15:18 + --> $DIR/feature-gate.rs:14:18 | LL | () if (((let 0 = 1))) => {} | ^^^^^^^^^ @@ -188,7 +188,7 @@ LL | () if (((let 0 = 1))) => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:19:23 + --> $DIR/feature-gate.rs:18:23 | LL | () if true && let 0 = 1 => {} | ^^^^^^^^^ @@ -197,7 +197,7 @@ LL | () if true && let 0 = 1 => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:23:15 + --> $DIR/feature-gate.rs:22:15 | LL | () if let 0 = 1 && true => {} | ^^^^^^^^^ @@ -206,7 +206,7 @@ LL | () if let 0 = 1 && true => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:27:16 + --> $DIR/feature-gate.rs:26:16 | LL | () if (let 0 = 1) && true => {} | ^^^^^^^^^ @@ -215,7 +215,7 @@ LL | () if (let 0 = 1) && true => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:31:24 + --> $DIR/feature-gate.rs:30:24 | LL | () if true && (let 0 = 1) => {} | ^^^^^^^^^ @@ -224,7 +224,7 @@ LL | () if true && (let 0 = 1) => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:35:16 + --> $DIR/feature-gate.rs:34:16 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ @@ -233,7 +233,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:35:31 + --> $DIR/feature-gate.rs:34:31 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ @@ -242,7 +242,7 @@ LL | () if (let 0 = 1) && (let 0 = 1) => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:41:15 + --> $DIR/feature-gate.rs:40:15 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -251,7 +251,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:41:28 + --> $DIR/feature-gate.rs:40:28 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -260,7 +260,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:41:42 + --> $DIR/feature-gate.rs:40:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -269,7 +269,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:41:55 + --> $DIR/feature-gate.rs:40:55 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -278,7 +278,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:41:68 + --> $DIR/feature-gate.rs:40:68 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -287,7 +287,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:53:15 + --> $DIR/feature-gate.rs:52:15 | LL | () if let Range { start: _, end: _ } = (true..true) && false => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -296,7 +296,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:69:16 + --> $DIR/feature-gate.rs:68:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^ @@ -305,7 +305,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0)); = note: as well as when nested within `&&` and parenthesis in those conditions error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:72:16 + --> $DIR/feature-gate.rs:71:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ @@ -313,6 +313,6 @@ LL | use_expr!((let 0 = 1)); = note: only supported directly in conditions of `if`- and `while`-expressions = note: as well as when nested within `&&` and parenthesis in those conditions -error: aborting due to 36 previous errors +error: aborting due to 35 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2294-if-let-guard/run-pass.rs b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs new file mode 100644 index 00000000000..a3663003790 --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs @@ -0,0 +1,34 @@ +// run-pass + +#![feature(if_let_guard)] +#![allow(incomplete_features)] + +enum Foo { + Bar, + Baz, + Qux(u8), +} + +fn bar(x: bool) -> Foo { + if x { Foo::Baz } else { Foo::Bar } +} + +fn baz(x: u8) -> Foo { + if x % 2 == 0 { Foo::Bar } else { Foo::Baz } +} + +fn qux(x: u8) -> Foo { + Foo::Qux(x.rotate_left(1)) +} + +fn main() { + match Some((true, 3)) { + Some((x, _)) if let Foo::Bar = bar(x) => panic!(), + Some((_, x)) if let Foo::Baz = baz(x) => {}, + _ => panic!(), + } + match Some(42) { + Some(x) if let Foo::Qux(y) = qux(x) => assert_eq!(y, 84), + _ => panic!(), + } +} diff --git a/src/test/ui/rfc-2294-if-let-guard/typeck.rs b/src/test/ui/rfc-2294-if-let-guard/typeck.rs new file mode 100644 index 00000000000..a4fc7f8cf2b --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/typeck.rs @@ -0,0 +1,16 @@ +#![feature(if_let_guard)] +#![allow(incomplete_features)] + +fn ok() -> Result, ()> { + Ok(Some(true)) +} + +fn main() { + match ok() { + Ok(x) if let Err(_) = x => {}, + //~^ ERROR mismatched types + Ok(x) if let 0 = x => {}, + //~^ ERROR mismatched types + _ => {} + } +} diff --git a/src/test/ui/rfc-2294-if-let-guard/typeck.stderr b/src/test/ui/rfc-2294-if-let-guard/typeck.stderr new file mode 100644 index 00000000000..7ce93fe7348 --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/typeck.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/typeck.rs:10:22 + | +LL | Ok(x) if let Err(_) = x => {}, + | ^^^^^^ expected enum `Option`, found enum `std::result::Result` + | + = note: expected enum `Option` + found enum `std::result::Result<_, _>` + +error[E0308]: mismatched types + --> $DIR/typeck.rs:12:22 + | +LL | Ok(x) if let 0 = x => {}, + | ^ expected enum `Option`, found integer + | + = note: expected enum `Option` + found type `{integer}` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.rs b/src/test/ui/rfc-2294-if-let-guard/warns.rs new file mode 100644 index 00000000000..9691a12f45b --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/warns.rs @@ -0,0 +1,22 @@ +#![feature(if_let_guard)] +#![allow(incomplete_features)] + +#[deny(irrefutable_let_patterns)] +fn irrefutable_let_guard() { + match Some(()) { + Some(x) if let () = x => {} + //~^ ERROR irrefutable if-let guard + _ => {} + } +} + +#[deny(unreachable_patterns)] +fn unreachable_pattern() { + match Some(()) { + x if let None | None = x => {} + //~^ ERROR unreachable pattern + _ => {} + } +} + +fn main() {} diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.stderr b/src/test/ui/rfc-2294-if-let-guard/warns.stderr new file mode 100644 index 00000000000..45720f9fbc5 --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/warns.stderr @@ -0,0 +1,26 @@ +error: irrefutable if-let guard + --> $DIR/warns.rs:7:24 + | +LL | Some(x) if let () = x => {} + | ^^ + | +note: the lint level is defined here + --> $DIR/warns.rs:4:8 + | +LL | #[deny(irrefutable_let_patterns)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/warns.rs:16:25 + | +LL | x if let None | None = x => {} + | ^^^^ + | +note: the lint level is defined here + --> $DIR/warns.rs:13:8 + | +LL | #[deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + -- cgit 1.4.1-3-g733a5 From 4255a5afd5d55532fda11f43ded5339ad27ea27e Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sun, 6 Dec 2020 19:01:03 +0100 Subject: Moved failing test to src/test/ui/ Still have not figured out how to make it work --- library/core/tests/mem.rs | 11 +-------- src/test/ui/assume-type-intrinsics.rs | 13 +++++++++++ src/test/ui/assume-type-intrinsics.stderr | 37 +++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/assume-type-intrinsics.rs create mode 100644 src/test/ui/assume-type-intrinsics.stderr (limited to 'src') diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index 4ebcf27e173..268c2ed283f 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -131,18 +131,9 @@ fn test_discriminant_send_sync() { } #[test] +#[cfg(not(bootstrap))] fn assume_init_good() { const TRUE: bool = unsafe { MaybeUninit::::new(true).assume_init() }; assert!(TRUE); } - -#[test] -fn assume_init_bad() { - const _BAD: () = unsafe { - MaybeUninit::::uninit().assume_init(); - //~^ ERROR the type `!` does not permit being left uninitialized - //~| ERROR this code causes undefined behavior when executed - //~| ERROR help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - }; -} diff --git a/src/test/ui/assume-type-intrinsics.rs b/src/test/ui/assume-type-intrinsics.rs new file mode 100644 index 00000000000..95562f3134f --- /dev/null +++ b/src/test/ui/assume-type-intrinsics.rs @@ -0,0 +1,13 @@ +#![feature(never_type)] +#![feature(const_maybe_uninit_assume_init)] + +fn main() { + use std::mem::MaybeUninit; + + const _BAD: () = unsafe { + MaybeUninit::::uninit().assume_init(); + //~^ ERROR: the type `!` does not permit being left uninitialized + //~| this code causes undefined behavior when executed + //~| WARN: the type `!` does not permit being left uninitialized + }; +} diff --git a/src/test/ui/assume-type-intrinsics.stderr b/src/test/ui/assume-type-intrinsics.stderr new file mode 100644 index 00000000000..be45d1ba384 --- /dev/null +++ b/src/test/ui/assume-type-intrinsics.stderr @@ -0,0 +1,37 @@ +error: any use of this value will cause an error + --> $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL + | +LL | intrinsics::assert_inhabited::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | attempted to instantiate uninhabited type `!` + | inside `MaybeUninit::::assume_init` at $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL + | inside `_BAD` at $DIR/assume-type-intrinsics.rs:8:9 + | + ::: $DIR/assume-type-intrinsics.rs:7:5 + | +LL | / const _BAD: () = unsafe { +LL | | MaybeUninit::::uninit().assume_init(); +LL | | +LL | | +LL | | +LL | | +LL | | }; + | |______- + | + = note: `#[deny(const_err)]` on by default + +warning: the type `!` does not permit being left uninitialized + --> $DIR/assume-type-intrinsics.rs:8:9 + | +LL | MaybeUninit::::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | + = note: `#[warn(invalid_value)]` on by default + = note: the `!` type has no valid value + +error: aborting due to previous error; 1 warning emitted + -- cgit 1.4.1-3-g733a5 From 3282b549acbb5922889329cddecd3dec700c54c2 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sun, 6 Dec 2020 19:29:35 +0100 Subject: Tests finally working --- src/test/ui/assume-type-intrinsics.rs | 4 +--- src/test/ui/assume-type-intrinsics.stderr | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/test/ui/assume-type-intrinsics.rs b/src/test/ui/assume-type-intrinsics.rs index 95562f3134f..8e9cb334527 100644 --- a/src/test/ui/assume-type-intrinsics.rs +++ b/src/test/ui/assume-type-intrinsics.rs @@ -6,8 +6,6 @@ fn main() { const _BAD: () = unsafe { MaybeUninit::::uninit().assume_init(); - //~^ ERROR: the type `!` does not permit being left uninitialized - //~| this code causes undefined behavior when executed - //~| WARN: the type `!` does not permit being left uninitialized + //~^ WARN: the type `!` does not permit being left uninitialized }; } diff --git a/src/test/ui/assume-type-intrinsics.stderr b/src/test/ui/assume-type-intrinsics.stderr index be45d1ba384..b776915affd 100644 --- a/src/test/ui/assume-type-intrinsics.stderr +++ b/src/test/ui/assume-type-intrinsics.stderr @@ -13,9 +13,6 @@ LL | intrinsics::assert_inhabited::(); LL | / const _BAD: () = unsafe { LL | | MaybeUninit::::uninit().assume_init(); LL | | -LL | | -LL | | -LL | | LL | | }; | |______- | -- cgit 1.4.1-3-g733a5 From 73a7d935dc55b4757706a966179459670e386582 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 7 Dec 2020 01:44:04 +0100 Subject: Add tests --- .../src/coherence/inherent_impls_overlap.rs | 3 +- .../auxiliary/repeat.rs | 54 ++++++++++++++++ .../ui/inherent-impls-overlap-check/no-overlap.rs | 34 +++++++++++ .../ui/inherent-impls-overlap-check/overlap.rs | 71 ++++++++++++++++++++++ .../ui/inherent-impls-overlap-check/overlap.stderr | 47 ++++++++++++++ 5 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs create mode 100644 src/test/ui/inherent-impls-overlap-check/no-overlap.rs create mode 100644 src/test/ui/inherent-impls-overlap-check/overlap.rs create mode 100644 src/test/ui/inherent-impls-overlap-check/overlap.stderr (limited to 'src') diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs index 4efb2a6273b..50d88674328 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs @@ -140,7 +140,8 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> { // Perform a O(n^2) algorithm for small n, // otherwise switch to an allocating algorithm with // faster asymptotic runtime. - if impls.len() < 30 { + const ALLOCATING_ALGO_THRESHOLD: usize = 500; + if impls.len() < ALLOCATING_ALGO_THRESHOLD { for (i, &(&impl1_def_id, impl_items1)) in impls_items.iter().enumerate() { for &(&impl2_def_id, impl_items2) in &impls_items[(i + 1)..] { if self.impls_have_common_items(impl_items1, impl_items2) { diff --git a/src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs b/src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs new file mode 100644 index 00000000000..42ed5d19deb --- /dev/null +++ b/src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs @@ -0,0 +1,54 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::{Ident, Group, TokenStream, TokenTree as Tt}; + +// This constant has to be above the ALLOCATING_ALGO_THRESHOLD +// constant in inherent_impls_overlap.rs +const REPEAT_COUNT: u32 = 501; + +#[proc_macro] +/// Repeats the input many times, while replacing idents +/// named "IDENT" with "id_$v", where v is a counter. +pub fn repeat_with_idents(input: TokenStream) -> TokenStream { + let mut res = Vec::new(); + fn visit_stream(res: &mut Vec, stream :TokenStream, v: u32) { + let mut stream_iter = stream.into_iter(); + while let Some(tt) = stream_iter.next() { + match tt { + Tt::Group(group) => { + let tt = Tt::Group(visit_group(group, v)); + res.push(tt); + }, + Tt::Ident(id) => { + let id = if &id.to_string() == "IDENT" { + Ident::new(&format!("id_{}", v), id.span()) + } else { + id + }; + res.push(Tt::Ident(id)); + }, + Tt::Punct(p) => { + res.push(Tt::Punct(p)); + }, + Tt::Literal(lit) => { + res.push(Tt::Literal(lit)); + }, + } + } + } + fn visit_group(group :Group, v: u32) -> Group { + let mut res = Vec::new(); + visit_stream(&mut res, group.stream(), v); + let stream = res.into_iter().collect(); + let delim = group.delimiter(); + Group::new(delim, stream) + } + for v in 0 .. REPEAT_COUNT { + visit_stream(&mut res, input.clone(), v) + } + res.into_iter().collect() +} diff --git a/src/test/ui/inherent-impls-overlap-check/no-overlap.rs b/src/test/ui/inherent-impls-overlap-check/no-overlap.rs new file mode 100644 index 00000000000..341bfc7b605 --- /dev/null +++ b/src/test/ui/inherent-impls-overlap-check/no-overlap.rs @@ -0,0 +1,34 @@ +// run-pass +// aux-build:repeat.rs + +// This tests the allocating algo branch of the +// inherent impls overlap checker. +// This branch was added by PR: +// https://github.com/rust-lang/rust/pull/78317 +// In this test, we repeat many impl blocks +// to trigger the allocating branch. + +#![allow(unused)] + +extern crate repeat; + +// Simple case where each impl block is distinct + +struct Foo {} + +repeat::repeat_with_idents!(impl Foo { fn IDENT() {} }); + +// There are overlapping impl blocks but due to generics, +// they may overlap. + +struct Bar(T); + +struct A; +struct B; + +repeat::repeat_with_idents!(impl Bar { fn IDENT() {} }); + +impl Bar { fn foo() {} } +impl Bar { fn foo() {} } + +fn main() {} diff --git a/src/test/ui/inherent-impls-overlap-check/overlap.rs b/src/test/ui/inherent-impls-overlap-check/overlap.rs new file mode 100644 index 00000000000..6f2801197e9 --- /dev/null +++ b/src/test/ui/inherent-impls-overlap-check/overlap.rs @@ -0,0 +1,71 @@ +// aux-build:repeat.rs + +#![allow(unused)] + +// This tests the allocating algo branch of the +// inherent impls overlap checker. +// This branch was added by PR: +// https://github.com/rust-lang/rust/pull/78317 +// In this test, we repeat many impl blocks +// to trigger the allocating branch. + +// Simple overlap + +extern crate repeat; + +struct Foo {} + +repeat::repeat_with_idents!(impl Foo { fn IDENT() {} }); + +impl Foo { fn hello() {} } //~ERROR duplicate definitions with name `hello` +impl Foo { fn hello() {} } + +// Transitive overlap + +struct Foo2 {} + +repeat::repeat_with_idents!(impl Foo2 { fn IDENT() {} }); + +impl Foo2 { + fn bar() {} + fn hello2() {} //~ERROR duplicate definitions with name `hello2` +} + +impl Foo2 { + fn baz() {} + fn hello2() {} +} + +// Slightly stronger transitive overlap + +struct Foo3 {} + +repeat::repeat_with_idents!(impl Foo3 { fn IDENT() {} }); + +impl Foo3 { + fn bar() {} //~ERROR duplicate definitions with name `bar` + fn hello3() {} //~ERROR duplicate definitions with name `hello3` +} + +impl Foo3 { + fn bar() {} + fn hello3() {} +} + +// Generic overlap + +struct Bar(T); + +struct A; +struct B; + +repeat::repeat_with_idents!(impl Bar { fn IDENT() {} }); + +impl Bar { fn foo() {} fn bar2() {} } +impl Bar { + fn foo() {} + fn bar2() {} //~ERROR duplicate definitions with name `bar2` +} +impl Bar { fn bar2() {} } + +fn main() {} diff --git a/src/test/ui/inherent-impls-overlap-check/overlap.stderr b/src/test/ui/inherent-impls-overlap-check/overlap.stderr new file mode 100644 index 00000000000..3dd2793712f --- /dev/null +++ b/src/test/ui/inherent-impls-overlap-check/overlap.stderr @@ -0,0 +1,47 @@ +error[E0592]: duplicate definitions with name `hello` + --> $DIR/overlap.rs:20:12 + | +LL | impl Foo { fn hello() {} } + | ^^^^^^^^^^ duplicate definitions for `hello` +LL | impl Foo { fn hello() {} } + | ---------- other definition for `hello` + +error[E0592]: duplicate definitions with name `hello2` + --> $DIR/overlap.rs:31:5 + | +LL | fn hello2() {} + | ^^^^^^^^^^^ duplicate definitions for `hello2` +... +LL | fn hello2() {} + | ----------- other definition for `hello2` + +error[E0592]: duplicate definitions with name `bar` + --> $DIR/overlap.rs:46:5 + | +LL | fn bar() {} + | ^^^^^^^^ duplicate definitions for `bar` +... +LL | fn bar() {} + | -------- other definition for `bar` + +error[E0592]: duplicate definitions with name `hello3` + --> $DIR/overlap.rs:47:5 + | +LL | fn hello3() {} + | ^^^^^^^^^^^ duplicate definitions for `hello3` +... +LL | fn hello3() {} + | ----------- other definition for `hello3` + +error[E0592]: duplicate definitions with name `bar2` + --> $DIR/overlap.rs:67:5 + | +LL | fn bar2() {} + | ^^^^^^^^^ duplicate definitions for `bar2` +LL | } +LL | impl Bar { fn bar2() {} } + | --------- other definition for `bar2` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0592`. -- cgit 1.4.1-3-g733a5 From 01aec8d18556be5e8d498c2f331b9015b7befde2 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 30 May 2020 15:02:32 -0400 Subject: [mir-opt] Allow debuginfo to be generated for a constant or a Place Prior to this commit, debuginfo was always generated by mapping a name to a Place. This has the side-effect that `SimplifyLocals` cannot remove locals that are only used for debuginfo because their other uses have been const-propagated. To allow these locals to be removed, we now allow debuginfo to point to a constant value. The `ConstProp` pass detects when debuginfo points to a local with a known constant value and replaces it with the value. This allows the later `SimplifyLocals` pass to remove the local. --- .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 5 +- compiler/rustc_codegen_ssa/src/mir/constant.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 105 +++++++++++++------ compiler/rustc_codegen_ssa/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 21 +++- compiler/rustc_middle/src/mir/visit.rs | 16 +-- compiler/rustc_mir/src/borrow_check/mod.rs | 26 ++--- .../rustc_mir/src/transform/const_debuginfo.rs | 98 ++++++++++++++++++ compiler/rustc_mir/src/transform/mod.rs | 2 + compiler/rustc_mir/src/transform/simplify_try.rs | 41 +++++--- compiler/rustc_mir/src/util/graphviz.rs | 2 +- compiler/rustc_mir/src/util/pretty.rs | 2 +- compiler/rustc_mir_build/src/build/matches/mod.rs | 4 +- compiler/rustc_mir_build/src/build/mod.rs | 6 +- src/test/incremental/hashes/let_expressions.rs | 4 +- .../const_debuginfo.main.ConstDebugInfo.diff | 115 +++++++++++++++++++++ src/test/mir-opt/const_debuginfo.rs | 24 +++++ ...to_variable.main.SimplifyLocals.after.32bit.mir | 18 +--- ...to_variable.main.SimplifyLocals.after.64bit.mir | 18 +--- ...7_inline_scopes_parenting.main.Inline.after.mir | 6 +- .../lower_intrinsics.f_u64.PreCodegen.before.mir | 2 +- ...ops.change_loop_body.PreCodegen.after.32bit.mir | 6 +- ...ops.change_loop_body.PreCodegen.after.64bit.mir | 6 +- 23 files changed, 406 insertions(+), 127 deletions(-) create mode 100644 compiler/rustc_mir/src/transform/const_debuginfo.rs create mode 100644 src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff create mode 100644 src/test/mir-opt/const_debuginfo.rs (limited to 'src') diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 96484034da7..31e43893ac8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1409,10 +1409,11 @@ fn generator_layout_and_saved_local_names( let state_arg = mir::Local::new(1); for var in &body.var_debug_info { - if var.place.local != state_arg { + let place = if let mir::VarDebugInfoContents::Place(p) = var.value { p } else { continue }; + if place.local != state_arg { continue; } - match var.place.projection[..] { + match place.projection[..] { [ // Deref of the `Pin<&mut Self>` state argument. mir::ProjectionElem::Field(..), diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index c8001b8daf0..3a85c268e0e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -11,7 +11,7 @@ use super::FunctionCx; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn eval_mir_constant_to_operand( - &mut self, + &self, bx: &mut Bx, constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { @@ -21,7 +21,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } pub fn eval_mir_constant( - &mut self, + &self, constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { match self.monomorphize(constant.literal).val { diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index c4191a4e23d..d5b2cbaa558 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; use rustc_target::abi::{LayoutOf, Size}; -use super::operand::OperandValue; +use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; use super::{FunctionCx, LocalRef}; @@ -116,6 +116,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { span } + fn spill_operand_to_stack( + operand: &OperandRef<'tcx, Bx::Value>, + name: Option, + bx: &mut Bx, + ) -> PlaceRef<'tcx, Bx::Value> { + // "Spill" the value onto the stack, for debuginfo, + // without forcing non-debuginfo uses of the local + // to also load from the stack every single time. + // FIXME(#68817) use `llvm.dbg.value` instead, + // at least for the cases which LLVM handles correctly. + let spill_slot = PlaceRef::alloca(bx, operand.layout); + if let Some(name) = name { + bx.set_var_name(spill_slot.llval, &(name + ".dbg.spill")); + } + operand.val.store(bx, spill_slot); + spill_slot + } + /// Apply debuginfo and/or name, after creating the `alloca` for a local, /// or initializing the local with an operand (whichever applies). pub fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) { @@ -226,17 +244,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - // "Spill" the value onto the stack, for debuginfo, - // without forcing non-debuginfo uses of the local - // to also load from the stack every single time. - // FIXME(#68817) use `llvm.dbg.value` instead, - // at least for the cases which LLVM handles correctly. - let spill_slot = PlaceRef::alloca(bx, operand.layout); - if let Some(name) = name { - bx.set_var_name(spill_slot.llval, &(name + ".dbg.spill")); - } - operand.val.store(bx, spill_slot); - spill_slot + Self::spill_operand_to_stack(operand, name, bx) } LocalRef::Place(place) => *place, @@ -308,6 +316,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`. pub fn compute_per_local_var_debug_info( &self, + bx: &mut Bx, ) -> Option>>> { let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full; @@ -322,31 +331,63 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { None }; + let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| { - let place = var.place; - let var_ty = self.monomorphized_place_ty(place.as_ref()); - let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg - && place.projection.is_empty() - && var.source_info.scope == mir::OUTERMOST_SOURCE_SCOPE - { - let arg_index = place.local.index() - 1; - - // FIXME(eddyb) shouldn't `ArgumentVariable` indices be - // offset in closures to account for the hidden environment? - // Also, is this `+ 1` needed at all? - VariableKind::ArgumentVariable(arg_index + 1) - } else { - VariableKind::LocalVariable + let (var_ty, var_kind) = match var.value { + mir::VarDebugInfoContents::Place(place) => { + let var_ty = self.monomorphized_place_ty(place.as_ref()); + let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg + && place.projection.is_empty() + && var.source_info.scope == mir::OUTERMOST_SOURCE_SCOPE + { + let arg_index = place.local.index() - 1; + + // FIXME(eddyb) shouldn't `ArgumentVariable` indices be + // offset in closures to account for the hidden environment? + // Also, is this `+ 1` needed at all? + VariableKind::ArgumentVariable(arg_index + 1) + } else { + VariableKind::LocalVariable + }; + (var_ty, var_kind) + } + mir::VarDebugInfoContents::Const(c) => { + let ty = self.monomorphize(c.literal.ty); + (ty, VariableKind::LocalVariable) + } }; + self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span) }); - per_local[var.place.local].push(PerLocalVarDebugInfo { - name: var.name, - source_info: var.source_info, - dbg_var, - projection: var.place.projection, - }); + match var.value { + mir::VarDebugInfoContents::Place(place) => { + per_local[place.local].push(PerLocalVarDebugInfo { + name: var.name, + source_info: var.source_info, + dbg_var, + projection: place.projection, + }); + } + mir::VarDebugInfoContents::Const(c) => { + if let Some(dbg_var) = dbg_var { + let dbg_loc = match self.dbg_loc(var.source_info) { + Some(dbg_loc) => dbg_loc, + None => continue, + }; + + if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) { + let base = Self::spill_operand_to_stack( + &operand, + Some(var.name.to_string()), + bx, + ); + + bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, Size::ZERO, &[]); + } + } + } + } } Some(per_local) } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 640f805d5e8..285140060be 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -186,7 +186,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( caller_location: None, }; - fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(); + fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut bx); for const_ in &mir.required_consts { if let Err(err) = fx.eval_mir_constant(const_) { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 814f91b0431..b54930e8d59 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1060,6 +1060,23 @@ impl<'tcx> LocalDecl<'tcx> { } } +#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)] +pub enum VarDebugInfoContents<'tcx> { + /// NOTE(eddyb) There's an unenforced invariant that this `Place` is + /// based on a `Local`, not a `Static`, and contains no indexing. + Place(Place<'tcx>), + Const(Constant<'tcx>), +} + +impl<'tcx> Debug for VarDebugInfoContents<'tcx> { + fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { + match self { + VarDebugInfoContents::Const(c) => write!(fmt, "{}", c), + VarDebugInfoContents::Place(p) => write!(fmt, "{:?}", p), + } + } +} + /// Debug information pertaining to a user variable. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)] pub struct VarDebugInfo<'tcx> { @@ -1071,9 +1088,7 @@ pub struct VarDebugInfo<'tcx> { pub source_info: SourceInfo, /// Where the data for this user variable is to be found. - /// NOTE(eddyb) There's an unenforced invariant that this `Place` is - /// based on a `Local`, not a `Static`, and contains no indexing. - pub place: Place<'tcx>, + pub value: VarDebugInfoContents<'tcx>, } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 7538818b8af..e281010eb06 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -829,16 +829,20 @@ macro_rules! make_mir_visitor { let VarDebugInfo { name: _, source_info, - place, + value, } = var_debug_info; self.visit_source_info(source_info); let location = START_BLOCK.start_location(); - self.visit_place( - place, - PlaceContext::NonUse(NonUseContext::VarDebugInfo), - location, - ); + match value { + VarDebugInfoContents::Const(c) => self.visit_constant(c, location), + VarDebugInfoContents::Place(place) => + self.visit_place( + place, + PlaceContext::NonUse(NonUseContext::VarDebugInfo), + location + ), + } } fn super_source_scope(&mut self, diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index de54c5582e0..3a6316b1ed3 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -11,7 +11,7 @@ use rustc_index::vec::IndexVec; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::mir::{ traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem, - PlaceRef, + PlaceRef, VarDebugInfoContents, }; use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -133,19 +133,21 @@ fn do_mir_borrowck<'a, 'tcx>( let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); for var_debug_info in &input_body.var_debug_info { - if let Some(local) = var_debug_info.place.as_local() { - if let Some(prev_name) = local_names[local] { - if var_debug_info.name != prev_name { - span_bug!( - var_debug_info.source_info.span, - "local {:?} has many names (`{}` vs `{}`)", - local, - prev_name, - var_debug_info.name - ); + if let VarDebugInfoContents::Place(place) = var_debug_info.value { + if let Some(local) = place.as_local() { + if let Some(prev_name) = local_names[local] { + if var_debug_info.name != prev_name { + span_bug!( + var_debug_info.source_info.span, + "local {:?} has many names (`{}` vs `{}`)", + local, + prev_name, + var_debug_info.name + ); + } } + local_names[local] = Some(var_debug_info.name); } - local_names[local] = Some(var_debug_info.name); } } diff --git a/compiler/rustc_mir/src/transform/const_debuginfo.rs b/compiler/rustc_mir/src/transform/const_debuginfo.rs new file mode 100644 index 00000000000..ed2c48b3568 --- /dev/null +++ b/compiler/rustc_mir/src/transform/const_debuginfo.rs @@ -0,0 +1,98 @@ +//! Finds locals which are assigned once to a const and unused except for debuginfo and converts +//! their debuginfo to use the const directly, allowing the local to be removed. + +use rustc_middle::{ + mir::{ + visit::{PlaceContext, Visitor}, + Body, Constant, Local, Location, Operand, Rvalue, StatementKind, VarDebugInfoContents, + }, + ty::TyCtxt, +}; + +use crate::transform::MirPass; +use rustc_index::{bit_set::BitSet, vec::IndexVec}; + +pub struct ConstDebugInfo; + +impl<'tcx> MirPass<'tcx> for ConstDebugInfo { + fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + trace!("running ConstDebugInfo on {:?}", body.source); + + for (local, constant) in find_optimization_oportunities(body) { + for debuginfo in &mut body.var_debug_info { + if let VarDebugInfoContents::Place(p) = debuginfo.value { + if p.local == local && p.projection.is_empty() { + trace!( + "changing debug info for {:?} from place {:?} to constant {:?}", + debuginfo.name, + p, + constant + ); + debuginfo.value = VarDebugInfoContents::Const(constant); + } + } + } + } + } +} + +struct LocalUseVisitor { + local_mutating_uses: IndexVec, + local_assignment_locations: IndexVec>, +} + +fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Constant<'tcx>)> { + let mut visitor = LocalUseVisitor { + local_mutating_uses: IndexVec::from_elem(0, &body.local_decls), + local_assignment_locations: IndexVec::from_elem(None, &body.local_decls), + }; + + visitor.visit_body(body); + + let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len()); + for debuginfo in &body.var_debug_info { + if let VarDebugInfoContents::Place(p) = debuginfo.value { + if let Some(l) = p.as_local() { + locals_to_debuginfo.insert(l); + } + } + } + + let mut eligable_locals = Vec::new(); + for (local, mutating_uses) in visitor.local_mutating_uses.drain_enumerated(..) { + if mutating_uses != 1 || !locals_to_debuginfo.contains(local) { + continue; + } + + if let Some(location) = visitor.local_assignment_locations[local] { + let bb = &body[location.block]; + + // The value is assigned as the result of a call, not a constant + if bb.statements.len() == location.statement_index { + continue; + } + + if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(box c)))) = + &bb.statements[location.statement_index].kind + { + if let Some(local) = p.as_local() { + eligable_locals.push((local, *c)); + } + } + } + } + + eligable_locals +} + +impl<'tcx> Visitor<'tcx> for LocalUseVisitor { + fn visit_local(&mut self, local: &Local, context: PlaceContext, location: Location) { + if context.is_mutating_use() { + self.local_mutating_uses[*local] = self.local_mutating_uses[*local].saturating_add(1); + + if context.is_place_assignment() { + self.local_assignment_locations[*local] = Some(location); + } + } + } +} diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index e86d11e248f..809e29fb982 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -21,6 +21,7 @@ pub mod check_consts; pub mod check_packed_ref; pub mod check_unsafety; pub mod cleanup_post_borrowck; +pub mod const_debuginfo; pub mod const_prop; pub mod coverage; pub mod deaggregator; @@ -408,6 +409,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &remove_noop_landing_pads::RemoveNoopLandingPads, &simplify::SimplifyCfg::new("final"), &nrvo::RenameReturnPlace, + &const_debuginfo::ConstDebugInfo, &simplify::SimplifyLocals, &multiple_return_terminators::MultipleReturnTerminators, ]; diff --git a/compiler/rustc_mir/src/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs index 27bb1def726..bea95bf43d2 100644 --- a/compiler/rustc_mir/src/transform/simplify_try.rs +++ b/compiler/rustc_mir/src/transform/simplify_try.rs @@ -246,14 +246,19 @@ fn get_arm_identity_info<'a, 'tcx>( tmp_assigned_vars.insert(*r); } - let dbg_info_to_adjust: Vec<_> = - debug_info - .iter() - .enumerate() - .filter_map(|(i, var_info)| { - if tmp_assigned_vars.contains(var_info.place.local) { Some(i) } else { None } - }) - .collect(); + let dbg_info_to_adjust: Vec<_> = debug_info + .iter() + .enumerate() + .filter_map(|(i, var_info)| { + if let VarDebugInfoContents::Place(p) = var_info.value { + if tmp_assigned_vars.contains(p.local) { + return Some(i); + } + } + + None + }) + .collect(); Some(ArmIdentityInfo { local_temp_0: local_tmp_s0, @@ -340,9 +345,11 @@ fn optimization_applies<'tcx>( // Check that debug info only points to full Locals and not projections. for dbg_idx in &opt_info.dbg_info_to_adjust { let dbg_info = &var_debug_info[*dbg_idx]; - if !dbg_info.place.projection.is_empty() { - trace!("NO: debug info for {:?} had a projection {:?}", dbg_info.name, dbg_info.place); - return false; + if let VarDebugInfoContents::Place(p) = dbg_info.value { + if !p.projection.is_empty() { + trace!("NO: debug info for {:?} had a projection {:?}", dbg_info.name, p); + return false; + } } } @@ -423,9 +430,15 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity { // Fix the debug info to point to the right local for dbg_index in opt_info.dbg_info_to_adjust { let dbg_info = &mut debug_info[dbg_index]; - assert!(dbg_info.place.projection.is_empty()); - dbg_info.place.local = opt_info.local_0; - dbg_info.place.projection = opt_info.dbg_projection; + assert!( + matches!(dbg_info.value, VarDebugInfoContents::Place(_)), + "value was not a Place" + ); + if let VarDebugInfoContents::Place(p) = &mut dbg_info.value { + assert!(p.projection.is_empty()); + p.local = opt_info.local_0; + p.projection = opt_info.dbg_projection; + } } trace!("block is now {:?}", bb.statements); diff --git a/compiler/rustc_mir/src/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs index 625f1a3e684..370010d65f0 100644 --- a/compiler/rustc_mir/src/util/graphviz.rs +++ b/compiler/rustc_mir/src/util/graphviz.rs @@ -220,7 +220,7 @@ fn write_graph_label<'tcx, W: Write>( w, r#"debug {} => {};
"#, var_debug_info.name, - escape(&var_debug_info.place) + escape(&var_debug_info.value), )?; } diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index cd60602b088..b6a1b652cf6 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -495,7 +495,7 @@ fn write_scope_tree( let indented_debug_info = format!( "{0:1$}debug {2} => {3:?};", - INDENT, indent, var_debug_info.name, var_debug_info.place, + INDENT, indent, var_debug_info.name, var_debug_info.value, ); writeln!( diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3ee15248ae2..5e7f9ce8760 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1992,7 +1992,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info.push(VarDebugInfo { name, source_info: debug_source_info, - place: for_arm_body.into(), + value: VarDebugInfoContents::Place(for_arm_body.into()), }); let locals = if has_guard.0 { let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> { @@ -2011,7 +2011,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info.push(VarDebugInfo { name, source_info: debug_source_info, - place: ref_for_guard.into(), + value: VarDebugInfoContents::Place(ref_for_guard.into()), }); LocalsForNode::ForGuard { ref_for_guard, for_arm_body } } else { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index c50389a850e..fc872da56bc 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -796,7 +796,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info.push(VarDebugInfo { name: ident.name, source_info, - place: arg_local.into(), + value: VarDebugInfoContents::Place(arg_local.into()), }); } } @@ -860,10 +860,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info.push(VarDebugInfo { name, source_info: SourceInfo::outermost(tcx_hir.span(var_id)), - place: Place { + value: VarDebugInfoContents::Place(Place { local: closure_env_arg, projection: tcx.intern_place_elems(&projs), - }, + }), }); mutability diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs index 918e72582d6..2c37b2e78ff 100644 --- a/src/test/incremental/hashes/let_expressions.rs +++ b/src/test/incremental/hashes/let_expressions.rs @@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="hir_owner_nodes,typeck,optimized_mir")] + except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_slot() { let _x: u64 = 0; @@ -166,7 +166,7 @@ pub fn change_mutability_of_binding_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="hir_owner_nodes,typeck,optimized_mir")] + except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_binding_in_pattern() { let (mut _a, _b) = (99u8, 'q'); diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff new file mode 100644 index 00000000000..47c3239b8bf --- /dev/null +++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -0,0 +1,115 @@ +- // MIR for `main` before ConstDebugInfo ++ // MIR for `main` after ConstDebugInfo + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/const_debuginfo.rs:8:11: 8:11 + let _1: u8; // in scope 0 at $DIR/const_debuginfo.rs:9:9: 9:10 + let mut _5: u8; // in scope 0 at $DIR/const_debuginfo.rs:12:15: 12:20 + let mut _6: u8; // in scope 0 at $DIR/const_debuginfo.rs:12:15: 12:16 + let mut _7: u8; // in scope 0 at $DIR/const_debuginfo.rs:12:19: 12:20 + let mut _8: u8; // in scope 0 at $DIR/const_debuginfo.rs:12:23: 12:24 + let mut _14: u32; // in scope 0 at $DIR/const_debuginfo.rs:21:13: 21:16 + let mut _15: u32; // in scope 0 at $DIR/const_debuginfo.rs:21:19: 21:22 + scope 1 { +- debug x => _1; // in scope 1 at $DIR/const_debuginfo.rs:9:9: 9:10 ++ debug x => const 1_u8; // in scope 1 at $DIR/const_debuginfo.rs:9:9: 9:10 + let _2: u8; // in scope 1 at $DIR/const_debuginfo.rs:10:9: 10:10 + scope 2 { +- debug y => _2; // in scope 2 at $DIR/const_debuginfo.rs:10:9: 10:10 ++ debug y => const 2_u8; // in scope 2 at $DIR/const_debuginfo.rs:10:9: 10:10 + let _3: u8; // in scope 2 at $DIR/const_debuginfo.rs:11:9: 11:10 + scope 3 { +- debug z => _3; // in scope 3 at $DIR/const_debuginfo.rs:11:9: 11:10 ++ debug z => const 3_u8; // in scope 3 at $DIR/const_debuginfo.rs:11:9: 11:10 + let _4: u8; // in scope 3 at $DIR/const_debuginfo.rs:12:9: 12:12 + scope 4 { +- debug sum => _4; // in scope 4 at $DIR/const_debuginfo.rs:12:9: 12:12 ++ debug sum => const 6_u8; // in scope 4 at $DIR/const_debuginfo.rs:12:9: 12:12 + let _9: &str; // in scope 4 at $DIR/const_debuginfo.rs:14:9: 14:10 + scope 5 { +- debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:14:9: 14:10 ++ debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:14:9: 14:10 + let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:16:9: 16:10 + scope 6 { + debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:16:9: 16:10 + let _11: std::option::Option; // in scope 6 at $DIR/const_debuginfo.rs:18:9: 18:10 + scope 7 { + debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:18:9: 18:10 + let _12: Point; // in scope 7 at $DIR/const_debuginfo.rs:20:9: 20:10 + scope 8 { + debug p => _12; // in scope 8 at $DIR/const_debuginfo.rs:20:9: 20:10 + let _13: u32; // in scope 8 at $DIR/const_debuginfo.rs:21:9: 21:10 + scope 9 { +- debug a => _13; // in scope 9 at $DIR/const_debuginfo.rs:21:9: 21:10 ++ debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:21:9: 21:10 + } + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/const_debuginfo.rs:9:9: 9:10 + _1 = const 1_u8; // scope 0 at $DIR/const_debuginfo.rs:9:13: 9:16 + StorageLive(_2); // scope 1 at $DIR/const_debuginfo.rs:10:9: 10:10 + _2 = const 2_u8; // scope 1 at $DIR/const_debuginfo.rs:10:13: 10:16 + StorageLive(_3); // scope 2 at $DIR/const_debuginfo.rs:11:9: 11:10 + _3 = const 3_u8; // scope 2 at $DIR/const_debuginfo.rs:11:13: 11:16 + StorageLive(_4); // scope 3 at $DIR/const_debuginfo.rs:12:9: 12:12 + StorageLive(_5); // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:20 + StorageLive(_6); // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:16 + _6 = const 1_u8; // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:16 + StorageLive(_7); // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20 + _7 = const 2_u8; // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20 + _5 = const 3_u8; // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:20 + StorageDead(_7); // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20 + StorageDead(_6); // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20 + StorageLive(_8); // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24 + _8 = const 3_u8; // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24 + _4 = const 6_u8; // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:24 + StorageDead(_8); // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24 + StorageDead(_5); // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24 + StorageLive(_9); // scope 4 at $DIR/const_debuginfo.rs:14:9: 14:10 + _9 = const "hello, world!"; // scope 4 at $DIR/const_debuginfo.rs:14:13: 14:28 + // ty::Const + // + ty: &str + // + val: Value(Slice { data: Allocation { bytes: [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [8191], len: Size { raw: 13 } }, size: Size { raw: 13 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 13 }) + // mir::Constant + // + span: $DIR/const_debuginfo.rs:14:13: 14:28 + // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [8191], len: Size { raw: 13 } }, size: Size { raw: 13 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 13 }) } + StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:16:9: 16:10 + (_10.0: bool) = const true; // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34 + (_10.1: bool) = const false; // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34 + (_10.2: u32) = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34 + StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:18:9: 18:10 + ((_11 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:18:13: 18:24 + discriminant(_11) = 1; // scope 6 at $DIR/const_debuginfo.rs:18:13: 18:24 + StorageLive(_12); // scope 7 at $DIR/const_debuginfo.rs:20:9: 20:10 + (_12.0: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:20:13: 20:35 + (_12.1: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:20:13: 20:35 + StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:21:9: 21:10 + StorageLive(_14); // scope 8 at $DIR/const_debuginfo.rs:21:13: 21:16 + _14 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:21:13: 21:16 + StorageLive(_15); // scope 8 at $DIR/const_debuginfo.rs:21:19: 21:22 + _15 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:21:19: 21:22 + _13 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:21:13: 21:22 + StorageDead(_15); // scope 8 at $DIR/const_debuginfo.rs:21:21: 21:22 + StorageDead(_14); // scope 8 at $DIR/const_debuginfo.rs:21:21: 21:22 + _0 = const (); // scope 0 at $DIR/const_debuginfo.rs:8:11: 22:2 + StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_12); // scope 7 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_10); // scope 5 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_9); // scope 4 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_4); // scope 3 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_3); // scope 2 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_2); // scope 1 at $DIR/const_debuginfo.rs:22:1: 22:2 + StorageDead(_1); // scope 0 at $DIR/const_debuginfo.rs:22:1: 22:2 + return; // scope 0 at $DIR/const_debuginfo.rs:22:2: 22:2 + } + } + diff --git a/src/test/mir-opt/const_debuginfo.rs b/src/test/mir-opt/const_debuginfo.rs new file mode 100644 index 00000000000..a66d66c60c7 --- /dev/null +++ b/src/test/mir-opt/const_debuginfo.rs @@ -0,0 +1,24 @@ +// compile-flags: -C overflow-checks=no + +struct Point { + x: u32, + y: u32, +} + +fn main() { + let x = 1u8; + let y = 2u8; + let z = 3u8; + let sum = x + y + z; + + let s = "hello, world!"; + + let f = (true, false, 123u32); + + let o = Some(99u16); + + let p = Point { x: 32, y: 32 }; + let a = p.x + p.y; +} + +// EMIT_MIR const_debuginfo.main.ConstDebugInfo.diff diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir index a78a6341c29..e4fbba3abfe 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir @@ -2,30 +2,18 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:11:11: 11:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 - _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - _2 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 - _3 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 _0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 } } diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir index a78a6341c29..e4fbba3abfe 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir @@ -2,30 +2,18 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:11:11: 11:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 - _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - _2 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 - _3 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 _0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 } } diff --git a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir index 3d386e3b175..4abbad2c1ef 100644 --- a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir @@ -11,9 +11,8 @@ fn main() -> () { debug f => _1; // in scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:5:9: 5:10 scope 2 (inlined main::{closure#0}) { // at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 debug x => _5; // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 - let _6: (); // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 scope 3 { - debug y => _6; // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 + debug y => const (); // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 } } } @@ -27,10 +26,7 @@ fn main() -> () { (_3.0: ()) = move _4; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 StorageLive(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 _5 = move (_3.0: ()); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 - StorageLive(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 - _6 = const (); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 _0 = const (); // scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 - StorageDead(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 StorageDead(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 StorageDead(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:9: 6:10 StorageDead(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:9: 6:10 diff --git a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir index 654dd8275c9..bd4f148285b 100644 --- a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir +++ b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir @@ -3,7 +3,7 @@ fn f_u64() -> () { let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:34:16: 34:16 scope 1 (inlined f_dispatch::) { // at $DIR/lower_intrinsics.rs:35:5: 35:21 - debug t => _2; // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 + debug t => const 0_u64; // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 let _1: (); // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 let mut _2: u64; // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 scope 2 (inlined std::mem::size_of::) { // at $DIR/lower_intrinsics.rs:35:5: 35:21 diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir index dae0cbb65a4..cb3632e0fb1 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir +++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir @@ -2,16 +2,12 @@ fn change_loop_body() -> () { let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:5:27: 5:27 - let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 scope 1 { - debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 + debug _x => const 0_i32; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 } bb0: { - StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 - _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19 _0 = const (); // scope 1 at $DIR/while_let_loops.rs:7:5: 10:6 - StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:11:1: 11:2 return; // scope 0 at $DIR/while_let_loops.rs:11:2: 11:2 } } diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir index dae0cbb65a4..cb3632e0fb1 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir +++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir @@ -2,16 +2,12 @@ fn change_loop_body() -> () { let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:5:27: 5:27 - let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 scope 1 { - debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 + debug _x => const 0_i32; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 } bb0: { - StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 - _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19 _0 = const (); // scope 1 at $DIR/while_let_loops.rs:7:5: 10:6 - StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:11:1: 11:2 return; // scope 0 at $DIR/while_let_loops.rs:11:2: 11:2 } } -- cgit 1.4.1-3-g733a5 From 97c7022d08fac94c09f671322c0696d65a75cca0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 7 Dec 2020 17:33:43 +0200 Subject: rustc_codegen_ssa: use bitcasts instead of type punning for scalar transmutes. --- compiler/rustc_codegen_ssa/src/mir/block.rs | 19 ++++++++++++++++ src/test/codegen/transmute-scalar.rs | 35 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/test/codegen/transmute-scalar.rs (limited to 'src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e59832a8eed..ce56f163549 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1395,6 +1395,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { dst: PlaceRef<'tcx, Bx::Value>, ) { let src = self.codegen_operand(bx, src); + + // Special-case transmutes between scalars as simple bitcasts. + match (&src.layout.abi, &dst.layout.abi) { + (abi::Abi::Scalar(src_scalar), abi::Abi::Scalar(dst_scalar)) => { + // HACK(eddyb) LLVM doesn't like `bitcast`s between pointers and non-pointers. + if (src_scalar.value == abi::Pointer) == (dst_scalar.value == abi::Pointer) { + assert_eq!(src.layout.size, dst.layout.size); + + // NOTE(eddyb) the `from_immediate` and `to_immediate_scalar` + // conversions allow handling `bool`s the same as `u8`s. + let src = bx.from_immediate(src.immediate()); + let src_as_dst = bx.bitcast(src, bx.backend_type(dst.layout)); + Immediate(bx.to_immediate_scalar(src_as_dst, dst_scalar)).store(bx, dst); + return; + } + } + _ => {} + } + let llty = bx.backend_type(src.layout); let cast_ptr = bx.pointercast(dst.llval, bx.type_ptr_to(llty)); let align = src.layout.align.abi.min(dst.align); diff --git a/src/test/codegen/transmute-scalar.rs b/src/test/codegen/transmute-scalar.rs new file mode 100644 index 00000000000..48aea4a2f08 --- /dev/null +++ b/src/test/codegen/transmute-scalar.rs @@ -0,0 +1,35 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +// CHECK: define i32 @f32_to_bits(float %x) +// CHECK: %2 = bitcast float %x to i32 +// CHECK-NEXT: store i32 %2, i32* %0 +// CHECK-NEXT: %3 = load i32, i32* %0 +// CHECK: ret i32 %3 +#[no_mangle] +pub fn f32_to_bits(x: f32) -> u32 { + unsafe { std::mem::transmute(x) } +} + +// CHECK: define i8 @bool_to_byte(i1 zeroext %b) +// CHECK: %1 = zext i1 %b to i8 +// CHECK-NEXT: store i8 %1, i8* %0 +// CHECK-NEXT: %2 = load i8, i8* %0 +// CHECK: ret i8 %2 +#[no_mangle] +pub fn bool_to_byte(b: bool) -> u8 { + unsafe { std::mem::transmute(b) } +} + +// CHECK: define zeroext i1 @byte_to_bool(i8 %byte) +// CHECK: %1 = trunc i8 %byte to i1 +// CHECK-NEXT: %2 = zext i1 %1 to i8 +// CHECK-NEXT: store i8 %2, i8* %0 +// CHECK-NEXT: %3 = load i8, i8* %0 +// CHECK-NEXT: %4 = trunc i8 %3 to i1 +// CHECK: ret i1 %4 +#[no_mangle] +pub unsafe fn byte_to_bool(byte: u8) -> bool { + std::mem::transmute(byte) +} -- cgit 1.4.1-3-g733a5 From d6baf3875cb9a3bbf3ebd2f7b33ab7f204b5908e Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Mon, 7 Dec 2020 12:54:55 -0700 Subject: Dogfood 'str_split_once() with Tidy --- src/tools/tidy/src/cargo.rs | 9 ++-- src/tools/tidy/src/error_codes_check.rs | 95 ++++++++++++++++++--------------- src/tools/tidy/src/extdeps.rs | 2 +- src/tools/tidy/src/features.rs | 1 + src/tools/tidy/src/lib.rs | 2 + src/tools/tidy/src/ui_tests.rs | 10 +--- 6 files changed, 63 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/tools/tidy/src/cargo.rs b/src/tools/tidy/src/cargo.rs index 7bdd78a91e7..e06616a59f3 100644 --- a/src/tools/tidy/src/cargo.rs +++ b/src/tools/tidy/src/cargo.rs @@ -59,11 +59,10 @@ fn verify(tomlfile: &Path, libfile: &Path, bad: &mut bool) { break; } - let mut parts = line.splitn(2, '='); - let krate = parts.next().unwrap().trim(); - if parts.next().is_none() { - continue; - } + let krate = match line.split_once('=') { + None => continue, + Some((krate, _)) => krate.trim(), + }; // Don't worry about depending on core/std while not writing `extern crate // core/std` -- that's intentional. diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index 82a5234ac5b..1c175901be8 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -85,47 +85,55 @@ fn extract_error_codes( for line in f.lines() { let s = line.trim(); if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") { - if let Some(err_code) = s.splitn(2, ':').next() { - let err_code = err_code.to_owned(); - if !error_codes.contains_key(&err_code) { - error_codes.insert(err_code.clone(), false); - } - // Now we extract the tests from the markdown file! - let md = some_or_continue!(s.splitn(2, "include_str!(\"").nth(1)); - let md_file_name = some_or_continue!(md.splitn(2, "\")").next()); - let path = some_or_continue!(path.parent()) - .join(md_file_name) - .canonicalize() - .expect("failed to canonicalize error explanation file path"); - match read_to_string(&path) { - Ok(content) => { - if !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) - && !check_if_error_code_is_test_in_explanation(&content, &err_code) - { - errors.push(format!( - "`{}` doesn't use its own error code in compile_fail example", - path.display(), - )); - } - if check_error_code_explanation(&content, error_codes, err_code) { - errors.push(format!( - "`{}` uses invalid tag `compile-fail` instead of `compile_fail`", - path.display(), - )); - } + let err_code = match s.split_once(':') { + None => continue, + Some((err_code, _)) => err_code.to_owned(), + }; + if !error_codes.contains_key(&err_code) { + error_codes.insert(err_code.clone(), false); + } + // Now we extract the tests from the markdown file! + let md_file_name = match s.split_once("include_str!(\"") { + None => continue, + Some((_, md)) => match md.split_once("\")") { + None => continue, + Some((file_name, _)) => file_name, + }, + }; + let path = some_or_continue!(path.parent()) + .join(md_file_name) + .canonicalize() + .expect("failed to canonicalize error explanation file path"); + match read_to_string(&path) { + Ok(content) => { + if !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) + && !check_if_error_code_is_test_in_explanation(&content, &err_code) + { + errors.push(format!( + "`{}` doesn't use its own error code in compile_fail example", + path.display(), + )); } - Err(e) => { - eprintln!("Couldn't read `{}`: {}", path.display(), e); + if check_error_code_explanation(&content, error_codes, err_code) { + errors.push(format!( + "`{}` uses invalid tag `compile-fail` instead of `compile_fail`", + path.display(), + )); } } + Err(e) => { + eprintln!("Couldn't read `{}`: {}", path.display(), e); + } } } else if reached_no_explanation && s.starts_with('E') { - if let Some(err_code) = s.splitn(2, ',').next() { - let err_code = err_code.to_owned(); - if !error_codes.contains_key(&err_code) { - // this check should *never* fail! - error_codes.insert(err_code, false); - } + let err_code = match s.split_once(',') { + None => s, + Some((err_code, _)) => err_code, + } + .to_string(); + if !error_codes.contains_key(&err_code) { + // this check should *never* fail! + error_codes.insert(err_code, false); } } else if s == ";" { reached_no_explanation = true; @@ -137,12 +145,15 @@ fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap continue, + Some((err_code, _)) => match err_code.split_once('[') { + None => continue, + Some((_, err_code)) => err_code, + }, + }; + let nb = error_codes.entry(err_code.to_owned()).or_insert(false); + *nb = true; } } } diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 1cf0d24e26f..93d4d3d8047 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -23,7 +23,7 @@ pub fn check(root: &Path, bad: &mut bool) { } // Extract source value. - let source = line.splitn(2, '=').nth(1).unwrap().trim(); + let source = line.split_once('=').unwrap().1.trim(); // Ensure source is allowed. if !ALLOWED_SOURCES.contains(&&*source) { diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index d8029ea04f0..3c2880d0d5e 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -112,6 +112,7 @@ pub fn check( let gate_test_str = "gate-test-"; let feature_name = match line.find(gate_test_str) { + // NB: the `splitn` always succeeds, even if the delimiter is not present. Some(i) => line[i + gate_test_str.len()..].splitn(2, ' ').next().unwrap(), None => continue, }; diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index cc4c43f0468..e11d293210b 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -3,6 +3,8 @@ //! This library contains the tidy lints and exposes it //! to be used by tools. +#![feature(str_split_once)] + use std::fs::File; use std::io::Read; use walkdir::{DirEntry, WalkDir}; diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 47b328dae47..4c8c1d58ed7 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -19,14 +19,8 @@ pub fn check(path: &Path, bad: &mut bool) { // // For now, just make sure that there is a corresponding // `$testname.rs` file. - let testname = file_path - .file_name() - .unwrap() - .to_str() - .unwrap() - .splitn(2, '.') - .next() - .unwrap(); + let testname = + file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0; if !file_path.with_file_name(testname).with_extension("rs").exists() { println!("Stray file with UI testing output: {:?}", file_path); *bad = true; -- cgit 1.4.1-3-g733a5 From 69ab0bcabff34b97cd8fe9f0c741748a9ffc8928 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Mon, 7 Dec 2020 21:26:09 +0100 Subject: Use 'error-pattern' in ui test --- src/test/ui/assume-type-intrinsics.rs | 4 +++- src/test/ui/assume-type-intrinsics.stderr | 19 +++---------------- 2 files changed, 6 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/test/ui/assume-type-intrinsics.rs b/src/test/ui/assume-type-intrinsics.rs index 8e9cb334527..77370e1ccc5 100644 --- a/src/test/ui/assume-type-intrinsics.rs +++ b/src/test/ui/assume-type-intrinsics.rs @@ -1,11 +1,13 @@ +// error-pattern: any use of this value will cause an error + #![feature(never_type)] #![feature(const_maybe_uninit_assume_init)] +#[allow(invalid_value)] fn main() { use std::mem::MaybeUninit; const _BAD: () = unsafe { MaybeUninit::::uninit().assume_init(); - //~^ WARN: the type `!` does not permit being left uninitialized }; } diff --git a/src/test/ui/assume-type-intrinsics.stderr b/src/test/ui/assume-type-intrinsics.stderr index b776915affd..6f400086a54 100644 --- a/src/test/ui/assume-type-intrinsics.stderr +++ b/src/test/ui/assume-type-intrinsics.stderr @@ -6,29 +6,16 @@ LL | intrinsics::assert_inhabited::(); | | | attempted to instantiate uninhabited type `!` | inside `MaybeUninit::::assume_init` at $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL - | inside `_BAD` at $DIR/assume-type-intrinsics.rs:8:9 + | inside `_BAD` at $DIR/assume-type-intrinsics.rs:11:9 | - ::: $DIR/assume-type-intrinsics.rs:7:5 + ::: $DIR/assume-type-intrinsics.rs:10:5 | LL | / const _BAD: () = unsafe { LL | | MaybeUninit::::uninit().assume_init(); -LL | | LL | | }; | |______- | = note: `#[deny(const_err)]` on by default -warning: the type `!` does not permit being left uninitialized - --> $DIR/assume-type-intrinsics.rs:8:9 - | -LL | MaybeUninit::::uninit().assume_init(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | - = note: `#[warn(invalid_value)]` on by default - = note: the `!` type has no valid value - -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 7bd47bd7a14a32be27382677a98d7a031785fc6e Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Mon, 7 Dec 2020 13:39:30 -0700 Subject: Dogfood 'str_split_once() with linkchecker --- src/tools/linkchecker/main.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index f213944e0ab..dcfe1bb803f 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -14,6 +14,8 @@ //! A few exceptions are allowed as there's known bugs in rustdoc, but this //! should catch the majority of "broken link" cases. +#![feature(str_split_once)] + use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::env; @@ -232,11 +234,12 @@ fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Opti { return; } - let mut parts = url.splitn(2, '#'); - let url = parts.next().unwrap(); - let fragment = parts.next(); - let mut parts = url.splitn(2, '?'); - let url = parts.next().unwrap(); + let (url, fragment) = match url.split_once('#') { + None => (url, None), + Some((url, fragment)) => (url, Some(fragment)), + }; + // NB: the `splitn` always succeeds, even if the delimiter is not present. + let url = url.splitn(2, '?').next().unwrap(); // Once we've plucked out the URL, parse it using our base url and // then try to extract a file path. -- cgit 1.4.1-3-g733a5 From 85e9ea015220cc74dc54873974ed7138ea22eced Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Mon, 7 Dec 2020 14:00:31 -0700 Subject: Dogfood 'str_split_once() with librustdoc --- src/librustdoc/config.rs | 15 +++++---------- src/librustdoc/html/render/mod.rs | 6 ++---- src/librustdoc/lib.rs | 1 + src/librustdoc/passes/collect_intra_doc_links.rs | 7 ++++--- 4 files changed, 12 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e60970af0d3..2d58614b139 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -397,12 +397,9 @@ impl Options { matches .opt_strs("default-setting") .iter() - .map(|s| { - let mut kv = s.splitn(2, '='); - // never panics because `splitn` always returns at least one element - let k = kv.next().unwrap().to_string(); - let v = kv.next().unwrap_or("true").to_string(); - (k, v) + .map(|s| match s.split_once('=') { + None => (s.clone(), "true".to_string()), + Some((k, v)) => (k.to_string(), v.to_string()), }) .collect(), ]; @@ -707,11 +704,9 @@ fn parse_extern_html_roots( ) -> Result, &'static str> { let mut externs = BTreeMap::new(); for arg in &matches.opt_strs("extern-html-root-url") { - let mut parts = arg.splitn(2, '='); - let name = parts.next().ok_or("--extern-html-root-url must not be empty")?; - let url = parts.next().ok_or("--extern-html-root-url must be of the form name=url")?; + let (name, url) = + arg.split_once('=').ok_or("--extern-html-root-url must be of the form name=url")?; externs.insert(name.to_string(), url.to_string()); } - Ok(externs) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 901f00b21da..efee4c0be06 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -167,10 +167,8 @@ impl Context { // `style-suffix.min.css`. Path::extension would just return `css` // which would result in `style.min-suffix.css` which isn't what we // want. - let mut iter = filename.splitn(2, '.'); - let base = iter.next().unwrap(); - let ext = iter.next().unwrap(); - let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext,); + let (base, ext) = filename.split_once('.').unwrap(); + let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext); self.dst.join(&filename) } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 26bf4b569ff..f851d1a2372 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -16,6 +16,7 @@ #![feature(once_cell)] #![feature(type_ascription)] #![feature(split_inclusive)] +#![feature(str_split_once)] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 551c086a8d4..fdbab74be50 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -435,8 +435,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Try looking for methods and associated items. let mut split = path_str.rsplitn(2, "::"); - // this can be an `unwrap()` because we ensure the link is never empty - let (item_str, item_name) = split.next().map(|i| (i, Symbol::intern(i))).unwrap(); + // NB: the `splitn`'s first element is always defined, even if the delimiter is not present. + let item_str = split.next().unwrap(); + let item_name = Symbol::intern(item_str); let path_root = split .next() .map(|f| f.to_owned()) @@ -447,7 +448,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ResolutionFailure::NotResolved { module_id, partial_res: None, - unresolved: item_str.into(), + unresolved: path_str.into(), } })?; -- cgit 1.4.1-3-g733a5 From f68cc68e798edfb1f5cc1913e97b34b10ee8791f Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Mon, 7 Dec 2020 15:07:24 -0700 Subject: Review feedback for collect_intra_doc_links.rs * Add assertion value is defined. * Simplify comment. * Fix bad change in err message. --- src/librustdoc/passes/collect_intra_doc_links.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index fdbab74be50..5ce64c4cd83 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -435,8 +435,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Try looking for methods and associated items. let mut split = path_str.rsplitn(2, "::"); - // NB: the `splitn`'s first element is always defined, even if the delimiter is not present. + // NB: `split`'s first element is always defined, even if the delimiter was not present. let item_str = split.next().unwrap(); + assert!(!item_str.is_empty()); let item_name = Symbol::intern(item_str); let path_root = split .next() @@ -448,7 +449,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ResolutionFailure::NotResolved { module_id, partial_res: None, - unresolved: path_str.into(), + unresolved: item_str.into(), } })?; -- cgit 1.4.1-3-g733a5 From 989edf4a5ffb0944e173ec23cb5614c252e8082e Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Tue, 8 Dec 2020 12:50:52 -0700 Subject: Review feedback * Use a match statement. * Clarify why we can't use `file_stem()`. * Error if the `:` is missing for Tidy error codes, rather than no-oping. --- compiler/rustc_mir/src/transform/coverage/debug.rs | 68 ++++++++++++---------- src/tools/tidy/src/error_codes_check.rs | 14 +++-- src/tools/tidy/src/ui_tests.rs | 3 + 3 files changed, 49 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index 1347656c23e..af81d9af0e2 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -152,38 +152,42 @@ impl DebugOptions { None => (setting_str, None), Some((k, v)) => (k, Some(v)), }; - if option == "allow_unused_expressions" { - allow_unused_expressions = bool_option_val(option, value); - debug!( - "{} env option `allow_unused_expressions` is set to {}", - RUSTC_COVERAGE_DEBUG_OPTIONS, allow_unused_expressions - ); - } else if option == "counter_format" { - match value { - None => { - bug!( - "`{}` option in environment variable {} requires one or more \ - plus-separated choices (a non-empty subset of \ - `id+block+operation`)", - option, - RUSTC_COVERAGE_DEBUG_OPTIONS - ); - } - Some(val) => { - counter_format = counter_format_option_val(val); - debug!( - "{} env option `counter_format` is set to {:?}", - RUSTC_COVERAGE_DEBUG_OPTIONS, counter_format - ); - } - }; - } else { - bug!( - "Unsupported setting `{}` in environment variable {}", - option, - RUSTC_COVERAGE_DEBUG_OPTIONS - ) - } + match option { + "allow_unused_expressions" => { + allow_unused_expressions = bool_option_val(option, value); + debug!( + "{} env option `allow_unused_expressions` is set to {}", + RUSTC_COVERAGE_DEBUG_OPTIONS, allow_unused_expressions + ); + } + "counter_format" => { + match value { + None => { + bug!( + "`{}` option in environment variable {} requires one or more \ + plus-separated choices (a non-empty subset of \ + `id+block+operation`)", + option, + RUSTC_COVERAGE_DEBUG_OPTIONS + ); + } + Some(val) => { + counter_format = counter_format_option_val(val); + debug!( + "{} env option `counter_format` is set to {:?}", + RUSTC_COVERAGE_DEBUG_OPTIONS, counter_format + ); + } + }; + } + _ => { + bug!( + "Unsupported setting `{}` in environment variable {}", + option, + RUSTC_COVERAGE_DEBUG_OPTIONS + ) + } + }; } } diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index 1c175901be8..a7199fdfce6 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -85,10 +85,16 @@ fn extract_error_codes( for line in f.lines() { let s = line.trim(); if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") { - let err_code = match s.split_once(':') { - None => continue, - Some((err_code, _)) => err_code.to_owned(), - }; + let err_code = s + .split_once(':') + .expect( + format!( + "Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} without a `:` delimiter", + s, + ).as_str() + ) + .0 + .to_owned(); if !error_codes.contains_key(&err_code) { error_codes.insert(err_code.clone(), false); } diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 4c8c1d58ed7..03f4efea983 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -19,6 +19,9 @@ pub fn check(path: &Path, bad: &mut bool) { // // For now, just make sure that there is a corresponding // `$testname.rs` file. + // + // NB: We do not use file_stem() as some file names have multiple `.`s and we + // must strip all of them. let testname = file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0; if !file_path.with_file_name(testname).with_extension("rs").exists() { -- cgit 1.4.1-3-g733a5 From 8909c4dc315bf1686449e762958558893c420923 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 8 Dec 2020 19:18:06 -0500 Subject: Fix rustup support in default_build_triple for python3 bootstrap completely ignores all errors when detecting a rustup version, so this wasn't noticed before. Fixes the following error: ``` rustup not detected: a bytes-like object is required, not 'str' falling back to auto-detect ``` This also takes the opportunity to only call rustup and other external commands only once during startup. --- src/bootstrap/bootstrap.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index a819e1b6e2f..f919f63e579 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -192,8 +192,10 @@ def default_build_triple(verbose): # If the user already has a host build triple with an existing `rustc` # install, use their preference. This fixes most issues with Windows builds # being detected as GNU instead of MSVC. + default_encoding = sys.getdefaultencoding() try: version = subprocess.check_output(["rustc", "--version", "--verbose"]) + version = version.decode(default_encoding) host = next(x for x in version.split('\n') if x.startswith("host: ")) triple = host.split("host: ")[1] if verbose: @@ -204,7 +206,6 @@ def default_build_triple(verbose): print("rustup not detected: {}".format(e)) print("falling back to auto-detect") - default_encoding = sys.getdefaultencoding() required = sys.platform != 'win32' ostype = require(["uname", "-s"], exit=required) cputype = require(['uname', '-m'], exit=required) @@ -794,7 +795,7 @@ class RustBuild(object): env.setdefault("RUSTFLAGS", "") env["RUSTFLAGS"] += " -Cdebuginfo=2" - build_section = "target.{}".format(self.build_triple()) + build_section = "target.{}".format(self.build) target_features = [] if self.get_toml("crt-static", build_section) == "true": target_features += ["+crt-static"] @@ -825,7 +826,11 @@ class RustBuild(object): run(args, env=env, verbose=self.verbose) def build_triple(self): - """Build triple as in LLVM""" + """Build triple as in LLVM + + Note that `default_build_triple` is moderately expensive, + so use `self.build` where possible. + """ config = self.get_toml('build') if config: return config -- cgit 1.4.1-3-g733a5 From 4e21942ba4d435c3211677ad42ddc528fff97857 Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 8 Dec 2020 21:56:22 -0800 Subject: Clarify the 'default is only allowed on...' error Code like impl Foo { default fn foo() {} } will trigger the error error: `default` is only allowed on items in `impl` definitions --> src/lib.rs:5:5 | 5 | default fn foo() {} | -------^^^^^^^^^ | | | `default` because of this but that's very confusing! I *did* put it on an item in an impl! So this commit changes the message to error: `default` is only allowed on items in trait impls --> src/lib.rs:5:5 | 5 | default fn foo() {} | -------^^^^^^^^^ | | | `default` because of this --- compiler/rustc_ast_passes/src/ast_validation.rs | 2 +- .../ui/parser/trait-item-with-defaultness-fail-semantic.rs | 12 ++++++------ .../parser/trait-item-with-defaultness-fail-semantic.stderr | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 4ec3e39facc..bf6d3322176 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -400,7 +400,7 @@ impl<'a> AstValidator<'a> { if let Defaultness::Default(def_span) = defaultness { let span = self.session.source_map().guess_head_span(span); self.err_handler() - .struct_span_err(span, "`default` is only allowed on items in `impl` definitions") + .struct_span_err(span, "`default` is only allowed on items in trait impls") .span_label(def_span, "`default` because of this") .emit(); } diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs index 34aee7f6935..f2d97b7bac3 100644 --- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs +++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs @@ -3,10 +3,10 @@ fn main() {} trait X { - default const A: u8; //~ ERROR `default` is only allowed on items in `impl` definitions - default const B: u8 = 0; //~ ERROR `default` is only allowed on items in `impl` definitions - default type D; //~ ERROR `default` is only allowed on items in `impl` definitions - default type C: Ord; //~ ERROR `default` is only allowed on items in `impl` definitions - default fn f1(); //~ ERROR `default` is only allowed on items in `impl` definitions - default fn f2() {} //~ ERROR `default` is only allowed on items in `impl` definitions + default const A: u8; //~ ERROR `default` is only allowed on items in trait impls + default const B: u8 = 0; //~ ERROR `default` is only allowed on items in trait impls + default type D; //~ ERROR `default` is only allowed on items in trait impls + default type C: Ord; //~ ERROR `default` is only allowed on items in trait impls + default fn f1(); //~ ERROR `default` is only allowed on items in trait impls + default fn f2() {} //~ ERROR `default` is only allowed on items in trait impls } diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr index cdc9ee8d9e7..76fa860334d 100644 --- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr +++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr @@ -1,4 +1,4 @@ -error: `default` is only allowed on items in `impl` definitions +error: `default` is only allowed on items in trait impls --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5 | LL | default const A: u8; @@ -6,7 +6,7 @@ LL | default const A: u8; | | | `default` because of this -error: `default` is only allowed on items in `impl` definitions +error: `default` is only allowed on items in trait impls --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5 | LL | default const B: u8 = 0; @@ -14,7 +14,7 @@ LL | default const B: u8 = 0; | | | `default` because of this -error: `default` is only allowed on items in `impl` definitions +error: `default` is only allowed on items in trait impls --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5 | LL | default type D; @@ -22,7 +22,7 @@ LL | default type D; | | | `default` because of this -error: `default` is only allowed on items in `impl` definitions +error: `default` is only allowed on items in trait impls --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5 | LL | default type C: Ord; @@ -30,7 +30,7 @@ LL | default type C: Ord; | | | `default` because of this -error: `default` is only allowed on items in `impl` definitions +error: `default` is only allowed on items in trait impls --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5 | LL | default fn f1(); @@ -38,7 +38,7 @@ LL | default fn f1(); | | | `default` because of this -error: `default` is only allowed on items in `impl` definitions +error: `default` is only allowed on items in trait impls --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5 | LL | default fn f2() {} -- cgit 1.4.1-3-g733a5 From 99df3406cf419cb5e45f5ee59c7b04cb294630c5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 7 Dec 2020 15:13:12 +0100 Subject: Hide associated constants too when collapsing implementation --- src/librustdoc/html/static/main.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 69984be5eb6..0c55a61bb7d 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2257,9 +2257,12 @@ function defocusSearchBar() { function implHider(addOrRemove, fullHide) { return function(n) { - var is_method = hasClass(n, "method") || fullHide; - if (is_method || hasClass(n, "type")) { - if (is_method === true) { + var shouldHide = + fullHide === true || + hasClass(n, "method") === true || + hasClass(n, "associatedconstant") === true; + if (shouldHide === true || hasClass(n, "type") === true) { + if (shouldHide === true) { if (addOrRemove) { addClass(n, "hidden-by-impl-hider"); } else { -- cgit 1.4.1-3-g733a5 From 5c1d2ced03fe8ce62deaf23abf62213d959ec4cb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 9 Dec 2020 21:54:24 +0200 Subject: tests: add 3 cases involving pointers to codegen/transmute-scalar. --- src/test/codegen/transmute-scalar.rs | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src') diff --git a/src/test/codegen/transmute-scalar.rs b/src/test/codegen/transmute-scalar.rs index 48aea4a2f08..f16335fdc74 100644 --- a/src/test/codegen/transmute-scalar.rs +++ b/src/test/codegen/transmute-scalar.rs @@ -2,6 +2,9 @@ #![crate_type = "lib"] +// FIXME(eddyb) all of these tests show memory stores and loads, even after a +// scalar `bitcast`, more special-casing is required to remove `alloca` usage. + // CHECK: define i32 @f32_to_bits(float %x) // CHECK: %2 = bitcast float %x to i32 // CHECK-NEXT: store i32 %2, i32* %0 @@ -33,3 +36,50 @@ pub fn bool_to_byte(b: bool) -> u8 { pub unsafe fn byte_to_bool(byte: u8) -> bool { std::mem::transmute(byte) } + +// CHECK: define i8* @ptr_to_ptr(i16* %p) +// CHECK: %2 = bitcast i16* %p to i8* +// CHECK-NEXT: store i8* %2, i8** %0 +// CHECK-NEXT: %3 = load i8*, i8** %0 +// CHECK: ret i8* %3 +#[no_mangle] +pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 { + unsafe { std::mem::transmute(p) } +} + +// HACK(eddyb) scalar `transmute`s between pointers and non-pointers are +// currently not special-cased like other scalar `transmute`s, because +// LLVM requires specifically `ptrtoint`/`inttoptr` instead of `bitcast`. +// +// Tests below show the non-special-cased behavior (with the possible +// future special-cased instructions in the "NOTE(eddyb)" comments). + +// CHECK: define [[USIZE:i[0-9]+]] @ptr_to_int(i16* %p) + +// NOTE(eddyb) see above, the following two CHECK lines should ideally be this: +// %2 = ptrtoint i16* %p to [[USIZE]] +// store [[USIZE]] %2, [[USIZE]]* %0 +// CHECK: %2 = bitcast [[USIZE]]* %0 to i16** +// CHECK-NEXT: store i16* %p, i16** %2 + +// CHECK-NEXT: %3 = load [[USIZE]], [[USIZE]]* %0 +// CHECK: ret [[USIZE]] %3 +#[no_mangle] +pub fn ptr_to_int(p: *mut u16) -> usize { + unsafe { std::mem::transmute(p) } +} + +// CHECK: define i16* @int_to_ptr([[USIZE]] %i) + +// NOTE(eddyb) see above, the following two CHECK lines should ideally be this: +// %2 = inttoptr [[USIZE]] %i to i16* +// store i16* %2, i16** %0 +// CHECK: %2 = bitcast i16** %0 to [[USIZE]]* +// CHECK-NEXT: store [[USIZE]] %i, [[USIZE]]* %2 + +// CHECK-NEXT: %3 = load i16*, i16** %0 +// CHECK: ret i16* %3 +#[no_mangle] +pub fn int_to_ptr(i: usize) -> *mut u16 { + unsafe { std::mem::transmute(i) } +} -- cgit 1.4.1-3-g733a5 From c6f2d49ff8be6b42bba94e7dc96e0fff8b5ca580 Mon Sep 17 00:00:00 2001 From: Chenguang Wang Date: Wed, 9 Dec 2020 18:56:27 -0800 Subject: fix issue #78496 --- .../src/transform/early_otherwise_branch.rs | 28 ++++++++++++++++++++++ src/test/ui/mir/issue-78496.rs | 16 +++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/test/ui/mir/issue-78496.rs (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index f91477911a4..5829c522935 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -283,6 +283,34 @@ impl<'a, 'tcx> Helper<'a, 'tcx> { return None; } + // when one place is the projection of the other, it's not safe to calculate their discriminant values sequentially. + // for example, this should not be optimized: + // + // ```rust + // enum E<'a> { Empty, Some(&'a E<'a>), } + // let Some(Some(_)) = e; + // ``` + // + // ```mir + // bb0: { + // _2 = discriminant(*_1) + // switchInt(move _2) -> [...] + // } + // bb1: { + // _3 = discriminant(*(((*_1) as Some).0: &E)) + // switchInt(move _3) -> [...] + // } + // ``` + let discr_place = discr_info.place_of_adt_discr_read; + let this_discr_place = this_bb_discr_info.place_of_adt_discr_read; + if discr_place.local == this_discr_place.local + && (discr_place.projection.starts_with(this_discr_place.projection) + || this_discr_place.projection.starts_with(discr_place.projection)) + { + trace!("NO: one target is the projection of another"); + return None; + } + // if we reach this point, the optimization applies, and we should be able to optimize this case // store the info that is needed to apply the optimization diff --git a/src/test/ui/mir/issue-78496.rs b/src/test/ui/mir/issue-78496.rs new file mode 100644 index 00000000000..cc45945a2b8 --- /dev/null +++ b/src/test/ui/mir/issue-78496.rs @@ -0,0 +1,16 @@ +// run-pass +// compile-flags: -Z mir-opt-level=2 -C opt-level=0 + +// example from #68867 +pub enum E<'a> { + Empty, + Some(&'a E<'a>), +} + +fn f(e: &E) -> u32 { + if let E::Some(E::Some(_)) = e { 1 } else { 2 } +} + +fn main() { + assert_eq!(f(&E::Empty), 2); +} -- cgit 1.4.1-3-g733a5 From 3812f70355132b53092e826c9d1a753dfd8a1874 Mon Sep 17 00:00:00 2001 From: Chenguang Wang Date: Wed, 9 Dec 2020 20:11:32 -0800 Subject: fix test case issue ref --- src/test/ui/mir/issue-78496.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/test/ui/mir/issue-78496.rs b/src/test/ui/mir/issue-78496.rs index cc45945a2b8..1b0687cfac3 100644 --- a/src/test/ui/mir/issue-78496.rs +++ b/src/test/ui/mir/issue-78496.rs @@ -1,7 +1,7 @@ // run-pass // compile-flags: -Z mir-opt-level=2 -C opt-level=0 -// example from #68867 +// example from #78496 pub enum E<'a> { Empty, Some(&'a E<'a>), -- cgit 1.4.1-3-g733a5 From 2363a20b9868ae41ac92cac4b06c167c3cb320aa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Dec 2020 11:38:12 +0100 Subject: Make search results tab and help button focusable with keyboard --- src/librustdoc/html/layout.rs | 2 +- src/librustdoc/html/static/main.js | 6 +++--- src/librustdoc/html/static/rustdoc.css | 11 ++++++----- src/librustdoc/html/static/themes/ayu.css | 10 +++++----- src/librustdoc/html/static/themes/dark.css | 7 ++++--- src/librustdoc/html/static/themes/light.css | 7 ++++--- 6 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index e8039942f4f..f2c74c46d7d 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -98,7 +98,7 @@ crate fn render( placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \ type=\"search\">\ \ - ? +
\ " + text + - "
(" + nbElems + ")
"; + return ""; } - return "
" + text + "
(" + nbElems + ")
"; + return ""; } function showResults(results) { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 8eef65a231d..61905b8eca8 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1176,21 +1176,22 @@ pre.rust { height: 35px; } -#titles > div { +#titles > button { float: left; width: 33.3%; text-align: center; font-size: 18px; cursor: pointer; + border: 0; border-top: 2px solid; } -#titles > div:not(:last-child) { +#titles > button:not(:last-child) { margin-right: 1px; width: calc(33.3% - 1px); } -#titles > div > div.count { +#titles > button > div.count { display: inline-block; font-size: 16px; } @@ -1459,7 +1460,7 @@ h4 > .notable-traits { top: 24px; } - #titles > div > div.count { + #titles > button > div.count { float: left; width: 100%; } @@ -1565,7 +1566,7 @@ h4 > .notable-traits { } @media (max-width: 416px) { - #titles, #titles > div { + #titles, #titles > button { height: 73px; } diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index c1f796f09e8..76bbe4f6201 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -403,22 +403,22 @@ pre.ignore:hover, .information:hover + pre.ignore { border-color: #5c6773; } -#titles > div.selected { +#titles > button.selected { background-color: #141920 !important; border-bottom: 1px solid #ffb44c !important; border-top: none; } -#titles > div:not(.selected) { +#titles > button:not(.selected) { background-color: transparent !important; border: none; } -#titles > div:hover { +#titles > button:hover { border-bottom: 1px solid rgba(242, 151, 24, 0.3); } -#titles > div > div.count { +#titles > button > div.count { color: #888; } @@ -434,7 +434,7 @@ above the `@media (max-width: 700px)` rules due to a bug in the css checker */ .block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro {} .content .highlighted.trait {} .content span.struct,.content a.struct,.block a.current.struct {} -#titles>div:hover,#titles>div.selected {} +#titles>button:hover,#titles>button.selected {} .content .highlighted.traitalias {} .content span.type,.content a.type,.block a.current.type {} .content span.union,.content a.union,.block a.current.union {} diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 946ca0a40c9..86ce99284eb 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -352,16 +352,17 @@ pre.ignore:hover, .information:hover + pre.ignore { border-color: #777; } -#titles > div:not(.selected) { +#titles > button:not(.selected) { background-color: #252525; border-top-color: #252525; } -#titles > div:hover, #titles > div.selected { +#titles > button:hover, #titles > button.selected { border-top-color: #0089ff; + background-color: #353535; } -#titles > div > div.count { +#titles > button > div.count { color: #888; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index e0b9a04921a..52cfdf6f7a3 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -343,16 +343,17 @@ pre.ignore:hover, .information:hover + pre.ignore { border-color: #999; } -#titles > div:not(.selected) { +#titles > button:not(.selected) { background-color: #e6e6e6; border-top-color: #e6e6e6; } -#titles > div:hover, #titles > div.selected { +#titles > button:hover, #titles > button.selected { border-top-color: #0089ff; + background-color: #353535; } -#titles > div > div.count { +#titles > button > div.count { color: #888; } -- cgit 1.4.1-3-g733a5 From 718fba92b0f319a271265df53fd0221447897311 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 10 Dec 2020 13:24:47 +0200 Subject: tests: codegen/transmute-scalar needs optimizations enabled. --- src/test/codegen/transmute-scalar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/test/codegen/transmute-scalar.rs b/src/test/codegen/transmute-scalar.rs index f16335fdc74..78b4aa3fb88 100644 --- a/src/test/codegen/transmute-scalar.rs +++ b/src/test/codegen/transmute-scalar.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes +// compile-flags: -O -C no-prepopulate-passes #![crate_type = "lib"] -- cgit 1.4.1-3-g733a5 From caab16fa20c582f1c7e39f835286482eaa51710a Mon Sep 17 00:00:00 2001 From: Daiki Ihara Date: Thu, 10 Dec 2020 01:03:44 +0900 Subject: Update const-fn doc in unstable-book Update src/doc/unstable-book/src/language-features/const-fn.md Co-authored-by: Ivan Tham --- .../src/language-features/const-fn.md | 23 ++-------------------- 1 file changed, 2 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/doc/unstable-book/src/language-features/const-fn.md b/src/doc/unstable-book/src/language-features/const-fn.md index 50dbbaf5674..bcf7f78b8fe 100644 --- a/src/doc/unstable-book/src/language-features/const-fn.md +++ b/src/doc/unstable-book/src/language-features/const-fn.md @@ -6,24 +6,5 @@ The tracking issue for this feature is: [#57563] ------------------------ -The `const_fn` feature allows marking free functions and inherent methods as -`const`, enabling them to be called in constants contexts, with constant -arguments. - -## Examples - -```rust -#![feature(const_fn)] - -const fn double(x: i32) -> i32 { - x * 2 -} - -const FIVE: i32 = 5; -const TEN: i32 = double(FIVE); - -fn main() { - assert_eq!(5, FIVE); - assert_eq!(10, TEN); -} -``` +The `const_fn` feature enables additional functionality not stabilized in the +[minimal subset of `const_fn`](https://github.com/rust-lang/rust/issues/53555) -- cgit 1.4.1-3-g733a5 From fb75c329c568e610e5251f7419f10a9a639f3d42 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 29 Nov 2020 15:22:36 +0000 Subject: ci: use 20.04 on x86_64-gnu-nopt builder This commit switches the x86_64-gnu-nopt builder to use Ubuntu 20.04, which contains a more recent gdb version than Ubuntu 16.04 (newer gdb versions fix a bug that Split DWARF can trigger, see rust-lang/rust#77177 for motivation). x86_64-gnu-nopt is chosen because it runs compare modes, which is how Split DWARF testing is implemented in rust-lang/rust#77177. Signed-off-by: David Wood --- src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile index f4071961f8e..77510d7ac62 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile @@ -1,6 +1,7 @@ -FROM ubuntu:16.04 +FROM ubuntu:20.04 -RUN apt-get update && apt-get install -y --no-install-recommends \ +# Avoid interactive prompts while installing `tzdata` dependency with `DEBIAN_FRONTEND`. +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ g++ \ make \ ninja-build \ -- cgit 1.4.1-3-g733a5 From d8ee8e769f56203de792a4e48289aaf0126e2208 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 10 Dec 2020 21:08:13 +0100 Subject: re-bless tests --- src/test/ui/assume-type-intrinsics.rs | 13 ------------- src/test/ui/assume-type-intrinsics.stderr | 21 --------------------- src/test/ui/consts/assume-type-intrinsics.rs | 13 +++++++++++++ src/test/ui/consts/assume-type-intrinsics.stderr | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+), 34 deletions(-) delete mode 100644 src/test/ui/assume-type-intrinsics.rs delete mode 100644 src/test/ui/assume-type-intrinsics.stderr create mode 100644 src/test/ui/consts/assume-type-intrinsics.rs create mode 100644 src/test/ui/consts/assume-type-intrinsics.stderr (limited to 'src') diff --git a/src/test/ui/assume-type-intrinsics.rs b/src/test/ui/assume-type-intrinsics.rs deleted file mode 100644 index 77370e1ccc5..00000000000 --- a/src/test/ui/assume-type-intrinsics.rs +++ /dev/null @@ -1,13 +0,0 @@ -// error-pattern: any use of this value will cause an error - -#![feature(never_type)] -#![feature(const_maybe_uninit_assume_init)] - -#[allow(invalid_value)] -fn main() { - use std::mem::MaybeUninit; - - const _BAD: () = unsafe { - MaybeUninit::::uninit().assume_init(); - }; -} diff --git a/src/test/ui/assume-type-intrinsics.stderr b/src/test/ui/assume-type-intrinsics.stderr deleted file mode 100644 index 6f400086a54..00000000000 --- a/src/test/ui/assume-type-intrinsics.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error: any use of this value will cause an error - --> $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL - | -LL | intrinsics::assert_inhabited::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | attempted to instantiate uninhabited type `!` - | inside `MaybeUninit::::assume_init` at $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL - | inside `_BAD` at $DIR/assume-type-intrinsics.rs:11:9 - | - ::: $DIR/assume-type-intrinsics.rs:10:5 - | -LL | / const _BAD: () = unsafe { -LL | | MaybeUninit::::uninit().assume_init(); -LL | | }; - | |______- - | - = note: `#[deny(const_err)]` on by default - -error: aborting due to previous error - diff --git a/src/test/ui/consts/assume-type-intrinsics.rs b/src/test/ui/consts/assume-type-intrinsics.rs new file mode 100644 index 00000000000..77370e1ccc5 --- /dev/null +++ b/src/test/ui/consts/assume-type-intrinsics.rs @@ -0,0 +1,13 @@ +// error-pattern: any use of this value will cause an error + +#![feature(never_type)] +#![feature(const_maybe_uninit_assume_init)] + +#[allow(invalid_value)] +fn main() { + use std::mem::MaybeUninit; + + const _BAD: () = unsafe { + MaybeUninit::::uninit().assume_init(); + }; +} diff --git a/src/test/ui/consts/assume-type-intrinsics.stderr b/src/test/ui/consts/assume-type-intrinsics.stderr new file mode 100644 index 00000000000..ed09f74e9b1 --- /dev/null +++ b/src/test/ui/consts/assume-type-intrinsics.stderr @@ -0,0 +1,21 @@ +error: any use of this value will cause an error + --> $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL + | +LL | intrinsics::assert_inhabited::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | aborted execution: attempted to instantiate uninhabited type `!` + | inside `MaybeUninit::::assume_init` at $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL + | inside `_BAD` at $DIR/assume-type-intrinsics.rs:11:9 + | + ::: $DIR/assume-type-intrinsics.rs:10:5 + | +LL | / const _BAD: () = unsafe { +LL | | MaybeUninit::::uninit().assume_init(); +LL | | }; + | |______- + | + = note: `#[deny(const_err)]` on by default + +error: aborting due to previous error + -- cgit 1.4.1-3-g733a5 From 59abdb6a7eef003b1a1b0711ceb9a1edb1d1b84c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 27 Jul 2020 21:25:36 -0700 Subject: Mark `-1` as an available niche for file descriptors Based on discussion from https://internals.rust-lang.org/t/can-the-standard-library-shrink-option-file/12768, the file descriptor -1 is chosen based on the POSIX API designs that use it as a sentinel to report errors. A bigger niche could've been chosen, particularly on Linux, but would not necessarily be portable. This PR also adds a test case to ensure that the -1 niche (which is kind of hacky and has no obvious test case) works correctly. It requires the "upper" bound, which is actually -1, to be expressed in two's complement. --- library/std/src/sys/unix/fd.rs | 8 +++++++- src/test/ui/print_type_sizes/niche-filling.rs | 16 ++++++++++++---- src/test/ui/print_type_sizes/niche-filling.stdout | 6 ++++++ 3 files changed, 25 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index d3a279a2355..0eeaa68d55a 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -12,6 +12,11 @@ use crate::sys_common::AsInner; use libc::{c_int, c_void}; #[derive(Debug)] +#[rustc_layout_scalar_valid_range_start(0)] +// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a +// 32-bit c_int. Below is -2, in two's complement, but that only works out +// because c_int is 32 bits. +#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] pub struct FileDesc { fd: c_int, } @@ -63,7 +68,8 @@ const fn max_iov() -> usize { impl FileDesc { pub fn new(fd: c_int) -> FileDesc { - FileDesc { fd } + assert_ne!(fd, -1); + unsafe { FileDesc { fd } } } pub fn raw(&self) -> c_int { diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index 37ac45f7e05..0716cee21c6 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -15,12 +15,19 @@ // padding and overall computed sizes can be quite different. #![feature(start)] +#![feature(rustc_attrs)] #![allow(dead_code)] use std::num::NonZeroU32; pub enum MyOption { None, Some(T) } +#[rustc_layout_scalar_valid_range_start(0)] +#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] +pub struct MyNotNegativeOne { + _i: i32, +} + impl Default for MyOption { fn default() -> Self { MyOption::None } } @@ -77,17 +84,18 @@ fn start(_: isize, _: *const *const u8) -> isize { let _a: MyOption = Default::default(); let _b: MyOption = Default::default(); let _c: MyOption = Default::default(); - let _b: MyOption> = Default::default(); + let _d: MyOption> = Default::default(); let _e: Enum4<(), char, (), ()> = Enum4::One(()); let _f: Enum4<(), (), bool, ()> = Enum4::One(()); let _g: Enum4<(), (), (), MyOption> = Enum4::One(()); + let _h: MyOption = Default::default(); // Unions do not currently participate in niche filling. - let _h: MyOption> = Default::default(); + let _i: MyOption> = Default::default(); // ...even when theoretically possible. - let _i: MyOption> = Default::default(); - let _j: MyOption> = Default::default(); + let _j: MyOption> = Default::default(); + let _k: MyOption> = Default::default(); 0 } diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index 1894cd218ee..d1753c26ca8 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -43,6 +43,12 @@ print-type-size variant `Three`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Four`: 0 bytes print-type-size field `.0`: 0 bytes +print-type-size type: `MyNotNegativeOne`: 4 bytes, alignment: 4 bytes +print-type-size field `._i`: 4 bytes +print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes -- cgit 1.4.1-3-g733a5 From 3918b82993708db5ddcfd476252cf7632281ce19 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 10 Dec 2020 15:27:07 -0500 Subject: Use `def_path_hash_to_def_id` when re-using a `RawDefId` Fixes #79890 Previously, we just copied a `RawDefId` from the 'old' map to the 'new' map. However, the `RawDefId` for a given `DefPathHash` may be different in the current compilation session. Using `def_path_hash_to_def_id` ensures that the `RawDefId` we use is valid in the current session. --- compiler/rustc_middle/src/dep_graph/mod.rs | 2 +- .../rustc_middle/src/ty/query/on_disk_cache.rs | 24 +++++++++++++++++++--- compiler/rustc_query_system/src/dep_graph/graph.rs | 4 ++-- src/test/incremental/auxiliary/issue-79890.rs | 1 + .../issue-79890-imported-crates-changed.rs | 7 +++++++ 5 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 src/test/incremental/auxiliary/issue-79890.rs create mode 100644 src/test/incremental/issue-79890-imported-crates-changed.rs (limited to 'src') diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index a94f6d25fc7..e641c1cd77b 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -93,7 +93,7 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { fn register_reused_dep_path_hash(&self, hash: DefPathHash) { if let Some(cache) = self.queries.on_disk_cache.as_ref() { - cache.register_reused_dep_path_hash(hash) + cache.register_reused_dep_path_hash(*self, hash) } } diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index 898cc24992b..3eed94b1ffb 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -454,6 +454,7 @@ impl<'sess> OnDiskCache<'sess> { fn try_remap_cnum(&self, tcx: TyCtxt<'_>, cnum: u32) -> Option { let cnum_map = self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx, &self.prev_cnums[..])); + debug!("try_remap_cnum({}): cnum_map={:?}", cnum, cnum_map); cnum_map[CrateNum::from_u32(cnum)] } @@ -466,9 +467,22 @@ impl<'sess> OnDiskCache<'sess> { .insert(hash, RawDefId { krate: def_id.krate.as_u32(), index: def_id.index.as_u32() }); } - pub fn register_reused_dep_path_hash(&self, hash: DefPathHash) { - if let Some(old_id) = self.foreign_def_path_hashes.get(&hash) { - self.latest_foreign_def_path_hashes.lock().insert(hash, *old_id); + /// If the given `hash` still exists in the current compilation, + /// calls `store_foreign_def_id` with its current `DefId`. + /// + /// Normally, `store_foreign_def_id_hash` can be called directly by + /// the dependency graph when we construct a `DepNode`. However, + /// when we re-use a deserialized `DepNode` from the previous compilation + /// session, we only have the `DefPathHash` available. This method is used + /// to that any `DepNode` that we re-use has a `DefPathHash` -> `RawId` written + /// out for usage in the next compilation session. + pub fn register_reused_dep_path_hash(&self, tcx: TyCtxt<'tcx>, hash: DefPathHash) { + // We can't simply copy the `RawDefId` from `foreign_def_path_hashes` to + // `latest_foreign_def_path_hashes`, since the `RawDefId` might have + // changed in the current compilation session (e.g. we've added/removed crates, + // or added/removed definitions before/after the target definition). + if let Some(def_id) = self.def_path_hash_to_def_id(tcx, hash) { + self.store_foreign_def_id_hash(def_id, hash); } } @@ -592,6 +606,7 @@ impl<'sess> OnDiskCache<'sess> { match cache.entry(hash) { Entry::Occupied(e) => *e.get(), Entry::Vacant(e) => { + debug!("def_path_hash_to_def_id({:?})", hash); // Check if the `DefPathHash` corresponds to a definition in the current // crate if let Some(def_id) = self.local_def_path_hash_to_def_id.get(&hash).cloned() { @@ -605,9 +620,11 @@ impl<'sess> OnDiskCache<'sess> { // current compilation session, the crate is guaranteed to be the same // (otherwise, we would compute a different `DefPathHash`). let raw_def_id = self.get_raw_def_id(&hash)?; + debug!("def_path_hash_to_def_id({:?}): raw_def_id = {:?}", hash, raw_def_id); // If the owning crate no longer exists, the corresponding definition definitely // no longer exists. let krate = self.try_remap_cnum(tcx, raw_def_id.krate)?; + debug!("def_path_hash_to_def_id({:?}): krate = {:?}", hash, krate); // If our `DefPathHash` corresponded to a definition in the local crate, // we should have either found it in `local_def_path_hash_to_def_id`, or // never attempted to load it in the first place. Any query result or `DepNode` @@ -621,6 +638,7 @@ impl<'sess> OnDiskCache<'sess> { // Try to find a definition in the current session, using the previous `DefIndex` // as an initial guess. let opt_def_id = tcx.cstore.def_path_hash_to_def_id(krate, raw_def_id.index, hash); + debug!("def_path_to_def_id({:?}): opt_def_id = {:?}", hash, opt_def_id); e.insert(opt_def_id); opt_def_id } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 8bde552e2d4..956d476d973 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -596,9 +596,9 @@ impl DepGraph { // an eval_always node, let's try to mark it green recursively. if !dep_dep_node.kind.is_eval_always() { debug!( - "try_mark_previous_green({:?}) --- state of dependency {:?} \ + "try_mark_previous_green({:?}) --- state of dependency {:?} ({}) \ is unknown, trying to mark it green", - dep_node, dep_dep_node + dep_node, dep_dep_node, dep_dep_node.hash, ); let node_index = self.try_mark_previous_green( diff --git a/src/test/incremental/auxiliary/issue-79890.rs b/src/test/incremental/auxiliary/issue-79890.rs new file mode 100644 index 00000000000..8eaeafa5207 --- /dev/null +++ b/src/test/incremental/auxiliary/issue-79890.rs @@ -0,0 +1 @@ +pub trait MyTrait {} diff --git a/src/test/incremental/issue-79890-imported-crates-changed.rs b/src/test/incremental/issue-79890-imported-crates-changed.rs new file mode 100644 index 00000000000..93daa5ca935 --- /dev/null +++ b/src/test/incremental/issue-79890-imported-crates-changed.rs @@ -0,0 +1,7 @@ +// aux-build:issue-79890.rs +// revisions:rpass1 rpass2 rpass3 +// compile-flags:--extern issue_79890 --test +// edition:2018 + +// Tests that we don't ICE when the set of imported crates changes +#[cfg(rpass2)] use issue_79890::MyTrait; -- cgit 1.4.1-3-g733a5 From 686237c49aed588bf266e8dece3130b779605109 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Fri, 11 Dec 2020 00:00:00 +0000 Subject: Lower `discriminant_value` intrinsic This allows const propagation to evaluate comparisons involving field-less enums using derived implementations of `PartialEq` (after inlining `eq`). --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 1 + compiler/rustc_middle/src/ty/sty.rs | 39 ++++++- .../rustc_mir/src/transform/lower_intrinsics.rs | 15 +++ ...er_intrinsics.discriminant.LowerIntrinsics.diff | 124 +++++++++++++++++++++ src/test/mir-opt/lower_intrinsics.rs | 18 ++- 5 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff (limited to 'src') diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 2ad470c2693..e3a6cabd600 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -489,6 +489,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Discriminant(ref place) => { let discr_ty = rvalue.ty(self.mir, bx.tcx()); + let discr_ty = self.monomorphize(discr_ty); let discr = self .codegen_place(&mut bx, place.as_ref()) .codegen_get_discr(&mut bx, discr_ty); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 78994c6e1c7..8d452399ba5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2213,13 +2213,44 @@ impl<'tcx> TyS<'tcx> { } /// Returns the type of the discriminant of this type. - pub fn discriminant_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + pub fn discriminant_ty(&'tcx self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self.kind() { ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx), ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx), - _ => { - // This can only be `0`, for now, so `u8` will suffice. - tcx.types.u8 + + ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => { + let assoc_items = + tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap()); + let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id; + tcx.mk_projection(discriminant_def_id, tcx.mk_substs([self.into()].iter())) + } + + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(..) + | ty::Foreign(_) + | ty::Str + | ty::Array(..) + | ty::Slice(_) + | ty::RawPtr(_) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Dynamic(..) + | ty::Closure(..) + | ty::GeneratorWitness(..) + | ty::Never + | ty::Tuple(_) + | ty::Error(_) + | ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8, + + ty::Bound(..) + | ty::Placeholder(_) + | ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + bug!("`discriminant_ty` applied to unexpected type: {:?}", self) } } } diff --git a/compiler/rustc_mir/src/transform/lower_intrinsics.rs b/compiler/rustc_mir/src/transform/lower_intrinsics.rs index 543acb74acb..f5968532eb3 100644 --- a/compiler/rustc_mir/src/transform/lower_intrinsics.rs +++ b/compiler/rustc_mir/src/transform/lower_intrinsics.rs @@ -83,6 +83,21 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } } + sym::discriminant_value => { + if let (Some((destination, target)), Some(arg)) = + (*destination, args[0].place()) + { + let arg = tcx.mk_place_deref(arg); + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(box ( + destination, + Rvalue::Discriminant(arg), + )), + }); + terminator.kind = TerminatorKind::Goto { target }; + } + } _ => {} } } diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff new file mode 100644 index 00000000000..a21cbfa767e --- /dev/null +++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -0,0 +1,124 @@ +- // MIR for `discriminant` before LowerIntrinsics ++ // MIR for `discriminant` after LowerIntrinsics + + fn discriminant(_1: T) -> () { + debug t => _1; // in scope 0 at $DIR/lower_intrinsics.rs:68:24: 68:25 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:68:30: 68:30 + let _2: ::Discriminant; // in scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45 + let mut _3: &T; // in scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44 + let _4: &T; // in scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44 + let _5: u8; // in scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45 + let mut _6: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 + let _7: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 + let _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:70:43: 70:44 + let _9: u8; // in scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46 + let mut _10: &(); // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 + let _11: &(); // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 + let _12: (); // in scope 0 at $DIR/lower_intrinsics.rs:71:43: 71:45 + let _13: isize; // in scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48 + let mut _14: &E; // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 + let _15: &E; // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 + let _16: E; // in scope 0 at $DIR/lower_intrinsics.rs:72:43: 72:47 + let mut _17: &E; // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 + let mut _18: &(); // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 + let mut _19: &i32; // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45 + StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44 + StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44 + _4 = &_1; // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44 + _3 = &(*_4); // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44 +- _2 = discriminant_value::(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:69:5: 69:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> ::Discriminant {std::intrinsics::discriminant_value::}, val: Value(Scalar()) } ++ _2 = discriminant((*_3)); // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45 ++ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45 + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:69:44: 69:45 + StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:69:45: 69:46 + StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:69:45: 69:46 + StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45 + StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 + StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 + _19 = const discriminant::::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 + // ty::Const + // + ty: &i32 + // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2])) + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:70:42: 70:44 + // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2])) } + _7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 + _6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44 +- _5 = discriminant_value::(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:70:5: 70:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r i32) -> ::Discriminant {std::intrinsics::discriminant_value::}, val: Value(Scalar()) } ++ _5 = discriminant((*_6)); // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45 ++ goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45 + } + + bb2: { + StorageDead(_6); // scope 0 at $DIR/lower_intrinsics.rs:70:44: 70:45 + StorageDead(_7); // scope 0 at $DIR/lower_intrinsics.rs:70:45: 70:46 + StorageDead(_5); // scope 0 at $DIR/lower_intrinsics.rs:70:45: 70:46 + StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46 + StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 + StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 + _18 = const discriminant::::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 + // ty::Const + // + ty: &() + // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1])) + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:71:42: 71:45 + // + literal: Const { ty: &(), val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1])) } + _11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 + _10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45 +- _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:71:5: 71:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r ()) -> <() as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<()>}, val: Value(Scalar()) } ++ _9 = discriminant((*_10)); // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46 ++ goto -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46 + } + + bb3: { + StorageDead(_10); // scope 0 at $DIR/lower_intrinsics.rs:71:45: 71:46 + StorageDead(_11); // scope 0 at $DIR/lower_intrinsics.rs:71:46: 71:47 + StorageDead(_9); // scope 0 at $DIR/lower_intrinsics.rs:71:46: 71:47 + StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48 + StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 + StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 + _17 = const discriminant::::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 + // ty::Const + // + ty: &E + // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0])) + // mir::Constant + // + span: $DIR/lower_intrinsics.rs:72:42: 72:47 + // + literal: Const { ty: &E, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0])) } + _15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 + _14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47 +- _13 = discriminant_value::(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48 +- // mir::Constant +- // + span: $DIR/lower_intrinsics.rs:72:5: 72:41 +- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r E) -> ::Discriminant {std::intrinsics::discriminant_value::}, val: Value(Scalar()) } ++ _13 = discriminant((*_14)); // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48 ++ goto -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48 + } + + bb4: { + StorageDead(_14); // scope 0 at $DIR/lower_intrinsics.rs:72:47: 72:48 + StorageDead(_15); // scope 0 at $DIR/lower_intrinsics.rs:72:48: 72:49 + StorageDead(_13); // scope 0 at $DIR/lower_intrinsics.rs:72:48: 72:49 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:68:30: 73:2 + drop(_1) -> bb5; // scope 0 at $DIR/lower_intrinsics.rs:73:1: 73:2 + } + + bb5: { + return; // scope 0 at $DIR/lower_intrinsics.rs:73:2: 73:2 + } + } + diff --git a/src/test/mir-opt/lower_intrinsics.rs b/src/test/mir-opt/lower_intrinsics.rs index de5f692b7da..8d28354a5f1 100644 --- a/src/test/mir-opt/lower_intrinsics.rs +++ b/src/test/mir-opt/lower_intrinsics.rs @@ -45,11 +45,11 @@ pub fn f_dispatch(t: T) { } #[inline(never)] -pub fn f_zst(t: T) { +pub fn f_zst(_t: T) { } #[inline(never)] -pub fn f_non_zst(t: T) {} +pub fn f_non_zst(_t: T) {} // EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff pub fn non_const() -> usize { @@ -57,3 +57,17 @@ pub fn non_const() -> usize { let size_of_t = core::intrinsics::size_of::; size_of_t() } + +pub enum E { + A, + B, + C, +} + +// EMIT_MIR lower_intrinsics.discriminant.LowerIntrinsics.diff +pub fn discriminant(t: T) { + core::intrinsics::discriminant_value(&t); + core::intrinsics::discriminant_value(&0); + core::intrinsics::discriminant_value(&()); + core::intrinsics::discriminant_value(&E::B); +} -- cgit 1.4.1-3-g733a5 From 01df56343bf1884d5e1d82e813e2930c6d9d5dd6 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Wed, 25 Nov 2020 15:15:55 -0500 Subject: Test cases for RFC 2229 --- .../2229_closure_analysis/diagnostics/arrays.rs | 86 ++++++++++++++++ .../diagnostics/arrays.stderr | 111 +++++++++++++++++++++ .../2229_closure_analysis/diagnostics/box.rs | 65 ++++++++++++ .../2229_closure_analysis/diagnostics/box.stderr | 55 ++++++++++ .../diagnostics/multilevel-path.rs | 28 ++++++ .../diagnostics/multilevel-path.stderr | 26 +++++ .../diagnostics/simple-struct-min-capture.rs | 26 +++++ .../diagnostics/simple-struct-min-capture.stderr | 26 +++++ .../closures/2229_closure_analysis/run_pass/box.rs | 97 ++++++++++++++++++ .../2229_closure_analysis/run_pass/box.stderr | 11 ++ .../run_pass/capture-disjoint-field-struct.rs | 28 ++++++ .../run_pass/capture-disjoint-field-struct.stderr | 11 ++ .../run_pass/capture-disjoint-field-tuple-mut.rs | 23 +++++ .../capture-disjoint-field-tuple-mut.stderr | 11 ++ .../run_pass/capture-disjoint-field-tuple.rs | 24 +++++ .../run_pass/capture-disjoint-field-tuple.stderr | 11 ++ .../run_pass/disjoint-capture-in-same-closure.rs | 27 +++++ .../disjoint-capture-in-same-closure.stderr | 11 ++ .../run_pass/filter-on-struct-member.rs | 41 ++++++++ .../run_pass/filter-on-struct-member.stderr | 11 ++ .../run_pass/multilevel-path-1.rs | 36 +++++++ .../run_pass/multilevel-path-1.stderr | 11 ++ .../run_pass/multilevel-path-2.rs | 34 +++++++ .../run_pass/multilevel-path-2.stderr | 11 ++ .../run_pass/multilevel-path-3.rs | 31 ++++++ .../run_pass/multilevel-path-3.stderr | 11 ++ .../run_pass/nested-closure.rs | 40 ++++++++ .../run_pass/nested-closure.stderr | 11 ++ 28 files changed, 914 insertions(+) create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/box.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr (limited to 'src') diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs new file mode 100644 index 00000000000..0b94317fd71 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs @@ -0,0 +1,86 @@ +// Test that arrays are completely captured by closures by relying on the borrow check diagnostics + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete + +fn arrays_1() { + let mut arr = [1, 2, 3, 4, 5]; + + let mut c = || { + arr[0] += 10; + }; + + // c will capture `arr` completely, therefore another index into the + // array can't be modified here + arr[1] += 10; + //~^ ERROR: cannot use `arr` because it was mutably borrowed + //~| ERROR: cannot use `arr[_]` because it was mutably borrowed + c(); +} + +fn arrays_2() { + let mut arr = [1, 2, 3, 4, 5]; + + let c = || { + println!("{:#?}", &arr[3..4]); + }; + + // c will capture `arr` completely, therefore another index into the + // array can't be modified here + arr[1] += 10; + //~^ ERROR: cannot assign to `arr[_]` because it is borrowed + c(); +} + +fn arrays_3() { + let mut arr = [1, 2, 3, 4, 5]; + + let c = || { + println!("{}", arr[3]); + }; + + // c will capture `arr` completely, therefore another index into the + // array can't be modified here + arr[1] += 10; + //~^ ERROR: cannot assign to `arr[_]` because it is borrowed + c(); +} + +fn arrays_4() { + let mut arr = [1, 2, 3, 4, 5]; + + let mut c = || { + arr[1] += 10; + }; + + // c will capture `arr` completely, therefore we cannot borrow another index + // into the array. + println!("{}", arr[3]); + //~^ ERROR: cannot use `arr` because it was mutably borrowed + //~| ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable + + c(); +} + +fn arrays_5() { + let mut arr = [1, 2, 3, 4, 5]; + + let mut c = || { + arr[1] += 10; + }; + + // c will capture `arr` completely, therefore we cannot borrow other indecies + // into the array. + println!("{:#?}", &arr[3..2]); + //~^ ERROR: cannot borrow `arr` as immutable because it is also borrowed as mutable + + c(); +} + +fn main() { + arrays_1(); + arrays_2(); + arrays_3(); + arrays_4(); + arrays_5(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr new file mode 100644 index 00000000000..77e3e71bc61 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr @@ -0,0 +1,111 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/arrays.rs:3:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0503]: cannot use `arr` because it was mutably borrowed + --> $DIR/arrays.rs:15:5 + | +LL | let mut c = || { + | -- borrow of `arr` occurs here +LL | arr[0] += 10; + | --- borrow occurs due to use of `arr` in closure +... +LL | arr[1] += 10; + | ^^^^^^ use of borrowed `arr` +... +LL | c(); + | - borrow later used here + +error[E0503]: cannot use `arr[_]` because it was mutably borrowed + --> $DIR/arrays.rs:15:5 + | +LL | let mut c = || { + | -- borrow of `arr` occurs here +LL | arr[0] += 10; + | --- borrow occurs due to use of `arr` in closure +... +LL | arr[1] += 10; + | ^^^^^^^^^^^^ use of borrowed `arr` +... +LL | c(); + | - borrow later used here + +error[E0506]: cannot assign to `arr[_]` because it is borrowed + --> $DIR/arrays.rs:30:5 + | +LL | let c = || { + | -- borrow of `arr[_]` occurs here +LL | println!("{:#?}", &arr[3..4]); + | --- borrow occurs due to use in closure +... +LL | arr[1] += 10; + | ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here +LL | +LL | c(); + | - borrow later used here + +error[E0506]: cannot assign to `arr[_]` because it is borrowed + --> $DIR/arrays.rs:44:5 + | +LL | let c = || { + | -- borrow of `arr[_]` occurs here +LL | println!("{}", arr[3]); + | --- borrow occurs due to use in closure +... +LL | arr[1] += 10; + | ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here +LL | +LL | c(); + | - borrow later used here + +error[E0503]: cannot use `arr` because it was mutably borrowed + --> $DIR/arrays.rs:58:20 + | +LL | let mut c = || { + | -- borrow of `arr` occurs here +LL | arr[1] += 10; + | --- borrow occurs due to use of `arr` in closure +... +LL | println!("{}", arr[3]); + | ^^^^^^ use of borrowed `arr` +... +LL | c(); + | - borrow later used here + +error[E0502]: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable + --> $DIR/arrays.rs:58:20 + | +LL | let mut c = || { + | -- mutable borrow occurs here +LL | arr[1] += 10; + | --- first borrow occurs due to use of `arr` in closure +... +LL | println!("{}", arr[3]); + | ^^^^^^ immutable borrow occurs here +... +LL | c(); + | - mutable borrow later used here + +error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable + --> $DIR/arrays.rs:74:24 + | +LL | let mut c = || { + | -- mutable borrow occurs here +LL | arr[1] += 10; + | --- first borrow occurs due to use of `arr` in closure +... +LL | println!("{:#?}", &arr[3..2]); + | ^^^ immutable borrow occurs here +... +LL | c(); + | - mutable borrow later used here + +error: aborting due to 7 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0502, E0503, E0506. +For more information about an error, try `rustc --explain E0502`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs new file mode 100644 index 00000000000..15be1d8c722 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs @@ -0,0 +1,65 @@ +// Test borrow checker when we precise capture when using boxes + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete + +struct MetaData { x: String, name: String } +struct Data { m: MetaData } +struct BoxedData(Box); +struct EvenMoreBoxedData(Box); + +// Check diagnostics when the same path is mutated both inside and outside the closure +fn box_1() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let mut e = EvenMoreBoxedData(Box::new(b)); + + let mut c = || { + e.0.0.m.x = format!("not-x"); + }; + + e.0.0.m.x = format!("not-x"); + //~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed + c(); +} + +// Check diagnostics when a path is mutated inside a closure while attempting to read it outside +// the closure. +fn box_2() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let mut e = EvenMoreBoxedData(Box::new(b)); + + let mut c = || { + e.0.0.m.x = format!("not-x"); + }; + + println!("{}", e.0.0.m.x); + //~^ ERROR: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed as mutable + c(); +} + +// Check diagnostics when a path is read inside a closure while attempting to mutate it outside +// the closure. +fn box_3() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let mut e = EvenMoreBoxedData(Box::new(b)); + + let c = || { + println!("{}", e.0.0.m.x); + }; + + e.0.0.m.x = format!("not-x"); + //~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed + c(); +} + +fn main() { + box_1(); + box_2(); + box_3(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr new file mode 100644 index 00000000000..17a9332fb3e --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr @@ -0,0 +1,55 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/box.rs:3:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed + --> $DIR/box.rs:22:5 + | +LL | let mut c = || { + | -- borrow of `e.0.0.m.x` occurs here +LL | e.0.0.m.x = format!("not-x"); + | - borrow occurs due to use in closure +... +LL | e.0.0.m.x = format!("not-x"); + | ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here +LL | +LL | c(); + | - borrow later used here + +error[E0502]: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed as mutable + --> $DIR/box.rs:39:20 + | +LL | let mut c = || { + | -- mutable borrow occurs here +LL | e.0.0.m.x = format!("not-x"); + | - first borrow occurs due to use of `e.0.0.m.x` in closure +... +LL | println!("{}", e.0.0.m.x); + | ^^^^^^^^^ immutable borrow occurs here +LL | +LL | c(); + | - mutable borrow later used here + +error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed + --> $DIR/box.rs:56:5 + | +LL | let c = || { + | -- borrow of `e.0.0.m.x` occurs here +LL | println!("{}", e.0.0.m.x); + | - borrow occurs due to use in closure +... +LL | e.0.0.m.x = format!("not-x"); + | ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here +LL | +LL | c(); + | - borrow later used here + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0502, E0506. +For more information about an error, try `rustc --explain E0502`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs new file mode 100644 index 00000000000..39b04c833e3 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs @@ -0,0 +1,28 @@ +// Test that when a borrow checker diagnostics are emitted, it's as precise +// as the capture by the closure. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +#![allow(unused)] + +struct Point { + x: i32, + y: i32, +} +struct Wrapper { + p: Point, +} + +fn main() { + let mut w = Wrapper { p: Point { x: 10, y: 10 } }; + + let mut c = || { + w.p.x += 20; + }; + + let py = &mut w.p.x; + //~^ ERROR: cannot borrow `w.p.x` as mutable more than once at a time + c(); + + *py = 20 +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr new file mode 100644 index 00000000000..e5a396c4e98 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr @@ -0,0 +1,26 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/multilevel-path.rs:4:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0499]: cannot borrow `w.p.x` as mutable more than once at a time + --> $DIR/multilevel-path.rs:23:14 + | +LL | let mut c = || { + | -- first mutable borrow occurs here +LL | w.p.x += 20; + | - first borrow occurs due to use of `w.p.x` in closure +... +LL | let py = &mut w.p.x; + | ^^^^^^^^^^ second mutable borrow occurs here +LL | +LL | c(); + | - first borrow later used here + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs new file mode 100644 index 00000000000..e78d8715e48 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs @@ -0,0 +1,26 @@ +// Test that borrow checker error is accurate and that min capture pass of the +// closure analysis is working as expected. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete + +#[derive(Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let mut p = Point { x: 10, y: 20 }; + + // `p` is captured via mutable borrow. + let mut c = || { + p.x += 10; + println!("{:?}", p); + }; + + + println!("{:?}", p); + //~^ ERROR: cannot borrow `p` as immutable because it is also borrowed as mutable + c(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr new file mode 100644 index 00000000000..45a61cd98b1 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr @@ -0,0 +1,26 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/simple-struct-min-capture.rs:4:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +error[E0502]: cannot borrow `p` as immutable because it is also borrowed as mutable + --> $DIR/simple-struct-min-capture.rs:23:22 + | +LL | let mut c = || { + | -- mutable borrow occurs here +LL | p.x += 10; + | - first borrow occurs due to use of `p` in closure +... +LL | println!("{:?}", p); + | ^ immutable borrow occurs here +LL | +LL | c(); + | - mutable borrow later used here + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs new file mode 100644 index 00000000000..3a66399d028 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs @@ -0,0 +1,97 @@ +// run-pass + +// Test precise capture when using boxes + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 + + +struct MetaData { x: String, name: String } +struct Data { m: MetaData } +struct BoxedData(Box); +struct EvenMoreBoxedData(Box); + +// Mutate disjoint paths, one inside one outside the closure +fn box_1() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let mut e = EvenMoreBoxedData(Box::new(b)); + + let mut c = || { + e.0.0.m.x = format!("not-x"); + }; + + e.0.0.m.name = format!("not-name"); + c(); +} + +// Mutate a path inside the closure and read a disjoint path outside the closure +fn box_2() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let mut e = EvenMoreBoxedData(Box::new(b)); + + let mut c = || { + e.0.0.m.x = format!("not-x"); + }; + + println!("{}", e.0.0.m.name); + c(); +} + +// Read a path inside the closure and mutate a disjoint path outside the closure +fn box_3() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let mut e = EvenMoreBoxedData(Box::new(b)); + + let c = || { + println!("{}", e.0.0.m.name); + }; + + e.0.0.m.x = format!("not-x"); + c(); +} + +// Read disjoint paths, one inside the closure and one outside the closure. +fn box_4() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let e = EvenMoreBoxedData(Box::new(b)); + + let c = || { + println!("{}", e.0.0.m.name); + }; + + println!("{}", e.0.0.m.x); + c(); +} + +// Read the same path, once inside the closure and once outside the closure. +fn box_5() { + let m = MetaData { x: format!("x"), name: format!("name") }; + let d = Data { m }; + let b = BoxedData(Box::new(d)); + let e = EvenMoreBoxedData(Box::new(b)); + + let c = || { + println!("{}", e.0.0.m.name); + }; + + println!("{}", e.0.0.m.name); + c(); +} + +fn main() { + box_1(); + box_2(); + box_3(); + box_4(); + box_5(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr new file mode 100644 index 00000000000..9883c01b946 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/box.rs:5:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs new file mode 100644 index 00000000000..2c359519b76 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs @@ -0,0 +1,28 @@ +// run-pass + +// Test that we can immutably borrow field of an instance of a structure from within a closure, +// while having a mutable borrow to another field of the same instance outside the closure. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 + +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; +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr new file mode 100644 index 00000000000..9b0dea770fb --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-disjoint-field-struct.rs:6:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs new file mode 100644 index 00000000000..2c6679feabe --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs @@ -0,0 +1,23 @@ +// run-pass + +// Test that we can mutate an element of a tuple from within a closure +// while immutably borrowing another element of the same tuple outside the closure. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] + +fn main() { + let mut t = (10, 10); + + let mut c = || { + let t1 = &mut t.1; + *t1 = 20; + }; + + // Test that `c` only captures t.1, therefore reading t.0 is allowed. + println!("{}", t.0); + c(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr new file mode 100644 index 00000000000..28d09153952 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-disjoint-field-tuple-mut.rs:6:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs new file mode 100644 index 00000000000..52f5cef9f01 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs @@ -0,0 +1,24 @@ +// run-pass + +// Test that we can immutably borrow an element of a tuple from within a closure, +// while having a mutable borrow to another element of the same tuple outside the closure. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![feature(rustc_attrs)] + +fn main() { + let mut t = (10, 10); + + let c = || { + println!("{}", t.0); + }; + + // `c` only captures t.0, therefore mutating t.1 is allowed. + let t1 = &mut t.1; + + c(); + *t1 = 20; +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr new file mode 100644 index 00000000000..4fb37f85f88 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-disjoint-field-tuple.rs:6:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs new file mode 100644 index 00000000000..3f8e197b783 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs @@ -0,0 +1,27 @@ +// run-pass + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 + +// Tests that if a closure uses indivual fields of the same object +// then that case is handled properly. + +#![allow(unused)] + +struct Struct { + x: i32, + y: i32, + s: String, +} + +fn main() { + let mut s = Struct { x: 10, y: 10, s: String::new() }; + + let mut c = { + s.x += 10; + s.y += 42; + s.s = String::from("new"); + }; +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr new file mode 100644 index 00000000000..bba90f8917a --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/disjoint-capture-in-same-closure.rs:3:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs new file mode 100644 index 00000000000..8c12593430e --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs @@ -0,0 +1,41 @@ +// run-pass + +// Test disjoint capture within an impl block + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 + +struct Filter { + div: i32, +} +impl Filter { + fn allowed(&self, x: i32) -> bool { + x % self.div == 1 + } +} + +struct Data { + filter: Filter, + list: Vec, +} +impl Data { + fn update(&mut self) { + // The closure passed to filter only captures self.filter, + // therefore mutating self.list is allowed. + self.list.retain( + |v| self.filter.allowed(*v), + ); + } +} + +fn main() { + let mut d = Data { filter: Filter { div: 3 }, list: Vec::new() }; + + for i in 1..10 { + d.list.push(i); + } + + d.update(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr new file mode 100644 index 00000000000..6930e18992a --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/filter-on-struct-member.rs:5:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs new file mode 100644 index 00000000000..142c156bd56 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs @@ -0,0 +1,36 @@ +// run-pass + +// Test that closures can catpure paths that are more precise than just one level +// from the root variable. +// +// If the closures can handle such precison we should be able to mutate one path in the closure +// while being able to mutate another path outside the closure, where the two paths are disjoint +// after applying two projections on the root variable. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![allow(unused)] + +struct Point { + x: i32, + y: i32, +} +struct Wrapper { + p: Point, +} + +fn main() { + let mut w = Wrapper { p: Point { x: 10, y: 10 } }; + + let mut c = || { + w.p.x += 20; + }; + + // `c` only captures `w.p.x`, therefore it's safe to mutate `w.p.y`. + let py = &mut w.p.y; + c(); + + *py = 20 +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr new file mode 100644 index 00000000000..94b877522f4 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/multilevel-path-1.rs:10:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs new file mode 100644 index 00000000000..d8f7d55d5aa --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs @@ -0,0 +1,34 @@ +// run-pass + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![allow(unused)] + +// If the closures can handle such precison we should be able to read one path in the closure +// while being able mutate another path outside the closure, where the two paths are disjoint +// after applying two projections on the root variable. + + +struct Point { + x: i32, + y: i32, +} +struct Wrapper { + p: Point, +} + +fn main() { + let mut w = Wrapper { p: Point { x: 10, y: 10 } }; + + let c = || { + println!("{}", w.p.x); + }; + + // `c` only captures `w.p.x`, therefore it's safe to mutate `w.p.y`. + let py = &mut w.p.y; + c(); + + *py = 20 +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr new file mode 100644 index 00000000000..100a0e167c5 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/multilevel-path-2.rs:3:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs new file mode 100644 index 00000000000..fc3d48ec458 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs @@ -0,0 +1,31 @@ +// run-pass + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 +#![allow(unused)] + +// Test that when `capture_disjoint_fields` is enabled we can read a path +// both inside and outside the closure at the same time. + +struct Point { + x: i32, + y: i32, +} +struct Wrapper { + p: Point, +} + +fn main() { + let mut w = Wrapper { p: Point { x: 10, y: 10 } }; + + let c = || { + println!("{}", w.p.x); + }; + + let px = &w.p.x; + c(); + + println!("{}", px); +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr new file mode 100644 index 00000000000..cf5be6a00e9 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/multilevel-path-3.rs:3:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs new file mode 100644 index 00000000000..238580929ef --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs @@ -0,0 +1,40 @@ +// run-pass + +// Test whether if we can do precise capture when using nested clsoure. + +#![feature(capture_disjoint_fields)] +//~^ WARNING: the feature `capture_disjoint_fields` is incomplete +//~| NOTE: `#[warn(incomplete_features)]` on by default +//~| NOTE: see issue #53488 + +struct Point { + x: i32, + y: i32, +} + +fn main() { + let mut p = Point { x: 5, y: 20 }; + + // c1 should capture `p.x` via immutable borrow and + // `p.y` via mutable borrow. + let mut c1 = || { + println!("{}", p.x); + + let incr = 10; + + let mut c2 = || p.y += incr; + c2(); + + println!("{}", p.y); + }; + + c1(); + + // This should not throw an error because `p.x` is borrowed via Immutable borrow, + // and multiple immutable borrow of the same place are allowed. + let px = &p.x; + + println!("{}", px); + + c1(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr new file mode 100644 index 00000000000..293aa82ce9f --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr @@ -0,0 +1,11 @@ +warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/nested-closure.rs:5:12 + | +LL | #![feature(capture_disjoint_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #53488 for more information + +warning: 1 warning emitted + -- cgit 1.4.1-3-g733a5 From ebfea6224bc3b72f3159cd8240a0f3e98366a604 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 11 Dec 2020 18:02:23 +0100 Subject: Fix item name display on mobile --- src/librustdoc/html/static/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 8eef65a231d..f208281d3b6 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1571,7 +1571,7 @@ h4 > .notable-traits { #main > table:not(.table-display) td { word-break: break-word; - min-width: 10%; + width: 50%; } .search-container > div { -- cgit 1.4.1-3-g733a5 From 17230b40686360c26e1c8b87a648c0a83968761c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 11 Dec 2020 18:08:44 +0100 Subject: update Miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/miri b/src/tools/miri index e54c5db4f0e..2065b52dfef 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit e54c5db4f0edbe51db42d2c3e63e9821537ed4f4 +Subproject commit 2065b52dfef3cd5a5216e65c21a056a69574bddc -- cgit 1.4.1-3-g733a5 From 9c36491538476dd3ff5ec834944aacdaceb12f30 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 11 Dec 2020 20:07:24 +0100 Subject: Fix main section position so that the search input remains clickable --- src/librustdoc/html/static/rustdoc.css | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index f208281d3b6..ebb8f98756d 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1569,6 +1569,10 @@ h4 > .notable-traits { height: 73px; } + #main { + margin-top: 100px; + } + #main > table:not(.table-display) td { word-break: break-word; width: 50%; -- cgit 1.4.1-3-g733a5 From ed80815bf2554c99c1cd140d5ce3ee7df19f90d7 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Fri, 11 Dec 2020 15:02:46 -0500 Subject: Move binder for dyn to each list item --- .../rustc_codegen_cranelift/src/value_and_place.rs | 24 ++-- .../rustc_infer/src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_lint/src/context.rs | 2 +- compiler/rustc_lint/src/unused.rs | 6 +- compiler/rustc_middle/src/ty/codec.rs | 10 +- compiler/rustc_middle/src/ty/context.rs | 34 +++-- compiler/rustc_middle/src/ty/error.rs | 2 +- compiler/rustc_middle/src/ty/flags.rs | 20 ++- compiler/rustc_middle/src/ty/print/mod.rs | 6 +- compiler/rustc_middle/src/ty/print/pretty.rs | 153 +++++++++++++-------- compiler/rustc_middle/src/ty/relate.rs | 20 +-- compiler/rustc_middle/src/ty/structural_impls.rs | 4 +- compiler/rustc_middle/src/ty/sty.rs | 60 +++----- .../src/interpret/intrinsics/type_name.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 4 +- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 41 +++--- .../src/traits/error_reporting/on_unimplemented.rs | 4 +- .../src/traits/object_safety.rs | 28 ++-- .../src/traits/select/confirmation.rs | 53 +++---- compiler/rustc_trait_selection/src/traits/wf.rs | 4 +- compiler/rustc_traits/src/chalk/lowering.rs | 63 +++++---- compiler/rustc_typeck/src/astconv/mod.rs | 20 +-- compiler/rustc_typeck/src/check/method/suggest.rs | 8 +- src/tools/clippy/clippy_lints/src/utils/mod.rs | 4 +- 25 files changed, 311 insertions(+), 265 deletions(-) (limited to 'src') diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index cb40d4ed9a6..5bcb11fd515 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -480,17 +480,19 @@ impl<'tcx> CPlace<'tcx> { // fn(&T) -> for<'l> fn(&'l T) is allowed } (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => { - let from_traits = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from_traits); - let to_traits = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to_traits); - assert_eq!( - from_traits, to_traits, - "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}", - from_traits, to_traits, fx, - ); + for (from, to) in from_traits.iter().zip(to_traits) { + let from = fx + .tcx + .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from); + let to = fx + .tcx + .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to); + assert_eq!( + from, to, + "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}", + from_traits, to_traits, fx, + ); + } // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed } _ => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 183fb314a00..fdec3c9fb73 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -496,7 +496,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn print_dyn_existential( self, - _predicates: &'tcx ty::List>, + _predicates: &'tcx ty::List>>, ) -> Result { Err(NonTrivialPath) } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 16563d21ff1..bfeef490489 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -786,7 +786,7 @@ impl<'tcx> LateContext<'tcx> { fn print_dyn_existential( self, - _predicates: &'tcx ty::List>, + _predicates: &'tcx ty::List>>, ) -> Result { Ok(()) } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 2a5ad5e6c98..5e1f94c071c 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -218,8 +218,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } ty::Dynamic(binder, _) => { let mut has_emitted = false; - for predicate in binder.skip_binder().iter() { - if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { + for predicate in binder.iter() { + if let ty::ExistentialPredicate::Trait(ref trait_ref) = + predicate.skip_binder() + { let def_id = trait_ref.def_id; let descr_post = &format!(" trait object{}{}", plural_suffix, descr_post,); diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index b2fc3710cd6..cd3bd96f9fc 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -321,10 +321,14 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List> { } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List> { +impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> + for ty::List>> +{ fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { let len = decoder.read_usize()?; - Ok(decoder.tcx().mk_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?) + Ok(decoder + .tcx() + .mk_poly_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?) } } @@ -373,7 +377,7 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::N impl_decodable_via_ref! { &'tcx ty::TypeckResults<'tcx>, &'tcx ty::List>, - &'tcx ty::List>, + &'tcx ty::List>>, &'tcx Allocation, &'tcx mir::Body<'tcx>, &'tcx mir::UnsafetyCheckResult, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1b3416e112b..9218040be9c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -87,7 +87,7 @@ pub struct CtxtInterners<'tcx> { substs: InternedSet<'tcx, InternalSubsts<'tcx>>, canonical_var_infos: InternedSet<'tcx, List>>, region: InternedSet<'tcx, RegionKind>, - existential_predicates: InternedSet<'tcx, List>>, + poly_existential_predicates: InternedSet<'tcx, List>>>, predicate: InternedSet<'tcx, PredicateInner<'tcx>>, predicates: InternedSet<'tcx, List>>, projs: InternedSet<'tcx, List>, @@ -103,7 +103,7 @@ impl<'tcx> CtxtInterners<'tcx> { type_list: Default::default(), substs: Default::default(), region: Default::default(), - existential_predicates: Default::default(), + poly_existential_predicates: Default::default(), canonical_var_infos: Default::default(), predicate: Default::default(), predicates: Default::default(), @@ -1610,7 +1610,7 @@ nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>} nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>} nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>} -nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} +nop_list_lift! {poly_existential_predicates; ty::Binder> => ty::Binder>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} nop_list_lift! {projs; ProjectionKind => ProjectionKind} @@ -2051,7 +2051,8 @@ slice_interners!( type_list: _intern_type_list(Ty<'tcx>), substs: _intern_substs(GenericArg<'tcx>), canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>), - existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>), + poly_existential_predicates: + _intern_poly_existential_predicates(ty::Binder>), predicates: _intern_predicates(Predicate<'tcx>), projs: _intern_projs(ProjectionKind), place_elems: _intern_place_elems(PlaceElem<'tcx>), @@ -2282,7 +2283,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_dynamic( self, - obj: ty::Binder<&'tcx List>>, + obj: &'tcx List>>, reg: ty::Region<'tcx>, ) -> Ty<'tcx> { self.mk_ty(Dynamic(obj, reg)) @@ -2412,13 +2413,17 @@ impl<'tcx> TyCtxt<'tcx> { Place { local: place.local, projection: self.intern_place_elems(&projection) } } - pub fn intern_existential_predicates( + pub fn intern_poly_existential_predicates( self, - eps: &[ExistentialPredicate<'tcx>], - ) -> &'tcx List> { + eps: &[ty::Binder>], + ) -> &'tcx List>> { assert!(!eps.is_empty()); - assert!(eps.array_windows().all(|[a, b]| a.stable_cmp(self, b) != Ordering::Greater)); - self._intern_existential_predicates(eps) + assert!( + eps.array_windows() + .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder()) + != Ordering::Greater) + ); + self._intern_poly_existential_predicates(eps) } pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List> { @@ -2475,13 +2480,16 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn mk_existential_predicates< - I: InternAs<[ExistentialPredicate<'tcx>], &'tcx List>>, + pub fn mk_poly_existential_predicates< + I: InternAs< + [ty::Binder>], + &'tcx List>>, + >, >( self, iter: I, ) -> I::Output { - iter.intern_with(|xs| self.intern_existential_predicates(xs)) + iter.intern_with(|xs| self.intern_poly_existential_predicates(xs)) } pub fn mk_predicates], &'tcx List>>>( diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 5ec0ec0c56a..97af927dfcb 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -58,7 +58,7 @@ pub enum TypeError<'tcx> { CyclicTy(Ty<'tcx>), CyclicConst(&'tcx ty::Const<'tcx>), ProjectionMismatched(ExpectedFound), - ExistentialMismatch(ExpectedFound<&'tcx ty::List>>), + ExistentialMismatch(ExpectedFound<&'tcx ty::List>>>), ObjectUnsafeCoercion(DefId), ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>), diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 8b97a87f214..4de3d159248 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -160,19 +160,15 @@ impl FlagComputation { } &ty::Dynamic(obj, r) => { - self.bound_computation(obj, |computation, obj| { - for predicate in obj.iter() { - match predicate { - ty::ExistentialPredicate::Trait(tr) => { - computation.add_substs(tr.substs) - } - ty::ExistentialPredicate::Projection(p) => { - computation.add_existential_projection(&p); - } - ty::ExistentialPredicate::AutoTrait(_) => {} + for predicate in obj.iter() { + self.bound_computation(predicate, |computation, predicate| match predicate { + ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs), + ty::ExistentialPredicate::Projection(p) => { + computation.add_existential_projection(&p); } - } - }); + ty::ExistentialPredicate::AutoTrait(_) => {} + }); + } self.add_region(r); } diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 2e00be2395b..c79e06b7fdd 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -63,7 +63,7 @@ pub trait Printer<'tcx>: Sized { fn print_dyn_existential( self, - predicates: &'tcx ty::List>, + predicates: &'tcx ty::List>>, ) -> Result; fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result; @@ -343,7 +343,9 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> { } } -impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List> { +impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> + for &'tcx ty::List>> +{ type Output = P::DynExistential; type Error = P::Error; fn print(&self, cx: P) -> Result { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 38f8e779f6a..09ef69e9690 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -209,6 +209,17 @@ pub trait PrettyPrinter<'tcx>: value.as_ref().skip_binder().print(self) } + fn wrap_binder Result>( + self, + value: &ty::Binder, + f: F, + ) -> Result + where + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + { + f(value.as_ref().skip_binder(), self) + } + /// Prints comma-separated elements. fn comma_sep(mut self, mut elems: impl Iterator) -> Result where @@ -753,72 +764,77 @@ pub trait PrettyPrinter<'tcx>: fn pretty_print_dyn_existential( mut self, - predicates: &'tcx ty::List>, + predicates: &'tcx ty::List>>, ) -> Result { - define_scoped_cx!(self); - // Generate the main trait ref, including associated types. let mut first = true; if let Some(principal) = predicates.principal() { - p!(print_def_path(principal.def_id, &[])); - - let mut resugared = false; - - // Special-case `Fn(...) -> ...` and resugar it. - let fn_trait_kind = self.tcx().fn_trait_kind_from_lang_item(principal.def_id); - if !self.tcx().sess.verbose() && fn_trait_kind.is_some() { - if let ty::Tuple(ref args) = principal.substs.type_at(0).kind() { - let mut projections = predicates.projection_bounds(); - if let (Some(proj), None) = (projections.next(), projections.next()) { - let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect(); - p!(pretty_fn_sig(&tys, false, proj.ty)); - resugared = true; + self = self.wrap_binder(&principal, |principal, mut cx| { + define_scoped_cx!(cx); + p!(print_def_path(principal.def_id, &[])); + + let mut resugared = false; + + // Special-case `Fn(...) -> ...` and resugar it. + let fn_trait_kind = cx.tcx().fn_trait_kind_from_lang_item(principal.def_id); + if !cx.tcx().sess.verbose() && fn_trait_kind.is_some() { + if let ty::Tuple(ref args) = principal.substs.type_at(0).kind() { + let mut projections = predicates.projection_bounds(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect(); + p!(pretty_fn_sig(&tys, false, proj.skip_binder().ty)); + resugared = true; + } } } - } - // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`, - // in order to place the projections inside the `<...>`. - if !resugared { - // Use a type that can't appear in defaults of type parameters. - let dummy_self = self.tcx().mk_ty_infer(ty::FreshTy(0)); - let principal = principal.with_self_ty(self.tcx(), dummy_self); + // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`, + // in order to place the projections inside the `<...>`. + if !resugared { + // Use a type that can't appear in defaults of type parameters. + let dummy_cx = cx.tcx().mk_ty_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(cx.tcx(), dummy_cx); + + let args = cx.generic_args_to_print( + cx.tcx().generics_of(principal.def_id), + principal.substs, + ); + + // Don't print `'_` if there's no unerased regions. + let print_regions = args.iter().any(|arg| match arg.unpack() { + GenericArgKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + }); + let mut args = args.iter().cloned().filter(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => print_regions, + _ => true, + }); + let mut projections = predicates.projection_bounds(); - let args = self.generic_args_to_print( - self.tcx().generics_of(principal.def_id), - principal.substs, - ); + let arg0 = args.next(); + let projection0 = projections.next(); + if arg0.is_some() || projection0.is_some() { + let args = arg0.into_iter().chain(args); + let projections = projection0.into_iter().chain(projections); - // Don't print `'_` if there's no unerased regions. - let print_regions = args.iter().any(|arg| match arg.unpack() { - GenericArgKind::Lifetime(r) => *r != ty::ReErased, - _ => false, - }); - let mut args = args.iter().cloned().filter(|arg| match arg.unpack() { - GenericArgKind::Lifetime(_) => print_regions, - _ => true, - }); - let mut projections = predicates.projection_bounds(); - - let arg0 = args.next(); - let projection0 = projections.next(); - if arg0.is_some() || projection0.is_some() { - let args = arg0.into_iter().chain(args); - let projections = projection0.into_iter().chain(projections); - - p!(generic_delimiters(|mut cx| { - cx = cx.comma_sep(args)?; - if arg0.is_some() && projection0.is_some() { - write!(cx, ", ")?; - } - cx.comma_sep(projections) - })); + p!(generic_delimiters(|mut cx| { + cx = cx.comma_sep(args)?; + if arg0.is_some() && projection0.is_some() { + write!(cx, ", ")?; + } + cx.comma_sep(projections) + })); + } } - } + Ok(cx) + })?; + first = false; } + define_scoped_cx!(self); + // Builtin bounds. // FIXME(eddyb) avoid printing twice (needed to ensure // that the auto traits are sorted *and* printed via cx). @@ -1391,7 +1407,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { fn print_dyn_existential( self, - predicates: &'tcx ty::List>, + predicates: &'tcx ty::List>>, ) -> Result { self.pretty_print_dyn_existential(predicates) } @@ -1537,6 +1553,17 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { self.pretty_in_binder(value) } + fn wrap_binder Result>( + self, + value: &ty::Binder, + f: C, + ) -> Result + where + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + { + self.pretty_wrap_binder(value, f) + } + fn typed_value( mut self, f: impl FnOnce(Self) -> Result, @@ -1790,6 +1817,22 @@ impl FmtPrinter<'_, 'tcx, F> { Ok(inner) } + pub fn pretty_wrap_binder Result>( + self, + value: &ty::Binder, + f: C, + ) -> Result + where + T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, + { + let old_region_index = self.region_index; + let (new, new_value) = self.name_all_regions(value)?; + let mut inner = f(&new_value.0, new)?; + inner.region_index = old_region_index; + inner.binder_depth -= 1; + Ok(inner) + } + fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) where T: TypeFoldable<'tcx>, @@ -1906,12 +1949,12 @@ impl ty::Binder> { forward_display_to_print! { Ty<'tcx>, - &'tcx ty::List>, + &'tcx ty::List>>, &'tcx ty::Const<'tcx>, // HACK(eddyb) these are exhaustive instead of generic, // because `for<'tcx>` isn't possible yet. - ty::Binder<&'tcx ty::List>>, + ty::Binder>, ty::Binder>, ty::Binder>, ty::Binder>, diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index ef5034e218d..8a3a6305d01 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -603,7 +603,7 @@ pub fn super_relate_consts>( new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty })) } -impl<'tcx> Relate<'tcx> for &'tcx ty::List> { +impl<'tcx> Relate<'tcx> for &'tcx ty::List>> { fn relate>( relation: &mut R, a: Self, @@ -616,9 +616,9 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { // in `a`. let mut a_v: Vec<_> = a.into_iter().collect(); let mut b_v: Vec<_> = b.into_iter().collect(); - a_v.sort_by(|a, b| a.stable_cmp(tcx, b)); + a_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); a_v.dedup(); - b_v.sort_by(|a, b| a.stable_cmp(tcx, b)); + b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); b_v.dedup(); if a_v.len() != b_v.len() { return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))); @@ -626,14 +626,18 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { let v = a_v.into_iter().zip(b_v.into_iter()).map(|(ep_a, ep_b)| { use crate::ty::ExistentialPredicate::*; - match (ep_a, ep_b) { - (Trait(a), Trait(b)) => Ok(Trait(relation.relate(a, b)?)), - (Projection(a), Projection(b)) => Ok(Projection(relation.relate(a, b)?)), - (AutoTrait(a), AutoTrait(b)) if a == b => Ok(AutoTrait(a)), + match (ep_a.skip_binder(), ep_b.skip_binder()) { + (Trait(a), Trait(b)) => Ok(ty::Binder::bind(Trait( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))), + (Projection(a), Projection(b)) => Ok(ty::Binder::bind(Projection( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))), + (AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))), _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))), } }); - Ok(tcx.mk_existential_predicates(v)?) + Ok(tcx.mk_poly_existential_predicates(v)?) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 94e69a93a6b..8af5792b3fb 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -843,9 +843,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List>> { fn super_fold_with>(self, folder: &mut F) -> Self { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_existential_predicates(v)) + ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 78994c6e1c7..f85a08005eb 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -152,7 +152,7 @@ pub enum TyKind<'tcx> { FnPtr(PolyFnSig<'tcx>), /// A trait, defined with `trait`. - Dynamic(Binder<&'tcx List>>, ty::Region<'tcx>), + Dynamic(&'tcx List>>, ty::Region<'tcx>), /// The anonymous type of a closure. Used to represent the type of /// `|a| a`. @@ -762,7 +762,7 @@ impl<'tcx> Binder> { } } -impl<'tcx> List> { +impl<'tcx> List>> { /// Returns the "principal `DefId`" of this set of existential predicates. /// /// A Rust trait object type consists (in addition to a lifetime bound) @@ -788,64 +788,42 @@ impl<'tcx> List> { /// is `{Send, Sync}`, while there is no principal. These trait objects /// have a "trivial" vtable consisting of just the size, alignment, /// and destructor. - pub fn principal(&self) -> Option> { - match self[0] { - ExistentialPredicate::Trait(tr) => Some(tr), - _ => None, - } + pub fn principal(&self) -> Option>> { + self[0] + .map_bound(|this| match this { + ExistentialPredicate::Trait(tr) => Some(tr), + _ => None, + }) + .transpose() } pub fn principal_def_id(&self) -> Option { - self.principal().map(|trait_ref| trait_ref.def_id) + self.principal().map(|trait_ref| trait_ref.skip_binder().def_id) } #[inline] pub fn projection_bounds<'a>( &'a self, - ) -> impl Iterator> + 'a { - self.iter().filter_map(|predicate| match predicate { - ExistentialPredicate::Projection(projection) => Some(projection), - _ => None, + ) -> impl Iterator>> + 'a { + self.iter().filter_map(|predicate| { + predicate + .map_bound(|pred| match pred { + ExistentialPredicate::Projection(projection) => Some(projection), + _ => None, + }) + .transpose() }) } #[inline] pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { - self.iter().filter_map(|predicate| match predicate { + self.iter().filter_map(|predicate| match predicate.skip_binder() { ExistentialPredicate::AutoTrait(did) => Some(did), _ => None, }) } } -impl<'tcx> Binder<&'tcx List>> { - pub fn principal(&self) -> Option>> { - self.map_bound(|b| b.principal()).transpose() - } - - pub fn principal_def_id(&self) -> Option { - self.skip_binder().principal_def_id() - } - - #[inline] - pub fn projection_bounds<'a>( - &'a self, - ) -> impl Iterator> + 'a { - self.skip_binder().projection_bounds().map(Binder::bind) - } - - #[inline] - pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { - self.skip_binder().auto_traits() - } - - pub fn iter<'a>( - &'a self, - ) -> impl DoubleEndedIterator>> + 'tcx { - self.skip_binder().iter().map(Binder::bind) - } -} - /// A complete reference to a trait. These take numerous guises in syntax, /// but perhaps the most recognizable form is in a where-clause: /// diff --git a/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs index 554ada1ab25..e1ec4cc5e97 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs @@ -74,7 +74,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List>, + predicates: &'tcx ty::List>>, ) -> Result { let mut first = true; for p in predicates { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4414bf57c6b..3b4249a93e1 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -184,8 +184,8 @@ where ty::Dynamic(predicates, ..) => { // All traits in the list are considered the "primary" part of the type // and are visited by shallow visitors. - for predicate in predicates.skip_binder() { - let trait_ref = match predicate { + for predicate in predicates { + let trait_ref = match predicate.skip_binder() { ty::ExistentialPredicate::Trait(trait_ref) => trait_ref, ty::ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx), ty::ExistentialPredicate::AutoTrait(def_id) => { diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index eba8e1a0613..6356a7e7832 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -222,7 +222,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List>, + predicates: &'tcx ty::List>>, ) -> Result { let mut first = true; for p in predicates { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index c28c2fecfbb..0294fb23c56 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -465,9 +465,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { ty::Dynamic(predicates, r) => { self.push("D"); - self = self.in_binder(&predicates, |cx, predicates| { - cx.print_dyn_existential(predicates) - })?; + self = self.print_dyn_existential(predicates)?; self = r.print(self)?; } @@ -486,26 +484,29 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List>, + predicates: &'tcx ty::List>>, ) -> Result { for predicate in predicates { - match predicate { - ty::ExistentialPredicate::Trait(trait_ref) => { - // Use a type that can't appear in defaults of type parameters. - let dummy_self = self.tcx.mk_ty_infer(ty::FreshTy(0)); - let trait_ref = trait_ref.with_self_ty(self.tcx, dummy_self); - self = self.print_def_path(trait_ref.def_id, trait_ref.substs)?; - } - ty::ExistentialPredicate::Projection(projection) => { - let name = self.tcx.associated_item(projection.item_def_id).ident; - self.push("p"); - self.push_ident(&name.as_str()); - self = projection.ty.print(self)?; - } - ty::ExistentialPredicate::AutoTrait(def_id) => { - self = self.print_def_path(def_id, &[])?; + self = self.in_binder(&predicate, |mut cx, predicate| { + match predicate { + ty::ExistentialPredicate::Trait(trait_ref) => { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = cx.tcx.mk_ty_infer(ty::FreshTy(0)); + let trait_ref = trait_ref.with_self_ty(cx.tcx, dummy_self); + cx = cx.print_def_path(trait_ref.def_id, trait_ref.substs)?; + } + ty::ExistentialPredicate::Projection(projection) => { + let name = cx.tcx.associated_item(projection.item_def_id).ident; + cx.push("p"); + cx.push_ident(&name.as_str()); + cx = projection.ty.print(cx)?; + } + ty::ExistentialPredicate::AutoTrait(def_id) => { + cx = cx.print_def_path(*def_id, &[])?; + } } - } + Ok(cx) + })?; } self.push("E"); Ok(self) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 1b5375938af..69f66f6e6b1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -219,8 +219,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } if let ty::Dynamic(traits, _) = self_ty.kind() { - for t in traits.skip_binder() { - if let ty::ExistentialPredicate::Trait(trait_ref) = t { + for t in traits.iter() { + if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() { flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id)))) } } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index d912a00d6b7..8b275db89f1 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -551,8 +551,9 @@ fn object_ty_for_trait<'tcx>( let trait_ref = ty::TraitRef::identity(tcx, trait_def_id); - let trait_predicate = - ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait( + ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref), + )); let mut associated_types = traits::supertraits(tcx, ty::Binder::dummy(trait_ref)) .flat_map(|super_trait_ref| { @@ -569,24 +570,19 @@ fn object_ty_for_trait<'tcx>( let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| { // We *can* get bound lifetimes here in cases like // `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`. - // - // binder moved to (*)... - let super_trait_ref = super_trait_ref.skip_binder(); - ty::ExistentialPredicate::Projection(ty::ExistentialProjection { - ty: tcx.mk_projection(item.def_id, super_trait_ref.substs), - item_def_id: item.def_id, - substs: super_trait_ref.substs, + super_trait_ref.map_bound(|super_trait_ref| { + ty::ExistentialPredicate::Projection(ty::ExistentialProjection { + ty: tcx.mk_projection(item.def_id, super_trait_ref.substs), + item_def_id: item.def_id, + substs: super_trait_ref.substs, + }) }) }); - let existential_predicates = - tcx.mk_existential_predicates(iter::once(trait_predicate).chain(projection_predicates)); + let existential_predicates = tcx + .mk_poly_existential_predicates(iter::once(trait_predicate).chain(projection_predicates)); - let object_ty = tcx.mk_dynamic( - // (*) ... binder re-introduced here - ty::Binder::bind(existential_predicates), - lifetime, - ); + let object_ty = tcx.mk_dynamic(existential_predicates, lifetime); debug!("object_ty_for_trait: object_ty=`{}`", object_ty); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a42c8021346..f873a6ceb60 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -375,24 +375,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty()); let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref); let data = match *self_ty.kind() { - ty::Dynamic(data, ..) => { - self.infcx - .replace_bound_vars_with_fresh_vars( - obligation.cause.span, - HigherRankedType, - data, - ) - .0 - } + ty::Dynamic(data, ..) => data, _ => span_bug!(obligation.cause.span, "object candidate with non-object"), }; - let object_trait_ref = data - .principal() - .unwrap_or_else(|| { - span_bug!(obligation.cause.span, "object candidate with no principal") - }) - .with_self_ty(self.tcx(), self_ty); + let object_trait_ref = data.principal().unwrap_or_else(|| { + span_bug!(obligation.cause.span, "object candidate with no principal") + }); + let object_trait_ref = self + .infcx + .replace_bound_vars_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + object_trait_ref, + ) + .0; + let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty); let mut nested = vec![]; @@ -711,15 +709,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Trait+Kx+'a -> Trait+Ky+'b (upcasts). (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { // See `assemble_candidates_for_unsizing` for more info. - let existential_predicates = data_a.map_bound(|data_a| { - let iter = data_a - .principal() - .map(ty::ExistentialPredicate::Trait) - .into_iter() - .chain(data_a.projection_bounds().map(ty::ExistentialPredicate::Projection)) - .chain(data_b.auto_traits().map(ty::ExistentialPredicate::AutoTrait)); - tcx.mk_existential_predicates(iter) - }); + let iter = data_a + .principal() + .map(|b| b.map_bound(ty::ExistentialPredicate::Trait)) + .into_iter() + .chain( + data_a + .projection_bounds() + .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)), + ) + .chain( + data_b + .auto_traits() + .map(ty::ExistentialPredicate::AutoTrait) + .map(ty::Binder::dummy), + ); + let existential_predicates = tcx.mk_poly_existential_predicates(iter); let source_trait = tcx.mk_dynamic(existential_predicates, r_b); // Require that the traits involved in this upcast are **equal**; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5bcb16d21e0..3f58fd72f40 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -706,7 +706,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { fn from_object_ty( &mut self, ty: Ty<'tcx>, - data: ty::Binder<&'tcx ty::List>>, + data: &'tcx ty::List>>, region: ty::Region<'tcx>, ) { // Imagine a type like this: @@ -769,7 +769,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// `infer::required_region_bounds`, see that for more information. pub fn object_region_bounds<'tcx>( tcx: TyCtxt<'tcx>, - existential_predicates: ty::Binder<&'tcx ty::List>>, + existential_predicates: &'tcx ty::List>>, ) -> Vec> { // Since we don't actually *know* the self type for an object, // this "open(err)" serves as a kind of dummy standin -- basically diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 9afb980f84d..3a747b09cd4 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -615,7 +615,7 @@ impl<'tcx> LowerInto<'tcx, Option LowerInto<'tcx, chalk_ir::Binders>>> - for Binder<&'tcx ty::List>> + for &'tcx ty::List>> { fn lower_into( self, @@ -627,48 +627,53 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders>]> // This means that any variables that are escaping `self` need to be // shifted in by one so that they are still escaping. - let shifted_predicates = ty::fold::shift_vars(interner.tcx, self, 1); + let predicates = ty::fold::shift_vars(interner.tcx, self, 1); - let (predicates, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, shifted_predicates); let self_ty = interner.tcx.mk_ty(ty::Bound( // This is going to be wrapped in a binder ty::DebruijnIndex::from_usize(1), ty::BoundTy { var: ty::BoundVar::from_usize(0), kind: ty::BoundTyKind::Anon }, )); - let where_clauses = predicates.into_iter().map(|predicate| match predicate { - ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => { - chalk_ir::Binders::new( + let where_clauses = predicates.into_iter().map(|predicate| { + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, predicate); + match predicate { + ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => { + chalk_ir::Binders::new( + binders.clone(), + chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { + trait_id: chalk_ir::TraitId(def_id), + substitution: interner + .tcx + .mk_substs_trait(self_ty, substs) + .lower_into(interner), + }), + ) + } + ty::ExistentialPredicate::Projection(predicate) => chalk_ir::Binders::new( + binders.clone(), + chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { + alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { + associated_ty_id: chalk_ir::AssocTypeId(predicate.item_def_id), + substitution: interner + .tcx + .mk_substs_trait(self_ty, predicate.substs) + .lower_into(interner), + }), + ty: predicate.ty.lower_into(interner), + }), + ), + ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( binders.clone(), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(def_id), substitution: interner .tcx - .mk_substs_trait(self_ty, substs) + .mk_substs_trait(self_ty, &[]) .lower_into(interner), }), - ) + ), } - ty::ExistentialPredicate::Projection(predicate) => chalk_ir::Binders::new( - binders.clone(), - chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { - alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(predicate.item_def_id), - substitution: interner - .tcx - .mk_substs_trait(self_ty, predicate.substs) - .lower_into(interner), - }), - ty: predicate.ty.lower_into(interner), - }), - ), - ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( - binders.clone(), - chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { - trait_id: chalk_ir::TraitId(def_id), - substitution: interner.tcx.mk_substs_trait(self_ty, &[]).lower_into(interner), - }), - ), }); // Binder for the bound variable representing the concrete underlying type. diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 7888cb1b9f5..693cd236299 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1254,22 +1254,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) }); - // Calling `skip_binder` is okay because the predicates are re-bound. - let regular_trait_predicates = existential_trait_refs - .map(|trait_ref| ty::ExistentialPredicate::Trait(trait_ref.skip_binder())); - let auto_trait_predicates = auto_traits - .into_iter() - .map(|trait_ref| ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id())); + let regular_trait_predicates = existential_trait_refs.map(|trait_ref| { + trait_ref.map_bound(|trait_ref| ty::ExistentialPredicate::Trait(trait_ref)) + }); + let auto_trait_predicates = auto_traits.into_iter().map(|trait_ref| { + ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id())) + }); let mut v = regular_trait_predicates .chain(auto_trait_predicates) .chain( existential_projections - .map(|x| ty::ExistentialPredicate::Projection(x.skip_binder())), + .map(|x| x.map_bound(|x| ty::ExistentialPredicate::Projection(x))), ) .collect::>(); - v.sort_by(|a, b| a.stable_cmp(tcx, b)); + v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); v.dedup(); - let existential_predicates = ty::Binder::bind(tcx.mk_existential_predicates(v.into_iter())); + let existential_predicates = tcx.mk_poly_existential_predicates(v.into_iter()); // Use explicitly-specified region bound. let region_bound = if !lifetime.is_elided() { @@ -2331,7 +2331,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn compute_object_lifetime_bound( &self, span: Span, - existential_predicates: ty::Binder<&'tcx ty::List>>, + existential_predicates: &'tcx ty::List>>, ) -> Option> // if None, use the default { let tcx = self.tcx(); diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 7ed2933c08b..369db87360b 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -619,8 +619,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(def, _) => bound_spans.push((def_span(def.did), msg)), // Point at the trait object that couldn't satisfy the bound. ty::Dynamic(preds, _) => { - for pred in preds.skip_binder() { - match pred { + for pred in preds.iter() { + match pred.skip_binder() { ty::ExistentialPredicate::Trait(tr) => { bound_spans.push((def_span(tr.def_id), msg.clone())) } @@ -673,9 +673,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .filter_map(|(pred, parent_pred)| { format_pred(*pred).map(|(p, self_ty)| match parent_pred { - None => format!("`{}`", p), + None => format!("`{}`", &p), Some(parent_pred) => match format_pred(*parent_pred) { - None => format!("`{}`", p), + None => format!("`{}`", &p), Some((parent_p, _)) => { collect_type_param_suggestions(self_ty, parent_pred, &p); format!("`{}`\nwhich is required by `{}`", p, parent_p) diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index 3a6b64c90e8..0deaee3a944 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -1449,8 +1449,8 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { false }, ty::Dynamic(binder, _) => { - for predicate in binder.skip_binder().iter() { - if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { + for predicate in binder.iter() { + if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() { if must_use_attr(&cx.tcx.get_attrs(trait_ref.def_id)).is_some() { return true; } -- cgit 1.4.1-3-g733a5 From 5c8de1cf4971e5800e2dd33393eef7ad7b8b78be Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Fri, 11 Dec 2020 17:32:03 +0100 Subject: use strip_prefix over slicing (clippy::manual_strip) --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 4 ++-- compiler/rustc_llvm/build.rs | 36 ++++++++++++++-------------- src/bootstrap/dist.rs | 2 +- src/librustdoc/html/markdown.rs | 4 ++-- 4 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index ec557b7a682..bf0d499e6c4 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -854,8 +854,8 @@ fn generic_simd_intrinsic( )); } - if name_str.starts_with("simd_shuffle") { - let n: u64 = name_str["simd_shuffle".len()..].parse().unwrap_or_else(|_| { + if let Some(stripped) = name_str.strip_prefix("simd_shuffle") { + let n: u64 = stripped.parse().unwrap_or_else(|_| { span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") }); diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 54b22ca49a2..621363bed80 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -201,10 +201,10 @@ fn main() { cmd.args(&components); for lib in output(&mut cmd).split_whitespace() { - let name = if lib.starts_with("-l") { - &lib[2..] - } else if lib.starts_with('-') { - &lib[1..] + let name = if let Some(stripped) = lib.strip_prefix("-l") { + stripped + } else if let Some(stripped) = lib.strip_prefix('-') { + stripped } else if Path::new(lib).exists() { // On MSVC llvm-config will print the full name to libraries, but // we're only interested in the name part @@ -241,17 +241,17 @@ fn main() { cmd.arg(llvm_link_arg).arg("--ldflags"); for lib in output(&mut cmd).split_whitespace() { if is_crossed { - if lib.starts_with("-LIBPATH:") { - println!("cargo:rustc-link-search=native={}", lib[9..].replace(&host, &target)); - } else if lib.starts_with("-L") { - println!("cargo:rustc-link-search=native={}", lib[2..].replace(&host, &target)); + if let Some(stripped) = lib.strip_prefix("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target)); + } else if let Some(stripped) = lib.strip_prefix("-L") { + println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target)); } - } else if lib.starts_with("-LIBPATH:") { - println!("cargo:rustc-link-search=native={}", &lib[9..]); - } else if lib.starts_with("-l") { - println!("cargo:rustc-link-lib={}", &lib[2..]); - } else if lib.starts_with("-L") { - println!("cargo:rustc-link-search=native={}", &lib[2..]); + } else if let Some(stripped) = lib.strip_prefix("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", stripped); + } else if let Some(stripped) = lib.strip_prefix("-l") { + println!("cargo:rustc-link-lib={}", stripped); + } else if let Some(stripped) = lib.strip_prefix("-L") { + println!("cargo:rustc-link-search=native={}", stripped); } } @@ -262,10 +262,10 @@ fn main() { let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS"); if let Some(s) = llvm_linker_flags { for lib in s.into_string().unwrap().split_whitespace() { - if lib.starts_with("-l") { - println!("cargo:rustc-link-lib={}", &lib[2..]); - } else if lib.starts_with("-L") { - println!("cargo:rustc-link-search=native={}", &lib[2..]); + if let Some(stripped) = lib.strip_prefix("-l") { + println!("cargo:rustc-link-lib={}", stripped); + } else if let Some(stripped) = lib.strip_prefix("-L") { + println!("cargo:rustc-link-search=native={}", stripped); } } } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 354be109cf2..360e51ed2bb 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1186,7 +1186,7 @@ pub fn sanitize_sh(path: &Path) -> String { return change_drive(unc_to_lfs(&path)).unwrap_or(path); fn unc_to_lfs(s: &str) -> &str { - if s.starts_with("//?/") { &s[4..] } else { s } + s.strip_prefix("//?/").unwrap_or(s) } fn change_drive(s: &str) -> Option { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index bdbb90837c7..22096203d4c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -139,9 +139,9 @@ fn map_line(s: &str) -> Line<'_> { let trimmed = s.trim(); if trimmed.starts_with("##") { Line::Shown(Cow::Owned(s.replacen("##", "#", 1))) - } else if trimmed.starts_with("# ") { + } else if let Some(stripped) = trimmed.strip_prefix("# ") { // # text - Line::Hidden(&trimmed[2..]) + Line::Hidden(&stripped) } else if trimmed == "#" { // We cannot handle '#text' because it could be #[attr]. Line::Hidden("") -- cgit 1.4.1-3-g733a5 From 82fe5c16622051a71a37c9c4909dd1f4e0857584 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Fri, 11 Dec 2020 17:40:59 +0100 Subject: don't convert types into identical types with .into() (clippy::useless_conversion) --- compiler/rustc_mir/src/transform/coverage/debug.rs | 4 ++-- src/librustdoc/passes/collect_intra_doc_links.rs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index af81d9af0e2..b66e37436a6 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -285,7 +285,7 @@ impl DebugCounters { ), }; counters - .insert(id.into(), DebugCounter::new(counter_kind.clone(), some_block_label)) + .insert(id, DebugCounter::new(counter_kind.clone(), some_block_label)) .expect_none( "attempt to add the same counter_kind to DebugCounters more than once", ); @@ -340,7 +340,7 @@ impl DebugCounters { if self.some_counters.is_some() && (counter_format.block || !counter_format.id) { let counters = self.some_counters.as_ref().unwrap(); if let Some(DebugCounter { some_block_label: Some(block_label), .. }) = - counters.get(&id.into()) + counters.get(&id) { return if counter_format.id { format!("{}#{}", block_label, id.index()) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5ce64c4cd83..d8d6f862921 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1012,7 +1012,6 @@ impl LinkCollector<'_, '_> { } else { // This is a bug. debug!("attempting to resolve item without parent module: {}", path_str); - let err_kind = ResolutionFailure::NoParentItem.into(); resolution_failure( self, &item, @@ -1020,7 +1019,7 @@ impl LinkCollector<'_, '_> { disambiguator, dox, link_range, - smallvec![err_kind], + smallvec![ResolutionFailure::NoParentItem], ); return None; }; -- cgit 1.4.1-3-g733a5 From db6c50998c929c9bab5ea2ffdddf5e0eef25d3c8 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Fri, 11 Dec 2020 17:49:00 +0100 Subject: don't clone types that are copy (clippy::clone_on_copy) --- compiler/rustc_mir/src/transform/early_otherwise_branch.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/confirmation.rs | 4 ++-- compiler/rustc_typeck/src/check/upvar.rs | 2 +- src/bootstrap/sanity.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index f91477911a4..0460ebe0c0d 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -217,7 +217,7 @@ impl<'a, 'tcx> Helper<'a, 'tcx> { // go through each target, finding a discriminant read, and a switch let results = discr.targets_with_values.iter().map(|(value, target)| { - self.find_discriminant_switch_pairing(&discr, target.clone(), value.clone()) + self.find_discriminant_switch_pairing(&discr, *target, *value) }); // if the optimization did not apply for one of the targets, then abort diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a42c8021346..ed22d5849e2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -447,7 +447,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); nested.push(Obligation::new( obligation.cause.clone(), - obligation.param_env.clone(), + obligation.param_env, normalized_super_trait, )); } @@ -485,7 +485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); nested.push(Obligation::new( obligation.cause.clone(), - obligation.param_env.clone(), + obligation.param_env, normalized_bound, )); } diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 019fa78fb1e..373f2307019 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -303,7 +303,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // upvar_capture_map only stores the UpvarCapture (CaptureKind), // so we create a fake capture info with no expression. let fake_capture_info = - ty::CaptureInfo { expr_id: None, capture_kind: capture_kind.clone() }; + ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind }; determine_capture_info(fake_capture_info, capture_info).capture_kind } else { capture_info.capture_kind diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 4cfcf6ca407..aafb71629ad 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -162,7 +162,7 @@ pub fn check(build: &mut Build) { build .config .target_config - .entry(target.clone()) + .entry(*target) .or_insert(Target::from_triple(&target.triple)); if target.contains("-none-") || target.contains("nvptx") { @@ -176,7 +176,7 @@ pub fn check(build: &mut Build) { // If this is a native target (host is also musl) and no musl-root is given, // fall back to the system toolchain in /usr before giving up if build.musl_root(*target).is_none() && build.config.build == *target { - let target = build.config.target_config.entry(target.clone()).or_default(); + let target = build.config.target_config.entry(*target).or_default(); target.musl_root = Some("/usr".into()); } match build.musl_libdir(*target) { -- cgit 1.4.1-3-g733a5 From b7795e135a642df024fc9bfee72abf7981c89ec8 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Fri, 11 Dec 2020 18:08:05 +0100 Subject: fix clippy::{needless_bool, manual_unwrap_or} --- .../src/transform/early_otherwise_branch.rs | 7 ++++--- compiler/rustc_session/src/session.rs | 5 +---- compiler/rustc_typeck/src/check/upvar.rs | 21 ++++++++++----------- compiler/rustc_typeck/src/collect.rs | 7 +------ src/bootstrap/sanity.rs | 6 +----- 5 files changed, 17 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index 0460ebe0c0d..6fbcc140978 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -216,9 +216,10 @@ impl<'a, 'tcx> Helper<'a, 'tcx> { let discr = self.find_switch_discriminant_info(bb, switch)?; // go through each target, finding a discriminant read, and a switch - let results = discr.targets_with_values.iter().map(|(value, target)| { - self.find_discriminant_switch_pairing(&discr, *target, *value) - }); + let results = discr + .targets_with_values + .iter() + .map(|(value, target)| self.find_discriminant_switch_pairing(&discr, *target, *value)); // if the optimization did not apply for one of the targets, then abort if results.clone().any(|x| x.is_none()) || results.len() == 0 { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 4e269f3172c..75faab12e3e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1109,10 +1109,7 @@ impl Session { } pub fn link_dead_code(&self) -> bool { - match self.opts.cg.link_dead_code { - Some(explicitly_set) => explicitly_set, - None => false, - } + self.opts.cg.link_dead_code.unwrap_or(false) } pub fn mark_attr_known(&self, attr: &Attribute) { diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 373f2307019..1b04351018a 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -297,17 +297,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_captures.insert(*var_hir_id, upvar_id); - let new_capture_kind = if let Some(capture_kind) = - upvar_capture_map.get(&upvar_id) - { - // upvar_capture_map only stores the UpvarCapture (CaptureKind), - // so we create a fake capture info with no expression. - let fake_capture_info = - ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind }; - determine_capture_info(fake_capture_info, capture_info).capture_kind - } else { - capture_info.capture_kind - }; + let new_capture_kind = + if let Some(capture_kind) = upvar_capture_map.get(&upvar_id) { + // upvar_capture_map only stores the UpvarCapture (CaptureKind), + // so we create a fake capture info with no expression. + let fake_capture_info = + ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind }; + determine_capture_info(fake_capture_info, capture_info).capture_kind + } else { + capture_info.capture_kind + }; upvar_capture_map.insert(upvar_id, new_capture_kind); } } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 38da1e5ea03..c70554cc627 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2141,13 +2141,8 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // * It must be an associated type for this trait (*not* a // supertrait). if let ty::Projection(projection) = ty.kind() { - if projection.substs == trait_identity_substs + projection.substs == trait_identity_substs && tcx.associated_item(projection.item_def_id).container.id() == def_id - { - true - } else { - false - } } else { false } diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index aafb71629ad..85b4a73439d 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -159,11 +159,7 @@ pub fn check(build: &mut Build) { panic!("the iOS target is only supported on macOS"); } - build - .config - .target_config - .entry(*target) - .or_insert(Target::from_triple(&target.triple)); + build.config.target_config.entry(*target).or_insert(Target::from_triple(&target.triple)); if target.contains("-none-") || target.contains("nvptx") { if build.no_std(*target) == Some(false) { -- cgit 1.4.1-3-g733a5 From af6aa9f4313983deddd64543c5ad6c15e2160163 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 11 Dec 2020 22:36:51 -0500 Subject: Pass Session into renderer --- src/librustdoc/formats/renderer.rs | 6 +++++- src/librustdoc/html/render/mod.rs | 5 +++++ src/librustdoc/json/mod.rs | 3 +++ src/librustdoc/lib.rs | 11 ++++++++--- 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index d0fdc69cc19..6334524eb1c 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -1,5 +1,7 @@ use std::sync::Arc; +use rustc_data_structures::sync::Lrc; +use rustc_session::Session; use rustc_span::edition::Edition; use crate::clean; @@ -19,6 +21,7 @@ crate trait FormatRenderer: Clone { render_info: RenderInfo, edition: Edition, cache: &mut Cache, + sess: Lrc, ) -> Result<(Self, clean::Crate), Error>; /// Renders a single non-module item. This means no recursive sub-item rendering is required. @@ -49,6 +52,7 @@ crate fn run_format( render_info: RenderInfo, diag: &rustc_errors::Handler, edition: Edition, + sess: Lrc, ) -> Result<(), Error> { let (krate, mut cache) = Cache::from_krate( render_info.clone(), @@ -59,7 +63,7 @@ crate fn run_format( ); let (mut format_renderer, mut krate) = - T::init(krate, options, render_info, edition, &mut cache)?; + T::init(krate, options, render_info, edition, &mut cache, sess)?; let cache = Arc::new(cache); // Freeze the cache now that the index has been built. Put an Arc into TLS for future diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 901f00b21da..ff8fd208eea 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -52,10 +52,12 @@ use rustc_ast_pretty::pprust; use rustc_attr::StabilityLevel; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Mutability; use rustc_middle::middle::stability; +use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::FileName; @@ -101,6 +103,7 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { /// rustdoc tree). #[derive(Clone)] crate struct Context { + crate sess: Lrc, /// Current hierarchy of components leading down to what's currently being /// rendered crate current: Vec, @@ -383,6 +386,7 @@ impl FormatRenderer for Context { _render_info: RenderInfo, edition: Edition, cache: &mut Cache, + sess: Lrc, ) -> Result<(Context, clean::Crate), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); @@ -494,6 +498,7 @@ impl FormatRenderer for Context { let cache = Arc::new(cache); let mut cx = Context { + sess, current: Vec::new(), dst, render_redirect_pages: false, diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 5f640bfddf1..884c4c72533 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -13,6 +13,8 @@ use std::path::PathBuf; use std::rc::Rc; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lrc; +use rustc_session::Session; use rustc_span::edition::Edition; use crate::clean; @@ -124,6 +126,7 @@ impl FormatRenderer for JsonRenderer { _render_info: RenderInfo, _edition: Edition, _cache: &mut Cache, + _sess: Lrc, ) -> Result<(Self, clean::Crate), Error> { debug!("Initializing json renderer"); Ok(( diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 26bf4b569ff..fbab5735ee7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -61,9 +61,11 @@ use std::default::Default; use std::env; use std::process; +use rustc_data_structures::sync::Lrc; use rustc_errors::ErrorReported; use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; use rustc_session::getopts; +use rustc_session::Session; use rustc_session::{early_error, early_warn}; #[macro_use] @@ -483,8 +485,9 @@ fn run_renderer( render_info: config::RenderInfo, diag: &rustc_errors::Handler, edition: rustc_span::edition::Edition, + sess: Lrc, ) -> MainResult { - match formats::run_format::(krate, renderopts, render_info, &diag, edition) { + match formats::run_format::(krate, renderopts, render_info, &diag, edition, sess) { Ok(_) => Ok(()), Err(e) => { let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error)); @@ -554,10 +557,12 @@ fn main_options(options: config::Options) -> MainResult { let diag = core::new_handler(error_format, None, &debugging_options); match output_format { None | Some(config::OutputFormat::Html) => sess.time("render_html", || { - run_renderer::(krate, renderopts, renderinfo, &diag, edition) + run_renderer::( + krate, renderopts, renderinfo, &diag, edition, sess, + ) }), Some(config::OutputFormat::Json) => sess.time("render_json", || { - run_renderer::(krate, renderopts, renderinfo, &diag, edition) + run_renderer::(krate, renderopts, renderinfo, &diag, edition, sess) }), } } -- cgit 1.4.1-3-g733a5 From 4fa95b3a078f261267293f3308dd62889167c0bd Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 11 Dec 2020 23:01:26 -0500 Subject: Calculate span info on-demand instead of ahead of time This should *vastly* reduce memory usage. --- src/librustdoc/clean/mod.rs | 24 ++------------- src/librustdoc/clean/types.rs | 41 ++++++++++++++----------- src/librustdoc/html/render/mod.rs | 25 ++++++++------- src/librustdoc/html/sources.rs | 17 +++++++--- src/librustdoc/json/conversions.rs | 11 ++++--- src/librustdoc/lib.rs | 5 +-- src/librustdoc/passes/calculate_doc_coverage.rs | 15 ++++----- 7 files changed, 69 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 16274430902..a21e9d9820c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -25,7 +25,7 @@ use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt}; use rustc_mir::const_eval::{is_const_fn, is_min_const_fn, is_unstable_const_fn}; use rustc_span::hygiene::{AstPass, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{self, ExpnKind, Pos}; +use rustc_span::{self, ExpnKind}; use rustc_typeck::hir_ty_to_ty; use std::collections::hash_map::Entry; @@ -1881,29 +1881,11 @@ impl Clean for hir::VariantData<'_> { } impl Clean for rustc_span::Span { - fn clean(&self, cx: &DocContext<'_>) -> Span { - if self.is_dummy() { - return Span::empty(); - } - + fn clean(&self, _cx: &DocContext<'_>) -> Span { // Get the macro invocation instead of the definition, // in case the span is result of a macro expansion. // (See rust-lang/rust#39726) - let span = self.source_callsite(); - - let sm = cx.sess().source_map(); - let filename = sm.span_to_filename(span); - let lo = sm.lookup_char_pos(span.lo()); - let hi = sm.lookup_char_pos(span.hi()); - Span { - filename, - cnum: lo.file.cnum, - loline: lo.line, - locol: lo.col.to_usize(), - hiline: hi.line, - hicol: hi.col.to_usize(), - original: span, - } + Span { original: self.source_callsite() } } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index d4796b7ed66..a8626af8832 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -17,15 +17,16 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_feature::UnstableFeatures; use rustc_hir as hir; use rustc_hir::def::Res; -use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::Mutability; use rustc_index::vec::IndexVec; use rustc_middle::ty::{AssocKind, TyCtxt}; +use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; use rustc_span::symbol::{kw, sym, Ident, Symbol, SymbolStr}; -use rustc_span::{self, FileName}; +use rustc_span::{self, FileName, Loc}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; @@ -1609,33 +1610,37 @@ crate enum VariantKind { Struct(VariantStruct), } +/// Small wrapper around `rustc_span::Span` that adds helper methods. #[derive(Clone, Debug)] crate struct Span { - crate filename: FileName, - crate cnum: CrateNum, - crate loline: usize, - crate locol: usize, - crate hiline: usize, - crate hicol: usize, crate original: rustc_span::Span, } impl Span { - crate fn empty() -> Span { - Span { - filename: FileName::Anon(0), - cnum: LOCAL_CRATE, - loline: 0, - locol: 0, - hiline: 0, - hicol: 0, - original: rustc_span::DUMMY_SP, - } + crate fn empty() -> Self { + Self { original: rustc_span::DUMMY_SP } } crate fn span(&self) -> rustc_span::Span { self.original } + + crate fn filename(&self, sess: &Session) -> FileName { + sess.source_map().span_to_filename(self.original) + } + + crate fn lo(&self, sess: &Session) -> Loc { + sess.source_map().lookup_char_pos(self.original.lo()) + } + + crate fn hi(&self, sess: &Session) -> Loc { + sess.source_map().lookup_char_pos(self.original.hi()) + } + + crate fn cnum(&self, sess: &Session) -> CrateNum { + // FIXME: is there a time when the lo and hi crate would be different? + self.lo(sess).file.cnum + } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index ff8fd208eea..b91f1a6c0e3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -103,7 +103,6 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { /// rustdoc tree). #[derive(Clone)] crate struct Context { - crate sess: Lrc, /// Current hierarchy of components leading down to what's currently being /// rendered crate current: Vec, @@ -124,6 +123,7 @@ crate struct Context { } crate struct SharedContext { + crate sess: Lrc, /// The path to the crate root source minus the file name. /// Used for simplifying paths to the highlighted source code files. crate src_root: PathBuf, @@ -176,6 +176,10 @@ impl Context { let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext,); self.dst.join(&filename) } + + fn sess(&self) -> &Session { + &self.shared.sess + } } impl SharedContext { @@ -459,6 +463,7 @@ impl FormatRenderer for Context { } let (sender, receiver) = channel(); let mut scx = SharedContext { + sess, collapsed: krate.collapsed, src_root, include_sources, @@ -498,7 +503,6 @@ impl FormatRenderer for Context { let cache = Arc::new(cache); let mut cx = Context { - sess, current: Vec::new(), dst, render_redirect_pages: false, @@ -1636,24 +1640,24 @@ impl Context { /// of their crate documentation isn't known. fn src_href(&self, item: &clean::Item, cache: &Cache) -> Option { let mut root = self.root_path(); - let mut path = String::new(); + let cnum = item.source.cnum(self.sess()); // We can safely ignore synthetic `SourceFile`s. - let file = match item.source.filename { + let file = match item.source.filename(self.sess()) { FileName::Real(ref path) => path.local_path().to_path_buf(), _ => return None, }; let file = &file; - let (krate, path) = if item.source.cnum == LOCAL_CRATE { + let (krate, path) = if cnum == LOCAL_CRATE { if let Some(path) = self.shared.local_sources.get(file) { (&self.shared.layout.krate, path) } else { return None; } } else { - let (krate, src_root) = match *cache.extern_locations.get(&item.source.cnum)? { + let (krate, src_root) = match *cache.extern_locations.get(&cnum)? { (ref name, ref src, ExternalLocation::Local) => (name, src), (ref name, ref src, ExternalLocation::Remote(ref s)) => { root = s.to_string(); @@ -1672,11 +1676,10 @@ impl Context { (krate, &path) }; - let lines = if item.source.loline == item.source.hiline { - item.source.loline.to_string() - } else { - format!("{}-{}", item.source.loline, item.source.hiline) - }; + let loline = item.source.lo(self.sess()).line; + let hiline = item.source.hi(self.sess()).line; + let lines = + if loline == hiline { loline.to_string() } else { format!("{}-{}", loline, hiline) }; Some(format!( "{root}src/{krate}/{path}#{lines}", root = Escape(&root), diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index e7b5a90d84d..ef9e9f350fb 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -7,6 +7,7 @@ use crate::html::highlight; use crate::html::layout; use crate::html::render::{SharedContext, BASIC_KEYWORDS}; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_session::Session; use rustc_span::source_map::FileName; use std::ffi::OsStr; use std::fs; @@ -34,37 +35,45 @@ struct SourceCollector<'a> { impl<'a> DocFolder for SourceCollector<'a> { fn fold_item(&mut self, item: clean::Item) -> Option { + // If we're not rendering sources, there's nothing to do. // If we're including source files, and we haven't seen this file yet, // then we need to render it out to the filesystem. if self.scx.include_sources // skip all synthetic "files" - && item.source.filename.is_real() + && item.source.filename(self.sess()).is_real() // skip non-local files - && item.source.cnum == LOCAL_CRATE + && item.source.cnum(self.sess()) == LOCAL_CRATE { + let filename = item.source.filename(self.sess()); // If it turns out that we couldn't read this file, then we probably // can't read any of the files (generating html output from json or // something like that), so just don't include sources for the // entire crate. The other option is maintaining this mapping on a // per-file basis, but that's probably not worth it... - self.scx.include_sources = match self.emit_source(&item.source.filename) { + self.scx.include_sources = match self.emit_source(&filename) { Ok(()) => true, Err(e) => { println!( "warning: source code was requested to be rendered, \ but processing `{}` had an error: {}", - item.source.filename, e + filename, e ); println!(" skipping rendering of source code"); false } }; } + // FIXME: if `include_sources` isn't set and DocFolder didn't require consuming the crate by value, + // we could return None here without having to walk the rest of the crate. Some(self.fold_item_recur(item)) } } impl<'a> SourceCollector<'a> { + fn sess(&self) -> &Session { + &self.scx.sess + } + /// Renders the given filename into its corresponding HTML source file. fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> { let p = match *filename { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index afb8dfa6766..9ae0a16ac35 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -56,9 +56,12 @@ impl From for Option { } impl From for Option { + #[allow(unreachable_code)] fn from(span: clean::Span) -> Self { - let clean::Span { loline, locol, hiline, hicol, .. } = span; - match span.filename { + // TODO: this should actually work + // Unfortunately this requires rethinking the whole framework, + // since this now needs a context and not just .into(). + match span.filename(todo!()) { rustc_span::FileName::Real(name) => Some(Span { filename: match name { rustc_span::RealFileName::Named(path) => path, @@ -66,8 +69,8 @@ impl From for Option { local_path } }, - begin: (loline, locol), - end: (hiline, hicol), + begin: todo!(), + end: todo!(), }), _ => None, } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index fbab5735ee7..e094ead12bd 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -555,13 +555,14 @@ fn main_options(options: config::Options) -> MainResult { info!("going to format"); let (error_format, edition, debugging_options) = diag_opts; let diag = core::new_handler(error_format, None, &debugging_options); + let sess_time = sess.clone(); match output_format { - None | Some(config::OutputFormat::Html) => sess.time("render_html", || { + None | Some(config::OutputFormat::Html) => sess_time.time("render_html", || { run_renderer::( krate, renderopts, renderinfo, &diag, edition, sess, ) }), - Some(config::OutputFormat::Json) => sess.time("render_json", || { + Some(config::OutputFormat::Json) => sess_time.time("render_json", || { run_renderer::(krate, renderopts, renderinfo, &diag, edition, sess) }), } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 3f9978c8fca..52f6a97089b 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -216,13 +216,9 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { return Some(i); } clean::ImplItem(ref impl_) => { + let filename = i.source.filename(self.ctx.sess()); if let Some(ref tr) = impl_.trait_ { - debug!( - "impl {:#} for {:#} in {}", - tr.print(), - impl_.for_.print(), - i.source.filename - ); + debug!("impl {:#} for {:#} in {}", tr.print(), impl_.for_.print(), filename,); // don't count trait impls, the missing-docs lint doesn't so we shouldn't // either @@ -231,7 +227,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { // inherent impls *can* be documented, and those docs show up, but in most // cases it doesn't make sense, as all methods on a type are in one single // impl block - debug!("impl {:#} in {}", impl_.for_.print(), i.source.filename); + debug!("impl {:#} in {}", impl_.for_.print(), filename); } } _ => { @@ -251,6 +247,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { None, ); + let filename = i.source.filename(self.ctx.sess()); let has_doc_example = tests.found_tests != 0; let hir_id = self.ctx.tcx.hir().local_def_id_to_hir_id(i.def_id.expect_local()); let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id); @@ -258,8 +255,8 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { // unless the user had an explicit `allow` let should_have_docs = level != lint::Level::Allow || matches!(source, LintSource::Default); - debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename); - self.items.entry(i.source.filename.clone()).or_default().count_item( + debug!("counting {:?} {:?} in {}", i.type_(), i.name, filename); + self.items.entry(filename).or_default().count_item( has_docs, has_doc_example, should_have_doc_example(self.ctx, &i), -- cgit 1.4.1-3-g733a5 From 0e574fb39ad99a7ffbfd7f2d52603d890dfa2084 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 11 Dec 2020 23:57:18 -0500 Subject: Fix the JSON backend This was simpler than expected. --- src/librustdoc/json/conversions.rs | 42 +++++++++++++++++++------------------- src/librustdoc/json/mod.rs | 6 ++++-- 2 files changed, 25 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 9ae0a16ac35..c463481db86 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -6,14 +6,16 @@ use std::convert::From; use rustc_ast::ast; use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_span::Pos; use crate::clean; use crate::doctree; use crate::formats::item_type::ItemType; use crate::json::types::*; +use crate::json::JsonRenderer; -impl From for Option { - fn from(item: clean::Item) -> Self { +impl JsonRenderer { + pub(super) fn convert_item(&self, item: clean::Item) -> Option { let item_type = ItemType::from(&item); let clean::Item { source, @@ -32,7 +34,7 @@ impl From for Option { id: def_id.into(), crate_id: def_id.krate.as_u32(), name, - source: source.into(), + source: self.convert_span(source), visibility: visibility.into(), docs: attrs.collapsed_doc_value().unwrap_or_default(), links: attrs @@ -53,25 +55,23 @@ impl From for Option { }), } } -} -impl From for Option { - #[allow(unreachable_code)] - fn from(span: clean::Span) -> Self { - // TODO: this should actually work - // Unfortunately this requires rethinking the whole framework, - // since this now needs a context and not just .into(). - match span.filename(todo!()) { - rustc_span::FileName::Real(name) => Some(Span { - filename: match name { - rustc_span::RealFileName::Named(path) => path, - rustc_span::RealFileName::Devirtualized { local_path, virtual_name: _ } => { - local_path - } - }, - begin: todo!(), - end: todo!(), - }), + fn convert_span(&self, span: clean::Span) -> Option { + match span.filename(&self.sess) { + rustc_span::FileName::Real(name) => { + let hi = span.hi(&self.sess); + let lo = span.lo(&self.sess); + Some(Span { + filename: match name { + rustc_span::RealFileName::Named(path) => path, + rustc_span::RealFileName::Devirtualized { local_path, virtual_name: _ } => { + local_path + } + }, + begin: (lo.line, lo.col.to_usize()), + end: (hi.line, hi.col.to_usize()), + }) + } _ => None, } } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 884c4c72533..5c5239d1b6a 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -26,6 +26,7 @@ use crate::html::render::cache::ExternalLocation; #[derive(Clone)] crate struct JsonRenderer { + sess: Lrc, /// A mapping of IDs that contains all local items for this crate which gets output as a top /// level field of the JSON blob. index: Rc>>, @@ -126,11 +127,12 @@ impl FormatRenderer for JsonRenderer { _render_info: RenderInfo, _edition: Edition, _cache: &mut Cache, - _sess: Lrc, + sess: Lrc, ) -> Result<(Self, clean::Crate), Error> { debug!("Initializing json renderer"); Ok(( JsonRenderer { + sess, index: Rc::new(RefCell::new(FxHashMap::default())), out_path: options.output, }, @@ -146,7 +148,7 @@ impl FormatRenderer for JsonRenderer { item.kind.inner_items().for_each(|i| self.item(i.clone(), cache).unwrap()); let id = item.def_id; - if let Some(mut new_item) = item.into(): Option { + if let Some(mut new_item) = self.convert_item(item) { if let types::ItemEnum::TraitItem(ref mut t) = new_item.inner { t.implementors = self.get_trait_implementors(id, cache) } else if let types::ItemEnum::StructItem(ref mut s) = new_item.inner { -- cgit 1.4.1-3-g733a5 From eb963ffe451bfbc001ea86712a94619903bfbaf8 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Fri, 11 Dec 2020 18:28:37 -0800 Subject: Fixes reported bugs in Rust Coverage Fixes: #79569 Fixes: #79566 Fixes: #79565 For the first issue (#79569), I got hit a `debug_assert!()` before encountering the reported error message (because I have `debug = true` enabled in my config.toml). The assertion showed me that some `SwitchInt`s can have more than one target pointing to the same `BasicBlock`. I had thought that was invalid, but since it seems to be possible, I'm allowing this now. I added a new test for this. ---- In the last two cases above, both tests (intentionally) fail to compile, but the `InstrumentCoverage` pass is invoked anyway. The MIR starts with an `Unreachable` `BasicBlock`, which I hadn't encountered before. (I had assumed the `InstrumentCoverage` pass would only be invoked with MIRs from successful compilations.) I don't have test infrastructure set up to test coverage on files that fail to compile, so I didn't add a new test. --- compiler/rustc_mir/src/transform/coverage/graph.rs | 28 ++- compiler/rustc_mir/src/transform/coverage/mod.rs | 8 + .../expected_export_coverage.match_or_pattern.json | 59 +++++ .../expected_show_coverage.match_or_pattern.txt | 50 ++++ .../expected_show_coverage_counters.async.txt | 12 +- ...ted_show_coverage_counters.match_or_pattern.txt | 98 ++++++++ ..._pattern.main.-------.InstrumentCoverage.0.html | 271 +++++++++++++++++++++ .../run-make-fulldeps/coverage/match_or_pattern.rs | 45 ++++ 8 files changed, 553 insertions(+), 18 deletions(-) create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage/match_or_pattern.rs (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/coverage/graph.rs b/compiler/rustc_mir/src/transform/coverage/graph.rs index 2408a999c05..b1a1bb957e7 100644 --- a/compiler/rustc_mir/src/transform/coverage/graph.rs +++ b/compiler/rustc_mir/src/transform/coverage/graph.rs @@ -32,24 +32,28 @@ impl CoverageGraph { // Pre-transform MIR `BasicBlock` successors and predecessors into the BasicCoverageBlock // equivalents. Note that since the BasicCoverageBlock graph has been fully simplified, the - // each predecessor of a BCB leader_bb should be in a unique BCB, and each successor of a - // BCB last_bb should be in its own unique BCB. Therefore, collecting the BCBs using - // `bb_to_bcb` should work without requiring a deduplication step. + // each predecessor of a BCB leader_bb should be in a unique BCB. It is possible for a + // `SwitchInt` to have multiple targets to the same destination `BasicBlock`, so + // de-duplication is required. This is done without reordering the successors. + let bcbs_len = bcbs.len(); + let mut seen = IndexVec::from_elem_n(false, bcbs_len); let successors = IndexVec::from_fn_n( |bcb| { + for b in seen.iter_mut() { + *b = false; + } let bcb_data = &bcbs[bcb]; - let bcb_successors = + let mut bcb_successors = Vec::new(); + for successor in bcb_filtered_successors(&mir_body, &bcb_data.terminator(mir_body).kind) .filter_map(|&successor_bb| bb_to_bcb[successor_bb]) - .collect::>(); - debug_assert!({ - let mut sorted = bcb_successors.clone(); - sorted.sort_unstable(); - let initial_len = sorted.len(); - sorted.dedup(); - sorted.len() == initial_len - }); + { + if !seen[successor] { + seen[successor] = true; + bcb_successors.push(successor); + } + } bcb_successors }, bcbs.len(), diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index f69748db238..53f7c28ee35 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -78,6 +78,14 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage { return; } + match mir_body.basic_blocks()[mir::START_BLOCK].terminator().kind { + TerminatorKind::Unreachable => { + trace!("InstrumentCoverage skipped for unreachable `START_BLOCK`"); + return; + } + _ => {} + } + trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); Instrumentor::new(&self.name(), tcx, mir_body).inject_counters(); trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json new file mode 100644 index 00000000000..8559fc84aa9 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/match_or_pattern.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 37, + "covered": 33, + "percent": 89.1891891891892 + }, + "regions": { + "count": 25, + "covered": 17, + "notcovered": 8, + "percent": 68 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 37, + "covered": 33, + "percent": 89.1891891891892 + }, + "regions": { + "count": 25, + "covered": 17, + "notcovered": 8, + "percent": 68 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt new file mode 100644 index 00000000000..a0fccb24f99 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt @@ -0,0 +1,50 @@ + 1| |#![feature(or_patterns)] + 2| | + 3| 1|fn main() { + 4| 1| // Initialize test constants in a way that cannot be determined at compile time, to ensure + 5| 1| // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + 6| 1| // dependent conditions. + 7| 1| let is_true = std::env::args().len() == 1; + 8| 1| + 9| 1| let mut a: u8 = 0; + 10| 1| let mut b: u8 = 0; + 11| 1| if is_true { + 12| 1| a = 2; + 13| 1| b = 0; + 14| 1| } + ^0 + 15| 1| match (a, b) { + 16| | // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`. + 17| | // This test confirms a fix for Issue #79569. + 18| 0| (0 | 1, 2 | 3) => {} + 19| 1| _ => {} + 20| | } + 21| 1| if is_true { + 22| 1| a = 0; + 23| 1| b = 0; + 24| 1| } + ^0 + 25| 1| match (a, b) { + 26| 0| (0 | 1, 2 | 3) => {} + 27| 1| _ => {} + 28| | } + 29| 1| if is_true { + 30| 1| a = 2; + 31| 1| b = 2; + 32| 1| } + ^0 + 33| 1| match (a, b) { + 34| 0| (0 | 1, 2 | 3) => {} + 35| 1| _ => {} + 36| | } + 37| 1| if is_true { + 38| 1| a = 0; + 39| 1| b = 2; + 40| 1| } + ^0 + 41| 1| match (a, b) { + 42| 1| (0 | 1, 2 | 3) => {} + 43| 0| _ => {} + 44| | } + 45| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt index ed91e8898ee..4df0bac8c86 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt @@ -28,11 +28,8 @@ Counter in file 0 79:14 -> 79:16, 0 Counter in file 0 81:1 -> 81:2, 0 Counter in file 0 91:25 -> 91:34, 0 Counter in file 0 5:1 -> 5:25, #1 -Counter in file 0 5:25 -> 6:14, #1 -Counter in file 0 7:9 -> 7:10, #2 -Counter in file 0 9:9 -> 9:10, (#1 - #2) -Counter in file 0 11:1 -> 11:2, (#2 + (#1 - #2)) Counter in file 0 21:1 -> 21:23, #1 +Counter in file 0 17:20 -> 17:21, #1 Counter in file 0 67:5 -> 67:23, #1 Counter in file 0 38:1 -> 38:19, #1 Counter in file 0 38:19 -> 42:12, #1 @@ -46,14 +43,18 @@ Counter in file 0 44:27 -> 44:32, #8 Counter in file 0 44:36 -> 44:38, (#6 + 0) Counter in file 0 45:14 -> 45:16, #7 Counter in file 0 47:1 -> 47:2, (#5 + (#6 + #7)) +Counter in file 0 13:20 -> 13:21, #1 Counter in file 0 29:1 -> 29:22, #1 Counter in file 0 93:1 -> 101:2, #1 Counter in file 0 91:1 -> 91:25, #1 +Counter in file 0 5:25 -> 6:14, #1 +Counter in file 0 7:9 -> 7:10, #2 +Counter in file 0 9:9 -> 9:10, (#1 - #2) +Counter in file 0 11:1 -> 11:2, (#2 + (#1 - #2)) Counter in file 0 51:5 -> 52:18, #1 Counter in file 0 53:13 -> 53:14, #2 Counter in file 0 63:13 -> 63:14, (#1 - #2) Counter in file 0 65:5 -> 65:6, (#2 + (#1 - #2)) -Counter in file 0 17:20 -> 17:21, #1 Counter in file 0 49:1 -> 68:12, #1 Counter in file 0 69:9 -> 69:10, #2 Counter in file 0 69:14 -> 69:27, (#1 + 0) @@ -70,7 +71,6 @@ Counter in file 0 87:14 -> 87:16, #3 Counter in file 0 89:1 -> 89:2, (#3 + (#2 + (#1 - (#3 + #2)))) Counter in file 0 17:1 -> 17:20, #1 Counter in file 0 66:5 -> 66:23, #1 -Counter in file 0 13:20 -> 13:21, #1 Counter in file 0 17:9 -> 17:10, #1 Counter in file 0 17:9 -> 17:10, #1 Counter in file 0 117:17 -> 117:19, #1 diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt new file mode 100644 index 00000000000..fc12612ce7d --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt @@ -0,0 +1,98 @@ +Counter in file 0 3:1 -> 11:15, #1 +Counter in file 0 11:16 -> 14:6, #2 +Counter in file 0 14:6 -> 14:7, (#1 - #2) +Counter in file 0 15:11 -> 15:17, (#2 + (#1 - #2)) +Counter in file 0 18:27 -> 18:29, #5 +Counter in file 0 19:14 -> 19:16, (#3 + #4) +Counter in file 0 21:8 -> 21:15, ((#3 + #4) + #5) +Counter in file 0 21:16 -> 24:6, #6 +Counter in file 0 24:6 -> 24:7, (((#3 + #4) + #5) - #6) +Counter in file 0 25:11 -> 25:17, (#6 + (((#3 + #4) + #5) - #6)) +Counter in file 0 26:27 -> 26:29, #9 +Counter in file 0 27:14 -> 27:16, (#7 + #8) +Counter in file 0 29:8 -> 29:15, ((#7 + #8) + #9) +Counter in file 0 29:16 -> 32:6, #10 +Counter in file 0 32:6 -> 32:7, (((#7 + #8) + #9) - #10) +Counter in file 0 33:11 -> 33:17, (#10 + (((#7 + #8) + #9) - #10)) +Counter in file 0 34:27 -> 34:29, #13 +Counter in file 0 35:14 -> 35:16, (#11 + #12) +Counter in file 0 37:8 -> 37:15, ((#11 + #12) + #13) +Counter in file 0 37:16 -> 40:6, #14 +Counter in file 0 40:6 -> 40:7, (((#11 + #12) + #13) - #14) +Counter in file 0 41:11 -> 41:17, (#14 + (((#11 + #12) + #13) - #14)) +Counter in file 0 42:27 -> 42:29, #17 +Counter in file 0 43:14 -> 43:16, (#15 + #16) +Counter in file 0 45:1 -> 45:2, ((#15 + #16) + #17) +Emitting segments for file: ../coverage/match_or_pattern.rs +Combined regions: + 3:1 -> 11:15 (count=1) + 11:16 -> 14:6 (count=1) + 14:6 -> 14:7 (count=0) + 15:11 -> 15:17 (count=1) + 18:27 -> 18:29 (count=0) + 19:14 -> 19:16 (count=1) + 21:8 -> 21:15 (count=1) + 21:16 -> 24:6 (count=1) + 24:6 -> 24:7 (count=0) + 25:11 -> 25:17 (count=1) + 26:27 -> 26:29 (count=0) + 27:14 -> 27:16 (count=1) + 29:8 -> 29:15 (count=1) + 29:16 -> 32:6 (count=1) + 32:6 -> 32:7 (count=0) + 33:11 -> 33:17 (count=1) + 34:27 -> 34:29 (count=0) + 35:14 -> 35:16 (count=1) + 37:8 -> 37:15 (count=1) + 37:16 -> 40:6 (count=1) + 40:6 -> 40:7 (count=0) + 41:11 -> 41:17 (count=1) + 42:27 -> 42:29 (count=1) + 43:14 -> 43:16 (count=0) + 45:1 -> 45:2 (count=1) +Segment at 3:1 (count = 1), RegionEntry +Segment at 11:15 (count = 0), Skipped +Segment at 11:16 (count = 1), RegionEntry +Segment at 14:6 (count = 0), RegionEntry +Segment at 14:7 (count = 0), Skipped +Segment at 15:11 (count = 1), RegionEntry +Segment at 15:17 (count = 0), Skipped +Segment at 18:27 (count = 0), RegionEntry +Segment at 18:29 (count = 0), Skipped +Segment at 19:14 (count = 1), RegionEntry +Segment at 19:16 (count = 0), Skipped +Segment at 21:8 (count = 1), RegionEntry +Segment at 21:15 (count = 0), Skipped +Segment at 21:16 (count = 1), RegionEntry +Segment at 24:6 (count = 0), RegionEntry +Segment at 24:7 (count = 0), Skipped +Segment at 25:11 (count = 1), RegionEntry +Segment at 25:17 (count = 0), Skipped +Segment at 26:27 (count = 0), RegionEntry +Segment at 26:29 (count = 0), Skipped +Segment at 27:14 (count = 1), RegionEntry +Segment at 27:16 (count = 0), Skipped +Segment at 29:8 (count = 1), RegionEntry +Segment at 29:15 (count = 0), Skipped +Segment at 29:16 (count = 1), RegionEntry +Segment at 32:6 (count = 0), RegionEntry +Segment at 32:7 (count = 0), Skipped +Segment at 33:11 (count = 1), RegionEntry +Segment at 33:17 (count = 0), Skipped +Segment at 34:27 (count = 0), RegionEntry +Segment at 34:29 (count = 0), Skipped +Segment at 35:14 (count = 1), RegionEntry +Segment at 35:16 (count = 0), Skipped +Segment at 37:8 (count = 1), RegionEntry +Segment at 37:15 (count = 0), Skipped +Segment at 37:16 (count = 1), RegionEntry +Segment at 40:6 (count = 0), RegionEntry +Segment at 40:7 (count = 0), Skipped +Segment at 41:11 (count = 1), RegionEntry +Segment at 41:17 (count = 0), Skipped +Segment at 42:27 (count = 1), RegionEntry +Segment at 42:29 (count = 0), Skipped +Segment at 43:14 (count = 0), RegionEntry +Segment at 43:16 (count = 0), Skipped +Segment at 45:1 (count = 1), RegionEntry +Segment at 45:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..133a85c8394 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,271 @@ + + + + +match_or_pattern.main - Coverage Spans + + + +
@0,1,2,3⦊fn main() { + // Initialize test constants in a way that cannot be determined at compile time, to ensure + // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + // dependent conditions. + let is_true = std::env::args().len() == 1; + + let mut a: u8 = 0; + let mut b: u8 = 0; + if is_true⦉@0,1,2,3 @4,6⦊{ + a = 2; + b = 0; + }⦉@4,6@5⦊‸⦉@5 + match @7⦊(a, b)⦉@7 { + // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`. + // This test confirms a fix for Issue #79569. + (0 | 1, 2 | 3) => @10,11⦊{}⦉@10,11 + _ => @8⦊{}⦉@8 + } + if @12⦊is_true⦉@12 @13,15⦊{ + a = 0; + b = 0; + }⦉@13,15@14⦊‸⦉@14 + match @16⦊(a, b)⦉@16 { + (0 | 1, 2 | 3) => @19,20⦊{}⦉@19,20 + _ => @17⦊{}⦉@17 + } + if @21⦊is_true⦉@21 @22,24⦊{ + a = 2; + b = 2; + }⦉@22,24@23⦊‸⦉@23 + match @25⦊(a, b)⦉@25 { + (0 | 1, 2 | 3) => @28,29⦊{}⦉@28,29 + _ => @26⦊{}⦉@26 + } + if @30⦊is_true⦉@30 @31,33⦊{ + a = 0; + b = 2; + }⦉@31,33@32⦊‸⦉@32 + match @34⦊(a, b)⦉@34 { + (0 | 1, 2 | 3) => @37,38⦊{}⦉@37,38 + _ => @35⦊{}⦉@35 + } +}@39⦊‸⦉@39
+ + diff --git a/src/test/run-make-fulldeps/coverage/match_or_pattern.rs b/src/test/run-make-fulldeps/coverage/match_or_pattern.rs new file mode 100644 index 00000000000..4c6a8a9b703 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/match_or_pattern.rs @@ -0,0 +1,45 @@ +#![feature(or_patterns)] + +fn main() { + // Initialize test constants in a way that cannot be determined at compile time, to ensure + // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from + // dependent conditions. + let is_true = std::env::args().len() == 1; + + let mut a: u8 = 0; + let mut b: u8 = 0; + if is_true { + a = 2; + b = 0; + } + match (a, b) { + // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`. + // This test confirms a fix for Issue #79569. + (0 | 1, 2 | 3) => {} + _ => {} + } + if is_true { + a = 0; + b = 0; + } + match (a, b) { + (0 | 1, 2 | 3) => {} + _ => {} + } + if is_true { + a = 2; + b = 2; + } + match (a, b) { + (0 | 1, 2 | 3) => {} + _ => {} + } + if is_true { + a = 0; + b = 2; + } + match (a, b) { + (0 | 1, 2 | 3) => {} + _ => {} + } +} -- cgit 1.4.1-3-g733a5 From 409382dd3cd9113757c11d3af2c509dac2edf8f2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 23 Nov 2020 20:50:02 -0500 Subject: Don't abort rustdoc tests if `tidy` isn't installed Before: ``` Check compiletest suite=rustdoc mode=rustdoc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu) running 396 tests ..................................................2020-11-23T12:12:37.735649Z ERROR compiletest::runtest: fatal error, panic: "failed to run tidy - is it installed? - No such file or directory (os error 2)" F................................................. 100/396 .................................................................................................... 200/396 .................................................................................................... 300/396 ...............................i...............2020-11-23T12:15:00.271271Z ERROR compiletest::runtest: fatal error, panic: "failed to run tidy - is it installed? - No such file or directory (os error 2)" F................................................ ``` After: ``` Check compiletest suite=rustdoc mode=rustdoc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu) running 4 tests .FFF failures: ---- [rustdoc] rustdoc/fn-pointer-arg-name.rs stdout ---- error: htmldocck failed! status: exit code: 1 command: "/usr/bin/python" "/home/joshua/rustc/src/etc/htmldocck.py" "/home/joshua/rustc/build/x86_64-unknown-linux-gnu/test/rustdoc/fn-pointer-arg-name" "/home/joshua/rustc/src/test/rustdoc/fn-pointer-arg-name.rs" stdout: ------------------------------------------ ------------------------------------------ stderr: ------------------------------------------ 4: @has check failed `XPATH PATTERN` did not match // @has - '//*[@class="rust fn"]' 'pub fn f(callback: fn(len: usize, foo: u32))' Encountered 1 errors ------------------------------------------ info: generating a diff against nightly rustdoc failed to run tidy - is it installed? - Permission denied (os error 13) failed to run tidy - is it installed? - Permission denied (os error 13) # a diff without running `tidy` ``` --- src/tools/compiletest/src/runtest.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ccef005173d..398f3e31c6a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2394,7 +2394,8 @@ impl<'test> TestCx<'test> { let proc_res = new_rustdoc.document(&compare_dir); if !proc_res.status.success() { - proc_res.fatal(Some("failed to run nightly rustdoc"), || ()); + eprintln!("failed to run nightly rustdoc"); + return; } #[rustfmt::skip] @@ -2409,22 +2410,26 @@ impl<'test> TestCx<'test> { ]; let tidy_dir = |dir| { let tidy = |file: &_| { - Command::new("tidy") - .args(&tidy_args) - .arg(file) - .spawn() - .unwrap_or_else(|err| { - self.fatal(&format!("failed to run tidy - is it installed? - {}", err)) - }) - .wait() - .unwrap() + let tidy_proc = Command::new("tidy").args(&tidy_args).arg(file).spawn(); + match tidy_proc { + Ok(mut proc) => { + proc.wait().unwrap(); + true + } + Err(err) => { + eprintln!("failed to run tidy - is it installed? - {}", err); + false + } + } }; for entry in walkdir::WalkDir::new(dir) { let entry = entry.expect("failed to read file"); if entry.file_type().is_file() && entry.path().extension().and_then(|p| p.to_str()) == Some("html".into()) { - tidy(entry.path()); + if !tidy(entry.path()) { + return; + } } } }; -- cgit 1.4.1-3-g733a5 From 804b72af4a478a406e3b73fa690a307c420daf0b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 26 Nov 2020 14:05:54 -0500 Subject: If tidy isn't installed, only give one error, not many --- src/tools/compiletest/src/common.rs | 3 +++ src/tools/compiletest/src/main.rs | 12 +++++++++++- src/tools/compiletest/src/runtest.rs | 26 ++++++++------------------ 3 files changed, 22 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index eba02333c8c..55d25fa7c52 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -327,6 +327,9 @@ pub struct Config { /// created in `//rustfix_missing_coverage.txt` pub rustfix_coverage: bool, + /// whether to run `tidy` when a rustdoc test fails + pub has_tidy: bool, + // Configuration for various run-make tests frobbing things like C compilers // or querying about various LLVM component information. pub cc: String, diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 5177dae8a66..c63bbaf70d3 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -14,7 +14,7 @@ use std::ffi::OsString; use std::fs; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, Stdio}; use std::time::SystemTime; use test::ColorConfig; use tracing::*; @@ -43,6 +43,10 @@ fn main() { panic!("Can't find Valgrind to run Valgrind tests"); } + if !config.has_tidy && config.mode == Mode::Rustdoc { + eprintln!("warning: `tidy` is not installed; generated diffs will be harder to read"); + } + log_config(&config); run_tests(config); } @@ -189,6 +193,11 @@ pub fn parse_config(args: Vec) -> Config { let src_base = opt_path(matches, "src-base"); let run_ignored = matches.opt_present("ignored"); + let has_tidy = Command::new("tidy") + .arg("--version") + .stdout(Stdio::null()) + .status() + .map_or(false, |status| status.success()); Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -244,6 +253,7 @@ pub fn parse_config(args: Vec) -> Config { remote_test_client: matches.opt_str("remote-test-client").map(PathBuf::from), compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse), rustfix_coverage: matches.opt_present("rustfix-coverage"), + has_tidy, cc: matches.opt_str("cc").unwrap(), cxx: matches.opt_str("cxx").unwrap(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 398f3e31c6a..d43e75248eb 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2409,32 +2409,22 @@ impl<'test> TestCx<'test> { "-modify", ]; let tidy_dir = |dir| { - let tidy = |file: &_| { - let tidy_proc = Command::new("tidy").args(&tidy_args).arg(file).spawn(); - match tidy_proc { - Ok(mut proc) => { - proc.wait().unwrap(); - true - } - Err(err) => { - eprintln!("failed to run tidy - is it installed? - {}", err); - false - } - } - }; for entry in walkdir::WalkDir::new(dir) { let entry = entry.expect("failed to read file"); if entry.file_type().is_file() && entry.path().extension().and_then(|p| p.to_str()) == Some("html".into()) { - if !tidy(entry.path()) { - return; - } + let status = + Command::new("tidy").args(&tidy_args).arg(entry.path()).status().unwrap(); + // `tidy` returns 1 if it modified the file. + assert!(status.success() || status.code() == Some(1)); } } }; - tidy_dir(out_dir); - tidy_dir(&compare_dir); + if self.config.has_tidy { + tidy_dir(out_dir); + tidy_dir(&compare_dir); + } let pager = { let output = Command::new("git").args(&["config", "--get", "core.pager"]).output().ok(); -- cgit 1.4.1-3-g733a5 From f9b97a8e458b73b7e670a940877f91f9ce0b9ce3 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 26 Nov 2020 15:48:21 -0500 Subject: Ignore .css files in the diff These are always static and never autogenerated, so the diffs aren't useful. --- src/tools/compiletest/src/runtest.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d43e75248eb..7af0d91271b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2437,7 +2437,8 @@ impl<'test> TestCx<'test> { }) }; let mut diff = Command::new("diff"); - diff.args(&["-u", "-r"]).args(&[&compare_dir, out_dir]); + // diff recursively, showing context, and excluding .css files + diff.args(&["-u", "-r", "-x", "*.css"]).args(&[&compare_dir, out_dir]); let output = if let Some(pager) = pager { let diff_pid = diff.stdout(Stdio::piped()).spawn().expect("failed to run `diff`"); -- cgit 1.4.1-3-g733a5 From 9684557c8f1b9fd55cb6fcc27533044022b0ed22 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 12 Dec 2020 09:38:35 -0500 Subject: Small cleanups - Use a tuple struct instead of a single field - Enforce calling `source_callsite()` by making the inner span private - Rename `empty` to `dummy` --- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 5 +---- src/librustdoc/clean/types.rs | 25 +++++++++++++++---------- 4 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 8feef9c259c..7a61a169c2b 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { }; Some(Item { - source: Span::empty(), + source: Span::dummy(), name: None, attrs: Default::default(), visibility: Inherited, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index f3067360f06..42778867bf8 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -479,7 +479,7 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) items.push(clean::Item { name: None, attrs: clean::Attributes::default(), - source: clean::Span::empty(), + source: clean::Span::dummy(), def_id: DefId::local(CRATE_DEF_INDEX), visibility: clean::Public, stability: None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a21e9d9820c..1a63a5092ca 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1882,10 +1882,7 @@ impl Clean for hir::VariantData<'_> { impl Clean for rustc_span::Span { fn clean(&self, _cx: &DocContext<'_>) -> Span { - // Get the macro invocation instead of the definition, - // in case the span is result of a macro expansion. - // (See rust-lang/rust#39726) - Span { original: self.source_callsite() } + Span::from_rustc_span(*self) } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index a8626af8832..0228d63ac00 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1610,31 +1610,36 @@ crate enum VariantKind { Struct(VariantStruct), } -/// Small wrapper around `rustc_span::Span` that adds helper methods. +/// Small wrapper around `rustc_span::Span` that adds helper methods and enforces calling `source_callsite`. #[derive(Clone, Debug)] -crate struct Span { - crate original: rustc_span::Span, -} +crate struct Span(rustc_span::Span); impl Span { - crate fn empty() -> Self { - Self { original: rustc_span::DUMMY_SP } + crate fn from_rustc_span(sp: rustc_span::Span) -> Self { + // Get the macro invocation instead of the definition, + // in case the span is result of a macro expansion. + // (See rust-lang/rust#39726) + Self(sp.source_callsite()) + } + + crate fn dummy() -> Self { + Self(rustc_span::DUMMY_SP) } crate fn span(&self) -> rustc_span::Span { - self.original + self.0 } crate fn filename(&self, sess: &Session) -> FileName { - sess.source_map().span_to_filename(self.original) + sess.source_map().span_to_filename(self.0) } crate fn lo(&self, sess: &Session) -> Loc { - sess.source_map().lookup_char_pos(self.original.lo()) + sess.source_map().lookup_char_pos(self.0.lo()) } crate fn hi(&self, sess: &Session) -> Loc { - sess.source_map().lookup_char_pos(self.original.hi()) + sess.source_map().lookup_char_pos(self.0.hi()) } crate fn cnum(&self, sess: &Session) -> CrateNum { -- cgit 1.4.1-3-g733a5 From ec09616078e89deab5f97e578b3400b045c09575 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 12 Dec 2020 19:18:44 +0300 Subject: tidy: Re-enable check for inline unit tests --- compiler/rustc_feature/src/lib.rs | 30 +++--------------------------- compiler/rustc_feature/src/tests.rs | 23 +++++++++++++++++++++++ src/tools/tidy/src/main.rs | 5 ++++- 3 files changed, 30 insertions(+), 28 deletions(-) create mode 100644 compiler/rustc_feature/src/tests.rs (limited to 'src') diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index f965f7fdefe..2a7c2a02fba 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -18,6 +18,9 @@ mod active; mod builtin_attrs; mod removed; +#[cfg(test)] +mod tests; + use rustc_span::{edition::Edition, symbol::Symbol, Span}; use std::fmt; use std::num::NonZeroU32; @@ -149,30 +152,3 @@ pub use builtin_attrs::{ AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP, }; pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES}; - -#[cfg(test)] -mod test { - use super::UnstableFeatures; - - #[test] - fn rustc_bootstrap_parsing() { - let is_bootstrap = |env, krate| { - std::env::set_var("RUSTC_BOOTSTRAP", env); - matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat) - }; - assert!(is_bootstrap("1", None)); - assert!(is_bootstrap("1", Some("x"))); - // RUSTC_BOOTSTRAP allows specifying a specific crate - assert!(is_bootstrap("x", Some("x"))); - // RUSTC_BOOTSTRAP allows multiple comma-delimited crates - assert!(is_bootstrap("x,y,z", Some("x"))); - assert!(is_bootstrap("x,y,z", Some("y"))); - // Crate that aren't specified do not get unstable features - assert!(!is_bootstrap("x", Some("a"))); - assert!(!is_bootstrap("x,y,z", Some("a"))); - assert!(!is_bootstrap("x,y,z", None)); - - // this is technically a breaking change, but there are no stability guarantees for RUSTC_BOOTSTRAP - assert!(!is_bootstrap("0", None)); - } -} diff --git a/compiler/rustc_feature/src/tests.rs b/compiler/rustc_feature/src/tests.rs new file mode 100644 index 00000000000..50433e44b13 --- /dev/null +++ b/compiler/rustc_feature/src/tests.rs @@ -0,0 +1,23 @@ +use super::UnstableFeatures; + +#[test] +fn rustc_bootstrap_parsing() { + let is_bootstrap = |env, krate| { + std::env::set_var("RUSTC_BOOTSTRAP", env); + matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat) + }; + assert!(is_bootstrap("1", None)); + assert!(is_bootstrap("1", Some("x"))); + // RUSTC_BOOTSTRAP allows specifying a specific crate + assert!(is_bootstrap("x", Some("x"))); + // RUSTC_BOOTSTRAP allows multiple comma-delimited crates + assert!(is_bootstrap("x,y,z", Some("x"))); + assert!(is_bootstrap("x,y,z", Some("y"))); + // Crate that aren't specified do not get unstable features + assert!(!is_bootstrap("x", Some("a"))); + assert!(!is_bootstrap("x,y,z", Some("a"))); + assert!(!is_bootstrap("x,y,z", None)); + + // this is technically a breaking change, but there are no stability guarantees for RUSTC_BOOTSTRAP + assert!(!is_bootstrap("0", None)); +} diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index e1525f8e1bf..080e1631624 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -35,9 +35,12 @@ fn main() { // Checks that only make sense for the std libs. pal::check(&library_path, &mut bad); - unit_tests::check(&library_path, &mut bad); // Checks that need to be done for both the compiler and std libraries. + unit_tests::check(&src_path, &mut bad); + unit_tests::check(&compiler_path, &mut bad); + unit_tests::check(&library_path, &mut bad); + bins::check(&src_path, &output_directory, &mut bad); bins::check(&compiler_path, &output_directory, &mut bad); bins::check(&library_path, &output_directory, &mut bad); -- cgit 1.4.1-3-g733a5 From 16f69b5430cd543d5767401d760cc644dc836906 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 12 Dec 2020 18:02:37 +0100 Subject: Don't checkout llvm-project when the LLVM backend isn't built --- src/bootstrap/bootstrap.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index a819e1b6e2f..63975c6deda 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -892,13 +892,17 @@ class RustBuild(object): filtered_submodules = [] submodules_names = [] llvm_checked_out = os.path.exists(os.path.join(self.rust_root, "src/llvm-project/.git")) + external_llvm_provided = self.get_toml('llvm-config') or self.downloading_llvm() + llvm_needed = not self.get_toml('codegen-backends', 'rust') \ + or "llvm" in self.get_toml('codegen-backends', 'rust') for module in submodules: if module.endswith("llvm-project"): - # Don't sync the llvm-project submodule either if an external LLVM - # was provided, or if we are downloading LLVM. Also, if the - # submodule has been initialized already, sync it anyways so that - # it doesn't mess up contributor pull requests. - if self.get_toml('llvm-config') or self.downloading_llvm(): + # Don't sync the llvm-project submodule if an external LLVM was + # provided, if we are downloading LLVM or if the LLVM backend is + # not being built. Also, if the submodule has been initialized + # already, sync it anyways so that it doesn't mess up contributor + # pull requests. + if external_llvm_provided or not llvm_needed: if self.get_toml('lld') != 'true' and not llvm_checked_out: continue check = self.check_submodule(module, slow_submodules) -- cgit 1.4.1-3-g733a5 From d79e19f3320be33f280a2b2eeb2e1ffd7f8f9162 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 12 Dec 2020 18:13:04 +0100 Subject: Don't require cmake and ninja when the LLVM backend is not used --- src/bootstrap/sanity.rs | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 4cfcf6ca407..8d7ad345ab4 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -17,6 +17,7 @@ use std::process::Command; use build_helper::{output, t}; +use crate::cache::INTERNER; use crate::config::Target; use crate::Build; @@ -79,18 +80,19 @@ pub fn check(build: &mut Build) { } // We need cmake, but only if we're actually building LLVM or sanitizers. - let building_llvm = build - .hosts - .iter() - .map(|host| { - build - .config - .target_config - .get(host) - .map(|config| config.llvm_config.is_none()) - .unwrap_or(true) - }) - .any(|build_llvm_ourselves| build_llvm_ourselves); + let building_llvm = build.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) + && build + .hosts + .iter() + .map(|host| { + build + .config + .target_config + .get(host) + .map(|config| config.llvm_config.is_none()) + .unwrap_or(true) + }) + .any(|build_llvm_ourselves| build_llvm_ourselves); if building_llvm || build.config.any_sanitizers_enabled() { cmd_finder.must_have("cmake"); } @@ -147,10 +149,12 @@ pub fn check(build: &mut Build) { } } - // Externally configured LLVM requires FileCheck to exist - let filecheck = build.llvm_filecheck(build.build); - if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests { - panic!("FileCheck executable {:?} does not exist", filecheck); + if build.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) { + // Externally configured LLVM requires FileCheck to exist + let filecheck = build.llvm_filecheck(build.build); + if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests { + panic!("FileCheck executable {:?} does not exist", filecheck); + } } for target in &build.targets { -- cgit 1.4.1-3-g733a5 From 2b455aa7d805a2a88e231585c7e89cb1652d3d3c Mon Sep 17 00:00:00 2001 From: Camelid Date: Sat, 12 Dec 2020 11:42:34 -0800 Subject: rustdoc light theme: Fix CSS for selected buttons The background was dark before, which made the text impossible to read. Now the background is white, which is how selected `div`s are rendered. As a result, the search results tabs now look identical to how they used to look (before #79896). --- src/librustdoc/html/static/themes/light.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 52cfdf6f7a3..997e1f00f85 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -349,8 +349,8 @@ pre.ignore:hover, .information:hover + pre.ignore { } #titles > button:hover, #titles > button.selected { + background-color: #ffffff; border-top-color: #0089ff; - background-color: #353535; } #titles > button > div.count { -- cgit 1.4.1-3-g733a5 From 130dbe46427068bf642697f70f68938117e13625 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 12 Dec 2020 15:40:58 -0500 Subject: Remove incorrect assert --- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5ce64c4cd83..e2fdf369087 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -436,8 +436,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Try looking for methods and associated items. let mut split = path_str.rsplitn(2, "::"); // NB: `split`'s first element is always defined, even if the delimiter was not present. + // NB: `item_str` could be empty when resolving in the root namespace (e.g. `::std`). let item_str = split.next().unwrap(); - assert!(!item_str.is_empty()); let item_name = Symbol::intern(item_str); let path_root = split .next() -- cgit 1.4.1-3-g733a5 From 1e27b65d8e877fd33ff8de20c359282577b8956c Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Thu, 3 Dec 2020 12:37:19 -0600 Subject: Recover on `const impl<> X for Y` --- compiler/rustc_parse/src/parser/item.rs | 41 ++++++++++++++++++++-- .../const-impl-norecover.rs | 13 +++++++ .../const-impl-norecover.stderr | 8 +++++ .../const-impl-recovery.rs | 16 +++++++++ .../const-impl-recovery.stderr | 24 +++++++++++++ 5 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr (limited to 'src') diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 5954b370e6d..4c92c198679 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -247,9 +247,14 @@ impl<'a> Parser<'a> { (ident, ItemKind::Static(ty, m, expr)) } else if let Const::Yes(const_span) = self.parse_constness() { // CONST ITEM - self.recover_const_mut(const_span); - let (ident, ty, expr) = self.parse_item_global(None)?; - (ident, ItemKind::Const(def(), ty, expr)) + if self.token.is_keyword(kw::Impl) { + // recover from `const impl`, suggest `impl const` + self.recover_const_impl(const_span, attrs, def())? + } else { + self.recover_const_mut(const_span); + let (ident, ty, expr) = self.parse_item_global(None)?; + (ident, ItemKind::Const(def(), ty, expr)) + } } else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() { // TRAIT ITEM self.parse_item_trait(attrs, lo)? @@ -988,6 +993,36 @@ impl<'a> Parser<'a> { } } + /// Recover on `const impl` with `const` already eaten. + fn recover_const_impl( + &mut self, + const_span: Span, + attrs: &mut Vec, + defaultness: Defaultness, + ) -> PResult<'a, ItemInfo> { + let impl_span = self.token.span; + let mut err = self.expected_ident_found(); + let mut impl_info = self.parse_item_impl(attrs, defaultness)?; + match impl_info.1 { + // only try to recover if this is implementing a trait for a type + ItemKind::Impl { of_trait: Some(ref trai), ref mut constness, .. } => { + *constness = Const::Yes(const_span); + + let before_trait = trai.path.span.shrink_to_lo(); + let const_up_to_impl = const_span.with_hi(impl_span.lo()); + err.multipart_suggestion( + "you might have meant to write a const trait impl", + vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())], + Applicability::MaybeIncorrect, + ) + .emit(); + } + ItemKind::Impl { .. } => return Err(err), + _ => unreachable!(), + } + Ok(impl_info) + } + /// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`. /// diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs new file mode 100644 index 00000000000..936c90e88aa --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs @@ -0,0 +1,13 @@ +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +struct Foo; + +const impl Foo { //~ ERROR: expected identifier, found keyword + fn bar() {} +} + +fn main() { + // shouldn't error here because we shouldn't have been able to recover above + Foo::bar(); +} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr new file mode 100644 index 00000000000..612511a4799 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found keyword `impl` + --> $DIR/const-impl-norecover.rs:6:7 + | +LL | const impl Foo { + | ^^^^ expected identifier, found keyword + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs new file mode 100644 index 00000000000..fd3dd2cef9d --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs @@ -0,0 +1,16 @@ +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +trait Foo {} + +const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword + +trait Bar {} + +const impl Bar for T {} //~ ERROR: expected identifier, found keyword + +const fn still_implements() {} + +const _: () = still_implements::(); + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr new file mode 100644 index 00000000000..84fb619dc96 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr @@ -0,0 +1,24 @@ +error: expected identifier, found keyword `impl` + --> $DIR/const-impl-recovery.rs:6:7 + | +LL | const impl Foo for i32 {} + | ^^^^ expected identifier, found keyword + | +help: you might have meant to write a const trait impl + | +LL | impl const Foo for i32 {} + |-- ^^^^^ + +error: expected identifier, found keyword `impl` + --> $DIR/const-impl-recovery.rs:10:7 + | +LL | const impl Bar for T {} + | ^^^^ expected identifier, found keyword + | +help: you might have meant to write a const trait impl + | +LL | impl const Bar for T {} + |-- ^^^^^ + +error: aborting due to 2 previous errors + -- cgit 1.4.1-3-g733a5 From e6fa6334dd54f7c96514b520c5b9f261df3fc16b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 12 Dec 2020 15:20:22 -0500 Subject: Properly capture trailing 'unglued' token If we try to capture the `Vec` in `Option>`, we'll need to capture a `>` token which was 'unglued' from a `>>` token. The processing of unglueing a token for parsing purposes bypasses the usual capturing infrastructure, so we currently lose the trailing `>`. As a result, we fall back to the reparsed `TokenStream`, causing us to lose spans. This commit makes token capturing keep track of a trailing 'unglued' token. Note that we don't need to care about unglueing except at the end of the captured tokens - if we capture both the first and second unglued tokens, then we'll end up capturing the full 'glued' token, which already works correctly. --- compiler/rustc_parse/src/parser/mod.rs | 67 +++++++++++++++++++--- src/test/ui/proc-macro/capture-unglued-token.rs | 20 +++++++ .../ui/proc-macro/capture-unglued-token.stdout | 28 +++++++++ 3 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/proc-macro/capture-unglued-token.rs create mode 100644 src/test/ui/proc-macro/capture-unglued-token.stdout (limited to 'src') diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index df4695b18e7..d51a0fcbf09 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -17,7 +17,7 @@ pub use path::PathStyle; use rustc_ast::ptr::P; use rustc_ast::token::{self, DelimToken, Token, TokenKind}; use rustc_ast::tokenstream::{self, DelimSpan, LazyTokenStream, Spacing}; -use rustc_ast::tokenstream::{CreateTokenStream, TokenStream, TokenTree}; +use rustc_ast::tokenstream::{CreateTokenStream, TokenStream, TokenTree, TreeAndSpacing}; use rustc_ast::DUMMY_NODE_ID; use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, CrateSugar, Extern, Unsafe}; use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacDelimiter, Mutability, StrLit}; @@ -132,6 +132,28 @@ struct TokenCursor { // Counts the number of calls to `next` or `next_desugared`, // depending on whether `desugar_doc_comments` is set. num_next_calls: usize, + // During parsing, we may sometimes need to 'unglue' a + // glued token into two component tokens + // (e.g. '>>' into '>' and '>), so that the parser + // can consume them one at a time. This process + // bypasses the normal capturing mechanism + // (e.g. `num_next_calls` will not be incremented), + // since the 'unglued' tokens due not exist in + // the original `TokenStream`. + // + // If we end up consuming both unglued tokens, + // then this is not an issue - we'll end up + // capturing the single 'glued' token. + // + // However, in certain circumstances, we may + // want to capture just the first 'unglued' token. + // For example, capturing the `Vec` + // in `Option>` requires us to unglue + // the trailing `>>` token. The `append_unglued_token` + // field is used to track this token - it gets + // appended to the captured stream when + // we evaluate a `LazyTokenStream` + append_unglued_token: Option, } #[derive(Clone)] @@ -336,6 +358,7 @@ impl<'a> Parser<'a> { stack: Vec::new(), num_next_calls: 0, desugar_doc_comments, + append_unglued_token: None, }, desugar_doc_comments, unmatched_angle_bracket_count: 0, @@ -359,6 +382,10 @@ impl<'a> Parser<'a> { self.token_cursor.next() }; self.token_cursor.num_next_calls += 1; + // We've retrieved an token from the underlying + // cursor, so we no longer need to worry about + // an unglued token. See `break_and_eat` for more details + self.token_cursor.append_unglued_token = None; if next.span.is_dummy() { // Tweak the location for better diagnostics, but keep syntactic context intact. next.span = fallback_span.with_ctxt(next.span.ctxt()); @@ -555,6 +582,14 @@ impl<'a> Parser<'a> { let first_span = self.sess.source_map().start_point(self.token.span); let second_span = self.token.span.with_lo(first_span.hi()); self.token = Token::new(first, first_span); + // Keep track of this token - if we end token capturing now, + // we'll want to append this token to the captured stream. + // + // If we consume any additional tokens, then this token + // is not needed (we'll capture the entire 'glued' token), + // and `next_tok` will set this field to `None` + self.token_cursor.append_unglued_token = + Some((TokenTree::Token(self.token.clone()), Spacing::Alone)); // Use the spacing of the glued token as the spacing // of the unglued second token. self.bump_with((Token::new(second, second_span), self.token_spacing)); @@ -1230,6 +1265,7 @@ impl<'a> Parser<'a> { num_calls: usize, desugar_doc_comments: bool, trailing_semi: bool, + append_unglued_token: Option, } impl CreateTokenStream for LazyTokenStreamImpl { fn create_token_stream(&self) -> TokenStream { @@ -1253,12 +1289,18 @@ impl<'a> Parser<'a> { })) .take(num_calls); - make_token_stream(tokens) + make_token_stream(tokens, self.append_unglued_token.clone()) } fn add_trailing_semi(&self) -> Box { if self.trailing_semi { panic!("Called `add_trailing_semi` twice!"); } + if self.append_unglued_token.is_some() { + panic!( + "Cannot call `add_trailing_semi` when we have an unglued token {:?}", + self.append_unglued_token + ); + } let mut new = self.clone(); new.trailing_semi = true; Box::new(new) @@ -1271,6 +1313,7 @@ impl<'a> Parser<'a> { cursor_snapshot, desugar_doc_comments: self.desugar_doc_comments, trailing_semi: false, + append_unglued_token: self.token_cursor.append_unglued_token.clone(), }; Ok((ret, Some(LazyTokenStream::new(lazy_impl)))) } @@ -1325,7 +1368,10 @@ pub fn emit_unclosed_delims(unclosed_delims: &mut Vec, sess: &Pa /// Converts a flattened iterator of tokens (including open and close delimiter tokens) /// into a `TokenStream`, creating a `TokenTree::Delimited` for each matching pair /// of open and close delims. -fn make_token_stream(tokens: impl Iterator) -> TokenStream { +fn make_token_stream( + tokens: impl Iterator, + append_unglued_token: Option, +) -> TokenStream { #[derive(Debug)] struct FrameData { open: Span, @@ -1348,14 +1394,17 @@ fn make_token_stream(tokens: impl Iterator) -> TokenStr .inner .push((delimited, Spacing::Alone)); } - token => stack - .last_mut() - .expect("Bottom token frame is missing!") - .inner - .push((TokenTree::Token(token), spacing)), + token => { + stack + .last_mut() + .expect("Bottom token frame is missing!") + .inner + .push((TokenTree::Token(token), spacing)); + } } } - let final_buf = stack.pop().expect("Missing final buf!"); + let mut final_buf = stack.pop().expect("Missing final buf!"); + final_buf.inner.extend(append_unglued_token); assert!(stack.is_empty(), "Stack should be empty: final_buf={:?} stack={:?}", final_buf, stack); TokenStream::new(final_buf.inner) } diff --git a/src/test/ui/proc-macro/capture-unglued-token.rs b/src/test/ui/proc-macro/capture-unglued-token.rs new file mode 100644 index 00000000000..727b779776b --- /dev/null +++ b/src/test/ui/proc-macro/capture-unglued-token.rs @@ -0,0 +1,20 @@ +// aux-build:test-macros.rs +// compile-flags: -Z span-debug +// check-pass + +// Tests that we properly handle parsing a nonterminal +// where we have two consecutive angle brackets (one inside +// the nonterminal, and one outside) + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; +extern crate test_macros; + +macro_rules! trailing_angle { + (Option<$field:ty>) => { + test_macros::print_bang_consume!($field); + } +} + +trailing_angle!(Option>); +fn main() {} diff --git a/src/test/ui/proc-macro/capture-unglued-token.stdout b/src/test/ui/proc-macro/capture-unglued-token.stdout new file mode 100644 index 00000000000..7e6b540332c --- /dev/null +++ b/src/test/ui/proc-macro/capture-unglued-token.stdout @@ -0,0 +1,28 @@ +PRINT-BANG INPUT (DISPLAY): Vec +PRINT-BANG RE-COLLECTED (DISPLAY): Vec < u8 > +PRINT-BANG INPUT (DEBUG): TokenStream [ + Group { + delimiter: None, + stream: TokenStream [ + Ident { + ident: "Vec", + span: $DIR/capture-unglued-token.rs:19:24: 19:27 (#0), + }, + Punct { + ch: '<', + spacing: Alone, + span: $DIR/capture-unglued-token.rs:19:27: 19:28 (#0), + }, + Ident { + ident: "u8", + span: $DIR/capture-unglued-token.rs:19:28: 19:30 (#0), + }, + Punct { + ch: '>', + spacing: Alone, + span: $DIR/capture-unglued-token.rs:19:30: 19:31 (#0), + }, + ], + span: $DIR/capture-unglued-token.rs:15:42: 15:48 (#4), + }, +] -- cgit 1.4.1-3-g733a5 From 5ce3f4c16636b261a8ce9ddfbbb30896338b9e37 Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 11 Dec 2020 19:52:51 -0800 Subject: Resolve enum field visibility correctly Previously, this code treated enum fields' visibility as if they were struct fields. However, that's not correct because the visibility of a struct field with `ast::VisibilityKind::Inherited` is private to the module it's defined in, whereas the visibility of an *enum* field with `ast::VisibilityKind::Inherited` is the visibility of the enum it belongs to. --- compiler/rustc_resolve/src/build_reduced_graph.rs | 11 +++++++- compiler/rustc_resolve/src/lib.rs | 1 + compiler/rustc_typeck/src/check/expr.rs | 4 +-- src/test/ui/issues/issue-79593.rs | 29 ++++++++++++++++++++ src/test/ui/issues/issue-79593.stderr | 33 +++++++++++++++++++++++ 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/issues/issue-79593.rs create mode 100644 src/test/ui/issues/issue-79593.stderr (limited to 'src') diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 6d7e4ebc253..06e9969697d 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -258,7 +258,16 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))) } ast::VisibilityKind::Inherited => { - Ok(ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id)) + if matches!(self.parent_scope.module.kind, ModuleKind::Def(DefKind::Enum, _, _)) { + // Any inherited visibility resolved directly inside an enum + // (e.g. variants or fields) inherits from the visibility of the enum. + let parent_enum = self.parent_scope.module.def_id().unwrap().expect_local(); + Ok(self.r.visibilities[&parent_enum]) + } else { + // If it's not in an enum, its visibility is restricted to the `mod` item + // that it's defined in. + Ok(ty::Visibility::Restricted(self.parent_scope.module.normal_ancestor_id)) + } } ast::VisibilityKind::Restricted { ref path, id, .. } => { // For visibilities we are not ready to provide correct implementation of "uniform diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e8a06265ada..f764fbc3f8d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -403,6 +403,7 @@ enum PathResult<'a> { }, } +#[derive(Debug)] enum ModuleKind { /// An anonymous module; e.g., just a block. /// diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index b8a2a4779d9..ec0e039b5d2 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1248,7 +1248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if no_accessible_remaining_fields { self.report_no_accessible_fields(adt_ty, span); } else { - self.report_missing_field(adt_ty, span, remaining_fields); + self.report_missing_fields(adt_ty, span, remaining_fields); } } @@ -1279,7 +1279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// error: aborting due to previous error /// ``` - fn report_missing_field( + fn report_missing_fields( &self, adt_ty: Ty<'tcx>, span: Span, diff --git a/src/test/ui/issues/issue-79593.rs b/src/test/ui/issues/issue-79593.rs new file mode 100644 index 00000000000..fb54b36940d --- /dev/null +++ b/src/test/ui/issues/issue-79593.rs @@ -0,0 +1,29 @@ +mod foo { + pub struct Pub { private: () } + + pub enum Enum { + Variant { x: (), y: () }, + Other + } + + fn correct() { + Pub {}; + //~^ ERROR missing field `private` in initializer of `Pub` + Enum::Variant { x: () }; + //~^ ERROR missing field `y` in initializer of `Enum` + } +} + +fn correct() { + foo::Pub {}; + //~^ ERROR cannot construct `Pub` with struct literal syntax due to inaccessible fields +} + +fn wrong() { + foo::Enum::Variant { x: () }; + //~^ ERROR missing field `y` in initializer of `Enum` + foo::Enum::Variant { }; + //~^ ERROR missing fields `x`, `y` in initializer of `Enum` +} + +fn main() {} diff --git a/src/test/ui/issues/issue-79593.stderr b/src/test/ui/issues/issue-79593.stderr new file mode 100644 index 00000000000..33dbd85032e --- /dev/null +++ b/src/test/ui/issues/issue-79593.stderr @@ -0,0 +1,33 @@ +error[E0063]: missing field `private` in initializer of `Pub` + --> $DIR/issue-79593.rs:10:9 + | +LL | Pub {}; + | ^^^ missing `private` + +error[E0063]: missing field `y` in initializer of `Enum` + --> $DIR/issue-79593.rs:12:9 + | +LL | Enum::Variant { x: () }; + | ^^^^^^^^^^^^^ missing `y` + +error: cannot construct `Pub` with struct literal syntax due to inaccessible fields + --> $DIR/issue-79593.rs:18:5 + | +LL | foo::Pub {}; + | ^^^^^^^^ + +error[E0063]: missing field `y` in initializer of `Enum` + --> $DIR/issue-79593.rs:23:5 + | +LL | foo::Enum::Variant { x: () }; + | ^^^^^^^^^^^^^^^^^^ missing `y` + +error[E0063]: missing fields `x`, `y` in initializer of `Enum` + --> $DIR/issue-79593.rs:25:5 + | +LL | foo::Enum::Variant { }; + | ^^^^^^^^^^^^^^^^^^ missing `x`, `y` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0063`. -- cgit 1.4.1-3-g733a5 From 9df0348299df0a0ceeefd587700cabea6adc2d53 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 11 Dec 2020 20:27:28 -0500 Subject: Fix building compiler docs with stage 0 --- src/bootstrap/builder.rs | 5 ++++- src/bootstrap/doc.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 6d97943548d..9af79e20630 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -732,11 +732,14 @@ impl<'a> Builder<'a> { .env("CFG_RELEASE_CHANNEL", &self.config.channel) .env("RUSTDOC_REAL", self.rustdoc(compiler)) .env("RUSTC_BOOTSTRAP", "1") - .arg("-Znormalize_docs") .arg("-Winvalid_codeblock_attributes"); if self.config.deny_warnings { cmd.arg("-Dwarnings"); } + // cfg(not(bootstrap)), can be removed on the next beta bump + if compiler.stage != 0 { + cmd.arg("-Znormalize-docs"); + } // Remove make-related flags that can cause jobserver problems. cmd.env_remove("MAKEFLAGS"); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index a296a1fe3f4..8cacc2512ef 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -527,7 +527,10 @@ impl Step for Rustc { cargo.rustdocflag("--document-private-items"); cargo.rustdocflag("--enable-index-page"); cargo.rustdocflag("-Zunstable-options"); - cargo.rustdocflag("-Znormalize-docs"); + // cfg(not(bootstrap)), can be removed on the next beta bump + if stage != 0 { + cargo.rustdocflag("-Znormalize-docs"); + } compile::rustc_cargo(builder, &mut cargo, target); // Only include compiler crates, no dependencies of those, such as `libc`. -- cgit 1.4.1-3-g733a5 From 98118bbde42112f74d2707c0a167a0a27191438c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 12 Dec 2020 23:30:13 +0100 Subject: Fixes submit event of the search input In HTML, when a button follows an input, if the enter keep is pressed on the input, instead of sending the submit event to the input, it'll create a click event on the button following it, which in this case made the help popup show up whenever "enter" was pressed. --- src/librustdoc/html/layout.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index f2c74c46d7d..b5169b05997 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -98,7 +98,7 @@ crate fn render( placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \ type=\"search\">\ \ - +
\ Date: Sun, 13 Dec 2020 19:23:16 +0800 Subject: Fix `cargo-binutils` link --- .../unstable-book/src/compiler-flags/source-based-code-coverage.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md index 6ca5ae40707..98bcadd12ee 100644 --- a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md +++ b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md @@ -118,7 +118,7 @@ LLVM's supplies two tools—`llvm-profdata` and `llvm-cov`—that process covera * If you are building the Rust compiler from source, you can optionally use the bundled LLVM tools, built from source. Those tool binaries can typically be found in your build platform directory at something like: `rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-*`. * You can install compatible versions of these tools via `rustup`. -The `rustup` option is guaranteed to install a compatible version of the LLVM tools, but they can be hard to find. We recommend [`cargo-bintools`], which installs Rust-specific wrappers around these and other LLVM tools, so you can invoke them via `cargo` commands! +The `rustup` option is guaranteed to install a compatible version of the LLVM tools, but they can be hard to find. We recommend [`cargo-binutils`], which installs Rust-specific wrappers around these and other LLVM tools, so you can invoke them via `cargo` commands! ```shell $ rustup component add llvm-tools-preview @@ -320,8 +320,8 @@ Rust's implementation and workflow for source-based code coverage is based on th [rustc-dev-guide-how-to-build-and-run]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html [`rustfilt`]: https://crates.io/crates/rustfilt [`json5format`]: https://crates.io/crates/json5format -[`cargo-bintools`]: https://crates.io/crates/cargo-bintools +[`cargo-binutils`]: https://crates.io/crates/cargo-binutils [`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge [`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report [`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show -[source-based code coverage in Clang]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html \ No newline at end of file +[source-based code coverage in Clang]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html -- cgit 1.4.1-3-g733a5 From cc9695543ea8f3973a2be2936df0efc724de1c16 Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Fri, 11 Dec 2020 23:54:47 +0100 Subject: Pass Clippy args also trough RUSTFLAGS --- README.md | 1 - src/driver.rs | 116 +++++++++++++++++++++++++++++++++++++++++-------------- src/main.rs | 98 ++++++++++++++++++++++++++++++++++++---------- tests/dogfood.rs | 2 +- 4 files changed, 165 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index aaa55e11c7d..dc931963726 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,6 @@ the lint(s) you are interested in: ```terminal cargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::... ``` -Note that if you've run clippy before, this may only take effect after you've modified a file or ran `cargo clean`. ### Specifying the minimum supported Rust version diff --git a/src/driver.rs b/src/driver.rs index e490ee54c0b..40f1b802e60 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -1,5 +1,6 @@ #![feature(rustc_private)] #![feature(once_cell)] +#![feature(bool_to_option)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] @@ -19,6 +20,7 @@ use rustc_tools_util::VersionInfo; use std::borrow::Cow; use std::env; +use std::iter; use std::lazy::SyncLazy; use std::ops::Deref; use std::panic; @@ -47,20 +49,6 @@ fn arg_value<'a, T: Deref>( None } -#[test] -fn test_arg_value() { - let args = &["--bar=bar", "--foobar", "123", "--foo"]; - - assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None); - assert_eq!(arg_value(args, "--bar", |_| false), None); - assert_eq!(arg_value(args, "--bar", |_| true), Some("bar")); - assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar")); - assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None); - assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None); - assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123")); - assert_eq!(arg_value(args, "--foo", |_| true), None); -} - struct DefaultCallbacks; impl rustc_driver::Callbacks for DefaultCallbacks {} @@ -182,6 +170,28 @@ fn toolchain_path(home: Option, toolchain: Option) -> Option(args: &mut Vec, clippy_args: I) +where + T: AsRef, + U: AsRef + ?Sized + 'a, + I: Iterator + Clone, +{ + let args_iter = clippy_args.map(AsRef::as_ref); + let args_count = args_iter.clone().count(); + + if args_count > 0 { + if let Some(start) = args.windows(args_count).enumerate().find_map(|(current, window)| { + window + .iter() + .map(AsRef::as_ref) + .eq(args_iter.clone()) + .then_some(current) + }) { + args.drain(start..start + args_count); + } + } +} + #[allow(clippy::too_many_lines)] pub fn main() { rustc_driver::init_rustc_env_logger(); @@ -278,20 +288,9 @@ pub fn main() { args.extend(vec!["--sysroot".into(), sys_root]); }; - let mut no_deps = false; - let clippy_args = env::var("CLIPPY_ARGS") - .unwrap_or_default() - .split("__CLIPPY_HACKERY__") - .filter_map(|s| match s { - "" => None, - "--no-deps" => { - no_deps = true; - None - }, - _ => Some(s.to_string()), - }) - .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]) - .collect::>(); + let clippy_args = env::var("CLIPPY_ARGS").unwrap_or_default(); + let clippy_args = clippy_args.split_whitespace(); + let no_deps = clippy_args.clone().any(|flag| flag == "--no-deps"); // We enable Clippy if one of the following conditions is met // - IF Clippy is run on its test suite OR @@ -304,7 +303,11 @@ pub fn main() { let clippy_enabled = clippy_tests_set || (!cap_lints_allow && (!no_deps || in_primary_package)); if clippy_enabled { - args.extend(clippy_args); + remove_clippy_args(&mut args, iter::once("--no-deps")); + args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]); + } else { + // Remove all flags passed through RUSTFLAGS if Clippy is not enabled. + remove_clippy_args(&mut args, clippy_args); } let mut clippy = ClippyCallbacks; @@ -315,3 +318,58 @@ pub fn main() { rustc_driver::RunCompiler::new(&args, callbacks).run() })) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_arg_value() { + let args = &["--bar=bar", "--foobar", "123", "--foo"]; + + assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None); + assert_eq!(arg_value(args, "--bar", |_| false), None); + assert_eq!(arg_value(args, "--bar", |_| true), Some("bar")); + assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar")); + assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None); + assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None); + assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123")); + assert_eq!(arg_value(args, "--foo", |_| true), None); + } + + #[test] + fn removes_clippy_args_from_start() { + let mut args = vec!["-D", "clippy::await_holding_lock", "--cfg", r#"feature="some_feat""#]; + let clippy_args = ["-D", "clippy::await_holding_lock"].iter(); + + remove_clippy_args(&mut args, clippy_args); + assert_eq!(args, &["--cfg", r#"feature="some_feat""#]); + } + + #[test] + fn removes_clippy_args_from_end() { + let mut args = vec!["-Zui-testing", "-A", "clippy::empty_loop", "--no-deps"]; + let clippy_args = ["-A", "clippy::empty_loop", "--no-deps"].iter(); + + remove_clippy_args(&mut args, clippy_args); + assert_eq!(args, &["-Zui-testing"]); + } + + #[test] + fn removes_clippy_args_from_middle() { + let mut args = vec!["-Zui-testing", "-W", "clippy::filter_map", "-L", "serde"]; + let clippy_args = ["-W", "clippy::filter_map"].iter(); + + remove_clippy_args(&mut args, clippy_args); + assert_eq!(args, &["-Zui-testing", "-L", "serde"]); + } + + #[test] + fn no_clippy_args_to_remove() { + let mut args = vec!["-Zui-testing", "-L", "serde"]; + let clippy_args: [&str; 0] = []; + + remove_clippy_args(&mut args, clippy_args.iter()); + assert_eq!(args, &["-Zui-testing", "-L", "serde"]); + } +} diff --git a/src/main.rs b/src/main.rs index ea06743394d..7594ea2c7b1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +#![feature(bool_to_option)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] @@ -62,11 +63,12 @@ struct ClippyCmd { unstable_options: bool, cargo_subcommand: &'static str, args: Vec, - clippy_args: Vec, + rustflags: Option, + clippy_args: Option, } impl ClippyCmd { - fn new(mut old_args: I) -> Self + fn new(mut old_args: I, rustflags: Option) -> Self where I: Iterator, { @@ -99,16 +101,19 @@ impl ClippyCmd { args.insert(0, "+nightly".to_string()); } - let mut clippy_args: Vec = old_args.collect(); - if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") { - clippy_args.push("--no-deps".into()); + let mut clippy_args = old_args.collect::>().join(" "); + if cargo_subcommand == "fix" && !clippy_args.contains("--no-deps") { + clippy_args = format!("{} --no-deps", clippy_args); } + let has_args = !clippy_args.is_empty(); ClippyCmd { unstable_options, cargo_subcommand, args, - clippy_args, + rustflags: has_args + .then(|| rustflags.map_or_else(|| clippy_args.clone(), |flags| format!("{} {}", clippy_args, flags))), + clippy_args: has_args.then_some(clippy_args), } } @@ -150,18 +155,19 @@ impl ClippyCmd { fn into_std_cmd(self) -> Command { let mut cmd = Command::new("cargo"); - let clippy_args: String = self - .clippy_args - .iter() - .map(|arg| format!("{}__CLIPPY_HACKERY__", arg)) - .collect(); cmd.env(self.path_env(), Self::path()) .envs(ClippyCmd::target_dir()) - .env("CLIPPY_ARGS", clippy_args) .arg(self.cargo_subcommand) .args(&self.args); + // HACK: pass Clippy args to the driver *also* through RUSTFLAGS. + // This guarantees that new builds will be triggered when Clippy flags change. + if let (Some(clippy_args), Some(rustflags)) = (self.clippy_args, self.rustflags) { + cmd.env("CLIPPY_ARGS", clippy_args); + cmd.env("RUSTFLAGS", rustflags); + } + cmd } } @@ -170,7 +176,7 @@ fn process(old_args: I) -> Result<(), i32> where I: Iterator, { - let cmd = ClippyCmd::new(old_args); + let cmd = ClippyCmd::new(old_args, env::var("RUSTFLAGS").ok()); let mut cmd = cmd.into_std_cmd(); @@ -195,7 +201,7 @@ mod tests { #[should_panic] fn fix_without_unstable() { let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string); - let _ = ClippyCmd::new(args); + let _ = ClippyCmd::new(args, None); } #[test] @@ -203,7 +209,8 @@ mod tests { let args = "cargo clippy --fix -Zunstable-options" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args); + let cmd = ClippyCmd::new(args, None); + assert_eq!("fix", cmd.cargo_subcommand); assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env()); assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options"))); @@ -214,8 +221,9 @@ mod tests { let args = "cargo clippy --fix -Zunstable-options" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args); - assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps")); + let cmd = ClippyCmd::new(args, None); + + assert!(cmd.clippy_args.unwrap().contains("--no-deps")); } #[test] @@ -223,14 +231,16 @@ mod tests { let args = "cargo clippy --fix -Zunstable-options -- --no-deps" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args); - assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1); + let cmd = ClippyCmd::new(args, None); + + assert_eq!(1, cmd.clippy_args.unwrap().matches("--no-deps").count()); } #[test] fn check() { let args = "cargo clippy".split_whitespace().map(ToString::to_string); - let cmd = ClippyCmd::new(args); + let cmd = ClippyCmd::new(args, None); + assert_eq!("check", cmd.cargo_subcommand); assert_eq!("RUSTC_WRAPPER", cmd.path_env()); } @@ -240,8 +250,54 @@ mod tests { let args = "cargo clippy -Zunstable-options" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args); + let cmd = ClippyCmd::new(args, None); + assert_eq!("check", cmd.cargo_subcommand); assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env()); } + + #[test] + fn clippy_args_into_rustflags() { + let args = "cargo clippy -- -W clippy::as_conversions" + .split_whitespace() + .map(ToString::to_string); + let rustflags = None; + let cmd = ClippyCmd::new(args, rustflags); + + assert_eq!("-W clippy::as_conversions", cmd.rustflags.unwrap()); + } + + #[test] + fn clippy_args_respect_existing_rustflags() { + let args = "cargo clippy -- -D clippy::await_holding_lock" + .split_whitespace() + .map(ToString::to_string); + let rustflags = Some(r#"--cfg feature="some_feat""#.into()); + let cmd = ClippyCmd::new(args, rustflags); + + assert_eq!( + r#"-D clippy::await_holding_lock --cfg feature="some_feat""#, + cmd.rustflags.unwrap() + ); + } + + #[test] + fn no_env_change_if_no_clippy_args() { + let args = "cargo clippy".split_whitespace().map(ToString::to_string); + let rustflags = Some(r#"--cfg feature="some_feat""#.into()); + let cmd = ClippyCmd::new(args, rustflags); + + assert!(cmd.clippy_args.is_none()); + assert!(cmd.rustflags.is_none()); + } + + #[test] + fn no_env_change_if_no_clippy_args_nor_rustflags() { + let args = "cargo clippy".split_whitespace().map(ToString::to_string); + let rustflags = None; + let cmd = ClippyCmd::new(args, rustflags); + + assert!(cmd.clippy_args.is_none()); + assert!(cmd.rustflags.is_none()); + } } diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 052223d6d6f..fda1413868e 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -23,7 +23,7 @@ fn dogfood_clippy() { .current_dir(root_dir) .env("CLIPPY_DOGFOOD", "1") .env("CARGO_INCREMENTAL", "0") - .arg("clippy-preview") + .arg("clippy") .arg("--all-targets") .arg("--all-features") .arg("--") -- cgit 1.4.1-3-g733a5 From f93d9654d2ce012e146b8dfa615ad724f4bb23fd Mon Sep 17 00:00:00 2001 From: Eduardo Broto Date: Sun, 13 Dec 2020 17:21:53 +0100 Subject: Address comments from PR review Also: enable tests for cargo-clippy --- Cargo.toml | 1 - src/main.rs | 68 ++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 40 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/Cargo.toml b/Cargo.toml index a765390c603..7f9d22e594b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ publish = false [[bin]] name = "cargo-clippy" -test = false path = "src/main.rs" [[bin]] diff --git a/src/main.rs b/src/main.rs index 7594ea2c7b1..1c0e04689a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![feature(bool_to_option)] +#![feature(command_access)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] @@ -63,12 +64,11 @@ struct ClippyCmd { unstable_options: bool, cargo_subcommand: &'static str, args: Vec, - rustflags: Option, clippy_args: Option, } impl ClippyCmd { - fn new(mut old_args: I, rustflags: Option) -> Self + fn new(mut old_args: I) -> Self where I: Iterator, { @@ -111,8 +111,6 @@ impl ClippyCmd { unstable_options, cargo_subcommand, args, - rustflags: has_args - .then(|| rustflags.map_or_else(|| clippy_args.clone(), |flags| format!("{} {}", clippy_args, flags))), clippy_args: has_args.then_some(clippy_args), } } @@ -153,7 +151,7 @@ impl ClippyCmd { .map(|p| ("CARGO_TARGET_DIR", p)) } - fn into_std_cmd(self) -> Command { + fn into_std_cmd(self, rustflags: Option) -> Command { let mut cmd = Command::new("cargo"); cmd.env(self.path_env(), Self::path()) @@ -163,9 +161,12 @@ impl ClippyCmd { // HACK: pass Clippy args to the driver *also* through RUSTFLAGS. // This guarantees that new builds will be triggered when Clippy flags change. - if let (Some(clippy_args), Some(rustflags)) = (self.clippy_args, self.rustflags) { + if let Some(clippy_args) = self.clippy_args { + cmd.env( + "RUSTFLAGS", + rustflags.map_or(clippy_args.clone(), |flags| format!("{} {}", clippy_args, flags)), + ); cmd.env("CLIPPY_ARGS", clippy_args); - cmd.env("RUSTFLAGS", rustflags); } cmd @@ -176,9 +177,9 @@ fn process(old_args: I) -> Result<(), i32> where I: Iterator, { - let cmd = ClippyCmd::new(old_args, env::var("RUSTFLAGS").ok()); + let cmd = ClippyCmd::new(old_args); - let mut cmd = cmd.into_std_cmd(); + let mut cmd = cmd.into_std_cmd(env::var("RUSTFLAGS").ok()); let exit_status = cmd .spawn() @@ -196,12 +197,13 @@ where #[cfg(test)] mod tests { use super::ClippyCmd; + use std::ffi::OsStr; #[test] #[should_panic] fn fix_without_unstable() { let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string); - let _ = ClippyCmd::new(args, None); + let _ = ClippyCmd::new(args); } #[test] @@ -209,7 +211,7 @@ mod tests { let args = "cargo clippy --fix -Zunstable-options" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args, None); + let cmd = ClippyCmd::new(args); assert_eq!("fix", cmd.cargo_subcommand); assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env()); @@ -221,7 +223,7 @@ mod tests { let args = "cargo clippy --fix -Zunstable-options" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args, None); + let cmd = ClippyCmd::new(args); assert!(cmd.clippy_args.unwrap().contains("--no-deps")); } @@ -231,7 +233,7 @@ mod tests { let args = "cargo clippy --fix -Zunstable-options -- --no-deps" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args, None); + let cmd = ClippyCmd::new(args); assert_eq!(1, cmd.clippy_args.unwrap().matches("--no-deps").count()); } @@ -239,7 +241,7 @@ mod tests { #[test] fn check() { let args = "cargo clippy".split_whitespace().map(ToString::to_string); - let cmd = ClippyCmd::new(args, None); + let cmd = ClippyCmd::new(args); assert_eq!("check", cmd.cargo_subcommand); assert_eq!("RUSTC_WRAPPER", cmd.path_env()); @@ -250,7 +252,7 @@ mod tests { let args = "cargo clippy -Zunstable-options" .split_whitespace() .map(ToString::to_string); - let cmd = ClippyCmd::new(args, None); + let cmd = ClippyCmd::new(args); assert_eq!("check", cmd.cargo_subcommand); assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env()); @@ -261,10 +263,14 @@ mod tests { let args = "cargo clippy -- -W clippy::as_conversions" .split_whitespace() .map(ToString::to_string); + let cmd = ClippyCmd::new(args); + let rustflags = None; - let cmd = ClippyCmd::new(args, rustflags); + let cmd = cmd.into_std_cmd(rustflags); - assert_eq!("-W clippy::as_conversions", cmd.rustflags.unwrap()); + assert!(cmd + .get_envs() + .any(|(key, val)| key == "RUSTFLAGS" && val == Some(OsStr::new("-W clippy::as_conversions")))); } #[test] @@ -272,32 +278,38 @@ mod tests { let args = "cargo clippy -- -D clippy::await_holding_lock" .split_whitespace() .map(ToString::to_string); + let cmd = ClippyCmd::new(args); + let rustflags = Some(r#"--cfg feature="some_feat""#.into()); - let cmd = ClippyCmd::new(args, rustflags); + let cmd = cmd.into_std_cmd(rustflags); - assert_eq!( - r#"-D clippy::await_holding_lock --cfg feature="some_feat""#, - cmd.rustflags.unwrap() - ); + assert!(cmd.get_envs().any(|(key, val)| key == "RUSTFLAGS" + && val == Some(OsStr::new(r#"-D clippy::await_holding_lock --cfg feature="some_feat""#)))); } #[test] fn no_env_change_if_no_clippy_args() { let args = "cargo clippy".split_whitespace().map(ToString::to_string); + let cmd = ClippyCmd::new(args); + let rustflags = Some(r#"--cfg feature="some_feat""#.into()); - let cmd = ClippyCmd::new(args, rustflags); + let cmd = cmd.into_std_cmd(rustflags); - assert!(cmd.clippy_args.is_none()); - assert!(cmd.rustflags.is_none()); + assert!(!cmd + .get_envs() + .any(|(key, _)| key == "RUSTFLAGS" || key == "CLIPPY_ARGS")); } #[test] fn no_env_change_if_no_clippy_args_nor_rustflags() { let args = "cargo clippy".split_whitespace().map(ToString::to_string); + let cmd = ClippyCmd::new(args); + let rustflags = None; - let cmd = ClippyCmd::new(args, rustflags); + let cmd = cmd.into_std_cmd(rustflags); - assert!(cmd.clippy_args.is_none()); - assert!(cmd.rustflags.is_none()); + assert!(!cmd + .get_envs() + .any(|(key, _)| key == "RUSTFLAGS" || key == "CLIPPY_ARGS")) } } -- cgit 1.4.1-3-g733a5 From ec0f1d70c955643a77e89d67eb2469ff5d7d6eba Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Sun, 13 Dec 2020 17:47:46 +0100 Subject: Refactor test_lang_string_parse to make it clearer --- src/librustdoc/html/markdown/tests.rs | 143 ++++++++++++++++------------------ 1 file changed, 69 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 9807d8632c7..75ff3c5af2f 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -51,82 +51,77 @@ fn test_unique_id() { #[test] fn test_lang_string_parse() { - fn t( - s: &str, - should_panic: bool, - no_run: bool, - ignore: Ignore, - rust: bool, - test_harness: bool, - compile_fail: bool, - allow_fail: bool, - error_codes: Vec, - edition: Option, - ) { - assert_eq!( - LangString::parse(s, ErrorCodes::Yes, true, None), - LangString { - should_panic, - no_run, - ignore, - rust, - test_harness, - compile_fail, - error_codes, - original: s.to_owned(), - allow_fail, - edition, - } - ) + fn t(lg: LangString) { + let s = &lg.original; + assert_eq!(LangString::parse(s, ErrorCodes::Yes, true, None), lg) } - let ignore_foo = Ignore::Some(vec!["foo".to_string()]); - fn v() -> Vec { - Vec::new() - } - - // marker | should_panic | no_run | ignore | rust | test_harness - // | compile_fail | allow_fail | error_codes | edition - t("", false, false, Ignore::None, true, false, false, false, v(), None); - t("rust", false, false, Ignore::None, true, false, false, false, v(), None); - t("sh", false, false, Ignore::None, false, false, false, false, v(), None); - t("ignore", false, false, Ignore::All, true, false, false, false, v(), None); - t("ignore-foo", false, false, ignore_foo, true, false, false, false, v(), None); - t("should_panic", true, false, Ignore::None, true, false, false, false, v(), None); - t("no_run", false, true, Ignore::None, true, false, false, false, v(), None); - t("test_harness", false, false, Ignore::None, true, true, false, false, v(), None); - t("compile_fail", false, true, Ignore::None, true, false, true, false, v(), None); - t("allow_fail", false, false, Ignore::None, true, false, false, true, v(), None); - t("{.no_run .example}", false, true, Ignore::None, true, false, false, false, v(), None); - t("{.sh .should_panic}", true, false, Ignore::None, false, false, false, false, v(), None); - t("{.example .rust}", false, false, Ignore::None, true, false, false, false, v(), None); - t("{.test_harness .rust}", false, false, Ignore::None, true, true, false, false, v(), None); - t("text, no_run", false, true, Ignore::None, false, false, false, false, v(), None); - t("text,no_run", false, true, Ignore::None, false, false, false, false, v(), None); - t( - "edition2015", - false, - false, - Ignore::None, - true, - false, - false, - false, - v(), - Some(Edition::Edition2015), - ); - t( - "edition2018", - false, - false, - Ignore::None, - true, - false, - false, - false, - v(), - Some(Edition::Edition2018), - ); + t(LangString::all_false()); + t(LangString { original: "rust".into(), ..LangString::all_false() }); + t(LangString { original: "sh".into(), rust: false, ..LangString::all_false() }); + t(LangString { original: "ignore".into(), ignore: Ignore::All, ..LangString::all_false() }); + t(LangString { + original: "ignore-foo".into(), + ignore: Ignore::Some(vec!["foo".to_string()]), + ..LangString::all_false() + }); + t(LangString { + original: "should_panic".into(), + should_panic: true, + ..LangString::all_false() + }); + t(LangString { original: "no_run".into(), no_run: true, ..LangString::all_false() }); + t(LangString { + original: "test_harness".into(), + test_harness: true, + ..LangString::all_false() + }); + t(LangString { + original: "compile_fail".into(), + no_run: true, + compile_fail: true, + ..LangString::all_false() + }); + t(LangString { original: "allow_fail".into(), allow_fail: true, ..LangString::all_false() }); + t(LangString { + original: "{.no_run .example}".into(), + no_run: true, + ..LangString::all_false() + }); + t(LangString { + original: "{.sh .should_panic}".into(), + should_panic: true, + rust: false, + ..LangString::all_false() + }); + t(LangString { original: "{.example .rust}".into(), ..LangString::all_false() }); + t(LangString { + original: "{.test_harness .rust}".into(), + test_harness: true, + ..LangString::all_false() + }); + t(LangString { + original: "text, no_run".into(), + no_run: true, + rust: false, + ..LangString::all_false() + }); + t(LangString { + original: "text,no_run".into(), + no_run: true, + rust: false, + ..LangString::all_false() + }); + t(LangString { + original: "edition2015".into(), + edition: Some(Edition::Edition2015), + ..LangString::all_false() + }); + t(LangString { + original: "edition2018".into(), + edition: Some(Edition::Edition2018), + ..LangString::all_false() + }); } #[test] -- cgit 1.4.1-3-g733a5 From 4c1addfcb77b4699be409112075cf3e33e8b5ea7 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 13 Dec 2020 15:13:41 -0500 Subject: Use imports instead of rewriting the type signature of `stable` This was an adventure; see https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/'higher.20ranked.20subtype.20error' --- src/librustdoc/lib.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 286a29edd95..94b6617a071 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -117,21 +117,9 @@ fn get_args() -> Option> { .collect() } -fn stable(name: &'static str, f: F) -> RustcOptGroup -where - F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, -{ - RustcOptGroup::stable(name, f) -} - -fn unstable(name: &'static str, f: F) -> RustcOptGroup -where - F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static, -{ - RustcOptGroup::unstable(name, f) -} - fn opts() -> Vec { + let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable; + let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable; vec![ stable("h", |o| o.optflag("h", "help", "show this help message")), stable("V", |o| o.optflag("V", "version", "print rustdoc's version")), -- cgit 1.4.1-3-g733a5 From adda964bb5229a7e7fa21d28c77f7ad71afb9b15 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 12 Dec 2020 15:15:06 +0900 Subject: Check the number of entries in UI test --- src/tools/tidy/src/ui_tests.rs | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 03f4efea983..72ffdabd522 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -1,9 +1,51 @@ -//! Tidy check to ensure that there are no stray `.stderr` files in UI test directories. +//! Tidy check to ensure below in UI test directories: +//! - the number of entries in each directory must be less than `ENTRY_LIMIT` +//! - there are no stray `.stderr` files use std::fs; use std::path::Path; +const ENTRY_LIMIT: usize = 1000; +// FIXME: The following limits should be reduced eventually. +const ROOT_ENTRY_LIMIT: usize = 1580; +const ISSUES_ENTRY_LIMIT: usize = 2830; + +fn check_entries(path: &Path, bad: &mut bool) { + let dirs = walkdir::WalkDir::new(&path.join("test/ui")) + .into_iter() + .filter_entry(|e| e.file_type().is_dir()); + for dir in dirs { + if let Ok(dir) = dir { + let dir_path = dir.path(); + + // Use special values for these dirs. + let is_root = path.join("test/ui") == dir_path; + let is_issues_dir = path.join("test/ui/issues") == dir_path; + let limit = if is_root { + ROOT_ENTRY_LIMIT + } else if is_issues_dir { + ISSUES_ENTRY_LIMIT + } else { + ENTRY_LIMIT + }; + + let count = std::fs::read_dir(dir_path).unwrap().count(); + if count >= limit { + tidy_error!( + bad, + "following path contains more than {} entries, \ + you should move the test to some relevant subdirectory (current: {}): {}", + limit, + count, + dir_path.display() + ); + } + } + } +} + pub fn check(path: &Path, bad: &mut bool) { + check_entries(&path, bad); for path in &[&path.join("test/ui"), &path.join("test/ui-fulldeps")] { super::walk_no_read(path, &mut |_| false, &mut |entry| { let file_path = entry.path(); -- cgit 1.4.1-3-g733a5 From 850437b6f9915a5281c5085d45480b7d29f4e1e6 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Fri, 9 Oct 2020 10:27:14 +0200 Subject: Cache link resolution results in current module Co-authored-by: Joshua Nelson --- src/librustdoc/passes/collect_intra_doc_links.rs | 93 ++++++++++++++++++++---- 1 file changed, 79 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 7358eae6edc..d888a87b9e7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -3,7 +3,7 @@ //! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md use rustc_ast as ast; -use rustc_data_structures::stable_set::FxHashSet; +use rustc_data_structures::{fx::FxHashMap, stable_set::FxHashSet}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_expand::base::SyntaxExtensionKind; use rustc_hir as hir; @@ -168,6 +168,31 @@ enum AnchorFailure { RustdocAnchorConflict(Res), } +#[derive(Clone, Debug, Hash, PartialEq, Eq)] +struct CacheKey { + module_id: DefId, + dis: Option, + path_str: String, + extra_fragment: Option, +} + +impl CacheKey { + fn new( + module_id: DefId, + dis: Option, + path_str: String, + extra_fragment: Option, + ) -> Self { + Self { module_id, dis, path_str, extra_fragment } + } +} + +#[derive(Clone, Debug, Hash)] +struct CachedLink { + pub res: (Res, Option), + pub side_channel: Option<(DefKind, DefId)>, +} + struct LinkCollector<'a, 'tcx> { cx: &'a DocContext<'tcx>, /// A stack of modules used to decide what scope to resolve in. @@ -179,11 +204,18 @@ struct LinkCollector<'a, 'tcx> { /// because `clean` and the disambiguator code expect them to be different. /// See the code for associated items on inherent impls for details. kind_side_channel: Cell>, + /// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link + visited_links: FxHashMap, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { fn new(cx: &'a DocContext<'tcx>) -> Self { - LinkCollector { cx, mod_ids: Vec::new(), kind_side_channel: Cell::new(None) } + LinkCollector { + cx, + mod_ids: Vec::new(), + kind_side_channel: Cell::new(None), + visited_links: FxHashMap::default(), + } } /// Given a full link, parse it as an [enum struct variant]. @@ -937,7 +969,7 @@ impl LinkCollector<'_, '_> { /// /// FIXME(jynelson): this is way too many arguments fn resolve_link( - &self, + &mut self, item: &Item, dox: &str, self_name: &Option, @@ -962,6 +994,7 @@ impl LinkCollector<'_, '_> { let link = ori_link.replace("`", ""); let parts = link.split('#').collect::>(); let (link, extra_fragment) = if parts.len() > 2 { + // A valid link can't have multiple #'s anchor_failure(cx, &item, &link, dox, link_range, AnchorFailure::MultipleAnchors); return None; } else if parts.len() == 2 { @@ -1075,16 +1108,9 @@ impl LinkCollector<'_, '_> { return None; } - let (mut res, mut fragment) = self.resolve_with_disambiguator( - disambiguator, - item, - dox, - path_str, - module_id, - extra_fragment, - &ori_link, - link_range.clone(), - )?; + let key = CacheKey::new(module_id, disambiguator, path_str.to_owned(), extra_fragment); + let (mut res, mut fragment) = + self.resolve_with_disambiguator_cached(key, item, dox, &ori_link, link_range.clone())?; // Check for a primitive which might conflict with a module // Report the ambiguity and require that the user specify which one they meant. @@ -1192,6 +1218,45 @@ impl LinkCollector<'_, '_> { } } + fn resolve_with_disambiguator_cached( + &mut self, + key: CacheKey, + item: &Item, + dox: &str, + ori_link: &str, + link_range: Option>, + ) -> Option<(Res, Option)> { + // Try to look up both the result and the corresponding side channel value + if let Some(ref cached) = self.visited_links.get(&key) { + self.kind_side_channel.set(cached.side_channel.clone()); + Some(cached.res.clone()) + } else { + match self.resolve_with_disambiguator( + key.dis, + item, + dox, + &key.path_str, + key.module_id, + key.extra_fragment.clone(), + ori_link, + link_range, + ) { + Some(res) => { + // Store result for the actual namespace + self.visited_links.insert( + key, + CachedLink { + res: res.clone(), + side_channel: self.kind_side_channel.clone().into_inner(), + }, + ); + Some(res) + } + _ => None, + } + } + } + /// After parsing the disambiguator, resolve the main part of the link. // FIXME(jynelson): wow this is just so much fn resolve_with_disambiguator( @@ -1356,7 +1421,7 @@ impl LinkCollector<'_, '_> { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] /// Disambiguators for a link. enum Disambiguator { /// `prim@` -- cgit 1.4.1-3-g733a5 From cc31b992b1919ddf0d0b05e90c0f37b40f77d4e8 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Mon, 30 Nov 2020 23:16:50 +0100 Subject: Review suggestions --- src/librustdoc/passes/collect_intra_doc_links.rs | 166 ++++++++++++----------- 1 file changed, 87 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index d888a87b9e7..167eb07a690 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -169,22 +169,18 @@ enum AnchorFailure { } #[derive(Clone, Debug, Hash, PartialEq, Eq)] -struct CacheKey { +struct ResolutionInfo { module_id: DefId, dis: Option, path_str: String, extra_fragment: Option, } -impl CacheKey { - fn new( - module_id: DefId, - dis: Option, - path_str: String, - extra_fragment: Option, - ) -> Self { - Self { module_id, dis, path_str, extra_fragment } - } +struct DiagnosticInfo<'a> { + item: &'a Item, + dox: &'a str, + ori_link: &'a str, + link_range: Option>, } #[derive(Clone, Debug, Hash)] @@ -205,7 +201,7 @@ struct LinkCollector<'a, 'tcx> { /// See the code for associated items on inherent impls for details. kind_side_channel: Cell>, /// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link - visited_links: FxHashMap, + visited_links: FxHashMap, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { @@ -1108,9 +1104,15 @@ impl LinkCollector<'_, '_> { return None; } - let key = CacheKey::new(module_id, disambiguator, path_str.to_owned(), extra_fragment); - let (mut res, mut fragment) = - self.resolve_with_disambiguator_cached(key, item, dox, &ori_link, link_range.clone())?; + let key = ResolutionInfo { + module_id, + dis: disambiguator, + path_str: path_str.to_owned(), + extra_fragment, + }; + let diag = + DiagnosticInfo { item, dox, ori_link: &ori_link, link_range: link_range.clone() }; + let (mut res, mut fragment) = self.resolve_with_disambiguator_cached(key, diag)?; // Check for a primitive which might conflict with a module // Report the ambiguity and require that the user specify which one they meant. @@ -1220,59 +1222,47 @@ impl LinkCollector<'_, '_> { fn resolve_with_disambiguator_cached( &mut self, - key: CacheKey, - item: &Item, - dox: &str, - ori_link: &str, - link_range: Option>, + key: ResolutionInfo, + diag: DiagnosticInfo<'_>, ) -> Option<(Res, Option)> { // Try to look up both the result and the corresponding side channel value if let Some(ref cached) = self.visited_links.get(&key) { self.kind_side_channel.set(cached.side_channel.clone()); - Some(cached.res.clone()) - } else { - match self.resolve_with_disambiguator( - key.dis, - item, - dox, - &key.path_str, - key.module_id, - key.extra_fragment.clone(), - ori_link, - link_range, - ) { - Some(res) => { - // Store result for the actual namespace - self.visited_links.insert( - key, - CachedLink { - res: res.clone(), - side_channel: self.kind_side_channel.clone().into_inner(), - }, - ); - Some(res) - } - _ => None, - } + return Some(cached.res.clone()); } + + let res = self.resolve_with_disambiguator(&key, diag); + + // Cache only if resolved successfully - don't silence duplicate errors + if let Some(res) = &res { + // Store result for the actual namespace + self.visited_links.insert( + key, + CachedLink { + res: res.clone(), + side_channel: self.kind_side_channel.clone().into_inner(), + }, + ); + } + + res } /// After parsing the disambiguator, resolve the main part of the link. // FIXME(jynelson): wow this is just so much fn resolve_with_disambiguator( &self, - disambiguator: Option, - item: &Item, - dox: &str, - path_str: &str, - base_node: DefId, - extra_fragment: Option, - ori_link: &str, - link_range: Option>, + key: &ResolutionInfo, + diag: DiagnosticInfo<'_>, ) -> Option<(Res, Option)> { + let disambiguator = key.dis; + let path_str = &key.path_str; + let base_node = key.module_id; + let extra_fragment = &key.extra_fragment; + match disambiguator.map(Disambiguator::ns) { Some(ns @ (ValueNS | TypeNS)) => { - match self.resolve(path_str, ns, base_node, &extra_fragment) { + match self.resolve(path_str, ns, base_node, extra_fragment) { Ok(res) => Some(res), Err(ErrorKind::Resolve(box mut kind)) => { // We only looked in one namespace. Try to give a better error if possible. @@ -1281,12 +1271,9 @@ impl LinkCollector<'_, '_> { // FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator` // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach for &new_ns in &[other_ns, MacroNS] { - if let Some(res) = self.check_full_res( - new_ns, - path_str, - base_node, - &extra_fragment, - ) { + if let Some(res) = + self.check_full_res(new_ns, path_str, base_node, extra_fragment) + { kind = ResolutionFailure::WrongNamespace(res, ns); break; } @@ -1294,11 +1281,11 @@ impl LinkCollector<'_, '_> { } resolution_failure( self, - &item, + diag.item, path_str, disambiguator, - dox, - link_range, + diag.dox, + diag.link_range, smallvec![kind], ); // This could just be a normal link or a broken link @@ -1307,7 +1294,14 @@ impl LinkCollector<'_, '_> { return None; } Err(ErrorKind::AnchorFailure(msg)) => { - anchor_failure(self.cx, &item, &ori_link, dox, link_range, msg); + anchor_failure( + self.cx, + diag.item, + diag.ori_link, + diag.dox, + diag.link_range, + msg, + ); return None; } } @@ -1318,21 +1312,35 @@ impl LinkCollector<'_, '_> { macro_ns: self .resolve_macro(path_str, base_node) .map(|res| (res, extra_fragment.clone())), - type_ns: match self.resolve(path_str, TypeNS, base_node, &extra_fragment) { + type_ns: match self.resolve(path_str, TypeNS, base_node, extra_fragment) { Ok(res) => { debug!("got res in TypeNS: {:?}", res); Ok(res) } Err(ErrorKind::AnchorFailure(msg)) => { - anchor_failure(self.cx, &item, ori_link, dox, link_range, msg); + anchor_failure( + self.cx, + diag.item, + diag.ori_link, + diag.dox, + diag.link_range, + msg, + ); return None; } Err(ErrorKind::Resolve(box kind)) => Err(kind), }, - value_ns: match self.resolve(path_str, ValueNS, base_node, &extra_fragment) { + value_ns: match self.resolve(path_str, ValueNS, base_node, extra_fragment) { Ok(res) => Ok(res), Err(ErrorKind::AnchorFailure(msg)) => { - anchor_failure(self.cx, &item, ori_link, dox, link_range, msg); + anchor_failure( + self.cx, + diag.item, + diag.ori_link, + diag.dox, + diag.link_range, + msg, + ); return None; } Err(ErrorKind::Resolve(box kind)) => Err(kind), @@ -1343,7 +1351,7 @@ impl LinkCollector<'_, '_> { Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => { Err(ResolutionFailure::WrongNamespace(res, TypeNS)) } - _ => match (fragment, extra_fragment) { + _ => match (fragment, extra_fragment.clone()) { (Some(fragment), Some(_)) => { // Shouldn't happen but who knows? Ok((res, Some(fragment))) @@ -1359,11 +1367,11 @@ impl LinkCollector<'_, '_> { if len == 0 { resolution_failure( self, - &item, + diag.item, path_str, disambiguator, - dox, - link_range, + diag.dox, + diag.link_range, candidates.into_iter().filter_map(|res| res.err()).collect(), ); // this could just be a normal link @@ -1382,10 +1390,10 @@ impl LinkCollector<'_, '_> { let candidates = candidates.map(|candidate| candidate.ok().map(|(res, _)| res)); ambiguity_error( self.cx, - &item, + diag.item, path_str, - dox, - link_range, + diag.dox, + diag.link_range, candidates.present_items().collect(), ); return None; @@ -1393,12 +1401,12 @@ impl LinkCollector<'_, '_> { } Some(MacroNS) => { match self.resolve_macro(path_str, base_node) { - Ok(res) => Some((res, extra_fragment)), + Ok(res) => Some((res, extra_fragment.clone())), Err(mut kind) => { // `resolve_macro` only looks in the macro namespace. Try to give a better error if possible. for &ns in &[TypeNS, ValueNS] { if let Some(res) = - self.check_full_res(ns, path_str, base_node, &extra_fragment) + self.check_full_res(ns, path_str, base_node, extra_fragment) { kind = ResolutionFailure::WrongNamespace(res, MacroNS); break; @@ -1406,11 +1414,11 @@ impl LinkCollector<'_, '_> { } resolution_failure( self, - &item, + diag.item, path_str, disambiguator, - dox, - link_range, + diag.dox, + diag.link_range, smallvec![kind], ); return None; -- cgit 1.4.1-3-g733a5 From fa64c272c8253c9df01fa4c28e34095735411e0e Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Mon, 30 Nov 2020 23:17:11 +0100 Subject: Add test case for Self:: links --- src/test/rustdoc/intra-link-self-cache.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/rustdoc/intra-link-self-cache.rs (limited to 'src') diff --git a/src/test/rustdoc/intra-link-self-cache.rs b/src/test/rustdoc/intra-link-self-cache.rs new file mode 100644 index 00000000000..add1530a5a6 --- /dev/null +++ b/src/test/rustdoc/intra-link-self-cache.rs @@ -0,0 +1,14 @@ +#![crate_name = "foo"] +// @has foo/enum.E1.html '//a/@href' '../foo/enum.E1.html#variant.A' + +/// [Self::A::b] +pub enum E1 { + A { b: usize } +} + +// @has foo/enum.E2.html '//a/@href' '../foo/enum.E2.html#variant.A' + +/// [Self::A::b] +pub enum E2 { + A { b: usize } +} -- cgit 1.4.1-3-g733a5 From becd0e8896079016cd615def3799b8133636b39e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 14 Dec 2020 23:10:15 +0900 Subject: Replace some `println!` with `tidy_error!` to simplify --- src/tools/tidy/src/deps.rs | 29 +++++++++++++---------------- src/tools/tidy/src/extdeps.rs | 3 +-- src/tools/tidy/src/features.rs | 1 - src/tools/tidy/src/lib.rs | 4 ++++ src/tools/tidy/src/ui_tests.rs | 6 ++---- 5 files changed, 20 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 057b0884e28..952782175f1 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -214,12 +214,12 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { for (name, license) in EXCEPTIONS { // Check that the package actually exists. if !metadata.packages.iter().any(|p| p.name == *name) { - println!( + tidy_error!( + bad, "could not find exception package `{}`\n\ Remove from EXCEPTIONS list if it is no longer used.", name ); - *bad = true; } // Check that the license hasn't changed. for pkg in metadata.packages.iter().filter(|p| p.name == *name) { @@ -232,11 +232,11 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { } match &pkg.license { None => { - println!( + tidy_error!( + bad, "dependency exception `{}` does not declare a license expression", pkg.id ); - *bad = true; } Some(pkg_license) => { if pkg_license.as_str() != *license { @@ -273,8 +273,7 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { let license = match &pkg.license { Some(license) => license, None => { - println!("dependency `{}` does not define a license expression", pkg.id,); - *bad = true; + tidy_error!(bad, "dependency `{}` does not define a license expression", pkg.id); continue; } }; @@ -286,8 +285,7 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) { // general, these should never be added. continue; } - println!("invalid license `{}` in `{}`", license, pkg.id); - *bad = true; + tidy_error!(bad, "invalid license `{}` in `{}`", license, pkg.id); } } } @@ -300,12 +298,12 @@ fn check_dependencies(metadata: &Metadata, bad: &mut bool) { // Check that the PERMITTED_DEPENDENCIES does not have unused entries. for name in PERMITTED_DEPENDENCIES { if !metadata.packages.iter().any(|p| p.name == *name) { - println!( + tidy_error!( + bad, "could not find allowed package `{}`\n\ Remove from PERMITTED_DEPENDENCIES list if it is no longer used.", name ); - *bad = true; } } // Get the list in a convenient form. @@ -322,11 +320,10 @@ fn check_dependencies(metadata: &Metadata, bad: &mut bool) { } if !unapproved.is_empty() { - println!("Dependencies not explicitly permitted:"); + tidy_error!(bad, "Dependencies not explicitly permitted:"); for dep in unapproved { println!("* {}", dep); } - *bad = true; } } @@ -381,16 +378,17 @@ fn check_crate_duplicate(metadata: &Metadata, bad: &mut bool) { let matches: Vec<_> = metadata.packages.iter().filter(|pkg| pkg.name == name).collect(); match matches.len() { 0 => { - println!( + tidy_error!( + bad, "crate `{}` is missing, update `check_crate_duplicate` \ if it is no longer used", name ); - *bad = true; } 1 => {} _ => { - println!( + tidy_error!( + bad, "crate `{}` is duplicated in `Cargo.lock`, \ it is too expensive to build multiple times, \ so make sure only one version appears across all dependencies", @@ -399,7 +397,6 @@ fn check_crate_duplicate(metadata: &Metadata, bad: &mut bool) { for pkg in matches { println!(" * {}", pkg.id); } - *bad = true; } } } diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 93d4d3d8047..aad57cacbb4 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -27,8 +27,7 @@ pub fn check(root: &Path, bad: &mut bool) { // Ensure source is allowed. if !ALLOWED_SOURCES.contains(&&*source) { - println!("invalid source: {}", source); - *bad = true; + tidy_error!(bad, "invalid source: {}", source); } } } diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 3c2880d0d5e..d78af2cd616 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -330,7 +330,6 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features let issue_str = parts.next().unwrap().trim(); let tracking_issue = if issue_str.starts_with("None") { if level == Status::Unstable && !next_feature_omits_tracking_issue { - *bad = true; tidy_error!( bad, "{}:{}: no tracking issue for feature {}", diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index e11d293210b..d282d240d82 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -28,6 +28,10 @@ macro_rules! t { } macro_rules! tidy_error { + ($bad:expr, $fmt:expr) => ({ + *$bad = true; + eprintln!("tidy error: {}", $fmt); + }); ($bad:expr, $fmt:expr, $($arg:tt)*) => ({ *$bad = true; eprint!("tidy error: "); diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 72ffdabd522..d8d2b449fee 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -67,14 +67,12 @@ pub fn check(path: &Path, bad: &mut bool) { let testname = file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0; if !file_path.with_file_name(testname).with_extension("rs").exists() { - println!("Stray file with UI testing output: {:?}", file_path); - *bad = true; + tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path); } if let Ok(metadata) = fs::metadata(file_path) { if metadata.len() == 0 { - println!("Empty file with UI testing output: {:?}", file_path); - *bad = true; + tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path); } } } -- cgit 1.4.1-3-g733a5 From 357565dc19fc7f1b53d309ed10f61d21d0076459 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 14 Dec 2020 23:33:20 +0900 Subject: expand-yaml-anchors: Make the output directory separator-insensitive --- src/tools/expand-yaml-anchors/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/expand-yaml-anchors/src/main.rs b/src/tools/expand-yaml-anchors/src/main.rs index f7ff64036a1..f8cf18a9309 100644 --- a/src/tools/expand-yaml-anchors/src/main.rs +++ b/src/tools/expand-yaml-anchors/src/main.rs @@ -87,7 +87,8 @@ impl App { let content = std::fs::read_to_string(source) .with_context(|| format!("failed to read {}", self.path(source)))?; - let mut buf = HEADER_MESSAGE.replace("{source}", &self.path(source).to_string()); + let mut buf = + HEADER_MESSAGE.replace("{source}", &self.path(source).to_string().replace("\\", "/")); let documents = YamlLoader::load_from_str(&content) .with_context(|| format!("failed to parse {}", self.path(source)))?; -- cgit 1.4.1-3-g733a5 From 4f550f1f930b9201bbeeb9fa10d42392a66cc9f2 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 14 Dec 2020 00:25:29 -0800 Subject: Improve warnings on incompatible options involving -Zinstrument-coverage Adds checks for: * `no_core` attribute * explicitly-enabled `legacy` symbol mangling * mir_opt_level > 1 (which enables inlining) I removed code from the `Inline` MIR pass that forcibly disabled inlining if `-Zinstrument-coverage` was set. The default `mir_opt_level` does not enable inlining anyway. But if the level is explicitly set and is greater than 1, I issue a warning. The new warnings show up in tests, which is much better for diagnosing potential option conflicts in these cases. --- compiler/rustc_interface/src/tests.rs | 4 +-- compiler/rustc_metadata/src/creader.rs | 11 +++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +++- compiler/rustc_mir/src/transform/const_prop.rs | 8 +++-- compiler/rustc_mir/src/transform/dest_prop.rs | 3 +- .../src/transform/early_otherwise_branch.rs | 3 +- compiler/rustc_mir/src/transform/inline.rs | 11 ++----- compiler/rustc_mir/src/transform/match_branches.rs | 3 +- compiler/rustc_mir/src/transform/mod.rs | 3 +- .../src/transform/multiple_return_terminators.rs | 3 +- compiler/rustc_mir/src/transform/nrvo.rs | 3 +- .../rustc_mir/src/transform/unreachable_prop.rs | 3 +- compiler/rustc_session/src/config.rs | 38 ++++++++++++++++++++-- compiler/rustc_session/src/options.rs | 12 +++---- compiler/rustc_symbol_mangling/src/lib.rs | 6 +++- src/tools/clippy/src/driver.rs | 34 ++++++++++--------- 16 files changed, 103 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2273266a3ff..7a7def0696d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -561,7 +561,7 @@ fn test_debugging_options_tracking_hash() { tracked!(link_only, true); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); - tracked!(mir_opt_level, 3); + tracked!(mir_opt_level, Some(3)); tracked!(mutable_noalias, true); tracked!(new_llvm_pass_manager, true); tracked!(no_codegen, true); @@ -587,7 +587,7 @@ fn test_debugging_options_tracking_hash() { tracked!(share_generics, Some(true)); tracked!(show_span, Some(String::from("abc"))); tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1)); - tracked!(symbol_mangling_version, SymbolManglingVersion::V0); + tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); tracked!(teach, true); tracked!(thinlto, Some(true)); tracked!(tune_cpu, Some(String::from("abc"))); diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 33cbf0fb234..019ca5174a2 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -706,7 +706,7 @@ impl<'a> CrateLoader<'a> { self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime()); } - fn inject_profiler_runtime(&mut self) { + fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { if (self.sess.opts.debugging_opts.instrument_coverage || self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled()) @@ -714,6 +714,13 @@ impl<'a> CrateLoader<'a> { { info!("loading profiler"); + if self.sess.contains_name(&krate.attrs, sym::no_core) { + self.sess.err( + "`profiler_builtins` crate (required by compiler options) \ + is not compatible with crate attribute `#![no_core]`", + ); + } + let name = sym::profiler_builtins; let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); @@ -879,7 +886,7 @@ impl<'a> CrateLoader<'a> { } pub fn postprocess(&mut self, krate: &ast::Crate) { - self.inject_profiler_runtime(); + self.inject_profiler_runtime(krate); self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 46dd0df65e0..b0c75c1de9d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -663,7 +663,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins), panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime), profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime), - symbol_mangling_version: tcx.sess.opts.debugging_opts.symbol_mangling_version, + symbol_mangling_version: tcx + .sess + .opts + .debugging_opts + .symbol_mangling_version + .unwrap_or(SymbolManglingVersion::default()), crate_deps, dylib_dependency_formats, diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 1d949e020ed..49b1cf92600 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -22,6 +22,7 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, }; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_session::lint; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TargetDataLayout}; @@ -708,7 +709,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 3 { self.eval_rvalue_with_identities(rvalue, place) } else { self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place)) @@ -886,7 +887,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// Returns `true` if and only if this `op` should be const-propagated into. fn should_const_prop(&mut self, op: OpTy<'tcx>) -> bool { - let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level; + let mir_opt_level = + self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); if mir_opt_level == 0 { return false; @@ -1056,7 +1058,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { // Only const prop copies and moves on `mir_opt_level=2` as doing so // currently slightly increases compile time in some cases. - if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 2 { self.propagate_operand(operand) } } diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs index 46de5dba6e0..2363b6d58e1 100644 --- a/compiler/rustc_mir/src/transform/dest_prop.rs +++ b/compiler/rustc_mir/src/transform/dest_prop.rs @@ -115,6 +115,7 @@ use rustc_middle::mir::{ Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; // Empirical measurements have resulted in some observations: // - Running on a body with a single block and 500 locals takes barely any time @@ -129,7 +130,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove // storage statements at the moment). - if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index f91477911a4..023561923ee 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -1,6 +1,7 @@ use crate::{transform::MirPass, util::patch::MirPatch}; use rustc_middle::mir::*; use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use std::fmt::Debug; use super::simplify::simplify_cfg; @@ -26,7 +27,7 @@ pub struct EarlyOtherwiseBranch; impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { return; } trace!("running EarlyOtherwiseBranch on {:?}", body.source); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 4eeb8969bb1..1a927f9bf50 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -9,6 +9,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{hygiene::ExpnKind, ExpnData, Span}; use rustc_target::spec::abi::Abi; @@ -37,15 +38,7 @@ struct CallSite<'tcx> { impl<'tcx> MirPass<'tcx> for Inline { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { - return; - } - - if tcx.sess.opts.debugging_opts.instrument_coverage { - // The current implementation of source code coverage injects code region counters - // into the MIR, and assumes a 1-to-1 correspondence between MIR and source-code- - // based function. - debug!("function inlining is disabled when compiling with `instrument_coverage`"); + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { return; } diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index 53eeecc780f..e28e3f59a5e 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -1,6 +1,7 @@ use crate::transform::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MatchBranchSimplification; @@ -38,7 +39,7 @@ pub struct MatchBranchSimplification; impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index e86d11e248f..039dfe2c0d5 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -10,6 +10,7 @@ use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{Span, Symbol}; use std::borrow::Cow; @@ -373,7 +374,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc } fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level; + let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); // Lowering generator control-flow and variables has to happen before we do anything else // to them. We run some optimizations before that, because they may be harder to do on the state diff --git a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs index 617086622cc..de4aee7ddbc 100644 --- a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs +++ b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs @@ -5,12 +5,13 @@ use crate::transform::{simplify, MirPass}; use rustc_index::bit_set::BitSet; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MultipleReturnTerminators; impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { return; } diff --git a/compiler/rustc_mir/src/transform/nrvo.rs b/compiler/rustc_mir/src/transform/nrvo.rs index ce02fb261df..6e1dc03b9cb 100644 --- a/compiler/rustc_mir/src/transform/nrvo.rs +++ b/compiler/rustc_mir/src/transform/nrvo.rs @@ -5,6 +5,7 @@ use rustc_index::bit_set::HybridBitSet; use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, BasicBlock, Local, Location}; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use crate::transform::MirPass; @@ -34,7 +35,7 @@ pub struct RenameReturnPlace; impl<'tcx> MirPass<'tcx> for RenameReturnPlace { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) == 0 { return; } diff --git a/compiler/rustc_mir/src/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs index e39c8656021..c9053ce81cd 100644 --- a/compiler/rustc_mir/src/transform/unreachable_prop.rs +++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs @@ -7,12 +7,13 @@ use crate::transform::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct UnreachablePropagation; impl MirPass<'_> for UnreachablePropagation { fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { // Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt // perf benchmark) LLVM may spend quite a lot of time optimizing the generated code. return; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 54abb65dc38..47e494b78c7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -174,6 +174,8 @@ pub enum MirSpanview { Block, } +pub const MIR_OPT_LEVEL_DEFAULT: usize = 1; + #[derive(Clone, PartialEq, Hash)] pub enum LinkerPluginLto { LinkerPlugin(PathBuf), @@ -212,6 +214,12 @@ pub enum SymbolManglingVersion { V0, } +impl SymbolManglingVersion { + pub fn default() -> Self { + SymbolManglingVersion::Legacy + } +} + impl_stable_hash_via_hash!(SymbolManglingVersion); #[derive(Clone, Copy, Debug, PartialEq, Hash)] @@ -1757,7 +1765,33 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over // multiple runs, including some changes to source code; so mangled names must be consistent // across compilations. - debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0; + match debugging_opts.symbol_mangling_version { + None => { + debugging_opts.symbol_mangling_version = Some(SymbolManglingVersion::V0); + } + Some(SymbolManglingVersion::Legacy) => { + early_warn( + error_format, + "-Z instrument-coverage requires symbol mangling version `v0`, \ + but `-Z symbol-mangling-version=legacy` was specified", + ); + } + Some(SymbolManglingVersion::V0) => {} + } + + match debugging_opts.mir_opt_level { + Some(level) if level > 1 => { + early_warn( + error_format, + &format!( + "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \ + limits the effectiveness of `-Z instrument-coverage`.", + level, + ), + ); + } + _ => {} + } } if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") { @@ -2162,7 +2196,7 @@ crate mod dep_tracking { impl_dep_tracking_hash_via_hash!(Edition); impl_dep_tracking_hash_via_hash!(LinkerPluginLto); impl_dep_tracking_hash_via_hash!(SwitchWithOptPath); - impl_dep_tracking_hash_via_hash!(SymbolManglingVersion); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(TrimmedDefPaths); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 74578f2dc17..1909550aca4 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -677,12 +677,12 @@ macro_rules! options { } fn parse_symbol_mangling_version( - slot: &mut SymbolManglingVersion, + slot: &mut Option, v: Option<&str>, ) -> bool { *slot = match v { - Some("legacy") => SymbolManglingVersion::Legacy, - Some("v0") => SymbolManglingVersion::V0, + Some("legacy") => Some(SymbolManglingVersion::Legacy), + Some("v0") => Some(SymbolManglingVersion::V0), _ => return false, }; true @@ -970,7 +970,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, mir_emit_retag: bool = (false, parse_bool, [TRACKED], "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ (default: no)"), - mir_opt_level: usize = (1, parse_uint, [TRACKED], + mir_opt_level: Option = (None, parse_opt_uint, [TRACKED], "MIR optimization level (0-3; default: 1)"), mutable_noalias: bool = (false, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: no)"), @@ -1088,9 +1088,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), strip: Strip = (Strip::None, parse_strip, [UNTRACKED], "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), - symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy, + symbol_mangling_version: Option = (None, parse_symbol_mangling_version, [TRACKED], - "which mangling version to use for symbol names"), + "which mangling version to use for symbol names ('legacy' (default) or 'v0')"), teach: bool = (false, parse_bool, [TRACKED], "show extended diagnostic help (default: no)"), terminal_width: Option = (None, parse_opt_uint, [UNTRACKED], diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 10245d21b63..945e788a146 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -245,7 +245,11 @@ fn compute_symbol_name( // 2. we favor `instantiating_crate` where possible (i.e. when `Some`) let mangling_version_crate = instantiating_crate.unwrap_or(def_id.krate); let mangling_version = if mangling_version_crate == LOCAL_CRATE { - tcx.sess.opts.debugging_opts.symbol_mangling_version + tcx.sess + .opts + .debugging_opts + .symbol_mangling_version + .unwrap_or(SymbolManglingVersion::default()) } else { tcx.symbol_mangling_version(mangling_version_crate) }; diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index ef31c72481a..9e5ae21f702 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -41,7 +41,7 @@ fn arg_value<'a, T: Deref>( match arg.next().or_else(|| args.next()) { Some(v) if pred(v) => return Some(v), - _ => {}, + _ => {} } } None @@ -85,7 +85,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // run on the unoptimized MIR. On the other hand this results in some false negatives. If // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. - config.opts.debugging_opts.mir_opt_level = 0; + config.opts.debugging_opts.mir_opt_level = Some(0); } } @@ -121,11 +121,12 @@ You can use tool lints to allow or deny lints from your code, eg.: const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new"; -static ICE_HOOK: SyncLazy) + Sync + Send + 'static>> = SyncLazy::new(|| { - let hook = panic::take_hook(); - panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL))); - hook -}); +static ICE_HOOK: SyncLazy) + Sync + Send + 'static>> = + SyncLazy::new(|| { + let hook = panic::take_hook(); + panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL))); + hook + }); fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Invoke our ICE handler, which prints the actual panic message and optionally a backtrace @@ -257,14 +258,17 @@ pub fn main() { // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument. // We're invoking the compiler programmatically, so we ignore this/ - let wrapper_mode = orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref()); + let wrapper_mode = + orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref()); if wrapper_mode { // we still want to be able to invoke it normally though orig_args.remove(1); } - if !wrapper_mode && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) { + if !wrapper_mode + && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) + { display_help(); exit(0); } @@ -285,13 +289,11 @@ pub fn main() { if clippy_enabled { args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]); if let Ok(extra_args) = env::var("CLIPPY_ARGS") { - args.extend(extra_args.split("__CLIPPY_HACKERY__").filter_map(|s| { - if s.is_empty() { - None - } else { - Some(s.to_string()) - } - })); + args.extend( + extra_args + .split("__CLIPPY_HACKERY__") + .filter_map(|s| if s.is_empty() { None } else { Some(s.to_string()) }), + ); } } let mut clippy = ClippyCallbacks; -- cgit 1.4.1-3-g733a5 From a9ff4bd838a976e0215d3b6c06014eabc028550e Mon Sep 17 00:00:00 2001 From: Tomasz MiÄ…sko Date: Tue, 15 Dec 2020 00:00:00 +0000 Subject: Always run intrinsics lowering pass Move intrinsics lowering pass from the optimization phase (where it would not run if -Zmir-opt-level=0), to the drop lowering phase where it runs unconditionally. The implementation of those intrinsics in code generation and interpreter is unnecessary. Remove it. --- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 16 +---------- compiler/rustc_mir/src/interpret/intrinsics.rs | 31 ++++++---------------- compiler/rustc_mir/src/transform/mod.rs | 2 +- ...er_intrinsics.discriminant.LowerIntrinsics.diff | 4 +++ .../lower_intrinsics.forget.LowerIntrinsics.diff | 8 ++++++ ...lower_intrinsics.non_const.LowerIntrinsics.diff | 4 +++ .../lower_intrinsics.size_of.LowerIntrinsics.diff | 4 +++ ...wer_intrinsics.unreachable.LowerIntrinsics.diff | 4 +++ .../lower_intrinsics.wrapping.LowerIntrinsics.diff | 4 +++ 9 files changed, 38 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 72a64a8c510..34022643101 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -83,9 +83,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - sym::unreachable => { - return; - } sym::va_start => bx.va_start(args[0].immediate()), sym::va_end => bx.va_end(args[0].immediate()), sym::size_of_val => { @@ -106,8 +103,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes()) } } - sym::size_of - | sym::pref_align_of + sym::pref_align_of | sym::min_align_of | sym::needs_drop | sym::type_id @@ -119,10 +115,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .unwrap(); OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx) } - // Effectively no-op - sym::forget => { - return; - } sym::offset => { let ptr = args[0].immediate(); let offset = args[1].immediate(); @@ -218,9 +210,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow - | sym::wrapping_add - | sym::wrapping_sub - | sym::wrapping_mul | sym::unchecked_div | sym::unchecked_rem | sym::unchecked_shl @@ -254,9 +243,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - sym::wrapping_add => bx.add(args[0].immediate(), args[1].immediate()), - sym::wrapping_sub => bx.sub(args[0].immediate(), args[1].immediate()), - sym::wrapping_mul => bx.mul(args[0].immediate(), args[1].immediate()), sym::exact_div => { if signed { bx.exactsdiv(args[0].immediate(), args[1].immediate()) diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index dfd77a8fca9..474e1f8e577 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -61,12 +61,11 @@ crate fn eval_nullary_intrinsic<'tcx>( ConstValue::Slice { data: alloc, start: 0, end: alloc.len() } } sym::needs_drop => ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)), - sym::size_of | sym::min_align_of | sym::pref_align_of => { + sym::min_align_of | sym::pref_align_of => { let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; let n = match name { sym::pref_align_of => layout.align.pref.bytes(), sym::min_align_of => layout.align.abi.bytes(), - sym::size_of => layout.size.bytes(), _ => bug!(), }; ConstValue::from_machine_usize(n, &tcx) @@ -125,7 +124,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let (dest, ret) = match ret { None => match intrinsic_name { sym::transmute => throw_ub_format!("transmuting to uninhabited type"), - sym::unreachable => throw_ub!(Unreachable), sym::abort => M::abort(self, "the program aborted execution".to_owned())?, // Unsupported diverging intrinsic. _ => return Ok(false), @@ -160,13 +158,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::min_align_of | sym::pref_align_of | sym::needs_drop - | sym::size_of | sym::type_id | sym::type_name | sym::variant_count => { let gid = GlobalId { instance, promoted: None }; let ty = match intrinsic_name { - sym::min_align_of | sym::pref_align_of | sym::size_of | sym::variant_count => { + sym::min_align_of | sym::pref_align_of | sym::variant_count => { self.tcx.types.usize } sym::needs_drop => self.tcx.types.bool, @@ -212,28 +209,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let out_val = numeric_intrinsic(intrinsic_name, bits, kind)?; self.write_scalar(out_val, dest)?; } - sym::wrapping_add - | sym::wrapping_sub - | sym::wrapping_mul - | sym::add_with_overflow - | sym::sub_with_overflow - | sym::mul_with_overflow => { + sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { let lhs = self.read_immediate(args[0])?; let rhs = self.read_immediate(args[1])?; - let (bin_op, ignore_overflow) = match intrinsic_name { - sym::wrapping_add => (BinOp::Add, true), - sym::wrapping_sub => (BinOp::Sub, true), - sym::wrapping_mul => (BinOp::Mul, true), - sym::add_with_overflow => (BinOp::Add, false), - sym::sub_with_overflow => (BinOp::Sub, false), - sym::mul_with_overflow => (BinOp::Mul, false), + let bin_op = match intrinsic_name { + sym::add_with_overflow => BinOp::Add, + sym::sub_with_overflow => BinOp::Sub, + sym::mul_with_overflow => BinOp::Mul, _ => bug!("Already checked for int ops"), }; - if ignore_overflow { - self.binop_ignore_overflow(bin_op, lhs, rhs, dest)?; - } else { - self.binop_with_overflow(bin_op, lhs, rhs, dest)?; - } + self.binop_with_overflow(bin_op, lhs, rhs, dest)?; } sym::saturating_add | sym::saturating_sub => { let l = self.read_immediate(args[0])?; diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index 809e29fb982..7f3b421cf76 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -364,6 +364,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late, // but before optimizations begin. &add_retag::AddRetag, + &lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::new("elaborate-drops"), // `Deaggregator` is conceptually part of MIR building, some backends rely on it happening // and it can help optimizations. @@ -392,7 +393,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // The main optimizations that we do on MIR. let optimizations: &[&dyn MirPass<'tcx>] = &[ - &lower_intrinsics::LowerIntrinsics, &remove_unneeded_drops::RemoveUnneededDrops, &match_branches::MatchBranchSimplification, // inst combine is after MatchBranchSimplification to clean up Ne(_1, false) diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff index a21cbfa767e..7da2ff02006 100644 --- a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -120,5 +120,9 @@ bb5: { return; // scope 0 at $DIR/lower_intrinsics.rs:73:2: 73:2 } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/lower_intrinsics.rs:68:1: 73:2 + } } diff --git a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff index 6b2d3833c2f..e9cc72f2138 100644 --- a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff @@ -25,7 +25,15 @@ StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:19:40: 19:41 StorageDead(_2); // scope 0 at $DIR/lower_intrinsics.rs:19:43: 19:44 _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:18:24: 20:2 + goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:20:1: 20:2 + } + + bb2: { return; // scope 0 at $DIR/lower_intrinsics.rs:20:2: 20:2 } + + bb3 (cleanup): { + resume; // scope 0 at $DIR/lower_intrinsics.rs:18:1: 20:2 + } } diff --git a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff index e973014c40d..218b1c96433 100644 --- a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff @@ -27,5 +27,9 @@ StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:59:1: 59:2 return; // scope 0 at $DIR/lower_intrinsics.rs:59:2: 59:2 } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/lower_intrinsics.rs:55:1: 59:2 + } } diff --git a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff index 262385e9f5e..b5a77702a8e 100644 --- a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff @@ -16,5 +16,9 @@ bb1: { return; // scope 0 at $DIR/lower_intrinsics.rs:15:2: 15:2 } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/lower_intrinsics.rs:13:1: 15:2 + } } diff --git a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff index b58cb333244..a04b79d47d4 100644 --- a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff @@ -18,5 +18,9 @@ - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(Scalar()) } + unreachable; // scope 1 at $DIR/lower_intrinsics.rs:24:14: 24:45 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/lower_intrinsics.rs:23:1: 25:2 + } } diff --git a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff index ce03ce90e52..badfef30e6f 100644 --- a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff @@ -79,5 +79,9 @@ StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:10:1: 10:2 return; // scope 0 at $DIR/lower_intrinsics.rs:10:2: 10:2 } + + bb4 (cleanup): { + resume; // scope 0 at $DIR/lower_intrinsics.rs:6:1: 10:2 + } } -- cgit 1.4.1-3-g733a5 From 0b18ed833c4406d8fc654b9f4990d2f80dc205c4 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Mon, 14 Dec 2020 07:35:03 -0500 Subject: Disable the constant debuginfo promotion pass by default It doesn't work correctly on *-pc-windows-gnu --- compiler/rustc_mir/src/transform/const_debuginfo.rs | 6 +++++- src/test/incremental/hashes/let_expressions.rs | 4 ++-- src/test/mir-opt/const_debuginfo.rs | 2 +- ...s_into_variable.main.SimplifyLocals.after.32bit.mir | 18 +++++++++++++++--- ...s_into_variable.main.SimplifyLocals.after.64bit.mir | 18 +++++++++++++++--- ...76997_inline_scopes_parenting.main.Inline.after.mir | 6 +++++- .../lower_intrinsics.f_u64.PreCodegen.before.mir | 2 +- ...t_loops.change_loop_body.PreCodegen.after.32bit.mir | 6 +++++- ...t_loops.change_loop_body.PreCodegen.after.64bit.mir | 6 +++++- 9 files changed, 54 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/const_debuginfo.rs b/compiler/rustc_mir/src/transform/const_debuginfo.rs index ed2c48b3568..3cdaf4c7dcd 100644 --- a/compiler/rustc_mir/src/transform/const_debuginfo.rs +++ b/compiler/rustc_mir/src/transform/const_debuginfo.rs @@ -15,7 +15,11 @@ use rustc_index::{bit_set::BitSet, vec::IndexVec}; pub struct ConstDebugInfo; impl<'tcx> MirPass<'tcx> for ConstDebugInfo { - fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + if !tcx.sess.opts.debugging_opts.unsound_mir_opts { + return; + } + trace!("running ConstDebugInfo on {:?}", body.source); for (local, constant) in find_optimization_oportunities(body) { diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs index 2c37b2e78ff..918e72582d6 100644 --- a/src/test/incremental/hashes/let_expressions.rs +++ b/src/test/incremental/hashes/let_expressions.rs @@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="hir_owner_nodes,typeck")] + except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_slot() { let _x: u64 = 0; @@ -166,7 +166,7 @@ pub fn change_mutability_of_binding_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="hir_owner_nodes,typeck")] + except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_binding_in_pattern() { let (mut _a, _b) = (99u8, 'q'); diff --git a/src/test/mir-opt/const_debuginfo.rs b/src/test/mir-opt/const_debuginfo.rs index a66d66c60c7..a188da38526 100644 --- a/src/test/mir-opt/const_debuginfo.rs +++ b/src/test/mir-opt/const_debuginfo.rs @@ -1,4 +1,4 @@ -// compile-flags: -C overflow-checks=no +// compile-flags: -C overflow-checks=no -Zunsound-mir-opts struct Point { x: u32, diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir index e4fbba3abfe..a78a6341c29 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir @@ -2,18 +2,30 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:11:11: 11:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 scope 1 { - debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 + let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 scope 2 { - debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 scope 3 { - debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 } } } bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 + _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 + StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + _2 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 + StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + _3 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 _0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 } } diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir index e4fbba3abfe..a78a6341c29 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir @@ -2,18 +2,30 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:11:11: 11:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 scope 1 { - debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 + let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 scope 2 { - debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 scope 3 { - debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 } } } bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 + _1 = const 4_i32; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18 + StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 + _2 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 + StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + _3 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 _0 = const (); // scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 } } diff --git a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir index 4abbad2c1ef..3d386e3b175 100644 --- a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir @@ -11,8 +11,9 @@ fn main() -> () { debug f => _1; // in scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:5:9: 5:10 scope 2 (inlined main::{closure#0}) { // at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 debug x => _5; // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 + let _6: (); // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 scope 3 { - debug y => const (); // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 + debug y => _6; // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 } } } @@ -26,7 +27,10 @@ fn main() -> () { (_3.0: ()) = move _4; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 StorageLive(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 _5 = move (_3.0: ()); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 + StorageLive(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 + _6 = const (); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 _0 = const (); // scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 + StorageDead(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 StorageDead(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10 StorageDead(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:9: 6:10 StorageDead(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:6:9: 6:10 diff --git a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir index bd4f148285b..654dd8275c9 100644 --- a/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir +++ b/src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir @@ -3,7 +3,7 @@ fn f_u64() -> () { let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:34:16: 34:16 scope 1 (inlined f_dispatch::) { // at $DIR/lower_intrinsics.rs:35:5: 35:21 - debug t => const 0_u64; // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 + debug t => _2; // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 let _1: (); // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 let mut _2: u64; // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21 scope 2 (inlined std::mem::size_of::) { // at $DIR/lower_intrinsics.rs:35:5: 35:21 diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir index cb3632e0fb1..dae0cbb65a4 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir +++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir @@ -2,12 +2,16 @@ fn change_loop_body() -> () { let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:5:27: 5:27 + let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 scope 1 { - debug _x => const 0_i32; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 + debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 } bb0: { + StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 + _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19 _0 = const (); // scope 1 at $DIR/while_let_loops.rs:7:5: 10:6 + StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:11:1: 11:2 return; // scope 0 at $DIR/while_let_loops.rs:11:2: 11:2 } } diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir index cb3632e0fb1..dae0cbb65a4 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir +++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir @@ -2,12 +2,16 @@ fn change_loop_body() -> () { let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:5:27: 5:27 + let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 scope 1 { - debug _x => const 0_i32; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 + debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 } bb0: { + StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15 + _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19 _0 = const (); // scope 1 at $DIR/while_let_loops.rs:7:5: 10:6 + StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:11:1: 11:2 return; // scope 0 at $DIR/while_let_loops.rs:11:2: 11:2 } } -- cgit 1.4.1-3-g733a5 From 36c639a2ce2808c2c95cacf0856026235ad6350f Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 14 Dec 2020 13:12:15 -0800 Subject: Convenience funcs for `some_option.unwrap_or(...)` This ensures consistent handling of default values for options that are None if not specified on the command line. --- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +---- compiler/rustc_mir/src/transform/const_prop.rs | 8 ++---- compiler/rustc_mir/src/transform/dest_prop.rs | 3 +- .../src/transform/early_otherwise_branch.rs | 3 +- compiler/rustc_mir/src/transform/inline.rs | 3 +- compiler/rustc_mir/src/transform/match_branches.rs | 3 +- compiler/rustc_mir/src/transform/mod.rs | 3 +- .../src/transform/multiple_return_terminators.rs | 3 +- compiler/rustc_mir/src/transform/nrvo.rs | 3 +- .../rustc_mir/src/transform/unreachable_prop.rs | 3 +- compiler/rustc_session/src/config.rs | 33 +++++++++------------- compiler/rustc_session/src/options.rs | 2 +- compiler/rustc_symbol_mangling/src/lib.rs | 6 +--- src/tools/clippy/src/driver.rs | 2 +- 15 files changed, 29 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 7a7def0696d..3e94f163773 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -561,7 +561,7 @@ fn test_debugging_options_tracking_hash() { tracked!(link_only, true); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); - tracked!(mir_opt_level, Some(3)); + tracked!(mir_opt_level, 3); tracked!(mutable_noalias, true); tracked!(new_llvm_pass_manager, true); tracked!(no_codegen, true); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b0c75c1de9d..7b67d15f64a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -663,12 +663,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins), panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime), profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime), - symbol_mangling_version: tcx - .sess - .opts - .debugging_opts - .symbol_mangling_version - .unwrap_or(SymbolManglingVersion::default()), + symbol_mangling_version: tcx.sess.opts.debugging_opts.get_symbol_mangling_version(), crate_deps, dylib_dependency_formats, diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 49b1cf92600..1d949e020ed 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -22,7 +22,6 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, }; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_session::lint; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TargetDataLayout}; @@ -709,7 +708,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 3 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 { self.eval_rvalue_with_identities(rvalue, place) } else { self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place)) @@ -887,8 +886,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// Returns `true` if and only if this `op` should be const-propagated into. fn should_const_prop(&mut self, op: OpTy<'tcx>) -> bool { - let mir_opt_level = - self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); + let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level; if mir_opt_level == 0 { return false; @@ -1058,7 +1056,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { // Only const prop copies and moves on `mir_opt_level=2` as doing so // currently slightly increases compile time in some cases. - if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 2 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { self.propagate_operand(operand) } } diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs index 2363b6d58e1..46de5dba6e0 100644 --- a/compiler/rustc_mir/src/transform/dest_prop.rs +++ b/compiler/rustc_mir/src/transform/dest_prop.rs @@ -115,7 +115,6 @@ use rustc_middle::mir::{ Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; // Empirical measurements have resulted in some observations: // - Running on a body with a single block and 500 locals takes barely any time @@ -130,7 +129,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove // storage statements at the moment). - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index 023561923ee..f91477911a4 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -1,7 +1,6 @@ use crate::{transform::MirPass, util::patch::MirPatch}; use rustc_middle::mir::*; use rustc_middle::ty::{Ty, TyCtxt}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use std::fmt::Debug; use super::simplify::simplify_cfg; @@ -27,7 +26,7 @@ pub struct EarlyOtherwiseBranch; impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { return; } trace!("running EarlyOtherwiseBranch on {:?}", body.source); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 1a927f9bf50..6e7575c1d71 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -9,7 +9,6 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{hygiene::ExpnKind, ExpnData, Span}; use rustc_target::spec::abi::Abi; @@ -38,7 +37,7 @@ struct CallSite<'tcx> { impl<'tcx> MirPass<'tcx> for Inline { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { return; } diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index e28e3f59a5e..53eeecc780f 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -1,7 +1,6 @@ use crate::transform::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MatchBranchSimplification; @@ -39,7 +38,7 @@ pub struct MatchBranchSimplification; impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index 039dfe2c0d5..e86d11e248f 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -10,7 +10,6 @@ use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{Span, Symbol}; use std::borrow::Cow; @@ -374,7 +373,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc } fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); + let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level; // Lowering generator control-flow and variables has to happen before we do anything else // to them. We run some optimizations before that, because they may be harder to do on the state diff --git a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs index de4aee7ddbc..617086622cc 100644 --- a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs +++ b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs @@ -5,13 +5,12 @@ use crate::transform::{simplify, MirPass}; use rustc_index::bit_set::BitSet; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MultipleReturnTerminators; impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { return; } diff --git a/compiler/rustc_mir/src/transform/nrvo.rs b/compiler/rustc_mir/src/transform/nrvo.rs index 6e1dc03b9cb..ce02fb261df 100644 --- a/compiler/rustc_mir/src/transform/nrvo.rs +++ b/compiler/rustc_mir/src/transform/nrvo.rs @@ -5,7 +5,6 @@ use rustc_index::bit_set::HybridBitSet; use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, BasicBlock, Local, Location}; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use crate::transform::MirPass; @@ -35,7 +34,7 @@ pub struct RenameReturnPlace; impl<'tcx> MirPass<'tcx> for RenameReturnPlace { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) == 0 { + if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { return; } diff --git a/compiler/rustc_mir/src/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs index c9053ce81cd..e39c8656021 100644 --- a/compiler/rustc_mir/src/transform/unreachable_prop.rs +++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs @@ -7,13 +7,12 @@ use crate::transform::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct UnreachablePropagation; impl MirPass<'_> for UnreachablePropagation { fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { // Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt // perf benchmark) LLVM may spend quite a lot of time optimizing the generated code. return; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 47e494b78c7..b77a8b631e0 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -174,8 +174,6 @@ pub enum MirSpanview { Block, } -pub const MIR_OPT_LEVEL_DEFAULT: usize = 1; - #[derive(Clone, PartialEq, Hash)] pub enum LinkerPluginLto { LinkerPlugin(PathBuf), @@ -214,12 +212,6 @@ pub enum SymbolManglingVersion { V0, } -impl SymbolManglingVersion { - pub fn default() -> Self { - SymbolManglingVersion::Legacy - } -} - impl_stable_hash_via_hash!(SymbolManglingVersion); #[derive(Clone, Copy, Debug, PartialEq, Hash)] @@ -700,6 +692,10 @@ impl DebuggingOptions { deduplicate_diagnostics: self.deduplicate_diagnostics, } } + + pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion { + self.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy) + } } // The type of entry function, so users can have their own entry functions @@ -1779,18 +1775,15 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { Some(SymbolManglingVersion::V0) => {} } - match debugging_opts.mir_opt_level { - Some(level) if level > 1 => { - early_warn( - error_format, - &format!( - "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \ - limits the effectiveness of `-Z instrument-coverage`.", - level, - ), - ); - } - _ => {} + if debugging_opts.mir_opt_level > 1 { + early_warn( + error_format, + &format!( + "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \ + limits the effectiveness of `-Z instrument-coverage`.", + debugging_opts.mir_opt_level, + ), + ); } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 1909550aca4..49a7888fd6a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -970,7 +970,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, mir_emit_retag: bool = (false, parse_bool, [TRACKED], "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ (default: no)"), - mir_opt_level: Option = (None, parse_opt_uint, [TRACKED], + mir_opt_level: usize = (1, parse_uint, [TRACKED], "MIR optimization level (0-3; default: 1)"), mutable_noalias: bool = (false, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: no)"), diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 945e788a146..7f8cded0ac0 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -245,11 +245,7 @@ fn compute_symbol_name( // 2. we favor `instantiating_crate` where possible (i.e. when `Some`) let mangling_version_crate = instantiating_crate.unwrap_or(def_id.krate); let mangling_version = if mangling_version_crate == LOCAL_CRATE { - tcx.sess - .opts - .debugging_opts - .symbol_mangling_version - .unwrap_or(SymbolManglingVersion::default()) + tcx.sess.opts.debugging_opts.get_symbol_mangling_version() } else { tcx.symbol_mangling_version(mangling_version_crate) }; diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 9e5ae21f702..87dd19c5d4d 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -85,7 +85,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // run on the unoptimized MIR. On the other hand this results in some false negatives. If // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. - config.opts.debugging_opts.mir_opt_level = Some(0); + config.opts.debugging_opts.mir_opt_level = 0; } } -- cgit 1.4.1-3-g733a5 From 89fc5034f4f8bca86cbf2c29c8c00366a7b4a33c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 14 Dec 2020 19:06:41 -0500 Subject: Remove unnecessary unwrap_or This was always questionable, and removing it doesn't fail any tests, so I think this was not affecting the behavior. It dates all the way back to the very first commit of rustdoc: 268f3f0ff5d80544ca21d565354eae6d3e29fb91 --- src/librustdoc/clean/mod.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a63a5092ca..1a004231a10 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -254,7 +254,6 @@ impl Clean for doctree::Module<'_> { cx, ); Item { - name: Some(what_rustc_thinks.name.unwrap_or_default()), attrs, source: span.clean(cx), ..what_rustc_thinks -- cgit 1.4.1-3-g733a5 From 7d452430fa9b3f9c7660c90adb2f05e4c4453336 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 14 Dec 2020 18:44:59 -0500 Subject: Get rid of `clean::Deprecation` This brings the size of `item.deprecation` from 56 to 16 bytes. --- compiler/rustc_attr/src/builtin.rs | 2 +- src/librustdoc/clean/mod.rs | 10 ---------- src/librustdoc/clean/types.rs | 11 ++--------- src/librustdoc/html/render/mod.rs | 19 +++++++++++++------ src/librustdoc/json/conversions.rs | 9 +++++---- 5 files changed, 21 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index bb7562bc80c..ead90f23ce7 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -621,7 +621,7 @@ pub fn eval_condition( } } -#[derive(Encodable, Decodable, Clone, HashStable_Generic)] +#[derive(Debug, Encodable, Decodable, Clone, HashStable_Generic)] pub struct Deprecation { pub since: Option, /// The note to issue a reason. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a63a5092ca..d62bd44dcf1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2342,16 +2342,6 @@ impl Clean for (&hir::MacroDef<'_>, Option) { } } -impl Clean for attr::Deprecation { - fn clean(&self, _: &DocContext<'_>) -> Deprecation { - Deprecation { - since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()), - note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()), - is_since_rustc_version: self.is_since_rustc_version, - } - } -} - impl Clean for hir::TypeBinding<'_> { fn clean(&self, cx: &DocContext<'_>) -> TypeBinding { TypeBinding { name: self.ident.name.clean(cx), kind: self.kind.clean(cx) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0228d63ac00..26b630440a1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -12,7 +12,7 @@ use rustc_ast::attr; use rustc_ast::util::comments::beautify_doc_string; use rustc_ast::{self as ast, AttrStyle}; use rustc_ast::{FloatTy, IntTy, UintTy}; -use rustc_attr::{ConstStability, Stability, StabilityLevel}; +use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_feature::UnstableFeatures; use rustc_hir as hir; @@ -156,7 +156,7 @@ impl Item { attrs: cx.tcx.get_attrs(def_id).clean(cx), visibility: cx.tcx.visibility(def_id).clean(cx), stability: cx.tcx.lookup_stability(def_id).cloned(), - deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx), + deprecation: cx.tcx.lookup_deprecation(def_id), const_stability: cx.tcx.lookup_const_stability(def_id).cloned(), } } @@ -1793,13 +1793,6 @@ crate struct ProcMacro { crate helpers: Vec, } -#[derive(Clone, Debug)] -crate struct Deprecation { - crate since: Option, - crate note: Option, - crate is_since_rustc_version: bool, -} - /// An type binding on an associated type (e.g., `A = Bar` in `Foo` or /// `A: Send + Sync` in `Foo`). #[derive(Clone, PartialEq, Eq, Debug, Hash)] diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index db04624dca8..5a120172c94 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -49,7 +49,7 @@ use std::sync::Arc; use itertools::Itertools; use rustc_ast_pretty::pprust; -use rustc_attr::StabilityLevel; +use rustc_attr::{Deprecation, StabilityLevel}; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; @@ -65,7 +65,7 @@ use rustc_span::symbol::{sym, Symbol}; use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; -use crate::clean::{self, AttributesExt, Deprecation, GetDefId, RenderedLink, SelfTy, TypeKind}; +use crate::clean::{self, AttributesExt, GetDefId, RenderedLink, SelfTy, TypeKind}; use crate::config::{RenderInfo, RenderOptions}; use crate::docfs::{DocFS, PathError}; use crate::doctree; @@ -2219,7 +2219,10 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String { // The trailing space after each tag is to space it properly against the rest of the docs. if let Some(depr) = &item.deprecation { let mut message = "Deprecated"; - if !stability::deprecation_in_effect(depr.is_since_rustc_version, depr.since.as_deref()) { + if !stability::deprecation_in_effect( + depr.is_since_rustc_version, + depr.since.map(|s| s.as_str()).as_deref(), + ) { message = "Deprecation planned"; } tags += &tag_html("deprecated", "", message); @@ -2268,20 +2271,24 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item let mut extra_info = vec![]; let error_codes = cx.shared.codes; - if let Some(Deprecation { ref note, ref since, is_since_rustc_version }) = item.deprecation { + if let Some(Deprecation { note, since, is_since_rustc_version, suggestion: _ }) = + item.deprecation + { // We display deprecation messages for #[deprecated] and #[rustc_deprecated] // but only display the future-deprecation messages for #[rustc_deprecated]. let mut message = if let Some(since) = since { + let since = &since.as_str(); if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) { - format!("Deprecating in {}", Escape(&since)) + format!("Deprecating in {}", Escape(since)) } else { - format!("Deprecated since {}", Escape(&since)) + format!("Deprecated since {}", Escape(since)) } } else { String::from("Deprecated") }; if let Some(note) = note { + let note = note.as_str(); let mut ids = cx.id_map.borrow_mut(); let html = MarkdownHtml( ¬e, diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index c463481db86..2da38be6ebe 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -77,10 +77,11 @@ impl JsonRenderer { } } -impl From for Deprecation { - fn from(deprecation: clean::Deprecation) -> Self { - let clean::Deprecation { since, note, is_since_rustc_version: _ } = deprecation; - Deprecation { since, note } +impl From for Deprecation { + fn from(deprecation: rustc_attr::Deprecation) -> Self { + #[rustfmt::skip] + let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation; + Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) } } } -- cgit 1.4.1-3-g733a5 From a16904fecf0ad1c46f9c11c6b193bdbb6421bf17 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 14 Dec 2020 19:30:36 -0500 Subject: Switch to Symbol for item.name This decreases the size of `Item` from 680 to 616 bytes. It also does a lot less work since it no longer has to copy as much. --- compiler/rustc_span/src/symbol.rs | 4 ++ src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 22 +++++------ src/librustdoc/clean/types.rs | 48 +++++++++++++++++++----- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/formats/renderer.rs | 3 +- src/librustdoc/html/render/cache.rs | 2 +- src/librustdoc/html/render/mod.rs | 27 ++++++------- src/librustdoc/json/conversions.rs | 2 +- src/librustdoc/passes/collect_intra_doc_links.rs | 11 +++++- 10 files changed, 78 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b60d466c3a7..f61a32a0f79 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1469,6 +1469,10 @@ impl Symbol { self.0.as_u32() } + pub fn is_empty(self) -> bool { + self == kw::Invalid + } + /// This method is supposed to be used in error messages, so it's expected to be /// identical to printing the original identifier token written in source code /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index f7b6553a935..d358a7a369d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -124,7 +124,7 @@ crate fn try_inline( let attrs = merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone); cx.renderinfo.borrow_mut().inlined.insert(did); - let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name.clean(cx)), kind, cx); + let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx); ret.push(clean::Item { attrs, ..what_rustc_thinks }); Some(ret) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a004231a10..2d2465e56f3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -169,7 +169,7 @@ impl Clean for CrateNum { for attr in attrs.lists(sym::doc) { if attr.has_name(sym::keyword) { if let Some(v) = attr.value_str() { - keyword = Some(v.to_string()); + keyword = Some(v); break; } } @@ -253,11 +253,7 @@ impl Clean for doctree::Module<'_> { ModuleItem(Module { is_crate: self.is_crate, items }), cx, ); - Item { - attrs, - source: span.clean(cx), - ..what_rustc_thinks - } + Item { attrs, source: span.clean(cx), ..what_rustc_thinks } } } @@ -1095,7 +1091,7 @@ impl Clean for hir::TraitItem<'_> { AssocTypeItem(bounds.clean(cx), default.clean(cx)) } }; - Item::from_def_id_and_parts(local_did, Some(self.ident.name.clean(cx)), inner, cx) + Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx) }) } } @@ -1123,7 +1119,7 @@ impl Clean for hir::ImplItem<'_> { TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true) } }; - Item::from_def_id_and_parts(local_did, Some(self.ident.name.clean(cx)), inner, cx) + Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx) }) } } @@ -1280,7 +1276,7 @@ impl Clean for ty::AssocItem { } }; - Item::from_def_id_and_parts(self.def_id, Some(self.ident.name.clean(cx)), kind, cx) + Item::from_def_id_and_parts(self.def_id, Some(self.ident.name), kind, cx) } } @@ -1770,7 +1766,7 @@ impl Clean for ty::FieldDef { fn clean(&self, cx: &DocContext<'_>) -> Item { let what_rustc_thinks = Item::from_def_id_and_parts( self.did, - Some(self.ident.name.clean(cx)), + Some(self.ident.name), StructFieldItem(cx.tcx.type_of(self.did).clean(cx)), cx, ); @@ -1846,7 +1842,7 @@ impl Clean for ty::VariantDef { .fields .iter() .map(|field| { - let name = Some(field.ident.name.clean(cx)); + let name = Some(field.ident.name); let kind = StructFieldItem(cx.tcx.type_of(field.did).clean(cx)); let what_rustc_thinks = Item::from_def_id_and_parts(field.did, name, kind, cx); @@ -1858,7 +1854,7 @@ impl Clean for ty::VariantDef { }; let what_rustc_thinks = Item::from_def_id_and_parts( self.def_id, - Some(self.ident.name.clean(cx)), + Some(self.ident.name), VariantItem(Variant { kind }), cx, ); @@ -2032,7 +2028,7 @@ impl Clean> for (&hir::Item<'_>, Option) { _ => unreachable!("not yet converted"), }; - vec![Item::from_def_id_and_parts(def_id, Some(name.clean(cx)), kind, cx)] + vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)] }) } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0228d63ac00..2c353a1e081 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -70,7 +70,7 @@ crate struct ExternalCrate { crate src: FileName, crate attrs: Attributes, crate primitives: Vec<(DefId, PrimitiveType)>, - crate keywords: Vec<(DefId, String)>, + crate keywords: Vec<(DefId, Symbol)>, } /// Anything with a source location and set of attributes and, optionally, a @@ -81,7 +81,7 @@ crate struct Item { /// Stringified span crate source: Span, /// Not everything has a name. E.g., impls - crate name: Option, + crate name: Option, crate attrs: Attributes, crate visibility: Visibility, crate kind: ItemKind, @@ -123,17 +123,12 @@ impl Item { kind: ItemKind, cx: &DocContext<'_>, ) -> Item { - Item::from_def_id_and_parts( - cx.tcx.hir().local_def_id(hir_id).to_def_id(), - name.clean(cx), - kind, - cx, - ) + Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx) } pub fn from_def_id_and_parts( def_id: DefId, - name: Option, + name: Option, kind: ItemKind, cx: &DocContext<'_>, ) -> Item { @@ -334,7 +329,7 @@ crate enum ItemKind { AssocTypeItem(Vec, Option), /// An item that has been stripped by a rustdoc pass StrippedItem(Box), - KeywordItem(String), + KeywordItem(Symbol), } impl ItemKind { @@ -1163,6 +1158,8 @@ crate enum Type { } #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)] +/// N.B. this has to be different from `hir::PrimTy` because it also includes types that aren't +/// paths, like `Unit`. crate enum PrimitiveType { Isize, I8, @@ -1502,6 +1499,37 @@ impl PrimitiveType { crate fn to_url_str(&self) -> &'static str { self.as_str() } + + crate fn as_sym(&self) -> Symbol { + use PrimitiveType::*; + match self { + Isize => sym::isize, + I8 => sym::i8, + I16 => sym::i16, + I32 => sym::i32, + I64 => sym::i64, + I128 => sym::i128, + Usize => sym::usize, + U8 => sym::u8, + U16 => sym::u16, + U32 => sym::u32, + U64 => sym::u64, + U128 => sym::u128, + F32 => sym::f32, + F64 => sym::f64, + Str => sym::str, + Bool => sym::bool, + Char => sym::char, + Array => sym::array, + Slice => sym::slice, + Tuple => sym::tuple, + Unit => sym::unit, + RawPointer => sym::pointer, + Reference => sym::reference, + Fn => kw::Fn, + Never => sym::never, + } + } } impl From for PrimitiveType { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 1b22d26f49b..f8743a4c42e 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -68,7 +68,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { m.items.extend(primitives.iter().map(|&(def_id, prim)| { Item::from_def_id_and_parts( def_id, - Some(prim.to_url_str().to_owned()), + Some(prim.as_sym()), ItemKind::PrimitiveItem(prim), cx, ) diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 6334524eb1c..c332da4db4e 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use rustc_data_structures::sync::Lrc; use rustc_session::Session; use rustc_span::edition::Edition; +use rustc_span::Symbol; use crate::clean; use crate::config::{RenderInfo, RenderOptions}; @@ -75,7 +76,7 @@ crate fn run_format( None => return Ok(()), }; - item.name = Some(krate.name.clone()); + item.name = Some(Symbol::intern(&krate.name)); // Render the crate documentation let mut work = vec![(format_renderer.clone(), item)]; diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 97f764517fa..91037bc160a 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -76,7 +76,7 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { if let Some(&(ref fqp, _)) = paths.get(&did) { search_index.push(IndexItem { ty: item.type_(), - name: item.name.clone().unwrap(), + name: item.name.unwrap().to_string(), path: fqp[..fqp.len() - 1].join("::"), desc: item.doc_value().map_or_else(|| String::new(), short_markdown_summary), parent: Some(did), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index db04624dca8..00f3723ce23 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -61,7 +61,7 @@ use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::FileName; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{kw, sym, Symbol}; use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; @@ -665,7 +665,7 @@ impl FormatRenderer for Context { if !buf.is_empty() { let name = item.name.as_ref().unwrap(); let item_type = item.type_(); - let file_name = &item_path(item_type, name); + let file_name = &item_path(item_type, &name.as_str()); self.shared.ensure_dir(&self.dst)?; let joint_dst = self.dst.join(file_name); self.shared.fs.write(&joint_dst, buf.as_bytes())?; @@ -1543,7 +1543,7 @@ impl Context { if !title.is_empty() { title.push_str("::"); } - title.push_str(it.name.as_ref().unwrap()); + title.push_str(&it.name.unwrap().as_str()); } title.push_str(" - Rust"); let tyname = it.type_(); @@ -1815,7 +1815,7 @@ fn item_path(ty: ItemType, name: &str) -> String { fn full_path(cx: &Context, item: &clean::Item) -> String { let mut s = cx.current.join("::"); s.push_str("::"); - s.push_str(item.name.as_ref().unwrap()); + s.push_str(&item.name.unwrap().as_str()); s } @@ -2065,9 +2065,9 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: (true, false) => return Ordering::Greater, } } - let lhs = i1.name.as_ref().map_or("", |s| &**s); - let rhs = i2.name.as_ref().map_or("", |s| &**s); - compare_names(lhs, rhs) + let lhs = i1.name.unwrap_or(kw::Invalid).as_str(); + let rhs = i2.name.unwrap_or(kw::Invalid).as_str(); + compare_names(&lhs, &rhs) } if cx.shared.sort_modules_alphabetically { @@ -2191,7 +2191,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: add = add, stab = stab.unwrap_or_else(String::new), unsafety_flag = unsafety_flag, - href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()), + href = item_path(myitem.type_(), &myitem.name.unwrap().as_str()), title = [full_path(cx, myitem), myitem.type_().to_string()] .iter() .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None }) @@ -2623,7 +2623,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, fn trait_item(w: &mut Buffer, cx: &Context, m: &clean::Item, t: &clean::Item, cache: &Cache) { let name = m.name.as_ref().unwrap(); - info!("Documenting {} on {}", name, t.name.as_deref().unwrap_or_default()); + info!("Documenting {} on {:?}", name, t.name); let item_type = m.type_(); let id = cx.derive_id(format!("{}.{}", item_type, name)); write!(w, "

", id = id,); @@ -2951,7 +2951,7 @@ fn render_assoc_item( AssocItemLink::GotoSource(did, provided_methods) => { // We're creating a link from an impl-item to the corresponding // trait-item and need to map the anchored type accordingly. - let ty = if provided_methods.contains(name) { + let ty = if provided_methods.contains(&*name.as_str()) { ItemType::Method } else { ItemType::TyMethod @@ -3434,10 +3434,7 @@ fn render_assoc_items( what: AssocItemRender<'_>, cache: &Cache, ) { - info!( - "Documenting associated items of {}", - containing_item.name.as_deref().unwrap_or_default() - ); + info!("Documenting associated items of {:?}", containing_item.name); let v = match cache.impls.get(&it) { Some(v) => v, None => return, @@ -4139,7 +4136,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca ty: \"{ty}\", \ relpath: \"{path}\"\ }};", - name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), + name = it.name.unwrap_or(kw::Invalid), ty = it.type_(), path = relpath ); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index c463481db86..49de4c6d2e7 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -33,7 +33,7 @@ impl JsonRenderer { _ => Some(Item { id: def_id.into(), crate_id: def_id.krate.as_u32(), - name, + name: name.map(|sym| sym.to_string()), source: self.convert_span(source), visibility: visibility.into(), docs: attrs.collapsed_doc_value().unwrap_or_default(), diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 7358eae6edc..3ec2d4b7c51 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -668,7 +668,7 @@ fn resolve_associated_trait_item( // Give precedence to methods that were overridden if !impl_.provided_trait_methods.contains(&*item_name.as_str()) { let mut items = impl_.items.into_iter().filter_map(|assoc| { - if assoc.name.as_deref() != Some(&*item_name.as_str()) { + if assoc.name != Some(item_name) { return None; } let kind = assoc @@ -1942,7 +1942,14 @@ fn privacy_error( dox: &str, link_range: Option>, ) { - let item_name = item.name.as_deref().unwrap_or(""); + let sym; + let item_name = match item.name { + Some(name) => { + sym = name.as_str(); + &*sym + } + None => "", + }; let msg = format!("public documentation for `{}` links to private item `{}`", item_name, path_str); -- cgit 1.4.1-3-g733a5 From 6580f11a5239296d55c717fbe54fa2f71b861469 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 3 Dec 2020 20:14:11 -0500 Subject: Don't look for blanket impls in intra-doc links This never worked and has been causing severe performance problems. Hopefully it will be re-landed at some point in the future when it actually works, but in the meantime it makes no sense to have the code around when it does nothing and actively makes rustdoc harder to use. --- src/librustdoc/clean/types.rs | 11 +--- src/librustdoc/passes/collect_intra_doc_links.rs | 83 ++++-------------------- 2 files changed, 15 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2c353a1e081..699dbda3216 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -21,7 +21,7 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::Mutability; use rustc_index::vec::IndexVec; -use rustc_middle::ty::{AssocKind, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DUMMY_SP; @@ -375,15 +375,6 @@ impl ItemKind { _ => false, } } - - crate fn as_assoc_kind(&self) -> Option { - match *self { - ItemKind::AssocConstItem(..) => Some(AssocKind::Const), - ItemKind::AssocTypeItem(..) => Some(AssocKind::Type), - ItemKind::TyMethodItem(..) | ItemKind::MethodItem(..) => Some(AssocKind::Fn), - _ => None, - } - } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index dc6f8ed6cbb..f9d81fb8635 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -31,7 +31,7 @@ use std::cell::Cell; use std::mem; use std::ops::Range; -use crate::clean::{self, Crate, GetDefId, Item, ItemLink, PrimitiveType}; +use crate::clean::{self, Crate, Item, ItemLink, PrimitiveType}; use crate::core::DocContext; use crate::fold::DocFolder; use crate::html::markdown::markdown_links; @@ -685,78 +685,23 @@ fn resolve_associated_trait_item( ns: Namespace, cx: &DocContext<'_>, ) -> Option<(ty::AssocKind, DefId)> { - let ty = cx.tcx.type_of(did); - // First consider blanket impls: `impl From for T` - let implicit_impls = crate::clean::get_auto_trait_and_blanket_impls(cx, ty, did); - let mut candidates: Vec<_> = implicit_impls - .flat_map(|impl_outer| { - match impl_outer.kind { - clean::ImplItem(impl_) => { - debug!("considering auto or blanket impl for trait {:?}", impl_.trait_); - // Give precedence to methods that were overridden - if !impl_.provided_trait_methods.contains(&*item_name.as_str()) { - let mut items = impl_.items.into_iter().filter_map(|assoc| { - if assoc.name != Some(item_name) { - return None; - } - let kind = assoc - .kind - .as_assoc_kind() - .expect("inner items for a trait should be associated items"); - if kind.namespace() != ns { - return None; - } - - trace!("considering associated item {:?}", assoc.kind); - // We have a slight issue: normal methods come from `clean` types, - // but provided methods come directly from `tcx`. - // Fortunately, we don't need the whole method, we just need to know - // what kind of associated item it is. - Some((kind, assoc.def_id)) - }); - let assoc = items.next(); - debug_assert_eq!(items.count(), 0); - assoc - } else { - // These are provided methods or default types: - // ``` - // trait T { - // type A = usize; - // fn has_default() -> A { 0 } - // } - // ``` - let trait_ = impl_.trait_.unwrap().def_id().unwrap(); - cx.tcx - .associated_items(trait_) - .find_by_name_and_namespace( - cx.tcx, - Ident::with_dummy_span(item_name), - ns, - trait_, - ) - .map(|assoc| (assoc.kind, assoc.def_id)) - } - } - _ => panic!("get_impls returned something that wasn't an impl"), - } - }) - .collect(); + // FIXME: this should also consider blanket impls (`impl X for T`). Unfortunately + // `get_auto_trait_and_blanket_impls` is broken because the caching behavior is wrong. In the + // meantime, just don't look for these blanket impls. // Next consider explicit impls: `impl MyTrait for MyType` // Give precedence to inherent impls. - if candidates.is_empty() { - let traits = traits_implemented_by(cx, did, module); - debug!("considering traits {:?}", traits); - candidates.extend(traits.iter().filter_map(|&trait_| { - cx.tcx - .associated_items(trait_) - .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, trait_) - .map(|assoc| (assoc.kind, assoc.def_id)) - })); - } + let traits = traits_implemented_by(cx, did, module); + debug!("considering traits {:?}", traits); + let mut candidates = traits.iter().filter_map(|&trait_| { + cx.tcx + .associated_items(trait_) + .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, trait_) + .map(|assoc| (assoc.kind, assoc.def_id)) + }); // FIXME(#74563): warn about ambiguity - debug!("the candidates were {:?}", candidates); - candidates.pop() + debug!("the candidates were {:?}", candidates.clone().collect::>()); + candidates.next() } /// Given a type, return all traits in scope in `module` implemented by that type. -- cgit 1.4.1-3-g733a5 From 5afb95a6ca94071a67fb4ab74a1636ea7dfaaa5d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 15 Dec 2020 20:47:06 -0500 Subject: Test that `core::assert!` is valid --- src/test/ui/no-std-macros.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/no-std-macros.rs (limited to 'src') diff --git a/src/test/ui/no-std-macros.rs b/src/test/ui/no-std-macros.rs new file mode 100644 index 00000000000..ada643c7ac0 --- /dev/null +++ b/src/test/ui/no-std-macros.rs @@ -0,0 +1,13 @@ +// compile-flags: --crate-type=lib +// check-pass +// issue #55482 +#![no_std] + +macro_rules! foo { + ($e:expr) => { + $crate::core::assert!($e); + $crate::core::assert_eq!($e, true); + }; +} + +pub fn foo() { foo!(true); } -- cgit 1.4.1-3-g733a5 From c18c7c7059cb1c63aad9892ecbed58c229c74098 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 14 Dec 2020 22:28:24 -0500 Subject: Remove redundant assignment `crate.name` is already set by `tcx.crate_name`, there's no need to override it. --- src/librustdoc/lib.rs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 94b6617a071..24045b4e29d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -519,17 +519,12 @@ fn main_options(options: config::Options) -> MainResult { // compiler all the way through the analysis passes. The rustdoc output is // then generated from the cleaned AST of the crate. This runs all the // plug/cleaning passes. - let crate_name = options.crate_name.clone(); let crate_version = options.crate_version.clone(); let output_format = options.output_format; let (mut krate, renderinfo, renderopts, sess) = core::run_core(options); info!("finished with rustc"); - if let Some(name) = crate_name { - krate.name = name - } - krate.version = crate_version; if show_coverage { -- cgit 1.4.1-3-g733a5 From 7ee8e1816f6603502e36b105990bca0f7e440816 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 14 Dec 2020 23:23:58 -0500 Subject: Use `Symbol`s for crate names --- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/types.rs | 4 ++-- src/librustdoc/formats/cache.rs | 11 ++++++----- src/librustdoc/formats/renderer.rs | 3 +-- src/librustdoc/html/render/cache.rs | 2 +- src/librustdoc/html/render/mod.rs | 28 ++++++++++++++++------------ src/librustdoc/html/sources.rs | 2 +- src/librustdoc/json/mod.rs | 2 +- 8 files changed, 29 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2d2465e56f3..a531956fb96 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -209,7 +209,7 @@ impl Clean for CrateNum { }; ExternalCrate { - name: cx.tcx.crate_name(*self).to_string(), + name: cx.tcx.crate_name(*self), src: krate_src, attrs: cx.tcx.get_attrs(root).clean(cx), primitives, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 2c353a1e081..cf9e81f30b1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -51,7 +51,7 @@ thread_local!(crate static MAX_DEF_ID: RefCell> = Def #[derive(Clone, Debug)] crate struct Crate { - crate name: String, + crate name: Symbol, crate version: Option, crate src: FileName, crate module: Option, @@ -66,7 +66,7 @@ crate struct Crate { #[derive(Clone, Debug)] crate struct ExternalCrate { - crate name: String, + crate name: Symbol, crate src: FileName, crate attrs: Attributes, crate primitives: Vec<(DefId, PrimitiveType)>, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index e82bc540e95..77a3e9fa954 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -8,6 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_middle::middle::privacy::AccessLevels; use rustc_span::source_map::FileName; +use rustc_span::Symbol; use crate::clean::{self, GetDefId}; use crate::config::RenderInfo; @@ -74,7 +75,7 @@ crate struct Cache { crate implementors: FxHashMap>, /// Cache of where external crate documentation can be found. - crate extern_locations: FxHashMap, + crate extern_locations: FxHashMap, /// Cache of where documentation for primitives can be found. crate primitive_locations: FxHashMap, @@ -173,10 +174,10 @@ impl Cache { }, _ => PathBuf::new(), }; - let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u); + let extern_url = extern_html_root_urls.get(&*e.name.as_str()).map(|u| &**u); cache .extern_locations - .insert(n, (e.name.clone(), src_root, extern_location(e, extern_url, &dst))); + .insert(n, (e.name, src_root, extern_location(e, extern_url, &dst))); let did = DefId { krate: n, index: CRATE_DEF_INDEX }; cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module)); @@ -195,7 +196,7 @@ impl Cache { cache.primitive_locations.insert(prim, def_id); } - cache.stack.push(krate.name.clone()); + cache.stack.push(krate.name.to_string()); krate = cache.fold_crate(krate); for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) { @@ -340,7 +341,7 @@ impl DocFolder for Cache { // Keep track of the fully qualified path for this item. let pushed = match item.name { - Some(ref n) if !n.is_empty() => { + Some(n) if !n.is_empty() => { self.stack.push(n.to_string()); true } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index c332da4db4e..f61919d78a0 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use rustc_data_structures::sync::Lrc; use rustc_session::Session; use rustc_span::edition::Edition; -use rustc_span::Symbol; use crate::clean; use crate::config::{RenderInfo, RenderOptions}; @@ -76,7 +75,7 @@ crate fn run_format( None => return Ok(()), }; - item.name = Some(Symbol::intern(&krate.name)); + item.name = Some(krate.name); // Render the crate documentation let mut work = vec![(format_renderer.clone(), item)]; diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 91037bc160a..ba06b6b182b 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -31,7 +31,7 @@ crate fn extern_location( ) -> ExternalLocation { use ExternalLocation::*; // See if there's documentation generated into the local directory - let local_location = dst.join(&e.name); + let local_location = dst.join(&*e.name.as_str()); if local_location.is_dir() { return Local; } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 00f3723ce23..d517151bc31 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -418,14 +418,15 @@ impl FormatRenderer for Context { // If user passed in `--playground-url` arg, we fill in crate name here let mut playground = None; if let Some(url) = playground_url { - playground = Some(markdown::Playground { crate_name: Some(krate.name.clone()), url }); + playground = + Some(markdown::Playground { crate_name: Some(krate.name.to_string()), url }); } let mut layout = layout::Layout { logo: String::new(), favicon: String::new(), external_html, default_settings, - krate: krate.name.clone(), + krate: krate.name.to_string(), css_file_extension: extension_css, generate_search_filter, }; @@ -445,7 +446,7 @@ impl FormatRenderer for Context { } (sym::html_playground_url, Some(s)) => { playground = Some(markdown::Playground { - crate_name: Some(krate.name.clone()), + crate_name: Some(krate.name.to_string()), url: s.to_string(), }); } @@ -530,7 +531,7 @@ impl FormatRenderer for Context { } fn after_krate(&mut self, krate: &clean::Crate, cache: &Cache) -> Result<(), Error> { - let final_file = self.dst.join(&krate.name).join("all.html"); + let final_file = self.dst.join(&*krate.name.as_str()).join("all.html"); let settings_file = self.dst.join("settings.html"); let crate_name = krate.name.clone(); @@ -1019,7 +1020,8 @@ themePicker.onblur = handleThemeButtonsBlur; } let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix)); - let (mut all_sources, _krates) = try_err!(collect(&dst, &krate.name, "sourcesIndex"), &dst); + let (mut all_sources, _krates) = + try_err!(collect(&dst, &krate.name.as_str(), "sourcesIndex"), &dst); all_sources.push(format!( "sourcesIndex[\"{}\"] = {};", &krate.name, @@ -1035,7 +1037,7 @@ themePicker.onblur = handleThemeButtonsBlur; // Update the search index let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix)); - let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name), &dst); + let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name.as_str()), &dst); all_indexes.push(search_index); // Sort the indexes by crate so the file will be generated identically even @@ -1070,7 +1072,7 @@ themePicker.onblur = handleThemeButtonsBlur; extra_scripts: &[], static_extra_scripts: &[], }; - krates.push(krate.name.clone()); + krates.push(krate.name.to_string()); krates.sort(); krates.dedup(); @@ -1162,7 +1164,7 @@ themePicker.onblur = handleThemeButtonsBlur; mydst.push(&format!("{}.{}.js", remote_item_type, remote_path[remote_path.len() - 1])); let (mut all_implementors, _) = - try_err!(collect(&mydst, &krate.name, "implementors"), &mydst); + try_err!(collect(&mydst, &krate.name.as_str(), "implementors"), &mydst); all_implementors.push(implementors); // Sort the implementors by crate so the file will be generated // identically even with rustdoc running in parallel. @@ -1648,16 +1650,17 @@ impl Context { }; let file = &file; + let symbol; let (krate, path) = if cnum == LOCAL_CRATE { if let Some(path) = self.shared.local_sources.get(file) { - (&self.shared.layout.krate, path) + (self.shared.layout.krate.as_str(), path) } else { return None; } } else { let (krate, src_root) = match *cache.extern_locations.get(&cnum)? { - (ref name, ref src, ExternalLocation::Local) => (name, src), - (ref name, ref src, ExternalLocation::Remote(ref s)) => { + (name, ref src, ExternalLocation::Local) => (name, src), + (name, ref src, ExternalLocation::Remote(ref s)) => { root = s.to_string(); (name, src) } @@ -1671,7 +1674,8 @@ impl Context { let mut fname = file.file_name().expect("source has no filename").to_os_string(); fname.push(".html"); path.push_str(&fname.to_string_lossy()); - (krate, &path) + symbol = krate.as_str(); + (&*symbol, &path) }; let loline = item.source.lo(self.sess()).line; diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index ef9e9f350fb..b6c3300906b 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -19,7 +19,7 @@ crate fn render( krate: clean::Crate, ) -> Result { info!("emitting source files"); - let dst = dst.join("src").join(&krate.name); + let dst = dst.join("src").join(&*krate.name.as_str()); scx.ensure_dir(&dst)?; let mut folder = SourceCollector { dst, scx }; Ok(folder.fold_crate(krate)) diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 5c5239d1b6a..7af26558b76 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -223,7 +223,7 @@ impl FormatRenderer for JsonRenderer { ( k.as_u32(), types::ExternalCrate { - name: v.0.clone(), + name: v.0.to_string(), html_root_url: match &v.2 { ExternalLocation::Remote(s) => Some(s.clone()), _ => None, -- cgit 1.4.1-3-g733a5 From 1d6b455fb476115712cf7246c5f4cecb7c66915b Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Tue, 15 Dec 2020 23:33:47 -0800 Subject: Fixed conflict with drop elaboration and coverage See https://github.com/rust-lang/rust/issues/80045#issuecomment-745733339 Coverage statements are moved to the beginning of the BCB. This does also affect what's counted before a panic, changing some results, but I think these results may even be preferred? In any case, there are no guarantees about what's counted when a panic occurs (by design). --- compiler/rustc_mir/src/transform/coverage/mod.rs | 4 ++-- .../coverage_graphviz.bar.InstrumentCoverage.0.dot | 2 +- .../coverage_graphviz.main.InstrumentCoverage.0.dot | 2 +- .../instrument_coverage.bar.InstrumentCoverage.diff | 2 +- .../instrument_coverage.main.InstrumentCoverage.diff | 8 ++++---- .../expected_export_coverage.assert.json | 20 ++++++++++---------- .../expected_export_coverage.overflow.json | 20 ++++++++++---------- .../expected_export_coverage.panic_unwind.json | 20 ++++++++++---------- .../expected_show_coverage.assert.txt | 8 ++++---- .../expected_show_coverage.overflow.txt | 10 +++++----- .../expected_show_coverage.panic_unwind.txt | 8 ++++---- .../expected_show_coverage_counters.assert.txt | 16 ++++++++-------- .../expected_show_coverage_counters.overflow.txt | 16 ++++++++-------- .../expected_show_coverage_counters.panic_unwind.txt | 16 ++++++++-------- 14 files changed, 76 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index 53f7c28ee35..4590d37c182 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -310,7 +310,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { inject_statement( self.mir_body, counter_kind, - self.bcb_last_bb(bcb), + self.bcb_leader_bb(bcb), Some(make_code_region(file_name, &self.source_file, span, body_span)), ); } @@ -470,7 +470,7 @@ fn inject_statement( code_region: some_code_region, }), }; - data.statements.push(statement); + data.statements.insert(0, statement); } // Non-code expressions are injected into the coverage map, without generating executable code. diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot index 124f2d8b97a..c00eae96e08 100644 --- a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot +++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot @@ -2,5 +2,5 @@ digraph Cov_0_4 { graph [fontname="Courier, monospace"]; node [fontname="Courier, monospace"]; edge [fontname="Courier, monospace"]; - bcb0__Cov_0_4 [shape="none", label=<
bcb0
Counter(bcb0) at 18:1-20:2
19:5-19:9: @0[0]: _0 = const true
20:2-20:2: @0.Return: return
bb0: Return
>]; + bcb0__Cov_0_4 [shape="none", label=<
bcb0
Counter(bcb0) at 18:1-20:2
19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2
20:2-20:2: @0.Return: return
bb0: Return
>]; } diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot index d88193da4fb..5b6d73a7dee 100644 --- a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot +++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot @@ -2,7 +2,7 @@ digraph Cov_0_3 { graph [fontname="Courier, monospace"]; node [fontname="Courier, monospace"]; edge [fontname="Courier, monospace"]; - bcb2__Cov_0_3 [shape="none", label=<
bcb2
Expression(bcb0 - bcb1) at 13:10-13:10
13:10-13:10: @4[0]: _1 = const ()
bb4: Goto
>]; + bcb2__Cov_0_3 [shape="none", label=<
bcb2
Expression(bcb0 - bcb1) at 13:10-13:10
13:10-13:10: @4[0]: Coverage::Expression(4294967295) = 1 - 2 for $DIR/coverage_graphviz.rs:13:10 - 13:11
bb4: Goto
>]; bcb1__Cov_0_3 [shape="none", label=<
bcb1
Counter(bcb1) at 12:13-12:18
12:13-12:18: @5[0]: _0 = const ()
Expression(bcb1 + 0) at 15:2-15:2
15:2-15:2: @5.Return: return
bb3: FalseEdge
bb5: Return
>]; bcb0__Cov_0_3 [shape="none", label=<
bcb0
Counter(bcb0) at 9:1-11:17
11:12-11:17: @1.Call: _2 = bar() -> [return: bb2, unwind: bb6]
11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)
bb0: FalseUnwind
bb1: Call
bb2: SwitchInt
>]; bcb2__Cov_0_3 -> bcb0__Cov_0_3 [label=<>]; diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff index 112a6983092..fef696df770 100644 --- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff @@ -5,8 +5,8 @@ let mut _0: bool; // return place in scope 0 at /the/src/instrument_coverage.rs:19:13: 19:17 bb0: { - _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9 + Coverage::Counter(1) for /the/src/instrument_coverage.rs:19:1 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 + _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9 return; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 } } diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 83dee7efa6d..9bd8c9cf613 100644 --- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -8,6 +8,7 @@ let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10 bb0: { ++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 falseUnwind -> [real: bb1, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } @@ -21,26 +22,25 @@ bb2: { FakeRead(ForMatchedPlace, _2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 -+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 switchInt(_2) -> [false: bb4, otherwise: bb3]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 } bb3: { ++ Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 ++ Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 } bb4: { ++ Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:14:10: 14:10 StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 -+ Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 goto -> bb0; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } bb5: { _0 = const (); // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18 StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 -+ Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 -+ Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 return; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json index 024b5f11179..bb857ba3f3b 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json +++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json @@ -17,14 +17,14 @@ }, "lines": { "count": 15, - "covered": 12, - "percent": 80 + "covered": 13, + "percent": 86.66666666666667 }, "regions": { "count": 14, - "covered": 12, - "notcovered": 2, - "percent": 85.71428571428571 + "covered": 13, + "notcovered": 1, + "percent": 92.85714285714286 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 15, - "covered": 12, - "percent": 80 + "covered": 13, + "percent": 86.66666666666667 }, "regions": { "count": 14, - "covered": 12, - "notcovered": 2, - "percent": 85.71428571428571 + "covered": 13, + "notcovered": 1, + "percent": 92.85714285714286 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json index 030d7b033f0..128f5888ed1 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json +++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json @@ -17,14 +17,14 @@ }, "lines": { "count": 23, - "covered": 19, - "percent": 82.6086956521739 + "covered": 21, + "percent": 91.30434782608695 }, "regions": { "count": 13, - "covered": 11, - "notcovered": 2, - "percent": 84.61538461538461 + "covered": 12, + "notcovered": 1, + "percent": 92.3076923076923 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 23, - "covered": 19, - "percent": 82.6086956521739 + "covered": 21, + "percent": 91.30434782608695 }, "regions": { "count": 13, - "covered": 11, - "notcovered": 2, - "percent": 84.61538461538461 + "covered": 12, + "notcovered": 1, + "percent": 92.3076923076923 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json index b1d44fdfeac..9c08dfd41a1 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json +++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json @@ -17,14 +17,14 @@ }, "lines": { "count": 19, - "covered": 16, - "percent": 84.21052631578947 + "covered": 17, + "percent": 89.47368421052632 }, "regions": { "count": 13, - "covered": 11, - "notcovered": 2, - "percent": 84.61538461538461 + "covered": 12, + "notcovered": 1, + "percent": 92.3076923076923 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 19, - "covered": 16, - "percent": 84.21052631578947 + "covered": 17, + "percent": 89.47368421052632 }, "regions": { "count": 13, - "covered": 11, - "notcovered": 2, - "percent": 84.61538461538461 + "covered": 12, + "notcovered": 1, + "percent": 92.3076923076923 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt index 355b53f7f3b..405688806ea 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt @@ -9,13 +9,13 @@ 8| | 9| 1|fn main() -> Result<(),u8> { 10| 1| let mut countdown = 10; - 11| 10| while countdown > 0 { - 12| 10| if countdown == 1 { - 13| 0| might_fail_assert(3); + 11| 11| while countdown > 0 { + 12| 11| if countdown == 1 { + 13| 1| might_fail_assert(3); 14| 10| } else if countdown < 5 { 15| 3| might_fail_assert(2); 16| 6| } - 17| 9| countdown -= 1; + 17| 10| countdown -= 1; 18| | } 19| 0| Ok(()) 20| 0|} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt index 4dccb3413ea..25e822bffd1 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt @@ -14,15 +14,15 @@ 14| | 15| 1|fn main() -> Result<(),u8> { 16| 1| let mut countdown = 10; - 17| 10| while countdown > 0 { - 18| 10| if countdown == 1 { - 19| 0| let result = might_overflow(10); - 20| 0| println!("Result: {}", result); + 17| 11| while countdown > 0 { + 18| 11| if countdown == 1 { + 19| 1| let result = might_overflow(10); + 20| 1| println!("Result: {}", result); 21| 10| } else if countdown < 5 { 22| 3| let result = might_overflow(1); 23| 3| println!("Result: {}", result); 24| 6| } - 25| 9| countdown -= 1; + 25| 10| countdown -= 1; 26| | } 27| 0| Ok(()) 28| 0|} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt index 9ae78fee4b5..c77ee5ddc20 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt @@ -12,13 +12,13 @@ 12| | 13| 1|fn main() -> Result<(), u8> { 14| 1| let mut countdown = 10; - 15| 10| while countdown > 0 { - 16| 10| if countdown == 1 { - 17| 0| might_panic(true); + 15| 11| while countdown > 0 { + 16| 11| if countdown == 1 { + 17| 1| might_panic(true); 18| 10| } else if countdown < 5 { 19| 3| might_panic(false); 20| 6| } - 21| 9| countdown -= 1; + 21| 10| countdown -= 1; 22| | } 23| 0| Ok(()) 24| 0|} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt index 916ebbbcc29..0866a9a59a1 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt @@ -20,13 +20,13 @@ Combined regions: 6:37 -> 6:61 (count=1) 7:1 -> 7:2 (count=3) 9:1 -> 10:27 (count=1) - 11:11 -> 11:24 (count=10) - 12:12 -> 12:26 (count=10) - 12:27 -> 14:10 (count=0) + 11:11 -> 11:24 (count=11) + 12:12 -> 12:26 (count=11) + 12:27 -> 14:10 (count=1) 14:19 -> 14:32 (count=10) 14:33 -> 16:10 (count=3) 16:10 -> 16:11 (count=6) - 17:9 -> 17:23 (count=9) + 17:9 -> 17:23 (count=10) 19:5 -> 20:2 (count=0) Segment at 4:1 (count = 4), RegionEntry Segment at 4:41 (count = 0), Skipped @@ -40,18 +40,18 @@ Segment at 7:1 (count = 3), RegionEntry Segment at 7:2 (count = 0), Skipped Segment at 9:1 (count = 1), RegionEntry Segment at 10:27 (count = 0), Skipped -Segment at 11:11 (count = 10), RegionEntry +Segment at 11:11 (count = 11), RegionEntry Segment at 11:24 (count = 0), Skipped -Segment at 12:12 (count = 10), RegionEntry +Segment at 12:12 (count = 11), RegionEntry Segment at 12:26 (count = 0), Skipped -Segment at 12:27 (count = 0), RegionEntry +Segment at 12:27 (count = 1), RegionEntry Segment at 14:10 (count = 0), Skipped Segment at 14:19 (count = 10), RegionEntry Segment at 14:32 (count = 0), Skipped Segment at 14:33 (count = 3), RegionEntry Segment at 16:10 (count = 6), RegionEntry Segment at 16:11 (count = 0), Skipped -Segment at 17:9 (count = 9), RegionEntry +Segment at 17:9 (count = 10), RegionEntry Segment at 17:23 (count = 0), Skipped Segment at 19:5 (count = 0), RegionEntry Segment at 20:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt index fbc3adbfb6d..380bb7cf170 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt @@ -18,13 +18,13 @@ Combined regions: 7:6 -> 7:7 (count=3) 8:9 -> 13:2 (count=4) 15:1 -> 16:27 (count=1) - 17:11 -> 17:24 (count=10) - 18:12 -> 18:26 (count=10) - 18:27 -> 21:10 (count=0) + 17:11 -> 17:24 (count=11) + 18:12 -> 18:26 (count=11) + 18:27 -> 21:10 (count=1) 21:19 -> 21:32 (count=10) 21:33 -> 24:10 (count=3) 24:10 -> 24:11 (count=6) - 25:9 -> 25:23 (count=9) + 25:9 -> 25:23 (count=10) 27:5 -> 28:2 (count=0) Segment at 4:1 (count = 4), RegionEntry Segment at 5:18 (count = 0), Skipped @@ -35,18 +35,18 @@ Segment at 8:9 (count = 4), RegionEntry Segment at 13:2 (count = 0), Skipped Segment at 15:1 (count = 1), RegionEntry Segment at 16:27 (count = 0), Skipped -Segment at 17:11 (count = 10), RegionEntry +Segment at 17:11 (count = 11), RegionEntry Segment at 17:24 (count = 0), Skipped -Segment at 18:12 (count = 10), RegionEntry +Segment at 18:12 (count = 11), RegionEntry Segment at 18:26 (count = 0), Skipped -Segment at 18:27 (count = 0), RegionEntry +Segment at 18:27 (count = 1), RegionEntry Segment at 21:10 (count = 0), Skipped Segment at 21:19 (count = 10), RegionEntry Segment at 21:32 (count = 0), Skipped Segment at 21:33 (count = 3), RegionEntry Segment at 24:10 (count = 6), RegionEntry Segment at 24:11 (count = 0), Skipped -Segment at 25:9 (count = 9), RegionEntry +Segment at 25:9 (count = 10), RegionEntry Segment at 25:23 (count = 0), Skipped Segment at 27:5 (count = 0), RegionEntry Segment at 28:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt index ad87f03026d..b3f61ad325d 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt @@ -18,13 +18,13 @@ Combined regions: 6:9 -> 7:26 (count=1) 8:12 -> 11:2 (count=3) 13:1 -> 14:27 (count=1) - 15:11 -> 15:24 (count=10) - 16:12 -> 16:26 (count=10) - 16:27 -> 18:10 (count=0) + 15:11 -> 15:24 (count=11) + 16:12 -> 16:26 (count=11) + 16:27 -> 18:10 (count=1) 18:19 -> 18:32 (count=10) 18:33 -> 20:10 (count=3) 20:10 -> 20:11 (count=6) - 21:9 -> 21:23 (count=9) + 21:9 -> 21:23 (count=10) 23:5 -> 24:2 (count=0) Segment at 4:1 (count = 4), RegionEntry Segment at 4:36 (count = 0), Skipped @@ -36,18 +36,18 @@ Segment at 8:12 (count = 3), RegionEntry Segment at 11:2 (count = 0), Skipped Segment at 13:1 (count = 1), RegionEntry Segment at 14:27 (count = 0), Skipped -Segment at 15:11 (count = 10), RegionEntry +Segment at 15:11 (count = 11), RegionEntry Segment at 15:24 (count = 0), Skipped -Segment at 16:12 (count = 10), RegionEntry +Segment at 16:12 (count = 11), RegionEntry Segment at 16:26 (count = 0), Skipped -Segment at 16:27 (count = 0), RegionEntry +Segment at 16:27 (count = 1), RegionEntry Segment at 18:10 (count = 0), Skipped Segment at 18:19 (count = 10), RegionEntry Segment at 18:32 (count = 0), Skipped Segment at 18:33 (count = 3), RegionEntry Segment at 20:10 (count = 6), RegionEntry Segment at 20:11 (count = 0), Skipped -Segment at 21:9 (count = 9), RegionEntry +Segment at 21:9 (count = 10), RegionEntry Segment at 21:23 (count = 0), Skipped Segment at 23:5 (count = 0), RegionEntry Segment at 24:2 (count = 0), Skipped -- cgit 1.4.1-3-g733a5 From 241160de72b5b55187ca54243e2a6e82e336d07c Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 14 Oct 2020 18:16:05 +0100 Subject: bootstrap: copy `llvm-dwp` to sysroot `llvm-dwp` is required for linking the DWARF objects into DWARF packages when using Split DWARF, especially given that rustc produces multiple DWARF objects (one for each codegen unit). Signed-off-by: David Wood --- src/bootstrap/compile.rs | 20 +++++++++++++++----- src/bootstrap/dist.rs | 15 +++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index cdad1cb4d49..fbebb26c746 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -969,15 +969,25 @@ impl Step for Assemble { copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); + // We prepend this bin directory to the user PATH when linking Rust binaries. To + // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`. let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host); + let libdir_bin = libdir.parent().unwrap().join("bin"); + t!(fs::create_dir_all(&libdir_bin)); + if let Some(lld_install) = lld_install { let src_exe = exe("lld", target_compiler.host); let dst_exe = exe("rust-lld", target_compiler.host); - // we prepend this bin directory to the user PATH when linking Rust binaries. To - // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`. - let dst = libdir.parent().unwrap().join("bin"); - t!(fs::create_dir_all(&dst)); - builder.copy(&lld_install.join("bin").join(&src_exe), &dst.join(&dst_exe)); + builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe)); + } + + // Similarly, copy `llvm-dwp` into libdir for Split DWARF. + { + let src_exe = exe("llvm-dwp", target_compiler.host); + let dst_exe = exe("rust-llvm-dwp", target_compiler.host); + let llvm_config_bin = builder.ensure(native::Llvm { target: target_compiler.host }); + let llvm_bin_dir = llvm_config_bin.parent().unwrap(); + builder.copy(&llvm_bin_dir.join(&src_exe), &libdir_bin.join(&dst_exe)); } // Ensure that `libLLVM.so` ends up in the newly build compiler directory, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 360e51ed2bb..25905895116 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -523,17 +523,20 @@ impl Step for Rustc { // component for now. maybe_install_llvm_runtime(builder, host, image); + let src_dir = builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin"); + let dst_dir = image.join("lib/rustlib").join(&*host.triple).join("bin"); + t!(fs::create_dir_all(&dst_dir)); + // Copy over lld if it's there if builder.config.lld_enabled { let exe = exe("rust-lld", compiler.host); - let src = - builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin").join(&exe); - // for the rationale about this rename check `compile::copy_lld_to_sysroot` - let dst = image.join("lib/rustlib").join(&*host.triple).join("bin").join(&exe); - t!(fs::create_dir_all(&dst.parent().unwrap())); - builder.copy(&src, &dst); + builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe)); } + // Copy over llvm-dwp if it's there + let exe = exe("rust-llvm-dwp", compiler.host); + builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe)); + // Man pages t!(fs::create_dir_all(image.join("share/man/man1"))); let man_src = builder.src.join("src/doc/man"); -- cgit 1.4.1-3-g733a5 From 2b22670bdf614374b9371a229e9bcf692f58c6b3 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 8 Nov 2020 17:26:59 +0000 Subject: tests: add run-make-fulldeps split-dwarf test This commit adds a run-make-fulldeps test which checks that a DWARF package file is emitted. Signed-off-by: David Wood --- src/test/run-make-fulldeps/split-dwarf/Makefile | 8 ++++++++ src/test/run-make-fulldeps/split-dwarf/foo.rs | 1 + 2 files changed, 9 insertions(+) create mode 100644 src/test/run-make-fulldeps/split-dwarf/Makefile create mode 100644 src/test/run-make-fulldeps/split-dwarf/foo.rs (limited to 'src') diff --git a/src/test/run-make-fulldeps/split-dwarf/Makefile b/src/test/run-make-fulldeps/split-dwarf/Makefile new file mode 100644 index 00000000000..e1a78e2edfc --- /dev/null +++ b/src/test/run-make-fulldeps/split-dwarf/Makefile @@ -0,0 +1,8 @@ +-include ../tools.mk + +# only-linux + +all: + $(RUSTC) -Z split-dwarf=split foo.rs + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) diff --git a/src/test/run-make-fulldeps/split-dwarf/foo.rs b/src/test/run-make-fulldeps/split-dwarf/foo.rs new file mode 100644 index 00000000000..f328e4d9d04 --- /dev/null +++ b/src/test/run-make-fulldeps/split-dwarf/foo.rs @@ -0,0 +1 @@ +fn main() {} -- cgit 1.4.1-3-g733a5 From 99ad915e32744eb771e9a0968bf7d0d1f52a9a07 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 8 Nov 2020 17:27:33 +0000 Subject: compiletest: add split dwarf compare mode This commit adds a Split DWARF compare mode to compiletest so that debuginfo tests are also tested using Split DWARF in split mode (and manually in single mode). Signed-off-by: David Wood --- compiler/rustc_codegen_ssa/src/back/link.rs | 7 +++++++ src/bootstrap/test.rs | 7 ++++++- src/tools/compiletest/src/common.rs | 6 ++++++ src/tools/compiletest/src/header.rs | 2 ++ src/tools/compiletest/src/runtest.rs | 6 ++++++ 5 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 123d1ae55fb..ccd4d103ddb 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1037,6 +1037,13 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool { return false; } + // Single mode keeps debuginfo in the same object file, but in such a way that it it skipped + // by the linker - so it's expected that when codegen units are linked together that this + // debuginfo would be lost without keeping around the temps. + if sess.opts.debugging_opts.split_dwarf == config::SplitDwarfKind::Single { + return true; + } + // If we're on OSX then the equivalent of split dwarf is turned on by // default. The final executable won't actually have any debug information // except it'll have pointers to elsewhere. Historically we've always run diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 78b5de7897d..b99692e8ba5 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -897,7 +897,12 @@ default_test!(Incremental { suite: "incremental" }); -default_test!(Debuginfo { path: "src/test/debuginfo", mode: "debuginfo", suite: "debuginfo" }); +default_test_with_compare_mode!(Debuginfo { + path: "src/test/debuginfo", + mode: "debuginfo", + suite: "debuginfo", + compare_mode: "split-dwarf" +}); host_test!(UiFullDeps { path: "src/test/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" }); diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 55d25fa7c52..80fbb06b946 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -127,6 +127,8 @@ pub enum CompareMode { Nll, Polonius, Chalk, + SplitDwarf, + SplitDwarfSingle, } impl CompareMode { @@ -135,6 +137,8 @@ impl CompareMode { CompareMode::Nll => "nll", CompareMode::Polonius => "polonius", CompareMode::Chalk => "chalk", + CompareMode::SplitDwarf => "split-dwarf", + CompareMode::SplitDwarfSingle => "split-dwarf-single", } } @@ -143,6 +147,8 @@ impl CompareMode { "nll" => CompareMode::Nll, "polonius" => CompareMode::Polonius, "chalk" => CompareMode::Chalk, + "split-dwarf" => CompareMode::SplitDwarf, + "split-dwarf-single" => CompareMode::SplitDwarfSingle, x => panic!("unknown --compare-mode option: {}", x), } } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 59f64e7df0f..a1be0a19f68 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -852,6 +852,8 @@ impl Config { Some(CompareMode::Nll) => name == "compare-mode-nll", Some(CompareMode::Polonius) => name == "compare-mode-polonius", Some(CompareMode::Chalk) => name == "compare-mode-chalk", + Some(CompareMode::SplitDwarf) => name == "compare-mode-split-dwarf", + Some(CompareMode::SplitDwarfSingle) => name == "compare-mode-split-dwarf-single", None => false, } || (cfg!(debug_assertions) && name == "debug") || diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7af0d91271b..828c4e89f0b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2017,6 +2017,12 @@ impl<'test> TestCx<'test> { Some(CompareMode::Chalk) => { rustc.args(&["-Zchalk"]); } + Some(CompareMode::SplitDwarf) => { + rustc.args(&["-Zsplit-dwarf=split"]); + } + Some(CompareMode::SplitDwarfSingle) => { + rustc.args(&["-Zsplit-dwarf=single"]); + } None => {} } -- cgit 1.4.1-3-g733a5 From cfc38d2d0892f0842dd50cd0bd889e9ae1ea7508 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Mon, 7 Dec 2020 12:34:27 +0100 Subject: Take into account negative impls in "trait item not found" suggestions --- compiler/rustc_typeck/src/check/method/suggest.rs | 108 +++++++++++++++------ .../explicitly-unimplemented-error-message.rs | 53 ++++++++++ .../explicitly-unimplemented-error-message.stderr | 60 ++++++++++++ 3 files changed, 193 insertions(+), 28 deletions(-) create mode 100644 src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs create mode 100644 src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr (limited to 'src') diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 7ed2933c08b..0f6253493cf 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -12,6 +12,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::hir::map as hir_map; +use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; use rustc_middle::ty::{ self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, @@ -1074,19 +1075,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { "items from traits can only be used if the trait is implemented and in scope" }); + let candidates_len = candidates.len(); let message = |action| { format!( "the following {traits_define} an item `{name}`, perhaps you need to {action} \ {one_of_them}:", traits_define = - if candidates.len() == 1 { "trait defines" } else { "traits define" }, + if candidates_len == 1 { "trait defines" } else { "traits define" }, action = action, - one_of_them = if candidates.len() == 1 { "it" } else { "one of them" }, + one_of_them = if candidates_len == 1 { "it" } else { "one of them" }, name = item_name, ) }; // Obtain the span for `param` and use it for a structured suggestion. - let mut suggested = false; if let (Some(ref param), Some(ref table)) = (param_type, self.in_progress_typeck_results) { @@ -1147,7 +1148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MaybeIncorrect, ); } - suggested = true; + return; } Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), @@ -1167,45 +1168,96 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }), Applicability::MaybeIncorrect, ); - suggested = true; + return; } _ => {} } } } - if !suggested { - let action = if let Some(param) = param_type { - format!("restrict type parameter `{}` with", param) - } else { - // FIXME: it might only need to be imported into scope, not implemented. - "implement".to_string() - }; - let mut use_note = true; - if let [trait_info] = &candidates[..] { - if let Some(span) = self.tcx.hir().span_if_local(trait_info.def_id) { - err.span_note( - self.tcx.sess.source_map().guess_head_span(span), - &format!( - "`{}` defines an item `{}`, perhaps you need to {} it", - self.tcx.def_path_str(trait_info.def_id), - item_name, - action - ), - ); - use_note = false + let (potential_candidates, explicitly_negative) = if param_type.is_some() { + // FIXME: Even though negative bounds are not implemented, we could maybe handle + // cases where a positive bound implies a negative impl. + (candidates, Vec::new()) + } else if let Some(simp_rcvr_ty) = simplify_type(self.tcx, rcvr_ty, true) { + let mut potential_candidates = Vec::new(); + let mut explicitly_negative = Vec::new(); + for candidate in candidates { + // Check if there's a negative impl of `candidate` for `rcvr_ty` + if self + .tcx + .all_impls(candidate.def_id) + .filter(|imp_did| { + self.tcx.impl_polarity(*imp_did) == ty::ImplPolarity::Negative + }) + .any(|imp_did| { + let imp = self.tcx.impl_trait_ref(imp_did).unwrap(); + let imp_simp = simplify_type(self.tcx, imp.self_ty(), true); + imp_simp.map(|s| s == simp_rcvr_ty).unwrap_or(false) + }) + { + explicitly_negative.push(candidate); + } else { + potential_candidates.push(candidate); } } - if use_note { + (potential_candidates, explicitly_negative) + } else { + // We don't know enough about `recv_ty` to make proper suggestions. + (candidates, Vec::new()) + }; + + let action = if let Some(param) = param_type { + format!("restrict type parameter `{}` with", param) + } else { + // FIXME: it might only need to be imported into scope, not implemented. + "implement".to_string() + }; + match &potential_candidates[..] { + [] => {} + [trait_info] if trait_info.def_id.is_local() => { + let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap(); + err.span_note( + self.tcx.sess.source_map().guess_head_span(span), + &format!( + "`{}` defines an item `{}`, perhaps you need to {} it", + self.tcx.def_path_str(trait_info.def_id), + item_name, + action + ), + ); + } + trait_infos => { let mut msg = message(action); - for (i, trait_info) in candidates.iter().enumerate() { + for (i, trait_info) in trait_infos.iter().enumerate() { msg.push_str(&format!( "\ncandidate #{}: `{}`", i + 1, self.tcx.def_path_str(trait_info.def_id), )); } - err.note(&msg[..]); + err.note(&msg); + } + } + match &explicitly_negative[..] { + [] => {} + [trait_info] => { + let msg = format!( + "the trait `{}` defines an item `{}`, but is explicitely unimplemented", + self.tcx.def_path_str(trait_info.def_id), + item_name + ); + err.note(&msg); + } + trait_infos => { + let mut msg = format!( + "the following traits define an item `{}`, but are explicitely unimplemented:", + item_name + ); + for trait_info in trait_infos { + msg.push_str(&format!("\n{}", self.tcx.def_path_str(trait_info.def_id))); + } + err.note(&msg); } } } diff --git a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs new file mode 100644 index 00000000000..3e336933937 --- /dev/null +++ b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs @@ -0,0 +1,53 @@ +// This tests issue #79683: note in the error message that the trait is +// explicitely unimplemented instead of suggesting to implement it. + +#![feature(negative_impls)] + +struct Qux; +//~^ NOTE method `clone` not found for this +//~^^ NOTE method `foo` not found for this + +impl !Clone for Qux {} + +trait Bar { + fn bar(&self); +} + +impl !Bar for u32 {} + +trait Foo { + fn foo(&self); +} +//~^^^ NOTE `Foo` defines an item `foo`, perhaps you need to implement it + +trait FooBar { + fn foo(&self); +} + +impl !Foo for Qux {} + +impl !FooBar for Qux {} + +impl !FooBar for u32 {} + +fn main() { + Qux.clone(); + //~^ ERROR no method named `clone` found for struct `Qux` + //~| NOTE method not found in `Qux` + //~| NOTE `Clone` defines an item `clone`, but is explicitely unimplemented + + 0_u32.bar(); + //~^ ERROR no method named `bar` found for type `u32` + //~| NOTE method not found in `u32` + //~| NOTE `Bar` defines an item `bar`, but is explicitely unimplemented + + Qux.foo(); + //~^ ERROR no method named `foo` found for struct `Qux` + //~| NOTE method not found in `Qux` + //~| NOTE the following traits define an item `foo`, but are explicitely unimplemented + + 0_u32.foo(); + //~^ ERROR no method named `foo` found for type `u32` + //~| NOTE method not found in `u32` + //~| NOTE `FooBar` defines an item `foo`, but is explicitely unimplemented +} diff --git a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr new file mode 100644 index 00000000000..d39daaba206 --- /dev/null +++ b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr @@ -0,0 +1,60 @@ +error[E0599]: no method named `clone` found for struct `Qux` in the current scope + --> $DIR/explicitly-unimplemented-error-message.rs:34:9 + | +LL | struct Qux; + | ----------- method `clone` not found for this +... +LL | Qux.clone(); + | ^^^^^ method not found in `Qux` + | + ::: $SRC_DIR/core/src/clone.rs:LL:COL + | +LL | fn clone(&self) -> Self; + | ----- + | | + | the method is available for `Arc` here + | the method is available for `Rc` here + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the trait `Clone` defines an item `clone`, but is explicitely unimplemented + +error[E0599]: no method named `bar` found for type `u32` in the current scope + --> $DIR/explicitly-unimplemented-error-message.rs:39:11 + | +LL | 0_u32.bar(); + | ^^^ method not found in `u32` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the trait `Bar` defines an item `bar`, but is explicitely unimplemented + +error[E0599]: no method named `foo` found for struct `Qux` in the current scope + --> $DIR/explicitly-unimplemented-error-message.rs:44:9 + | +LL | struct Qux; + | ----------- method `foo` not found for this +... +LL | Qux.foo(); + | ^^^ method not found in `Qux` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `foo`, but are explicitely unimplemented: + Foo + FooBar + +error[E0599]: no method named `foo` found for type `u32` in the current scope + --> $DIR/explicitly-unimplemented-error-message.rs:49:11 + | +LL | 0_u32.foo(); + | ^^^ method not found in `u32` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Foo` defines an item `foo`, perhaps you need to implement it + --> $DIR/explicitly-unimplemented-error-message.rs:18:1 + | +LL | trait Foo { + | ^^^^^^^^^ + = note: the trait `FooBar` defines an item `foo`, but is explicitely unimplemented + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0599`. -- cgit 1.4.1-3-g733a5 From ffa7a01a18589e335e5199fbeab427571ff0a8d2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 15 Dec 2020 23:51:38 -0500 Subject: Add more timing info to rustdoc --- src/librustdoc/clean/utils.rs | 11 +++++---- src/librustdoc/passes/collect_trait_impls.rs | 34 ++++++++++++++++------------ 2 files changed, 26 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index f8743a4c42e..54bb93fa464 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -551,10 +551,13 @@ crate fn get_auto_trait_and_blanket_impls( ty: Ty<'tcx>, param_env_def_id: DefId, ) -> impl Iterator { - AutoTraitFinder::new(cx) - .get_auto_trait_impls(ty, param_env_def_id) - .into_iter() - .chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id)) + let auto_impls = cx.sess().time("get_auto_trait_impls", || { + AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id) + }); + let blanket_impls = cx.sess().time("get_blanket_impls", || { + BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id) + }); + auto_impls.into_iter().chain(blanket_impls) } crate fn register_res(cx: &DocContext<'_>, res: Res) -> DefId { diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 1e9bc67de04..60fcbe74872 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -16,13 +16,13 @@ crate const COLLECT_TRAIT_IMPLS: Pass = Pass { crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { let mut synth = SyntheticImplCollector::new(cx); - let mut krate = synth.fold_crate(krate); + let mut krate = cx.sess().time("collect_synthetic_impls", || synth.fold_crate(krate)); let prims: FxHashSet = krate.primitives.iter().map(|p| p.1).collect(); let crate_items = { let mut coll = ItemCollector::new(); - krate = coll.fold_crate(krate); + krate = cx.sess().time("collect_items_for_trait_impls", || coll.fold_crate(krate)); coll.items }; @@ -39,16 +39,18 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { // Also try to inline primitive impls from other crates. for &def_id in PrimitiveType::all_impls(cx.tcx).values().flatten() { if !def_id.is_local() { - inline::build_impl(cx, None, def_id, None, &mut new_items); + cx.sess().time("build_primitive_trait_impl", || { + inline::build_impl(cx, None, def_id, None, &mut new_items); - // FIXME(eddyb) is this `doc(hidden)` check needed? - if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) { - let self_ty = cx.tcx.type_of(def_id); - let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id); - let mut renderinfo = cx.renderinfo.borrow_mut(); + // FIXME(eddyb) is this `doc(hidden)` check needed? + if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) { + let self_ty = cx.tcx.type_of(def_id); + let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id); + let mut renderinfo = cx.renderinfo.borrow_mut(); - new_items.extend(impls.filter(|i| renderinfo.inlined.insert(i.def_id))); - } + new_items.extend(impls.filter(|i| renderinfo.inlined.insert(i.def_id))); + } + }) } } @@ -151,11 +153,13 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> { if i.is_struct() || i.is_enum() || i.is_union() { // FIXME(eddyb) is this `doc(hidden)` check needed? if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) { - self.impls.extend(get_auto_trait_and_blanket_impls( - self.cx, - self.cx.tcx.type_of(i.def_id), - i.def_id, - )); + self.cx.sess().time("get_auto_trait_and_blanket_synthetic_impls", || { + self.impls.extend(get_auto_trait_and_blanket_impls( + self.cx, + self.cx.tcx.type_of(i.def_id), + i.def_id, + )); + }); } } -- cgit 1.4.1-3-g733a5 From 68932060868cda5b14f8e382d28df09905572176 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 16 Dec 2020 09:10:40 -0800 Subject: Revert "Auto merge of #78790 - Gankra:rust-src-vendor, r=Mark-Simulacrum" This reverts commit 7afc5172305cdae588a0318ce545749cf4ed947d, reversing changes made to d4ea0b3e46a0303d5802b632e88ba1ba84d9d16f. --- src/bootstrap/dist.rs | 26 ++------------------------ src/bootstrap/lib.rs | 21 --------------------- 2 files changed, 2 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 25905895116..393715e5561 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1043,30 +1043,6 @@ impl Step for Src { builder.copy(&builder.src.join(file), &dst_src.join(file)); } - // libtest includes std and everything else, so vendoring it - // creates exactly what's needed for `cargo -Zbuild-std` or any - // other analysis of the stdlib's source. Cargo also needs help - // finding the lock, so we copy it to libtest temporarily. - // - // Note that this requires std to only have one version of each - // crate. e.g. two versions of getopts won't be patchable. - let dst_libtest = dst_src.join("library/test"); - let dst_vendor = dst_src.join("vendor"); - let root_lock = dst_src.join("Cargo.lock"); - let temp_lock = dst_libtest.join("Cargo.lock"); - - // `cargo vendor` will delete everything from the lockfile that - // isn't used by libtest, so we need to not use any links! - builder.really_copy(&root_lock, &temp_lock); - - let mut cmd = Command::new(&builder.initial_cargo); - cmd.arg("vendor").arg(dst_vendor).current_dir(&dst_libtest); - builder.info("Dist src"); - let _time = timeit(builder); - builder.run(&mut cmd); - - builder.remove(&temp_lock); - // Create source tarball in rust-installer format let mut cmd = rust_installer(builder); cmd.arg("generate") @@ -1083,6 +1059,8 @@ impl Step for Src { .arg("--component-name=rust-src") .arg("--legacy-manifest-dirs=rustlib,cargo"); + builder.info("Dist src"); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 06ccd72186d..ece9bdc7a64 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1182,27 +1182,6 @@ impl Build { paths } - /// Copies a file from `src` to `dst` and doesn't use links, so - /// that the copy can be modified without affecting the original. - pub fn really_copy(&self, src: &Path, dst: &Path) { - if self.config.dry_run { - return; - } - self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst)); - if src == dst { - return; - } - let _ = fs::remove_file(&dst); - let metadata = t!(src.symlink_metadata()); - if let Err(e) = fs::copy(src, dst) { - panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e) - } - t!(fs::set_permissions(dst, metadata.permissions())); - let atime = FileTime::from_last_access_time(&metadata); - let mtime = FileTime::from_last_modification_time(&metadata); - t!(filetime::set_file_times(dst, atime, mtime)); - } - /// Copies a file from `src` to `dst` pub fn copy(&self, src: &Path, dst: &Path) { if self.config.dry_run { -- cgit 1.4.1-3-g733a5 From 1e1ca28f395b4c43cc2781676dafffd4f3269989 Mon Sep 17 00:00:00 2001 From: bstrie Date: Wed, 9 Dec 2020 18:26:42 -0500 Subject: Allow `since="TBD"` for rustc_deprecated --- compiler/rustc_middle/src/middle/stability.rs | 75 ++++++++++++---------- compiler/rustc_passes/src/stability.rs | 44 +++++++------ src/librustdoc/html/render/mod.rs | 6 +- src/test/rustdoc/rustc_deprecated-future.rs | 12 +++- .../ui/deprecation/rustc_deprecation-in-future.rs | 9 ++- .../deprecation/rustc_deprecation-in-future.stderr | 16 +++-- .../stability-attribute-sanity.rs | 6 +- .../stability-attribute-sanity.stderr | 12 +++- 8 files changed, 111 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 47c140e0b18..4f08057a7e3 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -132,37 +132,37 @@ pub fn report_unstable( /// Checks whether an item marked with `deprecated(since="X")` is currently /// deprecated (i.e., whether X is not greater than the current rustc version). pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) -> bool { - let since = if let Some(since) = since { - if is_since_rustc_version { - since - } else { - // We assume that the deprecation is in effect if it's not a - // rustc version. - return true; - } - } else { - // If since attribute is not set, then we're definitely in effect. - return true; - }; fn parse_version(ver: &str) -> Vec { // We ignore non-integer components of the version (e.g., "nightly"). ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() } - if let Some(rustc) = option_env!("CFG_RELEASE") { - let since: Vec = parse_version(&since); - let rustc: Vec = parse_version(rustc); - // We simply treat invalid `since` attributes as relating to a previous - // Rust version, thus always displaying the warning. - if since.len() != 3 { - return true; - } - since <= rustc - } else { - // By default, a deprecation warning applies to - // the current version of the compiler. - true + if !is_since_rustc_version { + // The `since` field doesn't have semantic purpose in the stable `deprecated` + // attribute, only in `rustc_deprecated`. + return true; } + + if let Some(since) = since { + if since == "TBD" { + return false; + } + + if let Some(rustc) = option_env!("CFG_RELEASE") { + let since: Vec = parse_version(&since); + let rustc: Vec = parse_version(rustc); + // We simply treat invalid `since` attributes as relating to a previous + // Rust version, thus always displaying the warning. + if since.len() != 3 { + return true; + } + return since <= rustc; + } + }; + + // Assume deprecation is in effect if "since" field is missing + // or if we can't determine the current Rust version. + true } pub fn deprecation_suggestion( @@ -182,19 +182,24 @@ pub fn deprecation_suggestion( } pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) { - let (message, lint) = if deprecation_in_effect( - depr.is_since_rustc_version, - depr.since.map(Symbol::as_str).as_deref(), - ) { + let since = depr.since.map(Symbol::as_str); + let (message, lint) = if deprecation_in_effect(depr.is_since_rustc_version, since.as_deref()) { (format!("use of deprecated {} `{}`", kind, path), DEPRECATED) } else { ( - format!( - "use of {} `{}` that will be deprecated in future version {}", - kind, - path, - depr.since.unwrap() - ), + if since.as_deref() == Some("TBD") { + format!( + "use of {} `{}` that will be deprecated in a future Rust version", + kind, path + ) + } else { + format!( + "use of {} `{}` that will be deprecated in future version {}", + kind, + path, + since.unwrap() + ) + }, DEPRECATED_IN_FUTURE, ) }; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index f6bbbd80bf1..3c2462aab26 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -182,28 +182,32 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { for (dep_v, stab_v) in dep_since.as_str().split('.').zip(stab_since.as_str().split('.')) { - if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::(), stab_v.parse()) { - match dep_v.cmp(&stab_v) { - Ordering::Less => { - self.tcx.sess.span_err( - item_sp, - "An API can't be stabilized \ - after it is deprecated", - ); + match stab_v.parse::() { + Err(_) => { + self.tcx.sess.span_err(item_sp, "Invalid stability version found"); + break; + } + Ok(stab_vp) => match dep_v.parse::() { + Ok(dep_vp) => match dep_vp.cmp(&stab_vp) { + Ordering::Less => { + self.tcx.sess.span_err( + item_sp, + "An API can't be stabilized after it is deprecated", + ); + break; + } + Ordering::Equal => continue, + Ordering::Greater => break, + }, + Err(_) => { + if dep_v != "TBD" { + self.tcx + .sess + .span_err(item_sp, "Invalid deprecation version found"); + } break; } - Ordering::Equal => continue, - Ordering::Greater => break, - } - } else { - // Act like it isn't less because the question is now nonsensical, - // and this makes us not do anything else interesting. - self.tcx.sess.span_err( - item_sp, - "Invalid stability or deprecation \ - version found", - ); - break; + }, } } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 88c5e94c276..00294878fe5 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2279,7 +2279,11 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item let mut message = if let Some(since) = since { let since = &since.as_str(); if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) { - format!("Deprecating in {}", Escape(since)) + if *since == "TBD" { + format!("Deprecating in a future Rust version") + } else { + format!("Deprecating in {}", Escape(since)) + } } else { format!("Deprecated since {}", Escape(since)) } diff --git a/src/test/rustdoc/rustc_deprecated-future.rs b/src/test/rustdoc/rustc_deprecated-future.rs index 3133775706b..95a767a8329 100644 --- a/src/test/rustdoc/rustc_deprecated-future.rs +++ b/src/test/rustdoc/rustc_deprecated-future.rs @@ -4,8 +4,16 @@ // @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \ // 'Deprecation planned' -// @has rustc_deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \ +// @has rustc_deprecated_future/struct.S1.html '//*[@class="stab deprecated"]' \ // 'Deprecating in 99.99.99: effectively never' #[rustc_deprecated(since = "99.99.99", reason = "effectively never")] #[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")] -pub struct S; +pub struct S1; + +// @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \ +// 'Deprecation planned' +// @has rustc_deprecated_future/struct.S2.html '//*[@class="stab deprecated"]' \ +// 'Deprecating in a future Rust version: literally never' +#[rustc_deprecated(since = "TBD", reason = "literally never")] +#[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")] +pub struct S2; diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.rs b/src/test/ui/deprecation/rustc_deprecation-in-future.rs index 6a619bcc49c..11f7960b757 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.rs +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.rs @@ -8,8 +8,13 @@ #[rustc_deprecated(since = "99.99.99", reason = "effectively never")] #[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")] -pub struct S; +pub struct S1; + +#[rustc_deprecated(since = "TBD", reason = "literally never")] +#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")] +pub struct S2; fn main() { - let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never + let _ = S1; //~ ERROR use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never + let _ = S2; //~ ERROR use of unit struct `S2` that will be deprecated in a future Rust version: literally never } diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr index e4f50d10dad..b5a7dd3c28d 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr @@ -1,8 +1,8 @@ -error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never - --> $DIR/rustc_deprecation-in-future.rs:14:13 +error: use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never + --> $DIR/rustc_deprecation-in-future.rs:18:13 | -LL | let _ = S; - | ^ +LL | let _ = S1; + | ^^ | note: the lint level is defined here --> $DIR/rustc_deprecation-in-future.rs:3:9 @@ -10,5 +10,11 @@ note: the lint level is defined here LL | #![deny(deprecated_in_future)] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: use of unit struct `S2` that will be deprecated in a future Rust version: literally never + --> $DIR/rustc_deprecation-in-future.rs:19:13 + | +LL | let _ = S2; + | ^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.rs b/src/test/ui/stability-attribute/stability-attribute-sanity.rs index abd603b356e..0c40f8ae1c6 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity.rs +++ b/src/test/ui/stability-attribute/stability-attribute-sanity.rs @@ -63,7 +63,11 @@ fn multiple3() { } #[rustc_const_unstable(feature = "c", issue = "none")] #[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels pub const fn multiple4() { } -//~^ ERROR Invalid stability or deprecation version found +//~^ ERROR Invalid stability version found + +#[stable(feature = "a", since = "1.0.0")] +#[rustc_deprecated(since = "invalid", reason = "text")] +fn invalid_deprecation_version() {} //~ ERROR Invalid deprecation version found #[rustc_deprecated(since = "a", reason = "text")] fn deprecated_without_unstable_or_stable() { } diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr index 97089f7df52..ee9a93359f0 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr @@ -96,19 +96,25 @@ error[E0544]: multiple stability levels LL | #[rustc_const_unstable(feature = "d", issue = "none")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: Invalid stability or deprecation version found +error: Invalid stability version found --> $DIR/stability-attribute-sanity.rs:65:1 | LL | pub const fn multiple4() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: Invalid deprecation version found + --> $DIR/stability-attribute-sanity.rs:70:1 + | +LL | fn invalid_deprecation_version() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute - --> $DIR/stability-attribute-sanity.rs:68:1 + --> $DIR/stability-attribute-sanity.rs:72:1 | LL | #[rustc_deprecated(since = "a", reason = "text")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 18 previous errors +error: aborting due to 19 previous errors Some errors have detailed explanations: E0539, E0541, E0546, E0550. For more information about an error, try `rustc --explain E0539`. -- cgit 1.4.1-3-g733a5 From 6132e21961be89d1b884dd03af0aef02347328ba Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 16 Dec 2020 19:16:36 +0000 Subject: bootstrap: include llvm-dwp in CI LLVM This commit includes the `llvm-dwp` tool in the CI LLVM (which rustc developers can download instead of building LLVM locally) - `llvm-dwp` is required by Split DWARF which landed in PR #77117. Signed-off-by: David Wood --- src/bootstrap/dist.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 25905895116..b1bb97cf83b 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2553,6 +2553,7 @@ impl Step for RustDev { install_bin("llvm-profdata"); install_bin("llvm-bcanalyzer"); install_bin("llvm-cov"); + install_bin("llvm-dwp"); builder.install(&builder.llvm_filecheck(target), &dst_bindir, 0o755); // Copy the include directory as well; needed mostly to build -- cgit 1.4.1-3-g733a5 From 50d221c9244c87f22a791af86cff8f3139523dbf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 16 Dec 2020 17:21:08 +0100 Subject: Replace String with Symbol where possible --- src/librustdoc/clean/auto_trait.rs | 11 ++-- src/librustdoc/clean/inline.rs | 8 +-- src/librustdoc/clean/mod.rs | 67 +++++++++++------------- src/librustdoc/clean/simplify.rs | 5 +- src/librustdoc/clean/types.rs | 20 +++---- src/librustdoc/clean/utils.rs | 39 ++++++++------ src/librustdoc/html/format.rs | 13 ++--- src/librustdoc/html/render/cache.rs | 2 +- src/librustdoc/json/conversions.rs | 14 +++-- src/librustdoc/passes/collect_intra_doc_links.rs | 13 +++-- src/librustdoc/passes/doc_test_lints.rs | 23 ++++---- 11 files changed, 109 insertions(+), 106 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 7a61a169c2b..72603f00697 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -333,10 +333,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { match br { // We only care about named late bound regions, as we need to add them // to the 'for<>' section - ty::BrNamed(_, name) => Some(GenericParamDef { - name: name.to_string(), - kind: GenericParamDefKind::Lifetime, - }), + ty::BrNamed(_, name) => { + Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime }) + } _ => None, } }) @@ -569,7 +568,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } WherePredicate::EqPredicate { lhs, rhs } => { match lhs { - Type::QPath { name: ref left_name, ref self_type, ref trait_ } => { + Type::QPath { name: left_name, ref self_type, ref trait_ } => { let ty = &*self_type; match **trait_ { Type::ResolvedPath { @@ -580,7 +579,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } => { let mut new_trait_path = trait_path.clone(); - if self.is_fn_ty(tcx, trait_) && left_name == FN_OUTPUT_NAME { + if self.is_fn_ty(tcx, trait_) && left_name == sym::Output { ty_to_fn .entry(*ty.clone()) .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone()))) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d358a7a369d..7bb8e5e8cfc 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -12,7 +12,7 @@ use rustc_metadata::creader::LoadedMacro; use rustc_middle::ty; use rustc_mir::const_eval::is_min_const_fn; use rustc_span::hygiene::MacroKind; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind}; @@ -583,7 +583,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean: for pred in &mut g.where_predicates { match *pred { clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref mut bounds } - if *s == "Self" => + if *s == kw::SelfUpper => { bounds.retain(|bound| match *bound { clean::GenericBound::TraitBound( @@ -606,7 +606,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean: name: ref _name, }, ref bounds, - } => !(bounds.is_empty() || *s == "Self" && did == trait_did), + } => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did), _ => true, }); g @@ -621,7 +621,7 @@ fn separate_supertrait_bounds( let mut ty_bounds = Vec::new(); g.where_predicates.retain(|pred| match *pred { clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds } - if *s == "Self" => + if *s == kw::SelfUpper => { ty_bounds.extend(bounds.iter().cloned()); false diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f5329bbb0cc..2105ec0b0ba 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -48,8 +48,6 @@ crate use self::types::Type::*; crate use self::types::Visibility::{Inherited, Public}; crate use self::types::*; -const FN_OUTPUT_NAME: &str = "Output"; - crate trait Clean { fn clean(&self, cx: &DocContext<'_>) -> T; } @@ -329,10 +327,9 @@ impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { .collect_referenced_late_bound_regions(&poly_trait_ref) .into_iter() .filter_map(|br| match br { - ty::BrNamed(_, name) => Some(GenericParamDef { - name: name.to_string(), - kind: GenericParamDefKind::Lifetime, - }), + ty::BrNamed(_, name) => { + Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime }) + } _ => None, }) .collect(); @@ -546,7 +543,7 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"), }; Type::QPath { - name: cx.tcx.associated_item(self.item_def_id).ident.name.clean(cx), + name: cx.tcx.associated_item(self.item_def_id).ident.name, self_type: box self.self_ty().clean(cx), trait_: box trait_, } @@ -556,14 +553,12 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { impl Clean for ty::GenericParamDef { fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef { let (name, kind) = match self.kind { - ty::GenericParamDefKind::Lifetime => { - (self.name.to_string(), GenericParamDefKind::Lifetime) - } + ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime), ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { let default = if has_default { Some(cx.tcx.type_of(self.def_id).clean(cx)) } else { None }; ( - self.name.clean(cx), + self.name, GenericParamDefKind::Type { did: self.def_id, bounds: vec![], // These are filled in from the where-clauses. @@ -573,7 +568,7 @@ impl Clean for ty::GenericParamDef { ) } ty::GenericParamDefKind::Const { .. } => ( - self.name.clean(cx), + self.name, GenericParamDefKind::Const { did: self.def_id, ty: cx.tcx.type_of(self.def_id).clean(cx), @@ -599,14 +594,14 @@ impl Clean for hir::GenericParam<'_> { for bound in bounds { s.push_str(&format!(" + {}", bound.name.ident())); } - s + Symbol::intern(&s) } else { - self.name.ident().to_string() + self.name.ident().name }; (name, GenericParamDefKind::Lifetime) } hir::GenericParamKind::Type { ref default, synthetic } => ( - self.name.ident().name.clean(cx), + self.name.ident().name, GenericParamDefKind::Type { did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(), bounds: self.bounds.clean(cx), @@ -615,7 +610,7 @@ impl Clean for hir::GenericParam<'_> { }, ), hir::GenericParamKind::Const { ref ty } => ( - self.name.ident().name.clean(cx), + self.name.ident().name, GenericParamDefKind::Const { did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(), ty: ty.clean(cx), @@ -730,7 +725,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx .collect::>(); // param index -> [(DefId of trait, associated type name, type)] - let mut impl_trait_proj = FxHashMap::)>>::default(); + let mut impl_trait_proj = FxHashMap::)>>::default(); let where_predicates = preds .predicates @@ -778,11 +773,10 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx if let Some(((_, trait_did, name), rhs)) = proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))) { - impl_trait_proj.entry(param_idx).or_default().push(( - trait_did, - name.to_string(), - rhs, - )); + impl_trait_proj + .entry(param_idx) + .or_default() + .push((trait_did, name, rhs)); } return None; @@ -800,7 +794,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx if let crate::core::ImplTraitParam::ParamIndex(idx) = param { if let Some(proj) = impl_trait_proj.remove(&idx) { for (trait_did, name, rhs) in proj { - simplify::merge_bounds(cx, &mut bounds, trait_did, &name, &rhs.clean(cx)); + simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs.clean(cx)); } } } else { @@ -936,9 +930,9 @@ impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { .iter() .enumerate() .map(|(i, ty)| { - let mut name = self.1.get(i).map(|ident| ident.to_string()).unwrap_or_default(); + let mut name = self.1.get(i).map(|ident| ident.name).unwrap_or(kw::Invalid); if name.is_empty() { - name = "_".to_string(); + name = kw::Underscore; } Argument { name, type_: ty.clean(cx) } }) @@ -995,7 +989,7 @@ impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { .iter() .map(|t| Argument { type_: t.clean(cx), - name: names.next().map_or_else(|| String::new(), |name| name.to_string()), + name: names.next().map(|i| i.name).unwrap_or(kw::Invalid), }) .collect(), }, @@ -1150,12 +1144,12 @@ impl Clean for ty::AssocItem { }; let self_arg_ty = sig.input(0).skip_binder(); if self_arg_ty == self_ty { - decl.inputs.values[0].type_ = Generic(String::from("Self")); + decl.inputs.values[0].type_ = Generic(kw::SelfUpper); } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() { if ty == self_ty { match decl.inputs.values[0].type_ { BorrowedRef { ref mut type_, .. } => { - **type_ = Generic(String::from("Self")) + **type_ = Generic(kw::SelfUpper) } _ => unreachable!(), } @@ -1210,7 +1204,7 @@ impl Clean for ty::AssocItem { } } ty::AssocKind::Type => { - let my_name = self.ident.name.clean(cx); + let my_name = self.ident.name; if let ty::TraitContainer(_) = self.container { let bounds = cx.tcx.explicit_item_bounds(self.def_id); @@ -1235,7 +1229,7 @@ impl Clean for ty::AssocItem { _ => return None, } match **self_type { - Generic(ref s) if *s == "Self" => {} + Generic(ref s) if *s == kw::SelfUpper => {} _ => return None, } Some(bounds) @@ -1408,7 +1402,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type { segments: trait_segments.clean(cx), }; Type::QPath { - name: p.segments.last().expect("segments were empty").ident.name.clean(cx), + name: p.segments.last().expect("segments were empty").ident.name, self_type: box qself.clean(cx), trait_: box resolve_type(cx, trait_path, hir_id), } @@ -1422,7 +1416,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type { }; let trait_path = hir::Path { span, res, segments: &[] }; Type::QPath { - name: segment.ident.name.clean(cx), + name: segment.ident.name, self_type: box qself.clean(cx), trait_: box resolve_type(cx, trait_path.clean(cx), hir_id), } @@ -1625,7 +1619,7 @@ impl<'tcx> Clean for Ty<'tcx> { let mut bindings = vec![]; for pb in obj.projection_bounds() { bindings.push(TypeBinding { - name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), + name: cx.tcx.associated_item(pb.item_def_id()).ident.name, kind: TypeBindingKind::Equality { ty: pb.skip_binder().ty.clean(cx) }, }); } @@ -1644,7 +1638,7 @@ impl<'tcx> Clean for Ty<'tcx> { if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&p.index.into()) { ImplTrait(bounds) } else { - Generic(p.name.to_string()) + Generic(p.name) } } @@ -1702,8 +1696,7 @@ impl<'tcx> Clean for Ty<'tcx> { .tcx .associated_item(proj.projection_ty.item_def_id) .ident - .name - .clean(cx), + .name, kind: TypeBindingKind::Equality { ty: proj.ty.clean(cx), }, @@ -2339,7 +2332,7 @@ impl Clean for (&hir::MacroDef<'_>, Option) { impl Clean for hir::TypeBinding<'_> { fn clean(&self, cx: &DocContext<'_>) -> TypeBinding { - TypeBinding { name: self.ident.name.clean(cx), kind: self.kind.clean(cx) } + TypeBinding { name: self.ident.name, kind: self.kind.clean(cx) } } } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 121c9d2bc4c..16aaa9cfd20 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -15,6 +15,7 @@ use std::collections::BTreeMap; use rustc_hir::def_id::DefId; use rustc_middle::ty; +use rustc_span::Symbol; use crate::clean; use crate::clean::GenericArgs as PP; @@ -78,7 +79,7 @@ crate fn merge_bounds( cx: &clean::DocContext<'_>, bounds: &mut Vec, trait_did: DefId, - name: &str, + name: Symbol, rhs: &clean::Type, ) -> bool { !bounds.iter_mut().any(|b| { @@ -100,7 +101,7 @@ crate fn merge_bounds( match last.args { PP::AngleBracketed { ref mut bindings, .. } => { bindings.push(clean::TypeBinding { - name: name.to_string(), + name, kind: clean::TypeBindingKind::Equality { ty: rhs.clone() }, }); } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index dbdcd68810b..9bade5ad2ec 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -949,7 +949,7 @@ impl GenericParamDefKind { #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate struct GenericParamDef { - crate name: String, + crate name: Symbol, crate kind: GenericParamDefKind, } @@ -1037,7 +1037,7 @@ crate struct Arguments { #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate struct Argument { crate type_: Type, - crate name: String, + crate name: Symbol, } #[derive(Clone, PartialEq, Debug)] @@ -1049,7 +1049,7 @@ crate enum SelfTy { impl Argument { crate fn to_self(&self) -> Option { - if self.name != "self" { + if self.name != kw::SelfLower { return None; } if self.type_.is_self_type() { @@ -1117,7 +1117,7 @@ crate enum Type { }, /// For parameterized types, so the consumer of the JSON don't go /// looking for types which don't exist anywhere. - Generic(String), + Generic(Symbol), /// Primitives are the fixed-size numeric types (plus int/usize/float), char, /// arrays, slices, and tuples. Primitive(PrimitiveType), @@ -1136,7 +1136,7 @@ crate enum Type { // `::Name` QPath { - name: String, + name: Symbol, self_type: Box, trait_: Box, }, @@ -1237,7 +1237,7 @@ impl Type { crate fn is_self_type(&self) -> bool { match *self { - Generic(ref name) => name == "Self", + Generic(name) => name == kw::SelfUpper, _ => false, } } @@ -1282,16 +1282,16 @@ impl Type { } } - crate fn projection(&self) -> Option<(&Type, DefId, &str)> { + crate fn projection(&self) -> Option<(&Type, DefId, Symbol)> { let (self_, trait_, name) = match self { - QPath { ref self_type, ref trait_, ref name } => (self_type, trait_, name), + QPath { ref self_type, ref trait_, name } => (self_type, trait_, name), _ => return None, }; let trait_did = match **trait_ { ResolvedPath { did, .. } => did, _ => return None, }; - Some((&self_, trait_did, name)) + Some((&self_, trait_did, *name)) } } @@ -1816,7 +1816,7 @@ crate struct ProcMacro { /// `A: Send + Sync` in `Foo`). #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate struct TypeBinding { - crate name: String, + crate name: Symbol, crate kind: TypeBindingKind, } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index f8743a4c42e..ec922b182e2 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -170,13 +170,13 @@ crate fn get_real_types( cx: &DocContext<'_>, recurse: i32, ) -> FxHashSet<(Type, TypeKind)> { - let arg_s = arg.print().to_string(); let mut res = FxHashSet::default(); if recurse >= 10 { // FIXME: remove this whole recurse thing when the recursion bug is fixed return res; } if arg.is_full_generic() { + let arg_s = Symbol::intern(&arg.print().to_string()); if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g { &WherePredicate::BoundPredicate { ref ty, .. } => ty.def_id() == arg.def_id(), _ => false, @@ -375,13 +375,13 @@ impl ToSource for rustc_span::Span { } } -crate fn name_from_pat(p: &hir::Pat<'_>) -> String { +crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { use rustc_hir::*; debug!("trying to get a name from pattern: {:?}", p); - match p.kind { - PatKind::Wild => "_".to_string(), - PatKind::Binding(_, _, ident, _) => ident.to_string(), + Symbol::intern(&match p.kind { + PatKind::Wild => return kw::Underscore, + PatKind::Binding(_, _, ident, _) => return ident.name, PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), PatKind::Struct(ref name, ref fields, etc) => format!( "{} {{ {}{} }}", @@ -393,32 +393,37 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> String { .join(", "), if etc { ", .." } else { "" } ), - PatKind::Or(ref pats) => { - pats.iter().map(|p| name_from_pat(&**p)).collect::>().join(" | ") - } + PatKind::Or(ref pats) => pats + .iter() + .map(|p| name_from_pat(&**p).to_string()) + .collect::>() + .join(" | "), PatKind::Tuple(ref elts, _) => format!( "({})", - elts.iter().map(|p| name_from_pat(&**p)).collect::>().join(", ") + elts.iter() + .map(|p| name_from_pat(&**p).to_string()) + .collect::>() + .join(", ") ), - PatKind::Box(ref p) => name_from_pat(&**p), - PatKind::Ref(ref p, _) => name_from_pat(&**p), + PatKind::Box(ref p) => return name_from_pat(&**p), + PatKind::Ref(ref p, _) => return name_from_pat(&**p), PatKind::Lit(..) => { warn!( "tried to get argument name from PatKind::Lit, which is silly in function arguments" ); - "()".to_string() + return Symbol::intern("()"); } PatKind::Range(..) => panic!( "tried to get argument name from PatKind::Range, \ which is not allowed in function arguments" ), PatKind::Slice(ref begin, ref mid, ref end) => { - let begin = begin.iter().map(|p| name_from_pat(&**p)); + let begin = begin.iter().map(|p| name_from_pat(&**p).to_string()); let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter(); - let end = end.iter().map(|p| name_from_pat(&**p)); + let end = end.iter().map(|p| name_from_pat(&**p).to_string()); format!("[{}]", begin.chain(mid).chain(end).collect::>().join(", ")) } - } + }) } crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { @@ -534,10 +539,10 @@ crate fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type { let is_generic = match path.res { Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)), Res::SelfTy(..) if path.segments.len() == 1 => { - return Generic(kw::SelfUpper.to_string()); + return Generic(kw::SelfUpper); } Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => { - return Generic(format!("{:#}", path.print())); + return Generic(Symbol::intern(&format!("{:#}", path.print()))); } Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true, _ => false, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 536c2e08fde..c49c4892237 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -172,7 +172,7 @@ impl clean::GenericParamDef { display_fn(move |f| match self.kind { clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name), clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => { - f.write_str(&self.name)?; + f.write_str(&*self.name.as_str())?; if !bounds.is_empty() { if f.alternate() { @@ -193,13 +193,10 @@ impl clean::GenericParamDef { Ok(()) } clean::GenericParamDefKind::Const { ref ty, .. } => { - f.write_str("const ")?; - f.write_str(&self.name)?; - if f.alternate() { - write!(f, ": {:#}", ty.print()) + write!(f, "const {}: {:#}", self.name, ty.print()) } else { - write!(f, ": {}", ty.print()) + write!(f, "const {}: {}", self.name, ty.print()) } } }) @@ -638,7 +635,7 @@ crate fn anchor(did: DefId, text: &str) -> impl fmt::Display + '_ { fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> fmt::Result { match *t { - clean::Generic(ref name) => f.write_str(name), + clean::Generic(name) => write!(f, "{}", name), clean::ResolvedPath { did, ref param_names, ref path, is_generic } => { if param_names.is_some() { f.write_str("dyn ")?; @@ -1203,7 +1200,7 @@ impl clean::ImportSource { impl clean::TypeBinding { crate fn print(&self) -> impl fmt::Display + '_ { display_fn(move |f| { - f.write_str(&self.name)?; + f.write_str(&*self.name.as_str())?; match self.kind { clean::TypeBindingKind::Equality { ref ty } => { if f.alternate() { diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 91037bc160a..80f54d8e161 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -208,7 +208,7 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option }); Some(path_segment.name.clone()) } - clean::Generic(ref s) if accept_generic => Some(s.clone()), + clean::Generic(s) if accept_generic => Some(s.to_string()), clean::Primitive(ref p) => Some(format!("{:?}", p)), clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_, accept_generic), // FIXME: add all from clean::Type. diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b5babfd10fd..809cfb9d743 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -136,7 +136,7 @@ impl From for Constant { impl From for TypeBinding { fn from(binding: clean::TypeBinding) -> Self { - TypeBinding { name: binding.name, binding: binding.kind.into() } + TypeBinding { name: binding.name.to_string(), binding: binding.kind.into() } } } @@ -275,7 +275,7 @@ impl From for Generics { impl From for GenericParamDef { fn from(generic_param: clean::GenericParamDef) -> Self { - GenericParamDef { name: generic_param.name, kind: generic_param.kind.into() } + GenericParamDef { name: generic_param.name.to_string(), kind: generic_param.kind.into() } } } @@ -351,7 +351,7 @@ impl From for Type { .map(|v| v.into_iter().map(Into::into).collect()) .unwrap_or_default(), }, - Generic(s) => Type::Generic(s), + Generic(s) => Type::Generic(s.to_string()), Primitive(p) => Type::Primitive(p.as_str().to_string()), BareFunction(f) => Type::FunctionPointer(Box::new((*f).into())), Tuple(t) => Type::Tuple(t.into_iter().map(Into::into).collect()), @@ -370,7 +370,7 @@ impl From for Type { type_: Box::new((*type_).into()), }, QPath { name, self_type, trait_ } => Type::QualifiedPath { - name, + name: name.to_string(), self_type: Box::new((*self_type).into()), trait_: Box::new((*trait_).into()), }, @@ -394,7 +394,11 @@ impl From for FnDecl { fn from(decl: clean::FnDecl) -> Self { let clean::FnDecl { inputs, output, c_variadic, attrs: _ } = decl; FnDecl { - inputs: inputs.values.into_iter().map(|arg| (arg.name, arg.type_.into())).collect(), + inputs: inputs + .values + .into_iter() + .map(|arg| (arg.name.to_string(), arg.type_.into())) + .collect(), output: match output { clean::FnRetTy::Return(t) => Some(t.into()), clean::FnRetTy::DefaultReturn => None, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f9d81fb8635..ea5bf94689b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -753,11 +753,14 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx /// /// These are common and we should just resolve to the trait in that case. fn is_derive_trait_collision(ns: &PerNS>>) -> bool { - matches!(*ns, PerNS { - type_ns: Ok((Res::Def(DefKind::Trait, _), _)), - macro_ns: Ok((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)), - .. - }) + matches!( + *ns, + PerNS { + type_ns: Ok((Res::Def(DefKind::Trait, _), _)), + macro_ns: Ok((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)), + .. + } + ) } impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index 299a73c8a01..1c1141e7c81 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -58,18 +58,19 @@ impl crate::doctest::Tester for Tests { } crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool { - if matches!(item.kind, + if matches!( + item.kind, clean::StructFieldItem(_) - | clean::VariantItem(_) - | clean::AssocConstItem(_, _) - | clean::AssocTypeItem(_, _) - | clean::TypedefItem(_, _) - | clean::StaticItem(_) - | clean::ConstantItem(_) - | clean::ExternCrateItem(_, _) - | clean::ImportItem(_) - | clean::PrimitiveItem(_) - | clean::KeywordItem(_) + | clean::VariantItem(_) + | clean::AssocConstItem(_, _) + | clean::AssocTypeItem(_, _) + | clean::TypedefItem(_, _) + | clean::StaticItem(_) + | clean::ConstantItem(_) + | clean::ExternCrateItem(_, _) + | clean::ImportItem(_) + | clean::PrimitiveItem(_) + | clean::KeywordItem(_) ) { return false; } -- cgit 1.4.1-3-g733a5 From 2edd3016c8bab6f849ca3a907ecd800777e36846 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 16 Dec 2020 20:15:57 -0500 Subject: Bless NLL test --- src/test/ui/issues/issue-40000.nll.stderr | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/test/ui/issues/issue-40000.nll.stderr b/src/test/ui/issues/issue-40000.nll.stderr index f673fbae8b7..4e2bde06a52 100644 --- a/src/test/ui/issues/issue-40000.nll.stderr +++ b/src/test/ui/issues/issue-40000.nll.stderr @@ -4,5 +4,11 @@ error: higher-ranked subtype error LL | foo(bar); | ^^^ -error: aborting due to previous error +error: higher-ranked subtype error + --> $DIR/issue-40000.rs:6:9 + | +LL | foo(bar); + | ^^^ + +error: aborting due to 2 previous errors -- cgit 1.4.1-3-g733a5 From c9fab5008479012ed944a8e542ed2a309ec2a385 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Wed, 16 Dec 2020 22:07:40 -0800 Subject: Remove redundant and unreliable coverage test results The `coverage-reports` tests still generate counters and JSON reports for inspection, but these files are no longer used in Makefile diffs, to reduce complexity and confusion from unreliable or unexpected test results, especially when maintaining them (i.e., generating `--bless`ed results). The associated `expected_` files for counters and JSON reports have been removed, leaving only the files actually used for testing: the `llvm-cov show` reports. --- .../run-make-fulldeps/coverage-reports/Makefile | 135 +++++---- .../expected_export_coverage.abort.json | 59 ---- .../expected_export_coverage.assert.json | 59 ---- .../expected_export_coverage.async.json | 59 ---- .../expected_export_coverage.closure.json | 59 ---- .../expected_export_coverage.conditions.json | 59 ---- .../expected_export_coverage.dead_code.json | 59 ---- .../expected_export_coverage.drop_trait.json | 59 ---- .../expected_export_coverage.generics.json | 59 ---- .../expected_export_coverage.if.json | 59 ---- .../expected_export_coverage.if_else.json | 59 ---- .../expected_export_coverage.inner_items.json | 59 ---- .../expected_export_coverage.lazy_boolean.json | 59 ---- .../expected_export_coverage.loop_break_value.json | 59 ---- .../expected_export_coverage.loops_branches.json | 59 ---- .../expected_export_coverage.match_or_pattern.json | 59 ---- .../expected_export_coverage.nested_loops.json | 59 ---- .../expected_export_coverage.overflow.json | 59 ---- .../expected_export_coverage.panic_unwind.json | 59 ---- .../expected_export_coverage.partial_eq.json | 59 ---- .../expected_export_coverage.simple_loop.json | 59 ---- .../expected_export_coverage.simple_match.json | 59 ---- .../expected_export_coverage.tight_inf_loop.json | 59 ---- .../expected_export_coverage.try_error_result.json | 59 ---- .../expected_export_coverage.uses_crate.json | 59 ---- .../expected_export_coverage.while.json | 59 ---- .../expected_export_coverage.while_early_ret.json | 59 ---- .../expected_export_coverage.yield.json | 59 ---- .../expected_show_coverage_counters.abort.txt | 67 ----- .../expected_show_coverage_counters.assert.txt | 57 ---- .../expected_show_coverage_counters.async.txt | 311 --------------------- .../expected_show_coverage_counters.closure.txt | 153 ---------- .../expected_show_coverage_counters.conditions.txt | 253 ----------------- .../expected_show_coverage_counters.dead_code.txt | 47 ---- .../expected_show_coverage_counters.drop_trait.txt | 18 -- .../expected_show_coverage_counters.generics.txt | 44 --- .../expected_show_coverage_counters.if.txt | 17 -- .../expected_show_coverage_counters.if_else.txt | 30 -- ...expected_show_coverage_counters.inner_items.txt | 44 --- ...xpected_show_coverage_counters.lazy_boolean.txt | 111 -------- ...ted_show_coverage_counters.loop_break_value.txt | 6 - ...ected_show_coverage_counters.loops_branches.txt | 33 --- ...ted_show_coverage_counters.match_or_pattern.txt | 98 ------- ...xpected_show_coverage_counters.nested_loops.txt | 58 ---- .../expected_show_coverage_counters.overflow.txt | 52 ---- ...xpected_show_coverage_counters.panic_unwind.txt | 53 ---- .../expected_show_coverage_counters.partial_eq.txt | 66 ----- ...expected_show_coverage_counters.simple_loop.txt | 29 -- ...xpected_show_coverage_counters.simple_match.txt | 45 --- ...ected_show_coverage_counters.tight_inf_loop.txt | 10 - ...ted_show_coverage_counters.try_error_result.txt | 63 ----- .../expected_show_coverage_counters.uses_crate.txt | 110 -------- .../expected_show_coverage_counters.while.txt | 18 -- ...cted_show_coverage_counters.while_early_ret.txt | 38 --- .../expected_show_coverage_counters.yield.txt | 94 ------- .../coverage-reports/prettify_json.py | 9 - 56 files changed, 86 insertions(+), 3576 deletions(-) delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt delete mode 100644 src/test/run-make-fulldeps/coverage-reports/prettify_json.py (limited to 'src') diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile index a5d6970009a..5c24f909130 100644 --- a/src/test/run-make-fulldeps/coverage-reports/Makefile +++ b/src/test/run-make-fulldeps/coverage-reports/Makefile @@ -9,11 +9,13 @@ BASEDIR=../coverage-reports SOURCEDIR=../coverage -# The `llvm-cov show` flag `--debug`, used to generate the `counters` output files, is only enabled -# if LLVM assertions are enabled. Requires Rust config `llvm/optimize` and not +# The `llvm-cov show` flag `--debug`, used to generate the `counters` output files, is only +# enabled if LLVM assertions are enabled. This requires Rust config `llvm/optimize` and not # `llvm/release_debuginfo`. Note that some CI builds disable debug assertions (by setting -# `NO_LLVM_ASSERTIONS=1`), so it is not OK to fail the test, but `bless`ed test results cannot be -# generated without debug assertions. +# `NO_LLVM_ASSERTIONS=1`), so the tests must still pass even if the `--debug` flag is +# not supported. (Note that `counters` files are only produced in the `$(TMPDIR)` +# directory, for inspection and debugging support. They are *not* copied to `expected_*` +# files when `--bless`ed.) LLVM_COV_DEBUG := $(shell \ "$(LLVM_BIN_DIR)"/llvm-cov show --debug 2>&1 | \ grep -q "Unknown command line argument '--debug'"; \ @@ -51,11 +53,10 @@ endif # Yes these `--ignore-filename-regex=` options are included in all invocations of `llvm-cov show` # for now, but it is effectively ignored for all tests that don't include this file anyway. # -# Note that it's also possible the `_counters..txt` and `.json` files may order -# results from multiple files inconsistently, which might also have to be accomodated if and when -# we allow `llvm-cov` to produce results for multiple files. (The path separators appear to be -# normalized to `/` in those files, thankfully.) But since we are ignoring results for all but one -# file, this workaround addresses those potential issues as well. +# (Note that it's also possible the `_counters..txt` and `.json` files (if generated) +# may order results from multiple files inconsistently, which might also have to be accomodated +# if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators +# appear to be normalized to `/` in those files, thankfully.) LLVM_COV_IGNORE_FILES=\ --ignore-filename-regex=uses_crate.rs @@ -77,9 +78,7 @@ endif .PHONY: clear_expected_if_blessed clear_expected_if_blessed: ifdef RUSTC_BLESS_TEST - rm -f expected_export_coverage.*.json - rm -f expected_show_coverage.*.txt - rm -f expected_show_coverage_counters.*.txt + rm -f expected_* endif -include clear_expected_if_blessed @@ -140,12 +139,8 @@ endif ifdef RUSTC_BLESS_TEST cp "$(TMPDIR)"/actual_show_coverage.$@.txt \ expected_show_coverage.$@.txt - cp "$(TMPDIR)"/actual_show_coverage_counters.$@.txt \ - expected_show_coverage_counters.$@.txt else - # Compare the show coverage output (`--bless` refreshes `typical` files) - # Note `llvm-cov show` output for some programs can vary, but can be ignored - # by inserting `// ignore-llvm-cov-show-diffs` at the top of the source file. + # Compare the show coverage output (`--bless` refreshes `typical` files). # # FIXME(richkadel): None of the Rust test source samples have the # `// ignore-llvm-cov-show-diffs` anymore. This directive exists to work around a limitation @@ -158,8 +153,10 @@ else # # This workaround only works if the coverage counts are identical across all reported # instantiations. If there is no way to ensure this, you may need to apply the - # `// ignore-llvm-cov-show-diffs` directive, and rely on the `.json` and counter - # files for validating results have not changed. + # `// ignore-llvm-cov-show-diffs` directive, and check for differences using the + # `.json` files to validate that results have not changed. (Until then, the JSON + # files are redundant, so there is no need to generate `expected_*.json` files or + # compare actual JSON results.) $(DIFF) --ignore-matching-lines='::<.*>.*:$$' \ expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \ @@ -169,37 +166,77 @@ else ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \ false \ ) - -ifdef DEBUG_FLAG - $(DIFF) expected_show_coverage_counters.$@.txt "$(TMPDIR)"/actual_show_coverage_counters.$@.txt || \ - ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \ - >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \ - ) || \ - ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \ - >&2 echo '(Ignore anyway until mangled function names in "counters" files are demangled.)' \ - ) - - # FIXME(richkadel): Apply the demangler to the `*_show_coverage_counters.*.txt` files, - # so the crate disambiguator differences will be stripped away. At that point, these files - # will be less likely to vary, and the last `echo` above (starting with "Ignore anyway") - # can be replaced with `false` to fail the test. endif -endif +#################################################################################################### - # Generate a coverage report in JSON, using `llvm-cov export`, and fail if - # there are differences from the expected output. - "$(LLVM_BIN_DIR)"/llvm-cov export \ - $(LLVM_COV_IGNORE_FILES) \ - --summary-only \ - --instr-profile="$(TMPDIR)"/$@.profdata \ - $(call BIN,"$(TMPDIR)"/$@) \ - | "$(PYTHON)" $(BASEDIR)/prettify_json.py \ - > "$(TMPDIR)"/actual_export_coverage.$@.json +# The following Makefile content was used to copy the generated `counters` files +# to `expected_` files (when `--bless`ed) and to compare them via `diff`; but for +# multiple reasons, these files cannot easily be used for test validation: +# +# * Output lines can be produced in non-deterministic order (depending on the +# target platform, and sometimes on unrelated codegen changes). +# * Some lines include demangled function names, making them more challenging +# to interpret and compare. +# +# The files are still generated (in `$(TMPDIR)`) to support developers wanting +# to inspect the counters, for debugging purposes. +# +# ifdef RUSTC_BLESS_TEST +# cp "$(TMPDIR)"/actual_show_coverage_counters.$@.txt \ +# expected_show_coverage_counters.$@.txt +# else +# +# ifdef DEBUG_FLAG +# $(DIFF) expected_show_coverage_counters.$@.txt "$(TMPDIR)"/actual_show_coverage_counters.$@.txt || \ +# ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \ +# >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \ +# ) || \ +# ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \ +# >&2 echo '(Ignore anyway until mangled function names in "counters" files are demangled.)' \ +# ) +# endif +# +# endif -ifdef RUSTC_BLESS_TEST - cp "$(TMPDIR)"/actual_export_coverage.$@.json expected_export_coverage.$@.json -else - # Check that exported JSON coverage data matches what we expect (`--bless` refreshes `expected`) - $(DIFF) expected_export_coverage.$@.json "$(TMPDIR)"/actual_export_coverage.$@.json -endif +#################################################################################################### + +# The following Makefile content, and short JSON script, were used to generate +# coverage reports in JSON when the `llvm-cov show` reports were less reliable for +# testing. At the present time, however, the `llvm-cov show` results, and methods +# for comparing them, are working for all tests, making the JSON reports redundant. +# +# If this changes in the future, the scripts are left here, commented out, but can +# be resurrected if desired. This could be used to compare *only* the JSON files; +# and in that case, the `llvm-cov show` reports can be ignored by inserting +# `// ignore-llvm-cov-show-diffs` at the top of the source file. +# +# # Generate a coverage report in JSON, using `llvm-cov export`, and fail if +# # there are differences from the expected output. +# "$(LLVM_BIN_DIR)"/llvm-cov export \ +# $(LLVM_COV_IGNORE_FILES) \ +# --summary-only \ +# --instr-profile="$(TMPDIR)"/$@.profdata \ +# $(call BIN,"$(TMPDIR)"/$@) \ +# | "$(PYTHON)" $(BASEDIR)/prettify_json.py \ +# > "$(TMPDIR)"/actual_export_coverage.$@.json +# +# ifdef RUSTC_BLESS_TEST +# cp "$(TMPDIR)"/actual_export_coverage.$@.json expected_export_coverage.$@.json +# else +# # Check that exported JSON coverage data matches what we expect (`--bless` refreshes `expected`) +# $(DIFF) expected_export_coverage.$@.json "$(TMPDIR)"/actual_export_coverage.$@.json +# endif +# +# # # If generating coverage reports in JSON, this Makefile is accompanied by +# # # a Python script, `prettify_json.py`, which is defined: +# # +# # #!/usr/bin/env python +# # +# # import sys +# # import json +# # +# # # Try to decode line in order to ensure it is a valid JSON document +# # for line in sys.stdin: +# # parsed = json.loads(line) +# # print (json.dumps(parsed, indent=2, separators=(',', ': '), sort_keys=True)) diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json deleted file mode 100644 index db7dd0b15e9..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/abort.rs", - "summary": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 19, - "covered": 17, - "percent": 89.47368421052632 - }, - "regions": { - "count": 17, - "covered": 16, - "notcovered": 1, - "percent": 94.11764705882352 - } - } - } - ], - "totals": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 19, - "covered": 17, - "percent": 89.47368421052632 - }, - "regions": { - "count": 17, - "covered": 16, - "notcovered": 1, - "percent": 94.11764705882352 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json deleted file mode 100644 index bb857ba3f3b..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/assert.rs", - "summary": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 15, - "covered": 13, - "percent": 86.66666666666667 - }, - "regions": { - "count": 14, - "covered": 13, - "notcovered": 1, - "percent": 92.85714285714286 - } - } - } - ], - "totals": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 15, - "covered": 13, - "percent": 86.66666666666667 - }, - "regions": { - "count": 14, - "covered": 13, - "notcovered": 1, - "percent": 92.85714285714286 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json deleted file mode 100644 index 794a2e38253..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/async.rs", - "summary": { - "functions": { - "count": 17, - "covered": 16, - "percent": 94.11764705882352 - }, - "instantiations": { - "count": 17, - "covered": 16, - "percent": 94.11764705882352 - }, - "lines": { - "count": 105, - "covered": 77, - "percent": 73.33333333333333 - }, - "regions": { - "count": 78, - "covered": 36, - "notcovered": 42, - "percent": 46.15384615384615 - } - } - } - ], - "totals": { - "functions": { - "count": 17, - "covered": 16, - "percent": 94.11764705882352 - }, - "instantiations": { - "count": 17, - "covered": 16, - "percent": 94.11764705882352 - }, - "lines": { - "count": 105, - "covered": 77, - "percent": 73.33333333333333 - }, - "regions": { - "count": 78, - "covered": 36, - "notcovered": 42, - "percent": 46.15384615384615 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json deleted file mode 100644 index 39e1dea66f9..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/closure.rs", - "summary": { - "functions": { - "count": 6, - "covered": 4, - "percent": 66.66666666666666 - }, - "instantiations": { - "count": 6, - "covered": 4, - "percent": 66.66666666666666 - }, - "lines": { - "count": 161, - "covered": 131, - "percent": 81.36645962732919 - }, - "regions": { - "count": 42, - "covered": 22, - "notcovered": 20, - "percent": 52.38095238095239 - } - } - } - ], - "totals": { - "functions": { - "count": 6, - "covered": 4, - "percent": 66.66666666666666 - }, - "instantiations": { - "count": 6, - "covered": 4, - "percent": 66.66666666666666 - }, - "lines": { - "count": 161, - "covered": 131, - "percent": 81.36645962732919 - }, - "regions": { - "count": 42, - "covered": 22, - "notcovered": 20, - "percent": 52.38095238095239 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json deleted file mode 100644 index 69356604856..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/conditions.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 64, - "covered": 33, - "percent": 51.5625 - }, - "regions": { - "count": 64, - "covered": 21, - "notcovered": 43, - "percent": 32.8125 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 64, - "covered": 33, - "percent": 51.5625 - }, - "regions": { - "count": 64, - "covered": 21, - "notcovered": 43, - "percent": 32.8125 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json deleted file mode 100644 index 6588ba90274..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/dead_code.rs", - "summary": { - "functions": { - "count": 1, - "covered": 0, - "percent": 0 - }, - "instantiations": { - "count": 1, - "covered": 0, - "percent": 0 - }, - "lines": { - "count": 33, - "covered": 11, - "percent": 33.33333333333333 - }, - "regions": { - "count": 12, - "covered": 3, - "notcovered": 9, - "percent": 25 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 0, - "percent": 0 - }, - "instantiations": { - "count": 1, - "covered": 0, - "percent": 0 - }, - "lines": { - "count": 33, - "covered": 11, - "percent": 33.33333333333333 - }, - "regions": { - "count": 12, - "covered": 3, - "notcovered": 9, - "percent": 25 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json deleted file mode 100644 index e303d3802f5..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/drop_trait.rs", - "summary": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 12, - "covered": 12, - "percent": 100 - }, - "regions": { - "count": 4, - "covered": 4, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "totals": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 12, - "covered": 12, - "percent": 100 - }, - "regions": { - "count": 4, - "covered": 4, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json deleted file mode 100644 index bfae69d7ac4..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/generics.rs", - "summary": { - "functions": { - "count": 3, - "covered": 3, - "percent": 100 - }, - "instantiations": { - "count": 5, - "covered": 5, - "percent": 100 - }, - "lines": { - "count": 18, - "covered": 18, - "percent": 100 - }, - "regions": { - "count": 5, - "covered": 5, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "totals": { - "functions": { - "count": 3, - "covered": 3, - "percent": 100 - }, - "instantiations": { - "count": 5, - "covered": 5, - "percent": 100 - }, - "lines": { - "count": 18, - "covered": 18, - "percent": 100 - }, - "regions": { - "count": 5, - "covered": 5, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json deleted file mode 100644 index 8f233f8bfc5..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/if.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 26, - "covered": 26, - "percent": 100 - }, - "regions": { - "count": 4, - "covered": 3, - "notcovered": 1, - "percent": 75 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 26, - "covered": 26, - "percent": 100 - }, - "regions": { - "count": 4, - "covered": 3, - "notcovered": 1, - "percent": 75 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json deleted file mode 100644 index 5c0454e1ecb..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/if_else.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 32, - "covered": 23, - "percent": 71.875 - }, - "regions": { - "count": 7, - "covered": 5, - "notcovered": 2, - "percent": 71.42857142857143 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 32, - "covered": 23, - "percent": 71.875 - }, - "regions": { - "count": 7, - "covered": 5, - "notcovered": 2, - "percent": 71.42857142857143 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json deleted file mode 100644 index 07ef9a9ab33..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/inner_items.rs", - "summary": { - "functions": { - "count": 4, - "covered": 4, - "percent": 100 - }, - "instantiations": { - "count": 4, - "covered": 4, - "percent": 100 - }, - "lines": { - "count": 29, - "covered": 29, - "percent": 100 - }, - "regions": { - "count": 11, - "covered": 9, - "notcovered": 2, - "percent": 81.81818181818183 - } - } - } - ], - "totals": { - "functions": { - "count": 4, - "covered": 4, - "percent": 100 - }, - "instantiations": { - "count": 4, - "covered": 4, - "percent": 100 - }, - "lines": { - "count": 29, - "covered": 29, - "percent": 100 - }, - "regions": { - "count": 11, - "covered": 9, - "notcovered": 2, - "percent": 81.81818181818183 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json deleted file mode 100644 index c3a96b08e6a..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/lazy_boolean.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 44, - "covered": 33, - "percent": 75 - }, - "regions": { - "count": 28, - "covered": 21, - "notcovered": 7, - "percent": 75 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 44, - "covered": 33, - "percent": 75 - }, - "regions": { - "count": 28, - "covered": 21, - "notcovered": 7, - "percent": 75 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json deleted file mode 100644 index 6cb1465c818..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/loop_break_value.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 11, - "covered": 11, - "percent": 100 - }, - "regions": { - "count": 1, - "covered": 1, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 11, - "covered": 11, - "percent": 100 - }, - "regions": { - "count": 1, - "covered": 1, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json deleted file mode 100644 index 6d566f2b818..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/loops_branches.rs", - "summary": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 11, - "covered": 11, - "percent": 100 - }, - "regions": { - "count": 8, - "covered": 7, - "notcovered": 1, - "percent": 87.5 - } - } - } - ], - "totals": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 11, - "covered": 11, - "percent": 100 - }, - "regions": { - "count": 8, - "covered": 7, - "notcovered": 1, - "percent": 87.5 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json deleted file mode 100644 index 8559fc84aa9..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.match_or_pattern.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/match_or_pattern.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 37, - "covered": 33, - "percent": 89.1891891891892 - }, - "regions": { - "count": 25, - "covered": 17, - "notcovered": 8, - "percent": 68 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 37, - "covered": 33, - "percent": 89.1891891891892 - }, - "regions": { - "count": 25, - "covered": 17, - "notcovered": 8, - "percent": 68 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json deleted file mode 100644 index bf3b5cb031b..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/nested_loops.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 22, - "covered": 17, - "percent": 77.27272727272727 - }, - "regions": { - "count": 14, - "covered": 11, - "notcovered": 3, - "percent": 78.57142857142857 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 22, - "covered": 17, - "percent": 77.27272727272727 - }, - "regions": { - "count": 14, - "covered": 11, - "notcovered": 3, - "percent": 78.57142857142857 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json deleted file mode 100644 index 128f5888ed1..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/overflow.rs", - "summary": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 23, - "covered": 21, - "percent": 91.30434782608695 - }, - "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 - } - } - } - ], - "totals": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 23, - "covered": 21, - "percent": 91.30434782608695 - }, - "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json deleted file mode 100644 index 9c08dfd41a1..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/panic_unwind.rs", - "summary": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 19, - "covered": 17, - "percent": 89.47368421052632 - }, - "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 - } - } - } - ], - "totals": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 19, - "covered": 17, - "percent": 89.47368421052632 - }, - "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json deleted file mode 100644 index 6a0d83a6d0e..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/partial_eq.rs", - "summary": { - "functions": { - "count": 5, - "covered": 4, - "percent": 80 - }, - "instantiations": { - "count": 5, - "covered": 4, - "percent": 80 - }, - "lines": { - "count": 18, - "covered": 16, - "percent": 88.88888888888889 - }, - "regions": { - "count": 24, - "covered": 5, - "notcovered": 19, - "percent": 20.833333333333336 - } - } - } - ], - "totals": { - "functions": { - "count": 5, - "covered": 4, - "percent": 80 - }, - "instantiations": { - "count": 5, - "covered": 4, - "percent": 80 - }, - "lines": { - "count": 18, - "covered": 16, - "percent": 88.88888888888889 - }, - "regions": { - "count": 24, - "covered": 5, - "notcovered": 19, - "percent": 20.833333333333336 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json deleted file mode 100644 index 4c849692a03..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/simple_loop.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 25, - "covered": 25, - "percent": 100 - }, - "regions": { - "count": 7, - "covered": 6, - "notcovered": 1, - "percent": 85.71428571428571 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 25, - "covered": 25, - "percent": 100 - }, - "regions": { - "count": 7, - "covered": 6, - "notcovered": 1, - "percent": 85.71428571428571 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json deleted file mode 100644 index 41bc4d57d59..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/simple_match.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 27, - "covered": 27, - "percent": 100 - }, - "regions": { - "count": 11, - "covered": 10, - "notcovered": 1, - "percent": 90.9090909090909 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 27, - "covered": 27, - "percent": 100 - }, - "regions": { - "count": 11, - "covered": 10, - "notcovered": 1, - "percent": 90.9090909090909 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json deleted file mode 100644 index 7f6c90b92d2..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/tight_inf_loop.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 4, - "covered": 4, - "percent": 100 - }, - "regions": { - "count": 2, - "covered": 2, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 4, - "covered": 4, - "percent": 100 - }, - "regions": { - "count": 2, - "covered": 2, - "notcovered": 0, - "percent": 100 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json deleted file mode 100644 index df4de9dc54b..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/try_error_result.rs", - "summary": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 20, - "covered": 18, - "percent": 90 - }, - "regions": { - "count": 16, - "covered": 12, - "notcovered": 4, - "percent": 75 - } - } - } - ], - "totals": { - "functions": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "instantiations": { - "count": 2, - "covered": 2, - "percent": 100 - }, - "lines": { - "count": 20, - "covered": 18, - "percent": 90 - }, - "regions": { - "count": 16, - "covered": 12, - "notcovered": 4, - "percent": 75 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json deleted file mode 100644 index 35ddd58fc43..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/lib/used_crate.rs", - "summary": { - "functions": { - "count": 6, - "covered": 5, - "percent": 83.33333333333334 - }, - "instantiations": { - "count": 10, - "covered": 8, - "percent": 80 - }, - "lines": { - "count": 46, - "covered": 26, - "percent": 56.52173913043478 - }, - "regions": { - "count": 19, - "covered": 8, - "notcovered": 11, - "percent": 42.10526315789473 - } - } - } - ], - "totals": { - "functions": { - "count": 6, - "covered": 5, - "percent": 83.33333333333334 - }, - "instantiations": { - "count": 10, - "covered": 8, - "percent": 80 - }, - "lines": { - "count": 46, - "covered": 26, - "percent": 56.52173913043478 - }, - "regions": { - "count": 19, - "covered": 8, - "notcovered": 11, - "percent": 42.10526315789473 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json deleted file mode 100644 index 339c533ada6..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/while.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 5, - "covered": 4, - "percent": 80 - }, - "regions": { - "count": 4, - "covered": 3, - "notcovered": 1, - "percent": 75 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 5, - "covered": 4, - "percent": 80 - }, - "regions": { - "count": 4, - "covered": 3, - "notcovered": 1, - "percent": 75 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json deleted file mode 100644 index b7fe2a0fb47..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/while_early_ret.rs", - "summary": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 19, - "covered": 17, - "percent": 89.47368421052632 - }, - "regions": { - "count": 9, - "covered": 7, - "notcovered": 2, - "percent": 77.77777777777779 - } - } - } - ], - "totals": { - "functions": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "instantiations": { - "count": 1, - "covered": 1, - "percent": 100 - }, - "lines": { - "count": 19, - "covered": 17, - "percent": 89.47368421052632 - }, - "regions": { - "count": 9, - "covered": 7, - "notcovered": 2, - "percent": 77.77777777777779 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json deleted file mode 100644 index 6fc41212bc0..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "../coverage/yield.rs", - "summary": { - "functions": { - "count": 3, - "covered": 3, - "percent": 100 - }, - "instantiations": { - "count": 3, - "covered": 3, - "percent": 100 - }, - "lines": { - "count": 26, - "covered": 19, - "percent": 73.07692307692307 - }, - "regions": { - "count": 23, - "covered": 17, - "notcovered": 6, - "percent": 73.91304347826086 - } - } - } - ], - "totals": { - "functions": { - "count": 3, - "covered": 3, - "percent": 100 - }, - "instantiations": { - "count": 3, - "covered": 3, - "percent": 100 - }, - "lines": { - "count": 26, - "covered": 19, - "percent": 73.07692307692307 - }, - "regions": { - "count": 23, - "covered": 17, - "notcovered": 6, - "percent": 73.91304347826086 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt deleted file mode 100644 index cbf7462eba5..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt +++ /dev/null @@ -1,67 +0,0 @@ -Counter in file 0 14:1 -> 15:27, #1 -Counter in file 0 16:11 -> 16:24, (#1 + (#2 + #3)) -Counter in file 0 17:12 -> 17:25, ((#1 + (#2 + #3)) - #4) -Counter in file 0 17:26 -> 19:10, #5 -Counter in file 0 19:10 -> 19:11, (((#1 + (#2 + #3)) - #4) - #5) -Counter in file 0 21:12 -> 21:25, (#5 + (((#1 + (#2 + #3)) - #4) - #5)) -Counter in file 0 21:26 -> 21:49, #6 -Counter in file 0 21:49 -> 21:50, ((#5 + (((#1 + (#2 + #3)) - #4) - #5)) - #6) -Counter in file 0 25:12 -> 25:25, (#6 + ((#5 + (((#1 + (#2 + #3)) - #4) - #5)) - #6)) -Counter in file 0 25:26 -> 25:49, #2 -Counter in file 0 25:49 -> 25:50, #3 -Counter in file 0 26:9 -> 26:23, (#2 + #3) -Counter in file 0 28:5 -> 29:2, #4 -Counter in file 0 5:1 -> 5:36, #1 -Counter in file 0 6:8 -> 6:20, (#1 + 0) -Counter in file 0 7:9 -> 8:37, #2 -Counter in file 0 9:12 -> 12:2, (#1 - #2) -Emitting segments for file: ../coverage/abort.rs -Combined regions: - 5:1 -> 5:36 (count=12) - 6:8 -> 6:20 (count=12) - 7:9 -> 8:37 (count=0) - 9:12 -> 12:2 (count=12) - 14:1 -> 15:27 (count=1) - 16:11 -> 16:24 (count=11) - 17:12 -> 17:25 (count=10) - 17:26 -> 19:10 (count=4) - 19:10 -> 19:11 (count=6) - 21:12 -> 21:25 (count=10) - 21:26 -> 21:49 (count=4) - 21:49 -> 21:50 (count=6) - 25:12 -> 25:25 (count=10) - 25:26 -> 25:49 (count=4) - 25:49 -> 25:50 (count=6) - 26:9 -> 26:23 (count=10) - 28:5 -> 29:2 (count=1) -Segment at 5:1 (count = 12), RegionEntry -Segment at 5:36 (count = 0), Skipped -Segment at 6:8 (count = 12), RegionEntry -Segment at 6:20 (count = 0), Skipped -Segment at 7:9 (count = 0), RegionEntry -Segment at 8:37 (count = 0), Skipped -Segment at 9:12 (count = 12), RegionEntry -Segment at 12:2 (count = 0), Skipped -Segment at 14:1 (count = 1), RegionEntry -Segment at 15:27 (count = 0), Skipped -Segment at 16:11 (count = 11), RegionEntry -Segment at 16:24 (count = 0), Skipped -Segment at 17:12 (count = 10), RegionEntry -Segment at 17:25 (count = 0), Skipped -Segment at 17:26 (count = 4), RegionEntry -Segment at 19:10 (count = 6), RegionEntry -Segment at 19:11 (count = 0), Skipped -Segment at 21:12 (count = 10), RegionEntry -Segment at 21:25 (count = 0), Skipped -Segment at 21:26 (count = 4), RegionEntry -Segment at 21:49 (count = 6), RegionEntry -Segment at 21:50 (count = 0), Skipped -Segment at 25:12 (count = 10), RegionEntry -Segment at 25:25 (count = 0), Skipped -Segment at 25:26 (count = 4), RegionEntry -Segment at 25:49 (count = 6), RegionEntry -Segment at 25:50 (count = 0), Skipped -Segment at 26:9 (count = 10), RegionEntry -Segment at 26:23 (count = 0), Skipped -Segment at 28:5 (count = 1), RegionEntry -Segment at 29:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt deleted file mode 100644 index 0866a9a59a1..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt +++ /dev/null @@ -1,57 +0,0 @@ -Counter in file 0 9:1 -> 10:27, #1 -Counter in file 0 11:11 -> 11:24, (#1 + (#2 + (#3 + #4))) -Counter in file 0 12:12 -> 12:26, ((#1 + (#2 + (#3 + #4))) - #5) -Counter in file 0 12:27 -> 14:10, #2 -Counter in file 0 14:19 -> 14:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2) -Counter in file 0 14:33 -> 16:10, #3 -Counter in file 0 16:10 -> 16:11, #4 -Counter in file 0 17:9 -> 17:23, (#2 + (#3 + #4)) -Counter in file 0 19:5 -> 20:2, #5 -Counter in file 0 4:1 -> 4:41, #1 -Counter in file 0 5:5 -> 5:48, (#1 + 0) -Counter in file 0 6:16 -> 6:21, (#1 + 0) -Counter in file 0 6:37 -> 6:61, #2 -Counter in file 0 7:1 -> 7:2, (#1 - #2) -Emitting segments for file: ../coverage/assert.rs -Combined regions: - 4:1 -> 4:41 (count=4) - 5:5 -> 5:48 (count=4) - 6:16 -> 6:21 (count=4) - 6:37 -> 6:61 (count=1) - 7:1 -> 7:2 (count=3) - 9:1 -> 10:27 (count=1) - 11:11 -> 11:24 (count=11) - 12:12 -> 12:26 (count=11) - 12:27 -> 14:10 (count=1) - 14:19 -> 14:32 (count=10) - 14:33 -> 16:10 (count=3) - 16:10 -> 16:11 (count=6) - 17:9 -> 17:23 (count=10) - 19:5 -> 20:2 (count=0) -Segment at 4:1 (count = 4), RegionEntry -Segment at 4:41 (count = 0), Skipped -Segment at 5:5 (count = 4), RegionEntry -Segment at 5:48 (count = 0), Skipped -Segment at 6:16 (count = 4), RegionEntry -Segment at 6:21 (count = 0), Skipped -Segment at 6:37 (count = 1), RegionEntry -Segment at 6:61 (count = 0), Skipped -Segment at 7:1 (count = 3), RegionEntry -Segment at 7:2 (count = 0), Skipped -Segment at 9:1 (count = 1), RegionEntry -Segment at 10:27 (count = 0), Skipped -Segment at 11:11 (count = 11), RegionEntry -Segment at 11:24 (count = 0), Skipped -Segment at 12:12 (count = 11), RegionEntry -Segment at 12:26 (count = 0), Skipped -Segment at 12:27 (count = 1), RegionEntry -Segment at 14:10 (count = 0), Skipped -Segment at 14:19 (count = 10), RegionEntry -Segment at 14:32 (count = 0), Skipped -Segment at 14:33 (count = 3), RegionEntry -Segment at 16:10 (count = 6), RegionEntry -Segment at 16:11 (count = 0), Skipped -Segment at 17:9 (count = 10), RegionEntry -Segment at 17:23 (count = 0), Skipped -Segment at 19:5 (count = 0), RegionEntry -Segment at 20:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt deleted file mode 100644 index 4df0bac8c86..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt +++ /dev/null @@ -1,311 +0,0 @@ -Counter in file 0 13:1 -> 13:20, #1 -Counter in file 0 15:1 -> 15:20, 0 -Counter in file 0 15:20 -> 15:21, 0 -Counter in file 0 19:1 -> 19:30, 0 -Counter in file 0 19:30 -> 19:31, 0 -Counter in file 0 21:23 -> 22:12, 0 -Counter in file 0 23:9 -> 23:10, 0 -Counter in file 0 23:14 -> 23:17, 0 -Counter in file 0 23:27 -> 23:28, 0 -Counter in file 0 23:32 -> 23:34, 0 -Counter in file 0 24:9 -> 24:10, 0 -Counter in file 0 24:14 -> 24:17, 0 -Counter in file 0 24:27 -> 24:28, 0 -Counter in file 0 24:32 -> 24:34, 0 -Counter in file 0 25:14 -> 25:16, 0 -Counter in file 0 27:1 -> 27:2, 0 -Counter in file 0 29:22 -> 32:12, 0 -Counter in file 0 33:9 -> 33:10, 0 -Counter in file 0 33:14 -> 33:19, 0 -Counter in file 0 33:26 -> 33:27, 0 -Counter in file 0 33:32 -> 33:34, 0 -Counter in file 0 34:14 -> 34:16, 0 -Counter in file 0 36:1 -> 36:2, 0 -Counter in file 0 75:1 -> 76:12, 0 -Counter in file 0 77:14 -> 77:16, 0 -Counter in file 0 78:14 -> 78:16, 0 -Counter in file 0 79:14 -> 79:16, 0 -Counter in file 0 81:1 -> 81:2, 0 -Counter in file 0 91:25 -> 91:34, 0 -Counter in file 0 5:1 -> 5:25, #1 -Counter in file 0 21:1 -> 21:23, #1 -Counter in file 0 17:20 -> 17:21, #1 -Counter in file 0 67:5 -> 67:23, #1 -Counter in file 0 38:1 -> 38:19, #1 -Counter in file 0 38:19 -> 42:12, #1 -Counter in file 0 43:9 -> 43:10, #3 -Counter in file 0 43:14 -> 43:18, (#1 + 0) -Counter in file 0 43:28 -> 43:33, #2 -Counter in file 0 43:39 -> 43:42, (#3 + 0) -Counter in file 0 44:9 -> 44:10, #6 -Counter in file 0 44:14 -> 44:17, #4 -Counter in file 0 44:27 -> 44:32, #8 -Counter in file 0 44:36 -> 44:38, (#6 + 0) -Counter in file 0 45:14 -> 45:16, #7 -Counter in file 0 47:1 -> 47:2, (#5 + (#6 + #7)) -Counter in file 0 13:20 -> 13:21, #1 -Counter in file 0 29:1 -> 29:22, #1 -Counter in file 0 93:1 -> 101:2, #1 -Counter in file 0 91:1 -> 91:25, #1 -Counter in file 0 5:25 -> 6:14, #1 -Counter in file 0 7:9 -> 7:10, #2 -Counter in file 0 9:9 -> 9:10, (#1 - #2) -Counter in file 0 11:1 -> 11:2, (#2 + (#1 - #2)) -Counter in file 0 51:5 -> 52:18, #1 -Counter in file 0 53:13 -> 53:14, #2 -Counter in file 0 63:13 -> 63:14, (#1 - #2) -Counter in file 0 65:5 -> 65:6, (#2 + (#1 - #2)) -Counter in file 0 49:1 -> 68:12, #1 -Counter in file 0 69:9 -> 69:10, #2 -Counter in file 0 69:14 -> 69:27, (#1 + 0) -Counter in file 0 69:31 -> 69:39, (#2 + 0) -Counter in file 0 70:9 -> 70:10, #3 -Counter in file 0 70:14 -> 70:26, #5 -Counter in file 0 70:30 -> 70:32, (#3 + 0) -Counter in file 0 71:14 -> 71:16, #4 -Counter in file 0 73:1 -> 73:2, (#2 + (#3 + #4)) -Counter in file 0 83:1 -> 84:12, #1 -Counter in file 0 85:14 -> 85:16, (#1 - (#3 + #2)) -Counter in file 0 86:14 -> 86:16, #2 -Counter in file 0 87:14 -> 87:16, #3 -Counter in file 0 89:1 -> 89:2, (#3 + (#2 + (#1 - (#3 + #2)))) -Counter in file 0 17:1 -> 17:20, #1 -Counter in file 0 66:5 -> 66:23, #1 -Counter in file 0 17:9 -> 17:10, #1 -Counter in file 0 17:9 -> 17:10, #1 -Counter in file 0 117:17 -> 117:19, #1 -Counter in file 0 17:9 -> 17:10, #1 -Counter in file 0 110:5 -> 120:54, #1 -Counter in file 0 123:32 -> 123:35, ((#1 + #2) - #2) -Counter in file 0 123:39 -> 123:73, (#1 + #2) -Counter in file 0 124:23 -> 124:26, (((#1 + #2) - #2) + 0) -Counter in file 0 125:14 -> 125:15, #2 -Counter in file 0 127:5 -> 127:6, (((#1 + #2) - #2) + 0) -Emitting segments for file: ../coverage/async.rs -Combined regions: - 5:1 -> 5:25 (count=1) - 5:25 -> 6:14 (count=1) - 7:9 -> 7:10 (count=1) - 9:9 -> 9:10 (count=0) - 11:1 -> 11:2 (count=1) - 13:1 -> 13:20 (count=0) - 15:1 -> 15:20 (count=0) - 15:20 -> 15:21 (count=0) - 17:1 -> 17:20 (count=1) - 17:20 -> 17:21 (count=1) - 19:1 -> 19:30 (count=0) - 19:30 -> 19:31 (count=0) - 21:1 -> 21:23 (count=1) - 21:23 -> 22:12 (count=0) - 23:9 -> 23:10 (count=0) - 23:14 -> 23:17 (count=0) - 23:27 -> 23:28 (count=0) - 23:32 -> 23:34 (count=0) - 24:9 -> 24:10 (count=0) - 24:14 -> 24:17 (count=0) - 24:27 -> 24:28 (count=0) - 24:32 -> 24:34 (count=0) - 25:14 -> 25:16 (count=0) - 27:1 -> 27:2 (count=0) - 29:1 -> 29:22 (count=1) - 29:22 -> 32:12 (count=0) - 33:9 -> 33:10 (count=0) - 33:14 -> 33:19 (count=0) - 33:26 -> 33:27 (count=0) - 33:32 -> 33:34 (count=0) - 34:14 -> 34:16 (count=0) - 36:1 -> 36:2 (count=0) - 38:1 -> 38:19 (count=1) - 38:19 -> 42:12 (count=1) - 43:9 -> 43:10 (count=0) - 43:14 -> 43:18 (count=1) - 43:28 -> 43:33 (count=1) - 43:39 -> 43:42 (count=0) - 44:9 -> 44:10 (count=0) - 44:14 -> 44:17 (count=1) - 44:27 -> 44:32 (count=1) - 44:36 -> 44:38 (count=0) - 45:14 -> 45:16 (count=1) - 47:1 -> 47:2 (count=1) - 49:1 -> 68:12 (count=1) - 51:5 -> 52:18 (count=1) - 53:13 -> 53:14 (count=0) - 63:13 -> 63:14 (count=1) - 65:5 -> 65:6 (count=1) - 67:5 -> 67:23 (count=1) - 69:9 -> 69:10 (count=0) - 69:14 -> 69:27 (count=1) - 69:31 -> 69:39 (count=0) - 70:9 -> 70:10 (count=0) - 70:14 -> 70:26 (count=1) - 70:30 -> 70:32 (count=0) - 71:14 -> 71:16 (count=1) - 73:1 -> 73:2 (count=1) - 75:1 -> 76:12 (count=0) - 77:14 -> 77:16 (count=0) - 78:14 -> 78:16 (count=0) - 79:14 -> 79:16 (count=0) - 81:1 -> 81:2 (count=0) - 83:1 -> 84:12 (count=1) - 85:14 -> 85:16 (count=0) - 86:14 -> 86:16 (count=0) - 87:14 -> 87:16 (count=1) - 89:1 -> 89:2 (count=1) - 91:1 -> 91:25 (count=1) - 91:25 -> 91:34 (count=0) - 93:1 -> 101:2 (count=1) - 110:5 -> 120:54 (count=1) - 117:17 -> 117:19 (count=1) - 123:32 -> 123:35 (count=1) - 123:39 -> 123:73 (count=1) - 124:23 -> 124:26 (count=1) - 125:14 -> 125:15 (count=0) - 127:5 -> 127:6 (count=1) -Segment at 5:1 (count = 1), RegionEntry -Segment at 5:25 (count = 1), RegionEntry -Segment at 6:14 (count = 0), Skipped -Segment at 7:9 (count = 1), RegionEntry -Segment at 7:10 (count = 0), Skipped -Segment at 9:9 (count = 0), RegionEntry -Segment at 9:10 (count = 0), Skipped -Segment at 11:1 (count = 1), RegionEntry -Segment at 11:2 (count = 0), Skipped -Segment at 13:1 (count = 0), RegionEntry -Segment at 13:20 (count = 0), Skipped -Segment at 15:1 (count = 0), RegionEntry -Segment at 15:20 (count = 0), RegionEntry -Segment at 15:21 (count = 0), Skipped -Segment at 17:1 (count = 1), RegionEntry -Segment at 17:20 (count = 1), RegionEntry -Segment at 17:21 (count = 0), Skipped -Segment at 19:1 (count = 0), RegionEntry -Segment at 19:30 (count = 0), RegionEntry -Segment at 19:31 (count = 0), Skipped -Segment at 21:1 (count = 1), RegionEntry -Segment at 21:23 (count = 0), RegionEntry -Segment at 22:12 (count = 0), Skipped -Segment at 23:9 (count = 0), RegionEntry -Segment at 23:10 (count = 0), Skipped -Segment at 23:14 (count = 0), RegionEntry -Segment at 23:17 (count = 0), Skipped -Segment at 23:27 (count = 0), RegionEntry -Segment at 23:28 (count = 0), Skipped -Segment at 23:32 (count = 0), RegionEntry -Segment at 23:34 (count = 0), Skipped -Segment at 24:9 (count = 0), RegionEntry -Segment at 24:10 (count = 0), Skipped -Segment at 24:14 (count = 0), RegionEntry -Segment at 24:17 (count = 0), Skipped -Segment at 24:27 (count = 0), RegionEntry -Segment at 24:28 (count = 0), Skipped -Segment at 24:32 (count = 0), RegionEntry -Segment at 24:34 (count = 0), Skipped -Segment at 25:14 (count = 0), RegionEntry -Segment at 25:16 (count = 0), Skipped -Segment at 27:1 (count = 0), RegionEntry -Segment at 27:2 (count = 0), Skipped -Segment at 29:1 (count = 1), RegionEntry -Segment at 29:22 (count = 0), RegionEntry -Segment at 32:12 (count = 0), Skipped -Segment at 33:9 (count = 0), RegionEntry -Segment at 33:10 (count = 0), Skipped -Segment at 33:14 (count = 0), RegionEntry -Segment at 33:19 (count = 0), Skipped -Segment at 33:26 (count = 0), RegionEntry -Segment at 33:27 (count = 0), Skipped -Segment at 33:32 (count = 0), RegionEntry -Segment at 33:34 (count = 0), Skipped -Segment at 34:14 (count = 0), RegionEntry -Segment at 34:16 (count = 0), Skipped -Segment at 36:1 (count = 0), RegionEntry -Segment at 36:2 (count = 0), Skipped -Segment at 38:1 (count = 1), RegionEntry -Segment at 38:19 (count = 1), RegionEntry -Segment at 42:12 (count = 0), Skipped -Segment at 43:9 (count = 0), RegionEntry -Segment at 43:10 (count = 0), Skipped -Segment at 43:14 (count = 1), RegionEntry -Segment at 43:18 (count = 0), Skipped -Segment at 43:28 (count = 1), RegionEntry -Segment at 43:33 (count = 0), Skipped -Segment at 43:39 (count = 0), RegionEntry -Segment at 43:42 (count = 0), Skipped -Segment at 44:9 (count = 0), RegionEntry -Segment at 44:10 (count = 0), Skipped -Segment at 44:14 (count = 1), RegionEntry -Segment at 44:17 (count = 0), Skipped -Segment at 44:27 (count = 1), RegionEntry -Segment at 44:32 (count = 0), Skipped -Segment at 44:36 (count = 0), RegionEntry -Segment at 44:38 (count = 0), Skipped -Segment at 45:14 (count = 1), RegionEntry -Segment at 45:16 (count = 0), Skipped -Segment at 47:1 (count = 1), RegionEntry -Segment at 47:2 (count = 0), Skipped -Segment at 49:1 (count = 1), RegionEntry -Segment at 51:5 (count = 1), RegionEntry -Segment at 52:18 (count = 1) -Segment at 53:13 (count = 0), RegionEntry -Segment at 53:14 (count = 1) -Segment at 63:13 (count = 1), RegionEntry -Segment at 63:14 (count = 1) -Segment at 65:5 (count = 1), RegionEntry -Segment at 65:6 (count = 1) -Segment at 67:5 (count = 1), RegionEntry -Segment at 67:23 (count = 1) -Segment at 68:12 (count = 0), Skipped -Segment at 69:9 (count = 0), RegionEntry -Segment at 69:10 (count = 0), Skipped -Segment at 69:14 (count = 1), RegionEntry -Segment at 69:27 (count = 0), Skipped -Segment at 69:31 (count = 0), RegionEntry -Segment at 69:39 (count = 0), Skipped -Segment at 70:9 (count = 0), RegionEntry -Segment at 70:10 (count = 0), Skipped -Segment at 70:14 (count = 1), RegionEntry -Segment at 70:26 (count = 0), Skipped -Segment at 70:30 (count = 0), RegionEntry -Segment at 70:32 (count = 0), Skipped -Segment at 71:14 (count = 1), RegionEntry -Segment at 71:16 (count = 0), Skipped -Segment at 73:1 (count = 1), RegionEntry -Segment at 73:2 (count = 0), Skipped -Segment at 75:1 (count = 0), RegionEntry -Segment at 76:12 (count = 0), Skipped -Segment at 77:14 (count = 0), RegionEntry -Segment at 77:16 (count = 0), Skipped -Segment at 78:14 (count = 0), RegionEntry -Segment at 78:16 (count = 0), Skipped -Segment at 79:14 (count = 0), RegionEntry -Segment at 79:16 (count = 0), Skipped -Segment at 81:1 (count = 0), RegionEntry -Segment at 81:2 (count = 0), Skipped -Segment at 83:1 (count = 1), RegionEntry -Segment at 84:12 (count = 0), Skipped -Segment at 85:14 (count = 0), RegionEntry -Segment at 85:16 (count = 0), Skipped -Segment at 86:14 (count = 0), RegionEntry -Segment at 86:16 (count = 0), Skipped -Segment at 87:14 (count = 1), RegionEntry -Segment at 87:16 (count = 0), Skipped -Segment at 89:1 (count = 1), RegionEntry -Segment at 89:2 (count = 0), Skipped -Segment at 91:1 (count = 1), RegionEntry -Segment at 91:25 (count = 0), RegionEntry -Segment at 91:34 (count = 0), Skipped -Segment at 93:1 (count = 1), RegionEntry -Segment at 101:2 (count = 0), Skipped -Segment at 110:5 (count = 1), RegionEntry -Segment at 117:17 (count = 1), RegionEntry -Segment at 117:19 (count = 1) -Segment at 120:54 (count = 0), Skipped -Segment at 123:32 (count = 1), RegionEntry -Segment at 123:35 (count = 0), Skipped -Segment at 123:39 (count = 1), RegionEntry -Segment at 123:73 (count = 0), Skipped -Segment at 124:23 (count = 1), RegionEntry -Segment at 124:26 (count = 0), Skipped -Segment at 125:14 (count = 0), RegionEntry -Segment at 125:15 (count = 0), Skipped -Segment at 127:5 (count = 1), RegionEntry -Segment at 127:6 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt deleted file mode 100644 index 1aacac0ed25..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt +++ /dev/null @@ -1,153 +0,0 @@ -Counter in file 0 98:5 -> 100:20, #1 -Counter in file 0 100:21 -> 102:10, #2 -Counter in file 0 102:10 -> 102:11, (#1 - #2) -Counter in file 0 103:9 -> 104:6, (#2 + (#1 - #2)) -Counter in file 0 123:5 -> 124:20, 0 -Counter in file 0 124:21 -> 126:10, 0 -Counter in file 0 126:10 -> 126:11, 0 -Counter in file 0 127:9 -> 128:6, 0 -Counter in file 0 131:53 -> 131:67, 0 -Counter in file 0 141:59 -> 141:85, 0 -Counter in file 0 143:56 -> 145:6, 0 -Counter in file 0 149:7 -> 149:33, 0 -Counter in file 0 153:7 -> 153:33, 0 -Counter in file 0 3:1 -> 18:13, #1 -Counter in file 0 25:14 -> 33:9, (#1 + 0) -Counter in file 0 40:6 -> 60:13, (#1 + 0) -Counter in file 0 67:14 -> 75:9, (#1 + 0) -Counter in file 0 82:6 -> 97:9, (#1 + 0) -Counter in file 0 104:6 -> 120:9, (#1 + 0) -Counter in file 0 128:6 -> 131:33, (#1 + 0) -Counter in file 0 131:67 -> 136:33, (#1 + 0) -Counter in file 0 136:75 -> 141:39, (#1 + 0) -Counter in file 0 141:85 -> 143:36, (#1 + 0) -Counter in file 0 145:6 -> 147:36, (#1 + 0) -Counter in file 0 149:33 -> 151:43, (#1 + 0) -Counter in file 0 153:33 -> 155:2, (#1 + 0) -Counter in file 0 61:13 -> 63:28, #1 -Counter in file 0 63:29 -> 65:18, #2 -Counter in file 0 65:18 -> 65:19, (#1 - #2) -Counter in file 0 66:17 -> 67:14, (#2 + (#1 - #2)) -Counter in file 0 76:5 -> 78:20, #1 -Counter in file 0 78:21 -> 80:10, #2 -Counter in file 0 80:10 -> 80:11, (#1 - #2) -Counter in file 0 81:9 -> 82:6, (#2 + (#1 - #2)) -Counter in file 0 34:5 -> 36:20, #1 -Counter in file 0 36:21 -> 38:10, #2 -Counter in file 0 38:10 -> 38:11, (#1 - #2) -Counter in file 0 39:9 -> 40:6, (#2 + (#1 - #2)) -Counter in file 0 19:13 -> 21:28, #1 -Counter in file 0 21:29 -> 23:18, #2 -Counter in file 0 23:18 -> 23:19, (#1 - #2) -Counter in file 0 24:17 -> 25:14, (#2 + (#1 - #2)) -Emitting segments for file: ../coverage/closure.rs -Combined regions: - 3:1 -> 18:13 (count=1) - 19:13 -> 21:28 (count=0) - 21:29 -> 23:18 (count=0) - 23:18 -> 23:19 (count=0) - 24:17 -> 25:14 (count=0) - 25:14 -> 33:9 (count=1) - 34:5 -> 36:20 (count=0) - 36:21 -> 38:10 (count=0) - 38:10 -> 38:11 (count=0) - 39:9 -> 40:6 (count=0) - 40:6 -> 60:13 (count=1) - 61:13 -> 63:28 (count=1) - 63:29 -> 65:18 (count=0) - 65:18 -> 65:19 (count=1) - 66:17 -> 67:14 (count=1) - 67:14 -> 75:9 (count=1) - 76:5 -> 78:20 (count=1) - 78:21 -> 80:10 (count=0) - 80:10 -> 80:11 (count=1) - 81:9 -> 82:6 (count=1) - 82:6 -> 97:9 (count=1) - 98:5 -> 100:20 (count=5) - 100:21 -> 102:10 (count=0) - 102:10 -> 102:11 (count=5) - 103:9 -> 104:6 (count=5) - 104:6 -> 120:9 (count=1) - 123:5 -> 124:20 (count=0) - 124:21 -> 126:10 (count=0) - 126:10 -> 126:11 (count=0) - 127:9 -> 128:6 (count=0) - 128:6 -> 131:33 (count=1) - 131:53 -> 131:67 (count=0) - 131:67 -> 136:33 (count=1) - 136:75 -> 141:39 (count=1) - 141:59 -> 141:85 (count=0) - 141:85 -> 143:36 (count=1) - 143:56 -> 145:6 (count=0) - 145:6 -> 147:36 (count=1) - 149:7 -> 149:33 (count=0) - 149:33 -> 151:43 (count=1) - 153:7 -> 153:33 (count=0) - 153:33 -> 155:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 18:13 (count = 0), Skipped -Segment at 19:13 (count = 0), RegionEntry -Segment at 21:28 (count = 0), Skipped -Segment at 21:29 (count = 0), RegionEntry -Segment at 23:18 (count = 0), RegionEntry -Segment at 23:19 (count = 0), Skipped -Segment at 24:17 (count = 0), RegionEntry -Segment at 25:14 (count = 1), RegionEntry -Segment at 33:9 (count = 0), Skipped -Segment at 34:5 (count = 0), RegionEntry -Segment at 36:20 (count = 0), Skipped -Segment at 36:21 (count = 0), RegionEntry -Segment at 38:10 (count = 0), RegionEntry -Segment at 38:11 (count = 0), Skipped -Segment at 39:9 (count = 0), RegionEntry -Segment at 40:6 (count = 1), RegionEntry -Segment at 60:13 (count = 0), Skipped -Segment at 61:13 (count = 1), RegionEntry -Segment at 63:28 (count = 0), Skipped -Segment at 63:29 (count = 0), RegionEntry -Segment at 65:18 (count = 1), RegionEntry -Segment at 65:19 (count = 0), Skipped -Segment at 66:17 (count = 1), RegionEntry -Segment at 67:14 (count = 1), RegionEntry -Segment at 75:9 (count = 0), Skipped -Segment at 76:5 (count = 1), RegionEntry -Segment at 78:20 (count = 0), Skipped -Segment at 78:21 (count = 0), RegionEntry -Segment at 80:10 (count = 1), RegionEntry -Segment at 80:11 (count = 0), Skipped -Segment at 81:9 (count = 1), RegionEntry -Segment at 82:6 (count = 1), RegionEntry -Segment at 97:9 (count = 0), Skipped -Segment at 98:5 (count = 5), RegionEntry -Segment at 100:20 (count = 0), Skipped -Segment at 100:21 (count = 0), RegionEntry -Segment at 102:10 (count = 5), RegionEntry -Segment at 102:11 (count = 0), Skipped -Segment at 103:9 (count = 5), RegionEntry -Segment at 104:6 (count = 1), RegionEntry -Segment at 120:9 (count = 0), Skipped -Segment at 123:5 (count = 0), RegionEntry -Segment at 124:20 (count = 0), Skipped -Segment at 124:21 (count = 0), RegionEntry -Segment at 126:10 (count = 0), RegionEntry -Segment at 126:11 (count = 0), Skipped -Segment at 127:9 (count = 0), RegionEntry -Segment at 128:6 (count = 1), RegionEntry -Segment at 131:33 (count = 0), Skipped -Segment at 131:53 (count = 0), RegionEntry -Segment at 131:67 (count = 1), RegionEntry -Segment at 136:33 (count = 0), Skipped -Segment at 136:75 (count = 1), RegionEntry -Segment at 141:39 (count = 0), Skipped -Segment at 141:59 (count = 0), RegionEntry -Segment at 141:85 (count = 1), RegionEntry -Segment at 143:36 (count = 0), Skipped -Segment at 143:56 (count = 0), RegionEntry -Segment at 145:6 (count = 1), RegionEntry -Segment at 147:36 (count = 0), Skipped -Segment at 149:7 (count = 0), RegionEntry -Segment at 149:33 (count = 1), RegionEntry -Segment at 151:43 (count = 0), Skipped -Segment at 153:7 (count = 0), RegionEntry -Segment at 153:33 (count = 1), RegionEntry -Segment at 155:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt deleted file mode 100644 index 3a9c6a9b92e..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt +++ /dev/null @@ -1,253 +0,0 @@ -Counter in file 0 3:1 -> 3:11, #1 -Counter in file 0 4:9 -> 5:12, (#1 + 0) -Counter in file 0 5:13 -> 7:6, #2 -Counter in file 0 10:9 -> 10:10, (#3 + (#12 + #13)) -Counter in file 0 10:16 -> 10:29, (#2 + 0) -Counter in file 0 11:9 -> 12:10, #3 -Counter in file 0 13:15 -> 13:28, ((#2 + 0) - #3) -Counter in file 0 14:12 -> 14:25, #4 -Counter in file 0 14:29 -> 14:42, (#4 - #15) -Counter in file 0 14:46 -> 14:60, #21 -Counter in file 0 14:61 -> 16:10, #12 -Counter in file 0 16:10 -> 16:11, #13 -Counter in file 0 17:9 -> 18:18, (#12 + #13) -Counter in file 0 20:9 -> 20:15, (((#2 + 0) - #3) - #4) -Counter in file 0 23:9 -> 24:12, ((#3 + (#12 + #13)) + 0) -Counter in file 0 24:13 -> 26:6, #14 -Counter in file 0 28:8 -> 28:21, (#14 + 0) -Counter in file 0 28:22 -> 30:6, #16 -Counter in file 0 30:15 -> 30:28, ((#14 + 0) - #16) -Counter in file 0 31:12 -> 31:25, (((#14 + 0) - #16) - #11) -Counter in file 0 31:29 -> 31:42, ((((#14 + 0) - #16) - #11) - #23) -Counter in file 0 31:46 -> 31:60, #31 -Counter in file 0 31:61 -> 33:10, #18 -Counter in file 0 33:10 -> 33:11, #19 -Counter in file 0 34:9 -> 34:23, (#18 + #19) -Counter in file 0 36:9 -> 36:15, #11 -Counter in file 0 39:8 -> 39:12, (#16 + (#18 + #19)) -Counter in file 0 40:13 -> 41:16, #20 -Counter in file 0 41:17 -> 43:10, #24 -Counter in file 0 45:12 -> 45:25, (#24 + 0) -Counter in file 0 45:26 -> 47:10, #25 -Counter in file 0 48:17 -> 48:30, ((#24 + 0) - #25) -Counter in file 0 49:16 -> 49:29, (((#24 + 0) - #25) - #10) -Counter in file 0 49:33 -> 49:46, ((((#24 + 0) - #25) - #10) - #35) -Counter in file 0 49:50 -> 49:64, #40 -Counter in file 0 49:65 -> 51:14, #26 -Counter in file 0 51:14 -> 51:15, #27 -Counter in file 0 52:13 -> 52:27, (#26 + #27) -Counter in file 0 54:13 -> 54:19, #10 -Counter in file 0 59:9 -> 60:12, ((#25 + (#26 + #27)) + 0) -Counter in file 0 60:13 -> 62:6, #28 -Counter in file 0 64:9 -> 64:10, (#30 + (#33 + #34)) -Counter in file 0 64:16 -> 64:29, (#28 + 0) -Counter in file 0 64:30 -> 66:6, #30 -Counter in file 0 66:15 -> 66:28, ((#28 + 0) - #30) -Counter in file 0 67:12 -> 67:25, (((#28 + 0) - #30) - #9) -Counter in file 0 67:29 -> 67:42, ((((#28 + 0) - #30) - #9) - #36) -Counter in file 0 67:46 -> 67:60, #42 -Counter in file 0 67:61 -> 69:10, #33 -Counter in file 0 69:10 -> 69:11, #34 -Counter in file 0 70:9 -> 70:23, (#33 + #34) -Counter in file 0 72:13 -> 74:15, #9 -Counter in file 0 77:9 -> 77:10, (#5 + (#6 + #7)) -Counter in file 0 77:16 -> 77:29, ((#30 + (#33 + #34)) + 0) -Counter in file 0 77:30 -> 79:6, #5 -Counter in file 0 79:15 -> 79:28, ((#30 + (#33 + #34)) - #5) -Counter in file 0 80:12 -> 80:25, (((#30 + (#33 + #34)) - #5) - #8) -Counter in file 0 80:29 -> 80:42, ((((#30 + (#33 + #34)) - #5) - #8) - #39) -Counter in file 0 80:46 -> 80:60, #45 -Counter in file 0 80:61 -> 82:10, #6 -Counter in file 0 82:10 -> 82:11, #7 -Counter in file 0 83:9 -> 83:23, (#6 + #7) -Counter in file 0 85:9 -> 85:15, #8 -Counter in file 0 87:1 -> 87:2, ((#5 + (#6 + #7)) + (((#8 + #9) + (#10 + #11)) + (((#2 + 0) - #3) - #4))) -Emitting segments for file: ../coverage/conditions.rs -Combined regions: - 3:1 -> 3:11 (count=1) - 4:9 -> 5:12 (count=1) - 5:13 -> 7:6 (count=1) - 10:9 -> 10:10 (count=1) - 10:16 -> 10:29 (count=1) - 11:9 -> 12:10 (count=1) - 13:15 -> 13:28 (count=0) - 14:12 -> 14:25 (count=0) - 14:29 -> 14:42 (count=0) - 14:46 -> 14:60 (count=0) - 14:61 -> 16:10 (count=0) - 16:10 -> 16:11 (count=0) - 17:9 -> 18:18 (count=0) - 20:9 -> 20:15 (count=0) - 23:9 -> 24:12 (count=1) - 24:13 -> 26:6 (count=1) - 28:8 -> 28:21 (count=1) - 28:22 -> 30:6 (count=1) - 30:15 -> 30:28 (count=0) - 31:12 -> 31:25 (count=0) - 31:29 -> 31:42 (count=0) - 31:46 -> 31:60 (count=0) - 31:61 -> 33:10 (count=0) - 33:10 -> 33:11 (count=0) - 34:9 -> 34:23 (count=0) - 36:9 -> 36:15 (count=0) - 39:8 -> 39:12 (count=1) - 40:13 -> 41:16 (count=1) - 41:17 -> 43:10 (count=1) - 45:12 -> 45:25 (count=1) - 45:26 -> 47:10 (count=1) - 48:17 -> 48:30 (count=0) - 49:16 -> 49:29 (count=0) - 49:33 -> 49:46 (count=0) - 49:50 -> 49:64 (count=0) - 49:65 -> 51:14 (count=0) - 51:14 -> 51:15 (count=0) - 52:13 -> 52:27 (count=0) - 54:13 -> 54:19 (count=0) - 59:9 -> 60:12 (count=1) - 60:13 -> 62:6 (count=1) - 64:9 -> 64:10 (count=0) - 64:16 -> 64:29 (count=1) - 64:30 -> 66:6 (count=0) - 66:15 -> 66:28 (count=1) - 67:12 -> 67:25 (count=0) - 67:29 -> 67:42 (count=0) - 67:46 -> 67:60 (count=0) - 67:61 -> 69:10 (count=0) - 69:10 -> 69:11 (count=0) - 70:9 -> 70:23 (count=0) - 72:13 -> 74:15 (count=1) - 77:9 -> 77:10 (count=0) - 77:16 -> 77:29 (count=0) - 77:30 -> 79:6 (count=0) - 79:15 -> 79:28 (count=0) - 80:12 -> 80:25 (count=0) - 80:29 -> 80:42 (count=0) - 80:46 -> 80:60 (count=0) - 80:61 -> 82:10 (count=0) - 82:10 -> 82:11 (count=0) - 83:9 -> 83:23 (count=0) - 85:9 -> 85:15 (count=0) - 87:1 -> 87:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 3:11 (count = 0), Skipped -Segment at 4:9 (count = 1), RegionEntry -Segment at 5:12 (count = 0), Skipped -Segment at 5:13 (count = 1), RegionEntry -Segment at 7:6 (count = 0), Skipped -Segment at 10:9 (count = 1), RegionEntry -Segment at 10:10 (count = 0), Skipped -Segment at 10:16 (count = 1), RegionEntry -Segment at 10:29 (count = 0), Skipped -Segment at 11:9 (count = 1), RegionEntry -Segment at 12:10 (count = 0), Skipped -Segment at 13:15 (count = 0), RegionEntry -Segment at 13:28 (count = 0), Skipped -Segment at 14:12 (count = 0), RegionEntry -Segment at 14:25 (count = 0), Skipped -Segment at 14:29 (count = 0), RegionEntry -Segment at 14:42 (count = 0), Skipped -Segment at 14:46 (count = 0), RegionEntry -Segment at 14:60 (count = 0), Skipped -Segment at 14:61 (count = 0), RegionEntry -Segment at 16:10 (count = 0), RegionEntry -Segment at 16:11 (count = 0), Skipped -Segment at 17:9 (count = 0), RegionEntry -Segment at 18:18 (count = 0), Skipped -Segment at 20:9 (count = 0), RegionEntry -Segment at 20:15 (count = 0), Skipped -Segment at 23:9 (count = 1), RegionEntry -Segment at 24:12 (count = 0), Skipped -Segment at 24:13 (count = 1), RegionEntry -Segment at 26:6 (count = 0), Skipped -Segment at 28:8 (count = 1), RegionEntry -Segment at 28:21 (count = 0), Skipped -Segment at 28:22 (count = 1), RegionEntry -Segment at 30:6 (count = 0), Skipped -Segment at 30:15 (count = 0), RegionEntry -Segment at 30:28 (count = 0), Skipped -Segment at 31:12 (count = 0), RegionEntry -Segment at 31:25 (count = 0), Skipped -Segment at 31:29 (count = 0), RegionEntry -Segment at 31:42 (count = 0), Skipped -Segment at 31:46 (count = 0), RegionEntry -Segment at 31:60 (count = 0), Skipped -Segment at 31:61 (count = 0), RegionEntry -Segment at 33:10 (count = 0), RegionEntry -Segment at 33:11 (count = 0), Skipped -Segment at 34:9 (count = 0), RegionEntry -Segment at 34:23 (count = 0), Skipped -Segment at 36:9 (count = 0), RegionEntry -Segment at 36:15 (count = 0), Skipped -Segment at 39:8 (count = 1), RegionEntry -Segment at 39:12 (count = 0), Skipped -Segment at 40:13 (count = 1), RegionEntry -Segment at 41:16 (count = 0), Skipped -Segment at 41:17 (count = 1), RegionEntry -Segment at 43:10 (count = 0), Skipped -Segment at 45:12 (count = 1), RegionEntry -Segment at 45:25 (count = 0), Skipped -Segment at 45:26 (count = 1), RegionEntry -Segment at 47:10 (count = 0), Skipped -Segment at 48:17 (count = 0), RegionEntry -Segment at 48:30 (count = 0), Skipped -Segment at 49:16 (count = 0), RegionEntry -Segment at 49:29 (count = 0), Skipped -Segment at 49:33 (count = 0), RegionEntry -Segment at 49:46 (count = 0), Skipped -Segment at 49:50 (count = 0), RegionEntry -Segment at 49:64 (count = 0), Skipped -Segment at 49:65 (count = 0), RegionEntry -Segment at 51:14 (count = 0), RegionEntry -Segment at 51:15 (count = 0), Skipped -Segment at 52:13 (count = 0), RegionEntry -Segment at 52:27 (count = 0), Skipped -Segment at 54:13 (count = 0), RegionEntry -Segment at 54:19 (count = 0), Skipped -Segment at 59:9 (count = 1), RegionEntry -Segment at 60:12 (count = 0), Skipped -Segment at 60:13 (count = 1), RegionEntry -Segment at 62:6 (count = 0), Skipped -Segment at 64:9 (count = 0), RegionEntry -Segment at 64:10 (count = 0), Skipped -Segment at 64:16 (count = 1), RegionEntry -Segment at 64:29 (count = 0), Skipped -Segment at 64:30 (count = 0), RegionEntry -Segment at 66:6 (count = 0), Skipped -Segment at 66:15 (count = 1), RegionEntry -Segment at 66:28 (count = 0), Skipped -Segment at 67:12 (count = 0), RegionEntry -Segment at 67:25 (count = 0), Skipped -Segment at 67:29 (count = 0), RegionEntry -Segment at 67:42 (count = 0), Skipped -Segment at 67:46 (count = 0), RegionEntry -Segment at 67:60 (count = 0), Skipped -Segment at 67:61 (count = 0), RegionEntry -Segment at 69:10 (count = 0), RegionEntry -Segment at 69:11 (count = 0), Skipped -Segment at 70:9 (count = 0), RegionEntry -Segment at 70:23 (count = 0), Skipped -Segment at 72:13 (count = 1), RegionEntry -Segment at 74:15 (count = 0), Skipped -Segment at 77:9 (count = 0), RegionEntry -Segment at 77:10 (count = 0), Skipped -Segment at 77:16 (count = 0), RegionEntry -Segment at 77:29 (count = 0), Skipped -Segment at 77:30 (count = 0), RegionEntry -Segment at 79:6 (count = 0), Skipped -Segment at 79:15 (count = 0), RegionEntry -Segment at 79:28 (count = 0), Skipped -Segment at 80:12 (count = 0), RegionEntry -Segment at 80:25 (count = 0), Skipped -Segment at 80:29 (count = 0), RegionEntry -Segment at 80:42 (count = 0), Skipped -Segment at 80:46 (count = 0), RegionEntry -Segment at 80:60 (count = 0), Skipped -Segment at 80:61 (count = 0), RegionEntry -Segment at 82:10 (count = 0), RegionEntry -Segment at 82:11 (count = 0), Skipped -Segment at 83:9 (count = 0), RegionEntry -Segment at 83:23 (count = 0), Skipped -Segment at 85:9 (count = 0), RegionEntry -Segment at 85:15 (count = 0), Skipped -Segment at 87:1 (count = 1), RegionEntry -Segment at 87:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt deleted file mode 100644 index a2187d477c8..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt +++ /dev/null @@ -1,47 +0,0 @@ -Counter in file 0 3:1 -> 10:15, 0 -Counter in file 0 10:16 -> 12:6, 0 -Counter in file 0 12:6 -> 12:7, 0 -Counter in file 0 13:1 -> 13:2, 0 -Counter in file 0 15:1 -> 22:15, 0 -Counter in file 0 22:16 -> 24:6, 0 -Counter in file 0 24:6 -> 24:7, 0 -Counter in file 0 25:1 -> 25:2, 0 -Counter in file 0 27:1 -> 34:15, #1 -Counter in file 0 34:16 -> 36:6, #2 -Counter in file 0 36:6 -> 36:7, (#1 - #2) -Counter in file 0 37:1 -> 37:2, (#2 + (#1 - #2)) -Emitting segments for file: ../coverage/dead_code.rs -Combined regions: - 3:1 -> 10:15 (count=0) - 10:16 -> 12:6 (count=0) - 12:6 -> 12:7 (count=0) - 13:1 -> 13:2 (count=0) - 15:1 -> 22:15 (count=0) - 22:16 -> 24:6 (count=0) - 24:6 -> 24:7 (count=0) - 25:1 -> 25:2 (count=0) - 27:1 -> 34:15 (count=1) - 34:16 -> 36:6 (count=1) - 36:6 -> 36:7 (count=0) - 37:1 -> 37:2 (count=1) -Segment at 3:1 (count = 0), RegionEntry -Segment at 10:15 (count = 0), Skipped -Segment at 10:16 (count = 0), RegionEntry -Segment at 12:6 (count = 0), RegionEntry -Segment at 12:7 (count = 0), Skipped -Segment at 13:1 (count = 0), RegionEntry -Segment at 13:2 (count = 0), Skipped -Segment at 15:1 (count = 0), RegionEntry -Segment at 22:15 (count = 0), Skipped -Segment at 22:16 (count = 0), RegionEntry -Segment at 24:6 (count = 0), RegionEntry -Segment at 24:7 (count = 0), Skipped -Segment at 25:1 (count = 0), RegionEntry -Segment at 25:2 (count = 0), Skipped -Segment at 27:1 (count = 1), RegionEntry -Segment at 34:15 (count = 0), Skipped -Segment at 34:16 (count = 1), RegionEntry -Segment at 36:6 (count = 0), RegionEntry -Segment at 36:7 (count = 0), Skipped -Segment at 37:1 (count = 1), RegionEntry -Segment at 37:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt deleted file mode 100644 index 66c51e3a298..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt +++ /dev/null @@ -1,18 +0,0 @@ -Counter in file 0 9:5 -> 11:6, #1 -Counter in file 0 14:1 -> 19:12, #1 -Counter in file 0 20:9 -> 21:22, #2 -Counter in file 0 27:1 -> 27:2, (#2 + 0) -Emitting segments for file: ../coverage/drop_trait.rs -Combined regions: - 9:5 -> 11:6 (count=2) - 14:1 -> 19:12 (count=1) - 20:9 -> 21:22 (count=1) - 27:1 -> 27:2 (count=1) -Segment at 9:5 (count = 2), RegionEntry -Segment at 11:6 (count = 0), Skipped -Segment at 14:1 (count = 1), RegionEntry -Segment at 19:12 (count = 0), Skipped -Segment at 20:9 (count = 1), RegionEntry -Segment at 21:22 (count = 0), Skipped -Segment at 27:1 (count = 1), RegionEntry -Segment at 27:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt deleted file mode 100644 index e2cbf6f709e..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt +++ /dev/null @@ -1,44 +0,0 @@ -Counter in file 0 17:5 -> 19:6, #1 -Counter in file 0 17:5 -> 19:6, #1 -Counter in file 0 22:1 -> 30:12, #1 -Counter in file 0 31:9 -> 32:22, #2 -Counter in file 0 42:1 -> 42:2, (#2 + 0) -Counter in file 0 10:5 -> 12:6, #1 -Counter in file 0 10:5 -> 12:6, #1 -Emitting segments for file: ../coverage/generics.rs -Combined regions: - 10:5 -> 12:6 (count=3) - 17:5 -> 19:6 (count=2) - 22:1 -> 30:12 (count=1) - 31:9 -> 32:22 (count=1) - 42:1 -> 42:2 (count=1) -Segment at 10:5 (count = 3), RegionEntry -Segment at 12:6 (count = 0), Skipped -Segment at 17:5 (count = 2), RegionEntry -Segment at 19:6 (count = 0), Skipped -Segment at 22:1 (count = 1), RegionEntry -Segment at 30:12 (count = 0), Skipped -Segment at 31:9 (count = 1), RegionEntry -Segment at 32:22 (count = 0), Skipped -Segment at 42:1 (count = 1), RegionEntry -Segment at 42:2 (count = 0), Skipped -Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworkdE12set_strengthB2_ -Combined regions: - 10:5 -> 12:6 (count=2) -Segment at 10:5 (count = 2), RegionEntry -Segment at 12:6 (count = 0), Skipped -Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworklE12set_strengthB2_ -Combined regions: - 10:5 -> 12:6 (count=1) -Segment at 10:5 (count = 1), RegionEntry -Segment at 12:6 (count = 0), Skipped -Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworklENtNtNtCs3rFBWs28XFJ_4core3ops4drop4Drop4dropB4_ -Combined regions: - 17:5 -> 19:6 (count=1) -Segment at 17:5 (count = 1), RegionEntry -Segment at 19:6 (count = 0), Skipped -Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworkdENtNtNtCs3rFBWs28XFJ_4core3ops4drop4Drop4dropB4_ -Combined regions: - 17:5 -> 19:6 (count=1) -Segment at 17:5 (count = 1), RegionEntry -Segment at 19:6 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt deleted file mode 100644 index 2e802a462ea..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt +++ /dev/null @@ -1,17 +0,0 @@ -Counter in file 0 3:1 -> 21:16, #1 -Counter in file 0 22:5 -> 27:6, #2 -Counter in file 0 27:6 -> 27:7, (#1 - #2) -Counter in file 0 28:1 -> 28:2, (#2 + (#1 - #2)) -Emitting segments for file: ../coverage/if.rs -Combined regions: - 3:1 -> 21:16 (count=1) - 22:5 -> 27:6 (count=1) - 27:6 -> 27:7 (count=0) - 28:1 -> 28:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 21:16 (count = 0), Skipped -Segment at 22:5 (count = 1), RegionEntry -Segment at 27:6 (count = 0), RegionEntry -Segment at 27:7 (count = 0), Skipped -Segment at 28:1 (count = 1), RegionEntry -Segment at 28:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt deleted file mode 100644 index 03b35b0f009..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt +++ /dev/null @@ -1,30 +0,0 @@ -Counter in file 0 3:1 -> 11:16, #1 -Counter in file 0 12:5 -> 17:6, #2 -Counter in file 0 20:9 -> 22:16, (#1 - #2) -Counter in file 0 26:9 -> 26:16, (#2 + (#1 - #2)) -Counter in file 0 27:5 -> 32:6, #3 -Counter in file 0 34:5 -> 39:6, ((#2 + (#1 - #2)) - #3) -Counter in file 0 40:1 -> 40:2, (#3 + ((#2 + (#1 - #2)) - #3)) -Emitting segments for file: ../coverage/if_else.rs -Combined regions: - 3:1 -> 11:16 (count=1) - 12:5 -> 17:6 (count=1) - 20:9 -> 22:16 (count=0) - 26:9 -> 26:16 (count=1) - 27:5 -> 32:6 (count=1) - 34:5 -> 39:6 (count=0) - 40:1 -> 40:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 11:16 (count = 0), Skipped -Segment at 12:5 (count = 1), RegionEntry -Segment at 17:6 (count = 0), Skipped -Segment at 20:9 (count = 0), RegionEntry -Segment at 22:16 (count = 0), Skipped -Segment at 26:9 (count = 1), RegionEntry -Segment at 26:16 (count = 0), Skipped -Segment at 27:5 (count = 1), RegionEntry -Segment at 32:6 (count = 0), Skipped -Segment at 34:5 (count = 0), RegionEntry -Segment at 39:6 (count = 0), Skipped -Segment at 40:1 (count = 1), RegionEntry -Segment at 40:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt deleted file mode 100644 index 5dc704d6149..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt +++ /dev/null @@ -1,44 +0,0 @@ -Counter in file 0 18:5 -> 22:6, #1 -Counter in file 0 3:1 -> 3:11, #1 -Counter in file 0 7:9 -> 10:15, (#1 + 0) -Counter in file 0 10:16 -> 12:6, #2 -Counter in file 0 12:6 -> 12:7, (#1 - #2) -Counter in file 0 48:8 -> 48:15, (#2 + (#1 - #2)) -Counter in file 0 48:16 -> 50:6, #3 -Counter in file 0 50:6 -> 50:7, ((#2 + (#1 - #2)) - #3) -Counter in file 0 52:9 -> 57:2, (#3 + ((#2 + (#1 - #2)) - #3)) -Counter in file 0 33:9 -> 36:10, #1 -Counter in file 0 40:9 -> 43:10, #1 -Emitting segments for file: ../coverage/inner_items.rs -Combined regions: - 3:1 -> 3:11 (count=1) - 7:9 -> 10:15 (count=1) - 10:16 -> 12:6 (count=1) - 12:6 -> 12:7 (count=0) - 18:5 -> 22:6 (count=3) - 33:9 -> 36:10 (count=1) - 40:9 -> 43:10 (count=1) - 48:8 -> 48:15 (count=1) - 48:16 -> 50:6 (count=1) - 50:6 -> 50:7 (count=0) - 52:9 -> 57:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 3:11 (count = 0), Skipped -Segment at 7:9 (count = 1), RegionEntry -Segment at 10:15 (count = 0), Skipped -Segment at 10:16 (count = 1), RegionEntry -Segment at 12:6 (count = 0), RegionEntry -Segment at 12:7 (count = 0), Skipped -Segment at 18:5 (count = 3), RegionEntry -Segment at 22:6 (count = 0), Skipped -Segment at 33:9 (count = 1), RegionEntry -Segment at 36:10 (count = 0), Skipped -Segment at 40:9 (count = 1), RegionEntry -Segment at 43:10 (count = 0), Skipped -Segment at 48:8 (count = 1), RegionEntry -Segment at 48:15 (count = 0), Skipped -Segment at 48:16 (count = 1), RegionEntry -Segment at 50:6 (count = 0), RegionEntry -Segment at 50:7 (count = 0), Skipped -Segment at 52:9 (count = 1), RegionEntry -Segment at 57:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt deleted file mode 100644 index d5667fb861e..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt +++ /dev/null @@ -1,111 +0,0 @@ -Counter in file 0 3:1 -> 10:15, #1 -Counter in file 0 10:16 -> 14:6, #2 -Counter in file 0 14:6 -> 14:7, (#1 - #2) -Counter in file 0 16:9 -> 16:17, ((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) -Counter in file 0 18:13 -> 18:18, (#2 + (#1 - #2)) -Counter in file 0 20:13 -> 20:18, ((#2 + (#1 - #2)) - #3) -Counter in file 0 23:9 -> 23:17, ((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) -Counter in file 0 25:13 -> 25:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) + 0) -Counter in file 0 27:13 -> 27:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) -Counter in file 0 29:9 -> 29:17, (#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) -Counter in file 0 29:20 -> 29:25, (((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) + 0) -Counter in file 0 29:29 -> 29:34, #7 -Counter in file 0 30:9 -> 30:17, (#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) -Counter in file 0 30:20 -> 30:25, ((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) + 0) -Counter in file 0 30:29 -> 30:34, #9 -Counter in file 0 33:9 -> 34:16, ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) + 0) -Counter in file 0 35:5 -> 38:6, #11 -Counter in file 0 38:6 -> 38:7, ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11) -Counter in file 0 41:9 -> 41:16, (#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) -Counter in file 0 42:5 -> 45:6, #12 -Counter in file 0 47:5 -> 50:6, ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12) -Counter in file 0 52:8 -> 52:16, (#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) -Counter in file 0 52:17 -> 54:6, #13 -Counter in file 0 54:6 -> 54:7, ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13) -Counter in file 0 56:8 -> 56:15, (#13 + ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13)) -Counter in file 0 56:16 -> 58:6, #14 -Counter in file 0 58:12 -> 60:6, ((#13 + ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13)) - #14) -Counter in file 0 61:1 -> 61:2, (#14 + ((#13 + ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13)) - #14)) -Emitting segments for file: ../coverage/lazy_boolean.rs -Combined regions: - 3:1 -> 10:15 (count=1) - 10:16 -> 14:6 (count=1) - 14:6 -> 14:7 (count=0) - 16:9 -> 16:17 (count=1) - 18:13 -> 18:18 (count=1) - 20:13 -> 20:18 (count=0) - 23:9 -> 23:17 (count=1) - 25:13 -> 25:18 (count=1) - 27:13 -> 27:18 (count=1) - 29:9 -> 29:17 (count=1) - 29:20 -> 29:25 (count=1) - 29:29 -> 29:34 (count=1) - 30:9 -> 30:17 (count=1) - 30:20 -> 30:25 (count=1) - 30:29 -> 30:34 (count=0) - 33:9 -> 34:16 (count=1) - 35:5 -> 38:6 (count=0) - 38:6 -> 38:7 (count=1) - 41:9 -> 41:16 (count=1) - 42:5 -> 45:6 (count=1) - 47:5 -> 50:6 (count=0) - 52:8 -> 52:16 (count=1) - 52:17 -> 54:6 (count=0) - 54:6 -> 54:7 (count=1) - 56:8 -> 56:15 (count=1) - 56:16 -> 58:6 (count=1) - 58:12 -> 60:6 (count=0) - 61:1 -> 61:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 10:15 (count = 0), Skipped -Segment at 10:16 (count = 1), RegionEntry -Segment at 14:6 (count = 0), RegionEntry -Segment at 14:7 (count = 0), Skipped -Segment at 16:9 (count = 1), RegionEntry -Segment at 16:17 (count = 0), Skipped -Segment at 18:13 (count = 1), RegionEntry -Segment at 18:18 (count = 0), Skipped -Segment at 20:13 (count = 0), RegionEntry -Segment at 20:18 (count = 0), Skipped -Segment at 23:9 (count = 1), RegionEntry -Segment at 23:17 (count = 0), Skipped -Segment at 25:13 (count = 1), RegionEntry -Segment at 25:18 (count = 0), Skipped -Segment at 27:13 (count = 1), RegionEntry -Segment at 27:18 (count = 0), Skipped -Segment at 29:9 (count = 1), RegionEntry -Segment at 29:17 (count = 0), Skipped -Segment at 29:20 (count = 1), RegionEntry -Segment at 29:25 (count = 0), Skipped -Segment at 29:29 (count = 1), RegionEntry -Segment at 29:34 (count = 0), Skipped -Segment at 30:9 (count = 1), RegionEntry -Segment at 30:17 (count = 0), Skipped -Segment at 30:20 (count = 1), RegionEntry -Segment at 30:25 (count = 0), Skipped -Segment at 30:29 (count = 0), RegionEntry -Segment at 30:34 (count = 0), Skipped -Segment at 33:9 (count = 1), RegionEntry -Segment at 34:16 (count = 0), Skipped -Segment at 35:5 (count = 0), RegionEntry -Segment at 38:6 (count = 1), RegionEntry -Segment at 38:7 (count = 0), Skipped -Segment at 41:9 (count = 1), RegionEntry -Segment at 41:16 (count = 0), Skipped -Segment at 42:5 (count = 1), RegionEntry -Segment at 45:6 (count = 0), Skipped -Segment at 47:5 (count = 0), RegionEntry -Segment at 50:6 (count = 0), Skipped -Segment at 52:8 (count = 1), RegionEntry -Segment at 52:16 (count = 0), Skipped -Segment at 52:17 (count = 0), RegionEntry -Segment at 54:6 (count = 1), RegionEntry -Segment at 54:7 (count = 0), Skipped -Segment at 56:8 (count = 1), RegionEntry -Segment at 56:15 (count = 0), Skipped -Segment at 56:16 (count = 1), RegionEntry -Segment at 58:6 (count = 0), Skipped -Segment at 58:12 (count = 0), RegionEntry -Segment at 60:6 (count = 0), Skipped -Segment at 61:1 (count = 1), RegionEntry -Segment at 61:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt deleted file mode 100644 index 17bd5c2ff31..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt +++ /dev/null @@ -1,6 +0,0 @@ -Counter in file 0 3:1 -> 13:2, #1 -Emitting segments for file: ../coverage/loop_break_value.rs -Combined regions: - 3:1 -> 13:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 13:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt deleted file mode 100644 index d1da50b1529..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt +++ /dev/null @@ -1,33 +0,0 @@ -Counter in file 0 9:5 -> 10:16, #1 -Counter in file 0 11:16 -> 11:21, #2 -Counter in file 0 14:14 -> 14:15, (#2 - #5) -Counter in file 0 15:13 -> 15:31, ((0 - #6) + (#2 - #5)) -Counter in file 0 15:31 -> 15:32, #4 -Counter in file 0 18:9 -> 18:15, (#3 + 0) -Counter in file 0 19:5 -> 19:6, (#4 + (#3 + 0)) -Counter in file 0 22:1 -> 25:2, #1 -Emitting segments for file: ../coverage/loops_branches.rs -Combined regions: - 9:5 -> 10:16 (count=1) - 11:16 -> 11:21 (count=1) - 14:14 -> 14:15 (count=1) - 15:13 -> 15:31 (count=1) - 15:31 -> 15:32 (count=0) - 18:9 -> 18:15 (count=1) - 19:5 -> 19:6 (count=1) - 22:1 -> 25:2 (count=1) -Segment at 9:5 (count = 1), RegionEntry -Segment at 10:16 (count = 0), Skipped -Segment at 11:16 (count = 1), RegionEntry -Segment at 11:21 (count = 0), Skipped -Segment at 14:14 (count = 1), RegionEntry -Segment at 14:15 (count = 0), Skipped -Segment at 15:13 (count = 1), RegionEntry -Segment at 15:31 (count = 0), RegionEntry -Segment at 15:32 (count = 0), Skipped -Segment at 18:9 (count = 1), RegionEntry -Segment at 18:15 (count = 0), Skipped -Segment at 19:5 (count = 1), RegionEntry -Segment at 19:6 (count = 0), Skipped -Segment at 22:1 (count = 1), RegionEntry -Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt deleted file mode 100644 index fc12612ce7d..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.match_or_pattern.txt +++ /dev/null @@ -1,98 +0,0 @@ -Counter in file 0 3:1 -> 11:15, #1 -Counter in file 0 11:16 -> 14:6, #2 -Counter in file 0 14:6 -> 14:7, (#1 - #2) -Counter in file 0 15:11 -> 15:17, (#2 + (#1 - #2)) -Counter in file 0 18:27 -> 18:29, #5 -Counter in file 0 19:14 -> 19:16, (#3 + #4) -Counter in file 0 21:8 -> 21:15, ((#3 + #4) + #5) -Counter in file 0 21:16 -> 24:6, #6 -Counter in file 0 24:6 -> 24:7, (((#3 + #4) + #5) - #6) -Counter in file 0 25:11 -> 25:17, (#6 + (((#3 + #4) + #5) - #6)) -Counter in file 0 26:27 -> 26:29, #9 -Counter in file 0 27:14 -> 27:16, (#7 + #8) -Counter in file 0 29:8 -> 29:15, ((#7 + #8) + #9) -Counter in file 0 29:16 -> 32:6, #10 -Counter in file 0 32:6 -> 32:7, (((#7 + #8) + #9) - #10) -Counter in file 0 33:11 -> 33:17, (#10 + (((#7 + #8) + #9) - #10)) -Counter in file 0 34:27 -> 34:29, #13 -Counter in file 0 35:14 -> 35:16, (#11 + #12) -Counter in file 0 37:8 -> 37:15, ((#11 + #12) + #13) -Counter in file 0 37:16 -> 40:6, #14 -Counter in file 0 40:6 -> 40:7, (((#11 + #12) + #13) - #14) -Counter in file 0 41:11 -> 41:17, (#14 + (((#11 + #12) + #13) - #14)) -Counter in file 0 42:27 -> 42:29, #17 -Counter in file 0 43:14 -> 43:16, (#15 + #16) -Counter in file 0 45:1 -> 45:2, ((#15 + #16) + #17) -Emitting segments for file: ../coverage/match_or_pattern.rs -Combined regions: - 3:1 -> 11:15 (count=1) - 11:16 -> 14:6 (count=1) - 14:6 -> 14:7 (count=0) - 15:11 -> 15:17 (count=1) - 18:27 -> 18:29 (count=0) - 19:14 -> 19:16 (count=1) - 21:8 -> 21:15 (count=1) - 21:16 -> 24:6 (count=1) - 24:6 -> 24:7 (count=0) - 25:11 -> 25:17 (count=1) - 26:27 -> 26:29 (count=0) - 27:14 -> 27:16 (count=1) - 29:8 -> 29:15 (count=1) - 29:16 -> 32:6 (count=1) - 32:6 -> 32:7 (count=0) - 33:11 -> 33:17 (count=1) - 34:27 -> 34:29 (count=0) - 35:14 -> 35:16 (count=1) - 37:8 -> 37:15 (count=1) - 37:16 -> 40:6 (count=1) - 40:6 -> 40:7 (count=0) - 41:11 -> 41:17 (count=1) - 42:27 -> 42:29 (count=1) - 43:14 -> 43:16 (count=0) - 45:1 -> 45:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 11:15 (count = 0), Skipped -Segment at 11:16 (count = 1), RegionEntry -Segment at 14:6 (count = 0), RegionEntry -Segment at 14:7 (count = 0), Skipped -Segment at 15:11 (count = 1), RegionEntry -Segment at 15:17 (count = 0), Skipped -Segment at 18:27 (count = 0), RegionEntry -Segment at 18:29 (count = 0), Skipped -Segment at 19:14 (count = 1), RegionEntry -Segment at 19:16 (count = 0), Skipped -Segment at 21:8 (count = 1), RegionEntry -Segment at 21:15 (count = 0), Skipped -Segment at 21:16 (count = 1), RegionEntry -Segment at 24:6 (count = 0), RegionEntry -Segment at 24:7 (count = 0), Skipped -Segment at 25:11 (count = 1), RegionEntry -Segment at 25:17 (count = 0), Skipped -Segment at 26:27 (count = 0), RegionEntry -Segment at 26:29 (count = 0), Skipped -Segment at 27:14 (count = 1), RegionEntry -Segment at 27:16 (count = 0), Skipped -Segment at 29:8 (count = 1), RegionEntry -Segment at 29:15 (count = 0), Skipped -Segment at 29:16 (count = 1), RegionEntry -Segment at 32:6 (count = 0), RegionEntry -Segment at 32:7 (count = 0), Skipped -Segment at 33:11 (count = 1), RegionEntry -Segment at 33:17 (count = 0), Skipped -Segment at 34:27 (count = 0), RegionEntry -Segment at 34:29 (count = 0), Skipped -Segment at 35:14 (count = 1), RegionEntry -Segment at 35:16 (count = 0), Skipped -Segment at 37:8 (count = 1), RegionEntry -Segment at 37:15 (count = 0), Skipped -Segment at 37:16 (count = 1), RegionEntry -Segment at 40:6 (count = 0), RegionEntry -Segment at 40:7 (count = 0), Skipped -Segment at 41:11 (count = 1), RegionEntry -Segment at 41:17 (count = 0), Skipped -Segment at 42:27 (count = 1), RegionEntry -Segment at 42:29 (count = 0), Skipped -Segment at 43:14 (count = 0), RegionEntry -Segment at 43:16 (count = 0), Skipped -Segment at 45:1 (count = 1), RegionEntry -Segment at 45:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt deleted file mode 100644 index f30dd9e3716..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt +++ /dev/null @@ -1,58 +0,0 @@ -Counter in file 0 1:1 -> 3:27, #1 -Counter in file 0 5:19 -> 5:32, (#1 + (#2 + #3)) -Counter in file 0 6:13 -> 7:24, ((#1 + (#2 + #3)) - #4) -Counter in file 0 8:13 -> 8:14, ((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) -Counter in file 0 8:18 -> 8:23, (((#1 + (#2 + #3)) - #4) + (#6 + #7)) -Counter in file 0 9:16 -> 9:22, (((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) + 0) -Counter in file 0 10:17 -> 10:22, #2 -Counter in file 0 11:14 -> 14:22, (((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) - #2) -Counter in file 0 15:17 -> 16:27, ((((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) - #2) - #7) -Counter in file 0 17:21 -> 17:33, #5 -Counter in file 0 18:24 -> 20:18, #6 -Counter in file 0 21:14 -> 21:15, #7 -Counter in file 0 23:9 -> 23:23, (#2 + #3) -Counter in file 0 25:1 -> 25:2, (#5 + #4) -Emitting segments for file: ../coverage/nested_loops.rs -Combined regions: - 1:1 -> 3:27 (count=1) - 5:19 -> 5:32 (count=1) - 6:13 -> 7:24 (count=1) - 8:13 -> 8:14 (count=3) - 8:18 -> 8:23 (count=3) - 9:16 -> 9:22 (count=3) - 10:17 -> 10:22 (count=0) - 11:14 -> 14:22 (count=3) - 15:17 -> 16:27 (count=1) - 17:21 -> 17:33 (count=1) - 18:24 -> 20:18 (count=0) - 21:14 -> 21:15 (count=2) - 23:9 -> 23:23 (count=0) - 25:1 -> 25:2 (count=1) -Segment at 1:1 (count = 1), RegionEntry -Segment at 3:27 (count = 0), Skipped -Segment at 5:19 (count = 1), RegionEntry -Segment at 5:32 (count = 0), Skipped -Segment at 6:13 (count = 1), RegionEntry -Segment at 7:24 (count = 0), Skipped -Segment at 8:13 (count = 3), RegionEntry -Segment at 8:14 (count = 0), Skipped -Segment at 8:18 (count = 3), RegionEntry -Segment at 8:23 (count = 0), Skipped -Segment at 9:16 (count = 3), RegionEntry -Segment at 9:22 (count = 0), Skipped -Segment at 10:17 (count = 0), RegionEntry -Segment at 10:22 (count = 0), Skipped -Segment at 11:14 (count = 3), RegionEntry -Segment at 14:22 (count = 0), Skipped -Segment at 15:17 (count = 1), RegionEntry -Segment at 16:27 (count = 0), Skipped -Segment at 17:21 (count = 1), RegionEntry -Segment at 17:33 (count = 0), Skipped -Segment at 18:24 (count = 0), RegionEntry -Segment at 20:18 (count = 0), Skipped -Segment at 21:14 (count = 2), RegionEntry -Segment at 21:15 (count = 0), Skipped -Segment at 23:9 (count = 0), RegionEntry -Segment at 23:23 (count = 0), Skipped -Segment at 25:1 (count = 1), RegionEntry -Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt deleted file mode 100644 index 380bb7cf170..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt +++ /dev/null @@ -1,52 +0,0 @@ -Counter in file 0 15:1 -> 16:27, #1 -Counter in file 0 17:11 -> 17:24, (#1 + (#2 + (#3 + #4))) -Counter in file 0 18:12 -> 18:26, ((#1 + (#2 + (#3 + #4))) - #5) -Counter in file 0 18:27 -> 21:10, #2 -Counter in file 0 21:19 -> 21:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2) -Counter in file 0 21:33 -> 24:10, #3 -Counter in file 0 24:10 -> 24:11, #4 -Counter in file 0 25:9 -> 25:23, (#2 + (#3 + #4)) -Counter in file 0 27:5 -> 28:2, #5 -Counter in file 0 4:1 -> 5:18, #1 -Counter in file 0 5:19 -> 7:6, #2 -Counter in file 0 7:6 -> 7:7, (#1 - #2) -Counter in file 0 8:9 -> 13:2, (#2 + (#1 - #2)) -Emitting segments for file: ../coverage/overflow.rs -Combined regions: - 4:1 -> 5:18 (count=4) - 5:19 -> 7:6 (count=1) - 7:6 -> 7:7 (count=3) - 8:9 -> 13:2 (count=4) - 15:1 -> 16:27 (count=1) - 17:11 -> 17:24 (count=11) - 18:12 -> 18:26 (count=11) - 18:27 -> 21:10 (count=1) - 21:19 -> 21:32 (count=10) - 21:33 -> 24:10 (count=3) - 24:10 -> 24:11 (count=6) - 25:9 -> 25:23 (count=10) - 27:5 -> 28:2 (count=0) -Segment at 4:1 (count = 4), RegionEntry -Segment at 5:18 (count = 0), Skipped -Segment at 5:19 (count = 1), RegionEntry -Segment at 7:6 (count = 3), RegionEntry -Segment at 7:7 (count = 0), Skipped -Segment at 8:9 (count = 4), RegionEntry -Segment at 13:2 (count = 0), Skipped -Segment at 15:1 (count = 1), RegionEntry -Segment at 16:27 (count = 0), Skipped -Segment at 17:11 (count = 11), RegionEntry -Segment at 17:24 (count = 0), Skipped -Segment at 18:12 (count = 11), RegionEntry -Segment at 18:26 (count = 0), Skipped -Segment at 18:27 (count = 1), RegionEntry -Segment at 21:10 (count = 0), Skipped -Segment at 21:19 (count = 10), RegionEntry -Segment at 21:32 (count = 0), Skipped -Segment at 21:33 (count = 3), RegionEntry -Segment at 24:10 (count = 6), RegionEntry -Segment at 24:11 (count = 0), Skipped -Segment at 25:9 (count = 10), RegionEntry -Segment at 25:23 (count = 0), Skipped -Segment at 27:5 (count = 0), RegionEntry -Segment at 28:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt deleted file mode 100644 index b3f61ad325d..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt +++ /dev/null @@ -1,53 +0,0 @@ -Counter in file 0 13:1 -> 14:27, #1 -Counter in file 0 15:11 -> 15:24, (#1 + (#2 + (#3 + #4))) -Counter in file 0 16:12 -> 16:26, ((#1 + (#2 + (#3 + #4))) - #5) -Counter in file 0 16:27 -> 18:10, #2 -Counter in file 0 18:19 -> 18:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2) -Counter in file 0 18:33 -> 20:10, #3 -Counter in file 0 20:10 -> 20:11, #4 -Counter in file 0 21:9 -> 21:23, (#2 + (#3 + #4)) -Counter in file 0 23:5 -> 24:2, #5 -Counter in file 0 4:1 -> 4:36, #1 -Counter in file 0 5:8 -> 5:20, (#1 + 0) -Counter in file 0 6:9 -> 7:26, #2 -Counter in file 0 8:12 -> 11:2, (#1 - #2) -Emitting segments for file: ../coverage/panic_unwind.rs -Combined regions: - 4:1 -> 4:36 (count=4) - 5:8 -> 5:20 (count=4) - 6:9 -> 7:26 (count=1) - 8:12 -> 11:2 (count=3) - 13:1 -> 14:27 (count=1) - 15:11 -> 15:24 (count=11) - 16:12 -> 16:26 (count=11) - 16:27 -> 18:10 (count=1) - 18:19 -> 18:32 (count=10) - 18:33 -> 20:10 (count=3) - 20:10 -> 20:11 (count=6) - 21:9 -> 21:23 (count=10) - 23:5 -> 24:2 (count=0) -Segment at 4:1 (count = 4), RegionEntry -Segment at 4:36 (count = 0), Skipped -Segment at 5:8 (count = 4), RegionEntry -Segment at 5:20 (count = 0), Skipped -Segment at 6:9 (count = 1), RegionEntry -Segment at 7:26 (count = 0), Skipped -Segment at 8:12 (count = 3), RegionEntry -Segment at 11:2 (count = 0), Skipped -Segment at 13:1 (count = 1), RegionEntry -Segment at 14:27 (count = 0), Skipped -Segment at 15:11 (count = 11), RegionEntry -Segment at 15:24 (count = 0), Skipped -Segment at 16:12 (count = 11), RegionEntry -Segment at 16:26 (count = 0), Skipped -Segment at 16:27 (count = 1), RegionEntry -Segment at 18:10 (count = 0), Skipped -Segment at 18:19 (count = 10), RegionEntry -Segment at 18:32 (count = 0), Skipped -Segment at 18:33 (count = 3), RegionEntry -Segment at 20:10 (count = 6), RegionEntry -Segment at 20:11 (count = 0), Skipped -Segment at 21:9 (count = 10), RegionEntry -Segment at 21:23 (count = 0), Skipped -Segment at 23:5 (count = 0), RegionEntry -Segment at 24:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt deleted file mode 100644 index fa5c12bb6f8..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt +++ /dev/null @@ -1,66 +0,0 @@ -Counter in file 0 4:10 -> 4:15, 0 -Counter in file 0 4:24 -> 4:25, 0 -Counter in file 0 4:24 -> 4:25, 0 -Counter in file 0 4:32 -> 4:33, 0 -Counter in file 0 4:32 -> 4:33, 0 -Counter in file 0 4:35 -> 4:36, 0 -Counter in file 0 4:39 -> 4:40, 0 -Counter in file 0 4:39 -> 4:40, 0 -Counter in file 0 4:39 -> 4:40, 0 -Counter in file 0 4:39 -> 4:40, 0 -Counter in file 0 4:48 -> 4:49, 0 -Counter in file 0 4:51 -> 4:52, 0 -Counter in file 0 4:53 -> 4:54, 0 -Counter in file 0 7:5 -> 7:6, #1 -Counter in file 0 7:5 -> 7:6, 0 -Counter in file 0 7:5 -> 7:6, 0 -Counter in file 0 7:5 -> 7:6, 0 -Counter in file 0 8:5 -> 8:17, 0 -Counter in file 0 8:5 -> 8:17, 0 -Counter in file 0 8:5 -> 8:17, 0 -Counter in file 0 21:1 -> 26:2, #1 -Counter in file 0 4:17 -> 4:22, #1 -Counter in file 0 12:5 -> 18:6, #1 -Counter in file 0 4:39 -> 4:40, #1 -Counter in file 0 8:5 -> 8:17, #1 -Emitting segments for file: ../coverage/partial_eq.rs -Combined regions: - 4:10 -> 4:15 (count=0) - 4:17 -> 4:22 (count=2) - 4:24 -> 4:25 (count=0) - 4:32 -> 4:33 (count=0) - 4:35 -> 4:36 (count=0) - 4:39 -> 4:40 (count=1) - 4:48 -> 4:49 (count=0) - 4:51 -> 4:52 (count=0) - 4:53 -> 4:54 (count=0) - 7:5 -> 7:6 (count=1) - 8:5 -> 8:17 (count=0) - 12:5 -> 18:6 (count=2) - 21:1 -> 26:2 (count=1) -Segment at 4:10 (count = 0), RegionEntry -Segment at 4:15 (count = 0), Skipped -Segment at 4:17 (count = 2), RegionEntry -Segment at 4:22 (count = 0), Skipped -Segment at 4:24 (count = 0), RegionEntry -Segment at 4:25 (count = 0), Skipped -Segment at 4:32 (count = 0), RegionEntry -Segment at 4:33 (count = 0), Skipped -Segment at 4:35 (count = 0), RegionEntry -Segment at 4:36 (count = 0), Skipped -Segment at 4:39 (count = 1), RegionEntry -Segment at 4:40 (count = 0), Skipped -Segment at 4:48 (count = 0), RegionEntry -Segment at 4:49 (count = 0), Skipped -Segment at 4:51 (count = 0), RegionEntry -Segment at 4:52 (count = 0), Skipped -Segment at 4:53 (count = 0), RegionEntry -Segment at 4:54 (count = 0), Skipped -Segment at 7:5 (count = 1), RegionEntry -Segment at 7:6 (count = 0), Skipped -Segment at 8:5 (count = 0), RegionEntry -Segment at 8:17 (count = 0), Skipped -Segment at 12:5 (count = 2), RegionEntry -Segment at 18:6 (count = 0), Skipped -Segment at 21:1 (count = 1), RegionEntry -Segment at 26:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt deleted file mode 100644 index c0b09486dfb..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt +++ /dev/null @@ -1,29 +0,0 @@ -Counter in file 0 3:1 -> 12:16, #1 -Counter in file 0 13:5 -> 18:6, #2 -Counter in file 0 18:6 -> 18:7, (#1 - #2) -Counter in file 0 23:13 -> 25:14, ((#2 + (#1 - #2)) + #3) -Counter in file 0 27:13 -> 27:18, (((#2 + (#1 - #2)) + #3) - #3) -Counter in file 0 29:10 -> 32:10, #3 -Counter in file 0 35:1 -> 35:2, ((((#2 + (#1 - #2)) + #3) - #3) + 0) -Emitting segments for file: ../coverage/simple_loop.rs -Combined regions: - 3:1 -> 12:16 (count=1) - 13:5 -> 18:6 (count=1) - 18:6 -> 18:7 (count=0) - 23:13 -> 25:14 (count=11) - 27:13 -> 27:18 (count=1) - 29:10 -> 32:10 (count=10) - 35:1 -> 35:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 12:16 (count = 0), Skipped -Segment at 13:5 (count = 1), RegionEntry -Segment at 18:6 (count = 0), RegionEntry -Segment at 18:7 (count = 0), Skipped -Segment at 23:13 (count = 11), RegionEntry -Segment at 25:14 (count = 0), Skipped -Segment at 27:13 (count = 1), RegionEntry -Segment at 27:18 (count = 0), Skipped -Segment at 29:10 (count = 10), RegionEntry -Segment at 32:10 (count = 0), Skipped -Segment at 35:1 (count = 1), RegionEntry -Segment at 35:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt deleted file mode 100644 index c01630bd87b..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt +++ /dev/null @@ -1,45 +0,0 @@ -Counter in file 0 3:1 -> 10:15, #1 -Counter in file 0 10:16 -> 12:6, #2 -Counter in file 0 12:6 -> 12:7, (#1 - #2) -Counter in file 0 15:9 -> 15:10, (((#2 + (#1 - #2)) + (#3 + #4)) - #5) -Counter in file 0 17:9 -> 17:13, ((#2 + (#1 - #2)) + (#3 + #4)) -Counter in file 0 22:13 -> 22:22, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0) -Counter in file 0 24:13 -> 24:14, #3 -Counter in file 0 26:17 -> 28:18, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0) -Counter in file 0 30:13 -> 37:14, (#3 + 0) -Counter in file 0 40:13 -> 40:15, #4 -Counter in file 0 43:1 -> 43:2, #5 -Emitting segments for file: ../coverage/simple_match.rs -Combined regions: - 3:1 -> 10:15 (count=1) - 10:16 -> 12:6 (count=1) - 12:6 -> 12:7 (count=0) - 15:9 -> 15:10 (count=2) - 17:9 -> 17:13 (count=3) - 22:13 -> 22:22 (count=2) - 24:13 -> 24:14 (count=1) - 26:17 -> 28:18 (count=2) - 30:13 -> 37:14 (count=1) - 40:13 -> 40:15 (count=1) - 43:1 -> 43:2 (count=1) -Segment at 3:1 (count = 1), RegionEntry -Segment at 10:15 (count = 0), Skipped -Segment at 10:16 (count = 1), RegionEntry -Segment at 12:6 (count = 0), RegionEntry -Segment at 12:7 (count = 0), Skipped -Segment at 15:9 (count = 2), RegionEntry -Segment at 15:10 (count = 0), Skipped -Segment at 17:9 (count = 3), RegionEntry -Segment at 17:13 (count = 0), Skipped -Segment at 22:13 (count = 2), RegionEntry -Segment at 22:22 (count = 0), Skipped -Segment at 24:13 (count = 1), RegionEntry -Segment at 24:14 (count = 0), Skipped -Segment at 26:17 (count = 2), RegionEntry -Segment at 28:18 (count = 0), Skipped -Segment at 30:13 (count = 1), RegionEntry -Segment at 37:14 (count = 0), Skipped -Segment at 40:13 (count = 1), RegionEntry -Segment at 40:15 (count = 0), Skipped -Segment at 43:1 (count = 1), RegionEntry -Segment at 43:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt deleted file mode 100644 index a6cd4298808..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt +++ /dev/null @@ -1,10 +0,0 @@ -Counter in file 0 1:1 -> 2:13, #1 -Counter in file 0 4:6 -> 5:2, (#1 - #2) -Emitting segments for file: ../coverage/tight_inf_loop.rs -Combined regions: - 1:1 -> 2:13 (count=1) - 4:6 -> 5:2 (count=1) -Segment at 1:1 (count = 1), RegionEntry -Segment at 2:13 (count = 0), Skipped -Segment at 4:6 (count = 1), RegionEntry -Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt deleted file mode 100644 index 2b7962df2f9..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt +++ /dev/null @@ -1,63 +0,0 @@ -Counter in file 0 12:1 -> 14:23, #1 -Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4) -Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3)) -Counter in file 0 21:9 -> 25:26, (((#1 + (#2 + #3)) - #4) + 0) -Counter in file 0 27:13 -> 27:41, #8 -Counter in file 0 27:41 -> 27:42, #5 -Counter in file 0 28:13 -> 28:42, (#8 - #5) -Counter in file 0 28:42 -> 28:43, #6 -Counter in file 0 32:13 -> 32:42, (((#1 + (#2 + #3)) - #4) - #8) -Counter in file 0 32:42 -> 32:43, #7 -Counter in file 0 35:5 -> 35:11, #4 -Counter in file 0 36:1 -> 36:2, ((#5 + (#6 + #7)) + #4) -Counter in file 0 4:1 -> 5:20, #1 -Counter in file 0 6:9 -> 6:16, #2 -Counter in file 0 8:9 -> 8:15, (#1 - #2) -Counter in file 0 10:1 -> 10:2, (#2 + (#1 - #2)) -Emitting segments for file: ../coverage/try_error_result.rs -Combined regions: - 4:1 -> 5:20 (count=6) - 6:9 -> 6:16 (count=1) - 8:9 -> 8:15 (count=5) - 10:1 -> 10:2 (count=6) - 12:1 -> 14:23 (count=1) - 17:9 -> 17:10 (count=6) - 19:9 -> 19:14 (count=6) - 21:9 -> 25:26 (count=6) - 27:13 -> 27:41 (count=1) - 27:41 -> 27:42 (count=1) - 28:13 -> 28:42 (count=0) - 28:42 -> 28:43 (count=0) - 32:13 -> 32:42 (count=5) - 32:42 -> 32:43 (count=0) - 35:5 -> 35:11 (count=0) - 36:1 -> 36:2 (count=1) -Segment at 4:1 (count = 6), RegionEntry -Segment at 5:20 (count = 0), Skipped -Segment at 6:9 (count = 1), RegionEntry -Segment at 6:16 (count = 0), Skipped -Segment at 8:9 (count = 5), RegionEntry -Segment at 8:15 (count = 0), Skipped -Segment at 10:1 (count = 6), RegionEntry -Segment at 10:2 (count = 0), Skipped -Segment at 12:1 (count = 1), RegionEntry -Segment at 14:23 (count = 0), Skipped -Segment at 17:9 (count = 6), RegionEntry -Segment at 17:10 (count = 0), Skipped -Segment at 19:9 (count = 6), RegionEntry -Segment at 19:14 (count = 0), Skipped -Segment at 21:9 (count = 6), RegionEntry -Segment at 25:26 (count = 0), Skipped -Segment at 27:13 (count = 1), RegionEntry -Segment at 27:41 (count = 1), RegionEntry -Segment at 27:42 (count = 0), Skipped -Segment at 28:13 (count = 0), RegionEntry -Segment at 28:42 (count = 0), RegionEntry -Segment at 28:43 (count = 0), Skipped -Segment at 32:13 (count = 5), RegionEntry -Segment at 32:42 (count = 0), RegionEntry -Segment at 32:43 (count = 0), Skipped -Segment at 35:5 (count = 0), RegionEntry -Segment at 35:11 (count = 0), Skipped -Segment at 36:1 (count = 1), RegionEntry -Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt deleted file mode 100644 index b0319cd9e18..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt +++ /dev/null @@ -1,110 +0,0 @@ -Counter in file 0 17:1 -> 19:2, #1 -Counter in file 0 25:1 -> 27:2, #1 -Counter in file 0 17:1 -> 19:2, #1 -Counter in file 0 5:1 -> 12:2, #1 -Counter in file 0 17:1 -> 19:2, 0 -Counter in file 0 33:1 -> 35:2, 0 -Counter in file 0 45:1 -> 48:16, 0 -Counter in file 0 48:17 -> 50:6, 0 -Counter in file 0 50:6 -> 50:7, 0 -Counter in file 0 51:1 -> 51:2, 0 -Counter in file 0 53:1 -> 61:2, #1 -Counter in file 0 25:1 -> 27:2, #1 -Counter in file 0 29:1 -> 31:2, #1 -Counter in file 0 21:1 -> 23:2, #1 -Counter in file 0 5:1 -> 5:24, #1 -Counter in file 0 9:9 -> 11:15, (#1 + 0) -Counter in file 0 11:16 -> 13:6, #2 -Counter in file 0 13:6 -> 13:7, (#1 - #2) -Counter in file 0 14:5 -> 15:2, (#2 + (#1 - #2)) -Counter in file 0 21:1 -> 23:2, #1 -Counter in file 0 37:1 -> 40:16, #1 -Counter in file 0 40:17 -> 42:6, #2 -Counter in file 0 42:6 -> 42:7, (#1 - #2) -Counter in file 0 43:1 -> 43:2, (#2 + (#1 - #2)) -Emitting segments for file: ../coverage/lib/used_crate.rs -Combined regions: - 5:1 -> 5:24 (count=1) - 9:9 -> 11:15 (count=1) - 11:16 -> 13:6 (count=1) - 13:6 -> 13:7 (count=0) - 14:5 -> 15:2 (count=1) - 17:1 -> 19:2 (count=2) - 21:1 -> 23:2 (count=2) - 25:1 -> 27:2 (count=2) - 29:1 -> 31:2 (count=2) - 33:1 -> 35:2 (count=0) - 37:1 -> 40:16 (count=0) - 40:17 -> 42:6 (count=0) - 42:6 -> 42:7 (count=0) - 43:1 -> 43:2 (count=0) - 45:1 -> 48:16 (count=0) - 48:17 -> 50:6 (count=0) - 50:6 -> 50:7 (count=0) - 51:1 -> 51:2 (count=0) - 53:1 -> 61:2 (count=1) -Segment at 5:1 (count = 1), RegionEntry -Segment at 5:24 (count = 0), Skipped -Segment at 9:9 (count = 1), RegionEntry -Segment at 11:15 (count = 0), Skipped -Segment at 11:16 (count = 1), RegionEntry -Segment at 13:6 (count = 0), RegionEntry -Segment at 13:7 (count = 0), Skipped -Segment at 14:5 (count = 1), RegionEntry -Segment at 15:2 (count = 0), Skipped -Segment at 17:1 (count = 2), RegionEntry -Segment at 19:2 (count = 0), Skipped -Segment at 21:1 (count = 2), RegionEntry -Segment at 23:2 (count = 0), Skipped -Segment at 25:1 (count = 2), RegionEntry -Segment at 27:2 (count = 0), Skipped -Segment at 29:1 (count = 2), RegionEntry -Segment at 31:2 (count = 0), Skipped -Segment at 33:1 (count = 0), RegionEntry -Segment at 35:2 (count = 0), Skipped -Segment at 37:1 (count = 0), RegionEntry -Segment at 40:16 (count = 0), Skipped -Segment at 40:17 (count = 0), RegionEntry -Segment at 42:6 (count = 0), RegionEntry -Segment at 42:7 (count = 0), Skipped -Segment at 43:1 (count = 0), RegionEntry -Segment at 43:2 (count = 0), Skipped -Segment at 45:1 (count = 0), RegionEntry -Segment at 48:16 (count = 0), Skipped -Segment at 48:17 (count = 0), RegionEntry -Segment at 50:6 (count = 0), RegionEntry -Segment at 50:7 (count = 0), Skipped -Segment at 51:1 (count = 0), RegionEntry -Segment at 51:2 (count = 0), Skipped -Segment at 53:1 (count = 1), RegionEntry -Segment at 61:2 (count = 0), Skipped -Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionReECs4fqI2P2rA04_10uses_crate -Combined regions: - 17:1 -> 19:2 (count=1) -Segment at 17:1 (count = 1), RegionEntry -Segment at 19:2 (count = 0), Skipped -Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionRINtNtCs3QflaznQylx_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate -Combined regions: - 17:1 -> 19:2 (count=1) -Segment at 17:1 (count = 1), RegionEntry -Segment at 19:2 (count = 0), Skipped -Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate46used_only_from_this_lib_crate_generic_functionINtNtCs3QflaznQylx_5alloc3vec3VeclEEB2_ -Combined regions: - 21:1 -> 23:2 (count=1) -Segment at 21:1 (count = 1), RegionEntry -Segment at 23:2 (count = 0), Skipped -Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate46used_only_from_this_lib_crate_generic_functionReEB2_ -Combined regions: - 21:1 -> 23:2 (count=1) -Segment at 21:1 (count = 1), RegionEntry -Segment at 23:2 (count = 0), Skipped -Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate50used_from_bin_crate_and_lib_crate_generic_functionINtNtCs3QflaznQylx_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate -Combined regions: - 25:1 -> 27:2 (count=1) -Segment at 25:1 (count = 1), RegionEntry -Segment at 27:2 (count = 0), Skipped -Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate50used_from_bin_crate_and_lib_crate_generic_functionReEB2_ -Combined regions: - 25:1 -> 27:2 (count=1) -Segment at 25:1 (count = 1), RegionEntry -Segment at 27:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt deleted file mode 100644 index 90629ac84cd..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt +++ /dev/null @@ -1,18 +0,0 @@ -Counter in file 0 1:1 -> 2:16, #1 -Counter in file 0 3:11 -> 3:20, (#1 + #2) -Counter in file 0 3:21 -> 4:6, #2 -Counter in file 0 5:1 -> 5:2, ((#1 + #2) - #2) -Emitting segments for file: ../coverage/while.rs -Combined regions: - 1:1 -> 2:16 (count=1) - 3:11 -> 3:20 (count=1) - 3:21 -> 4:6 (count=0) - 5:1 -> 5:2 (count=1) -Segment at 1:1 (count = 1), RegionEntry -Segment at 2:16 (count = 0), Skipped -Segment at 3:11 (count = 1), RegionEntry -Segment at 3:20 (count = 0), Skipped -Segment at 3:21 (count = 0), RegionEntry -Segment at 4:6 (count = 0), Skipped -Segment at 5:1 (count = 1), RegionEntry -Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt deleted file mode 100644 index 12f444945a1..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt +++ /dev/null @@ -1,38 +0,0 @@ -Counter in file 0 4:1 -> 5:27, #1 -Counter in file 0 7:9 -> 9:10, (#1 + #2) -Counter in file 0 12:13 -> 14:14, ((#1 + #2) - #3) -Counter in file 0 18:21 -> 20:22, (((#1 + #2) - #3) - #2) -Counter in file 0 22:21 -> 22:27, #4 -Counter in file 0 26:21 -> 26:27, #5 -Counter in file 0 29:10 -> 32:10, #2 -Counter in file 0 35:5 -> 35:11, #3 -Counter in file 0 36:1 -> 36:2, ((#4 + #5) + #3) -Emitting segments for file: ../coverage/while_early_ret.rs -Combined regions: - 4:1 -> 5:27 (count=1) - 7:9 -> 9:10 (count=7) - 12:13 -> 14:14 (count=7) - 18:21 -> 20:22 (count=1) - 22:21 -> 22:27 (count=0) - 26:21 -> 26:27 (count=1) - 29:10 -> 32:10 (count=6) - 35:5 -> 35:11 (count=0) - 36:1 -> 36:2 (count=1) -Segment at 4:1 (count = 1), RegionEntry -Segment at 5:27 (count = 0), Skipped -Segment at 7:9 (count = 7), RegionEntry -Segment at 9:10 (count = 0), Skipped -Segment at 12:13 (count = 7), RegionEntry -Segment at 14:14 (count = 0), Skipped -Segment at 18:21 (count = 1), RegionEntry -Segment at 20:22 (count = 0), Skipped -Segment at 22:21 (count = 0), RegionEntry -Segment at 22:27 (count = 0), Skipped -Segment at 26:21 (count = 1), RegionEntry -Segment at 26:27 (count = 0), Skipped -Segment at 29:10 (count = 6), RegionEntry -Segment at 32:10 (count = 0), Skipped -Segment at 35:5 (count = 0), RegionEntry -Segment at 35:11 (count = 0), Skipped -Segment at 36:1 (count = 1), RegionEntry -Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt deleted file mode 100644 index 6ed3e465611..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt +++ /dev/null @@ -1,94 +0,0 @@ -Counter in file 0 7:1 -> 7:11, #1 -Counter in file 0 8:9 -> 8:22, (#1 + 0) -Counter in file 0 13:11 -> 14:35, (#1 + 0) -Counter in file 0 14:39 -> 14:41, #4 -Counter in file 0 15:14 -> 15:52, (#2 + #3) -Counter in file 0 17:11 -> 17:46, (#4 + 0) -Counter in file 0 18:34 -> 18:39, (#4 - #5) -Counter in file 0 18:44 -> 18:46, ((#4 - #5) - #6) -Counter in file 0 19:14 -> 19:52, (#5 + #6) -Counter in file 0 22:9 -> 22:22, (((#4 - #5) - #6) + 0) -Counter in file 0 29:11 -> 30:35, (((#4 - #5) - #6) + 0) -Counter in file 0 30:39 -> 30:41, #9 -Counter in file 0 31:14 -> 31:52, (#7 + #8) -Counter in file 0 33:11 -> 34:35, (#9 + 0) -Counter in file 0 34:39 -> 34:41, #12 -Counter in file 0 35:14 -> 35:52, (#10 + #11) -Counter in file 0 37:1 -> 37:2, (#12 + 0) -Counter in file 0 8:28 -> 9:16, #1 -Counter in file 0 10:16 -> 11:6, #2 -Counter in file 0 22:28 -> 23:16, #1 -Counter in file 0 24:9 -> 24:16, #2 -Counter in file 0 25:9 -> 25:16, #3 -Counter in file 0 26:16 -> 27:6, #4 -Emitting segments for file: ../coverage/yield.rs -Combined regions: - 7:1 -> 7:11 (count=1) - 8:9 -> 8:22 (count=1) - 8:28 -> 9:16 (count=1) - 10:16 -> 11:6 (count=1) - 13:11 -> 14:35 (count=1) - 14:39 -> 14:41 (count=1) - 15:14 -> 15:52 (count=0) - 17:11 -> 17:46 (count=1) - 18:34 -> 18:39 (count=1) - 18:44 -> 18:46 (count=1) - 19:14 -> 19:52 (count=0) - 22:9 -> 22:22 (count=1) - 22:28 -> 23:16 (count=1) - 24:9 -> 24:16 (count=1) - 25:9 -> 25:16 (count=0) - 26:16 -> 27:6 (count=0) - 29:11 -> 30:35 (count=1) - 30:39 -> 30:41 (count=1) - 31:14 -> 31:52 (count=0) - 33:11 -> 34:35 (count=1) - 34:39 -> 34:41 (count=1) - 35:14 -> 35:52 (count=0) - 37:1 -> 37:2 (count=1) -Segment at 7:1 (count = 1), RegionEntry -Segment at 7:11 (count = 0), Skipped -Segment at 8:9 (count = 1), RegionEntry -Segment at 8:22 (count = 0), Skipped -Segment at 8:28 (count = 1), RegionEntry -Segment at 9:16 (count = 0), Skipped -Segment at 10:16 (count = 1), RegionEntry -Segment at 11:6 (count = 0), Skipped -Segment at 13:11 (count = 1), RegionEntry -Segment at 14:35 (count = 0), Skipped -Segment at 14:39 (count = 1), RegionEntry -Segment at 14:41 (count = 0), Skipped -Segment at 15:14 (count = 0), RegionEntry -Segment at 15:52 (count = 0), Skipped -Segment at 17:11 (count = 1), RegionEntry -Segment at 17:46 (count = 0), Skipped -Segment at 18:34 (count = 1), RegionEntry -Segment at 18:39 (count = 0), Skipped -Segment at 18:44 (count = 1), RegionEntry -Segment at 18:46 (count = 0), Skipped -Segment at 19:14 (count = 0), RegionEntry -Segment at 19:52 (count = 0), Skipped -Segment at 22:9 (count = 1), RegionEntry -Segment at 22:22 (count = 0), Skipped -Segment at 22:28 (count = 1), RegionEntry -Segment at 23:16 (count = 0), Skipped -Segment at 24:9 (count = 1), RegionEntry -Segment at 24:16 (count = 0), Skipped -Segment at 25:9 (count = 0), RegionEntry -Segment at 25:16 (count = 0), Skipped -Segment at 26:16 (count = 0), RegionEntry -Segment at 27:6 (count = 0), Skipped -Segment at 29:11 (count = 1), RegionEntry -Segment at 30:35 (count = 0), Skipped -Segment at 30:39 (count = 1), RegionEntry -Segment at 30:41 (count = 0), Skipped -Segment at 31:14 (count = 0), RegionEntry -Segment at 31:52 (count = 0), Skipped -Segment at 33:11 (count = 1), RegionEntry -Segment at 34:35 (count = 0), Skipped -Segment at 34:39 (count = 1), RegionEntry -Segment at 34:41 (count = 0), Skipped -Segment at 35:14 (count = 0), RegionEntry -Segment at 35:52 (count = 0), Skipped -Segment at 37:1 (count = 1), RegionEntry -Segment at 37:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports/prettify_json.py b/src/test/run-make-fulldeps/coverage-reports/prettify_json.py deleted file mode 100644 index ed9279841f7..00000000000 --- a/src/test/run-make-fulldeps/coverage-reports/prettify_json.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python - -import sys -import json - -# Try to decode line in order to ensure it is a valid JSON document -for line in sys.stdin: - parsed = json.loads(line) - print (json.dumps(parsed, indent=2, separators=(',', ': '), sort_keys=True)) -- cgit 1.4.1-3-g733a5 From 62eab830c859bc4d3d53032e5b7288c7ea6f0c56 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 17 Dec 2020 10:29:58 +0000 Subject: bootstrap: update ci-llvm stamp after #80087 Unfortunately, #80087 forgot to update the ci-llvm stamp, so the updated ci-llvm tarball with `llvm-dwp` wasn't downloaded by users. This commit updates the ci-llvm stamp to resolve that problem. Signed-off-by: David Wood --- src/bootstrap/download-ci-llvm-stamp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index d857618eefa..b29ecd65401 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/78131 +Last change is for: https://github.com/rust-lang/rust/pull/80087 -- cgit 1.4.1-3-g733a5 From e9ca2909ad49b9a15c7da29cc4350dda4aeefb10 Mon Sep 17 00:00:00 2001 From: Daiki Ihara Date: Mon, 14 Dec 2020 21:14:17 +0900 Subject: Add test case for break expr with misspelled value Update src/test/ui/loops/loop-break-value.rs Co-authored-by: Ivan Tham --- src/test/ui/label/label_misspelled.rs | 18 ++++++++++++ src/test/ui/label/label_misspelled.stderr | 47 +++++++++++++++++++++++++++++++ src/test/ui/loops/loop-break-value.rs | 6 ++++ src/test/ui/loops/loop-break-value.stderr | 24 ++++++++++++++-- 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/label/label_misspelled.rs create mode 100644 src/test/ui/label/label_misspelled.stderr (limited to 'src') diff --git a/src/test/ui/label/label_misspelled.rs b/src/test/ui/label/label_misspelled.rs new file mode 100644 index 00000000000..ebfd5642c9f --- /dev/null +++ b/src/test/ui/label/label_misspelled.rs @@ -0,0 +1,18 @@ +fn main() { + 'LOOP: loop { + LOOP; + //~^ ERROR cannot find value `LOOP` in this scope + }; + 'while_loop: while true { //~ WARN denote infinite loops with + while_loop; + //~^ ERROR cannot find value `while_loop` in this scope + }; + 'while_let: while let Some(_) = Some(()) { + while_let; + //~^ ERROR cannot find value `while_let` in this scope + } + 'for_loop: for _ in 0..3 { + for_loop; + //~^ ERROR cannot find value `for_loop` in this scope + }; +} diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr new file mode 100644 index 00000000000..1368ca4126c --- /dev/null +++ b/src/test/ui/label/label_misspelled.stderr @@ -0,0 +1,47 @@ +error[E0425]: cannot find value `LOOP` in this scope + --> $DIR/label_misspelled.rs:3:9 + | +LL | LOOP; + | ^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'LOOP` + +error[E0425]: cannot find value `while_loop` in this scope + --> $DIR/label_misspelled.rs:7:9 + | +LL | while_loop; + | ^^^^^^^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'while_loop` + +error[E0425]: cannot find value `while_let` in this scope + --> $DIR/label_misspelled.rs:11:9 + | +LL | while_let; + | ^^^^^^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'while_let` + +error[E0425]: cannot find value `for_loop` in this scope + --> $DIR/label_misspelled.rs:15:9 + | +LL | for_loop; + | ^^^^^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'for_loop` + +warning: denote infinite loops with `loop { ... }` + --> $DIR/label_misspelled.rs:6:5 + | +LL | 'while_loop: while true { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/loops/loop-break-value.rs b/src/test/ui/loops/loop-break-value.rs index 6c4160c36aa..8a080cfdf49 100644 --- a/src/test/ui/loops/loop-break-value.rs +++ b/src/test/ui/loops/loop-break-value.rs @@ -90,4 +90,10 @@ fn main() { break; //~ ERROR mismatched types break 4; }; + + 'LOOP: for _ in 0 .. 9 { + break LOOP; + //~^ ERROR cannot find value `LOOP` in this scope + //~| ERROR `break` with value from a `for` loop + } } diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index 0503d3d4c78..0237435c8b4 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -1,3 +1,12 @@ +error[E0425]: cannot find value `LOOP` in this scope + --> $DIR/loop-break-value.rs:95:15 + | +LL | break LOOP; + | ^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'LOOP` + warning: denote infinite loops with `loop { ... }` --> $DIR/loop-break-value.rs:26:5 | @@ -94,6 +103,17 @@ help: instead, use `break` on its own without a value inside this `for` loop LL | break; | ^^^^^ +error[E0571]: `break` with value from a `for` loop + --> $DIR/loop-break-value.rs:95:9 + | +LL | break LOOP; + | ^^^^^^^^^^ can only break with a value inside `loop` or breakable block + | +help: instead, use `break` on its own without a value inside this `for` loop + | +LL | break; + | ^^^^^ + error[E0308]: mismatched types --> $DIR/loop-break-value.rs:4:31 | @@ -151,7 +171,7 @@ LL | break; | expected integer, found `()` | help: give it a value of the expected type: `break value` -error: aborting due to 16 previous errors; 1 warning emitted +error: aborting due to 18 previous errors; 1 warning emitted -Some errors have detailed explanations: E0308, E0571. +Some errors have detailed explanations: E0308, E0425, E0571. For more information about an error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 46e9212ecb0454d1d5cc9c4d641f4277512111c8 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Thu, 17 Dec 2020 16:56:59 +0100 Subject: Change the message for `if_let_guard` feature gate --- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- src/test/ui/rfc-2294-if-let-guard/feature-gate.rs | 4 ++-- src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 9d54d89e080..bb222675239 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -620,7 +620,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { } }; } - gate_all!(if_let_guard, "`if let` guard is not implemented"); + gate_all!(if_let_guard, "`if let` guards are experimental"); gate_all!(let_chains, "`let` expressions in this position are experimental"); gate_all!(async_closure, "async closures are unstable"); gate_all!(generators, "yield syntax is experimental"); diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs index 311d1afcfc0..4ba7e1eeefa 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs @@ -5,7 +5,7 @@ use std::ops::Range; fn _if_let_guard() { match () { () if let 0 = 1 => {} - //~^ ERROR `if let` guard is not implemented + //~^ ERROR `if let` guards are experimental () if (let 0 = 1) => {} //~^ ERROR `let` expressions in this position are experimental @@ -74,7 +74,7 @@ fn _macros() { match () { #[cfg(FALSE)] () if let 0 = 1 => {} - //~^ ERROR `if let` guard is not implemented + //~^ ERROR `if let` guards are experimental _ => {} } use_expr!(let 0 = 1); diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr index 1670078e0d3..113870c19f5 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr @@ -7,7 +7,7 @@ LL | macro_rules! use_expr { LL | use_expr!(let 0 = 1); | ^^^ no rules expected this token in macro call -error[E0658]: `if let` guard is not implemented +error[E0658]: `if let` guards are experimental --> $DIR/feature-gate.rs:7:12 | LL | () if let 0 = 1 => {} @@ -16,7 +16,7 @@ LL | () if let 0 = 1 => {} = note: see issue #51114 for more information = help: add `#![feature(if_let_guard)]` to the crate attributes to enable -error[E0658]: `if let` guard is not implemented +error[E0658]: `if let` guards are experimental --> $DIR/feature-gate.rs:76:12 | LL | () if let 0 = 1 => {} -- cgit 1.4.1-3-g733a5 From 0ac58f7bf86cd8a3616484b3ff1a794521368536 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 11 Dec 2020 21:37:14 -0500 Subject: Split apart create_config and run_core --- src/librustdoc/core.rs | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b2eeaf584bf..ed3bc02a5de 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -273,12 +273,9 @@ where (lint_opts, lint_caps) } -crate fn run_core( - options: RustdocOptions, -) -> (clean::Crate, RenderInfo, RenderOptions, Lrc) { - // Parse, resolve, and typecheck the given crate. - - let RustdocOptions { +/// Parse, resolve, and typecheck the given crate. +fn create_config( + RustdocOptions { input, crate_name, proc_macro_crate, @@ -294,21 +291,10 @@ crate fn run_core( lint_opts, describe_lints, lint_cap, - default_passes, - manual_passes, display_warnings, - render_options, - output_format, .. - } = options; - - let extern_names: Vec = externs - .iter() - .filter(|(_, entry)| entry.add_prelude) - .map(|(name, _)| name) - .cloned() - .collect(); - + }: RustdocOptions, +) -> rustc_interface::Config { // Add the doc cfg into the doc build. cfgs.push("doc".to_string()); @@ -374,7 +360,7 @@ crate fn run_core( ..Options::default() }; - let config = interface::Config { + interface::Config { opts: sessopts, crate_cfg: interface::parse_cfgspecs(cfgs), input, @@ -417,7 +403,25 @@ crate fn run_core( }), make_codegen_backend: None, registry: rustc_driver::diagnostics_registry(), - }; + } +} + +crate fn run_core( + options: RustdocOptions, +) -> (clean::Crate, RenderInfo, RenderOptions, Lrc) { + let extern_names: Vec = options + .externs + .iter() + .filter(|(_, entry)| entry.add_prelude) + .map(|(name, _)| name) + .cloned() + .collect(); + let default_passes = options.default_passes; + let output_format = options.output_format; + // TODO: fix this clone (especially render_options) + let manual_passes = options.manual_passes.clone(); + let render_options = options.render_options.clone(); + let config = create_config(options); interface::create_compiler_and_run(config, |compiler| { compiler.enter(|queries| { -- cgit 1.4.1-3-g733a5 From 34e8b0aae1fe66e0e0c0f70957cc647361a79ff5 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 11 Dec 2020 21:46:58 -0500 Subject: Separate `create_resolver` into a new function --- src/librustdoc/core.rs | 79 +++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index ed3bc02a5de..cd05d922f5f 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -11,7 +11,7 @@ use rustc_hir::{ intravisit::{self, NestedVisitorMap, Visitor}, Path, }; -use rustc_interface::interface; +use rustc_interface::{interface, Queries}; use rustc_middle::hir::map::Map; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; @@ -409,16 +409,10 @@ fn create_config( crate fn run_core( options: RustdocOptions, ) -> (clean::Crate, RenderInfo, RenderOptions, Lrc) { - let extern_names: Vec = options - .externs - .iter() - .filter(|(_, entry)| entry.add_prelude) - .map(|(name, _)| name) - .cloned() - .collect(); let default_passes = options.default_passes; let output_format = options.output_format; // TODO: fix this clone (especially render_options) + let externs = options.externs.clone(); let manual_passes = options.manual_passes.clone(); let render_options = options.render_options.clone(); let config = create_config(options); @@ -430,34 +424,7 @@ crate fn run_core( // We need to hold on to the complete resolver, so we cause everything to be // cloned for the analysis passes to use. Suboptimal, but necessary in the // current architecture. - let resolver = { - let parts = abort_on_err(queries.expansion(), sess).peek(); - let resolver = parts.1.borrow(); - - // Before we actually clone it, let's force all the extern'd crates to - // actually be loaded, just in case they're only referred to inside - // intra-doc-links - resolver.borrow_mut().access(|resolver| { - sess.time("load_extern_crates", || { - for extern_name in &extern_names { - debug!("loading extern crate {}", extern_name); - resolver - .resolve_str_path_error( - DUMMY_SP, - extern_name, - TypeNS, - LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), - ) - .unwrap_or_else(|()| { - panic!("Unable to resolve external crate {}", extern_name) - }); - } - }); - }); - - // Now we're good to clone the resolver because everything should be loaded - resolver.clone() - }; + let resolver = create_resolver(externs, queries, &sess); if sess.has_errors() { sess.fatal("Compilation failed, aborting rustdoc"); @@ -482,6 +449,46 @@ crate fn run_core( }) } +fn create_resolver<'a>( + externs: config::Externs, + queries: &Queries<'a>, + sess: &Session, +) -> Lrc> { + let extern_names: Vec = externs + .iter() + .filter(|(_, entry)| entry.add_prelude) + .map(|(name, _)| name) + .cloned() + .collect(); + + let parts = abort_on_err(queries.expansion(), sess).peek(); + let resolver = parts.1.borrow(); + + // Before we actually clone it, let's force all the extern'd crates to + // actually be loaded, just in case they're only referred to inside + // intra-doc-links + resolver.borrow_mut().access(|resolver| { + sess.time("load_extern_crates", || { + for extern_name in &extern_names { + debug!("loading extern crate {}", extern_name); + resolver + .resolve_str_path_error( + DUMMY_SP, + extern_name, + TypeNS, + LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), + ) + .unwrap_or_else(|()| { + panic!("Unable to resolve external crate {}", extern_name) + }); + } + }); + }); + + // Now we're good to clone the resolver because everything should be loaded + resolver.clone() +} + fn run_global_ctxt( tcx: TyCtxt<'_>, resolver: Rc>, -- cgit 1.4.1-3-g733a5 From 79ab333cf0e8b49676cabc7d8bdaa785a688a67a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 11 Dec 2020 21:57:48 -0500 Subject: Move `run_renderer` into the main `global_ctxt` closure --- src/librustdoc/core.rs | 49 ++--------------------- src/librustdoc/lib.rs | 103 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 81 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index cd05d922f5f..3b789dfd66f 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -274,7 +274,7 @@ where } /// Parse, resolve, and typecheck the given crate. -fn create_config( +crate fn create_config( RustdocOptions { input, crate_name, @@ -406,50 +406,7 @@ fn create_config( } } -crate fn run_core( - options: RustdocOptions, -) -> (clean::Crate, RenderInfo, RenderOptions, Lrc) { - let default_passes = options.default_passes; - let output_format = options.output_format; - // TODO: fix this clone (especially render_options) - let externs = options.externs.clone(); - let manual_passes = options.manual_passes.clone(); - let render_options = options.render_options.clone(); - let config = create_config(options); - - interface::create_compiler_and_run(config, |compiler| { - compiler.enter(|queries| { - let sess = compiler.session(); - - // We need to hold on to the complete resolver, so we cause everything to be - // cloned for the analysis passes to use. Suboptimal, but necessary in the - // current architecture. - let resolver = create_resolver(externs, queries, &sess); - - if sess.has_errors() { - sess.fatal("Compilation failed, aborting rustdoc"); - } - - let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); - - let (krate, render_info, opts) = sess.time("run_global_ctxt", || { - global_ctxt.enter(|tcx| { - run_global_ctxt( - tcx, - resolver, - default_passes, - manual_passes, - render_options, - output_format, - ) - }) - }); - (krate, render_info, opts, Lrc::clone(sess)) - }) - }) -} - -fn create_resolver<'a>( +crate fn create_resolver<'a>( externs: config::Externs, queries: &Queries<'a>, sess: &Session, @@ -489,7 +446,7 @@ fn create_resolver<'a>( resolver.clone() } -fn run_global_ctxt( +crate fn run_global_ctxt( tcx: TyCtxt<'_>, resolver: Rc>, mut default_passes: passes::DefaultPassOption, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 24045b4e29d..93c849859ab 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -63,7 +63,9 @@ use std::env; use std::process; use rustc_data_structures::sync::Lrc; +use rustc_driver::abort_on_err; use rustc_errors::ErrorReported; +use rustc_interface::interface; use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; use rustc_session::getopts; use rustc_session::Session; @@ -520,34 +522,85 @@ fn main_options(options: config::Options) -> MainResult { // then generated from the cleaned AST of the crate. This runs all the // plug/cleaning passes. let crate_version = options.crate_version.clone(); + + let default_passes = options.default_passes; let output_format = options.output_format; - let (mut krate, renderinfo, renderopts, sess) = core::run_core(options); + // TODO: fix this clone (especially render_options) + let externs = options.externs.clone(); + let manual_passes = options.manual_passes.clone(); + let render_options = options.render_options.clone(); + let config = core::create_config(options); - info!("finished with rustc"); + interface::create_compiler_and_run(config, |compiler| { + compiler.enter(|queries| { + let sess = compiler.session(); - krate.version = crate_version; + // We need to hold on to the complete resolver, so we cause everything to be + // cloned for the analysis passes to use. Suboptimal, but necessary in the + // current architecture. + let resolver = core::create_resolver(externs, queries, &sess); - if show_coverage { - // if we ran coverage, bail early, we don't need to also generate docs at this point - // (also we didn't load in any of the useful passes) - return Ok(()); - } else if run_check { - // Since we're in "check" mode, no need to generate anything beyond this point. - return Ok(()); - } + if sess.has_errors() { + sess.fatal("Compilation failed, aborting rustdoc"); + } - info!("going to format"); - let (error_format, edition, debugging_options) = diag_opts; - let diag = core::new_handler(error_format, None, &debugging_options); - let sess_time = sess.clone(); - match output_format { - None | Some(config::OutputFormat::Html) => sess_time.time("render_html", || { - run_renderer::( - krate, renderopts, renderinfo, &diag, edition, sess, - ) - }), - Some(config::OutputFormat::Json) => sess_time.time("render_json", || { - run_renderer::(krate, renderopts, renderinfo, &diag, edition, sess) - }), - } + let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); + + global_ctxt.enter(|tcx| { + let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || { + core::run_global_ctxt( + tcx, + resolver, + default_passes, + manual_passes, + render_options, + output_format, + ) + }); + info!("finished with rustc"); + + if let Some(name) = crate_name { + krate.name = name + } + + krate.version = crate_version; + + if show_coverage { + // if we ran coverage, bail early, we don't need to also generate docs at this point + // (also we didn't load in any of the useful passes) + return Ok(()); + } else if run_check { + // Since we're in "check" mode, no need to generate anything beyond this point. + return Ok(()); + } + + info!("going to format"); + let (error_format, edition, debugging_options) = diag_opts; + let diag = core::new_handler(error_format, None, &debugging_options); + let sess_format = sess.clone(); + match output_format { + None | Some(config::OutputFormat::Html) => sess.time("render_html", || { + run_renderer::( + krate, + render_opts, + render_info, + &diag, + edition, + sess_format, + ) + }), + Some(config::OutputFormat::Json) => sess.time("render_json", || { + run_renderer::( + krate, + render_opts, + render_info, + &diag, + edition, + sess_format, + ) + }), + } + }) + }) + }) } -- cgit 1.4.1-3-g733a5 From 9221d4d1d347ee50f31d2bf50e13ecfdf14c4611 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 16 Dec 2020 14:23:14 -0500 Subject: [tmp] Pass `TyCtxt` through to the render backend First actually useful step in https://github.com/rust-lang/rust/issues/76382 This doesn't yet compile because there's no way to get a `Lrc` from a TyCtxt, only a `&Session`. --- src/librustdoc/formats/renderer.rs | 9 ++++----- src/librustdoc/html/render/mod.rs | 5 +++-- src/librustdoc/json/mod.rs | 5 +++-- src/librustdoc/lib.rs | 13 +++++-------- 4 files changed, 15 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index f61919d78a0..7ec29a70bd0 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -1,7 +1,6 @@ use std::sync::Arc; -use rustc_data_structures::sync::Lrc; -use rustc_session::Session; +use rustc_middle::ty; use rustc_span::edition::Edition; use crate::clean; @@ -21,7 +20,7 @@ crate trait FormatRenderer: Clone { render_info: RenderInfo, edition: Edition, cache: &mut Cache, - sess: Lrc, + tcx: ty::TyCtxt<'_>, ) -> Result<(Self, clean::Crate), Error>; /// Renders a single non-module item. This means no recursive sub-item rendering is required. @@ -52,7 +51,7 @@ crate fn run_format( render_info: RenderInfo, diag: &rustc_errors::Handler, edition: Edition, - sess: Lrc, + tcx: ty::TyCtxt<'_>, ) -> Result<(), Error> { let (krate, mut cache) = Cache::from_krate( render_info.clone(), @@ -63,7 +62,7 @@ crate fn run_format( ); let (mut format_renderer, mut krate) = - T::init(krate, options, render_info, edition, &mut cache, sess)?; + T::init(krate, options, render_info, edition, &mut cache, tcx)?; let cache = Arc::new(cache); // Freeze the cache now that the index has been built. Put an Arc into TLS for future diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index a775c85435c..d8d46adfb63 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -57,6 +57,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Mutability; use rustc_middle::middle::stability; +use rustc_middle::ty; use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; @@ -388,7 +389,7 @@ impl FormatRenderer for Context { _render_info: RenderInfo, edition: Edition, cache: &mut Cache, - sess: Lrc, + tcx: ty::TyCtxt<'_>, ) -> Result<(Context, clean::Crate), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); @@ -462,7 +463,7 @@ impl FormatRenderer for Context { } let (sender, receiver) = channel(); let mut scx = SharedContext { - sess, + tcx, collapsed: krate.collapsed, src_root, include_sources, diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 7af26558b76..3d970918407 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -14,6 +14,7 @@ use std::rc::Rc; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; +use rustc_middle::ty; use rustc_session::Session; use rustc_span::edition::Edition; @@ -127,12 +128,12 @@ impl FormatRenderer for JsonRenderer { _render_info: RenderInfo, _edition: Edition, _cache: &mut Cache, - sess: Lrc, + tcx: ty::TyCtxt<'_>, ) -> Result<(Self, clean::Crate), Error> { debug!("Initializing json renderer"); Ok(( JsonRenderer { - sess, + sess: tcx.sess, index: Rc::new(RefCell::new(FxHashMap::default())), out_path: options.output, }, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 93c849859ab..caa0706fd2b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -62,13 +62,11 @@ use std::default::Default; use std::env; use std::process; -use rustc_data_structures::sync::Lrc; use rustc_driver::abort_on_err; use rustc_errors::ErrorReported; -use rustc_interface::interface; +use rustc_middle::ty; use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; use rustc_session::getopts; -use rustc_session::Session; use rustc_session::{early_error, early_warn}; #[macro_use] @@ -476,9 +474,9 @@ fn run_renderer( render_info: config::RenderInfo, diag: &rustc_errors::Handler, edition: rustc_span::edition::Edition, - sess: Lrc, + tcx: ty::TyCtxt<'_>, ) -> MainResult { - match formats::run_format::(krate, renderopts, render_info, &diag, edition, sess) { + match formats::run_format::(krate, renderopts, render_info, &diag, edition, tcx) { Ok(_) => Ok(()), Err(e) => { let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error)); @@ -577,7 +575,6 @@ fn main_options(options: config::Options) -> MainResult { info!("going to format"); let (error_format, edition, debugging_options) = diag_opts; let diag = core::new_handler(error_format, None, &debugging_options); - let sess_format = sess.clone(); match output_format { None | Some(config::OutputFormat::Html) => sess.time("render_html", || { run_renderer::( @@ -586,7 +583,7 @@ fn main_options(options: config::Options) -> MainResult { render_info, &diag, edition, - sess_format, + tcx, ) }), Some(config::OutputFormat::Json) => sess.time("render_json", || { @@ -596,7 +593,7 @@ fn main_options(options: config::Options) -> MainResult { render_info, &diag, edition, - sess_format, + tcx, ) }), } -- cgit 1.4.1-3-g733a5 From 47c969436adf2cc5acfbddf1061fb30d0fdacd34 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 16 Dec 2020 14:34:08 -0500 Subject: Make it compile --- src/librustdoc/formats/renderer.rs | 8 +-- src/librustdoc/html/render/mod.rs | 122 +++++++++++++++++++++++-------------- src/librustdoc/html/sources.rs | 12 ++-- src/librustdoc/json/conversions.rs | 8 +-- src/librustdoc/json/mod.rs | 17 +++--- src/librustdoc/lib.rs | 9 +-- 6 files changed, 104 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 7ec29a70bd0..fbbd3c1ccf5 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -11,7 +11,7 @@ use crate::formats::cache::{Cache, CACHE_KEY}; /// Allows for different backends to rustdoc to be used with the `run_format()` function. Each /// backend renderer has hooks for initialization, documenting an item, entering and exiting a /// module, and cleanup/finalizing output. -crate trait FormatRenderer: Clone { +crate trait FormatRenderer<'tcx>: Clone { /// Sets up any state required for the renderer. When this is called the cache has already been /// populated. fn init( @@ -20,7 +20,7 @@ crate trait FormatRenderer: Clone { render_info: RenderInfo, edition: Edition, cache: &mut Cache, - tcx: ty::TyCtxt<'_>, + tcx: ty::TyCtxt<'tcx>, ) -> Result<(Self, clean::Crate), Error>; /// Renders a single non-module item. This means no recursive sub-item rendering is required. @@ -45,13 +45,13 @@ crate trait FormatRenderer: Clone { } /// Main method for rendering a crate. -crate fn run_format( +crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( krate: clean::Crate, options: RenderOptions, render_info: RenderInfo, diag: &rustc_errors::Handler, edition: Edition, - tcx: ty::TyCtxt<'_>, + tcx: ty::TyCtxt<'tcx>, ) -> Result<(), Error> { let (krate, mut cache) = Cache::from_krate( render_info.clone(), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index d8d46adfb63..e6d3fdbe185 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -52,12 +52,12 @@ use rustc_ast_pretty::pprust; use rustc_attr::{Deprecation, StabilityLevel}; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Mutability; use rustc_middle::middle::stability; use rustc_middle::ty; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; @@ -103,7 +103,7 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { /// easily cloned because it is cloned per work-job (about once per item in the /// rustdoc tree). #[derive(Clone)] -crate struct Context { +crate struct Context<'tcx> { /// Current hierarchy of components leading down to what's currently being /// rendered crate current: Vec, @@ -116,15 +116,15 @@ crate struct Context { crate render_redirect_pages: bool, /// The map used to ensure all generated 'id=' attributes are unique. id_map: Rc>, - crate shared: Arc, + crate shared: Arc>, all: Rc>, /// Storage for the errors produced while generating documentation so they /// can be printed together at the end. crate errors: Rc>, } -crate struct SharedContext { - crate sess: Lrc, +crate struct SharedContext<'tcx> { + crate tcx: TyCtxt<'tcx>, /// The path to the crate root source minus the file name. /// Used for simplifying paths to the highlighted source code files. crate src_root: PathBuf, @@ -164,7 +164,7 @@ crate struct SharedContext { playground: Option, } -impl Context { +impl Context<'_> { fn path(&self, filename: &str) -> PathBuf { // We use splitn vs Path::extension here because we might get a filename // like `style.min.css` and we want to process that into @@ -177,11 +177,11 @@ impl Context { } fn sess(&self) -> &Session { - &self.shared.sess + &self.shared.tcx.sess } } -impl SharedContext { +impl SharedContext<'_> { crate fn ensure_dir(&self, dst: &Path) -> Result<(), Error> { let mut dirs = self.created_dirs.borrow_mut(); if !dirs.contains(dst) { @@ -382,15 +382,15 @@ crate fn initial_ids() -> Vec { } /// Generates the documentation for `crate` into the directory `dst` -impl FormatRenderer for Context { +impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { fn init( mut krate: clean::Crate, options: RenderOptions, _render_info: RenderInfo, edition: Edition, cache: &mut Cache, - tcx: ty::TyCtxt<'_>, - ) -> Result<(Context, clean::Crate), Error> { + tcx: ty::TyCtxt<'tcx>, + ) -> Result<(Self, clean::Crate), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); let RenderOptions { @@ -689,7 +689,7 @@ impl FormatRenderer for Context { } fn write_shared( - cx: &Context, + cx: &Context<'_>, krate: &clean::Crate, search_index: String, options: &RenderOptions, @@ -1206,7 +1206,7 @@ fn write_minify( } } -fn write_srclink(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) { +fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Cache) { if let Some(l) = cx.src_href(item, cache) { write!( buf, @@ -1517,7 +1517,7 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result { fn derive_id(&self, id: String) -> String { let mut map = self.id_map.borrow_mut(); map.derive(id) @@ -1702,7 +1702,7 @@ where write!(w, "") } -fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) { +fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Cache) { debug_assert!(!item.is_stripped()); // Write the breadcrumb trail header for the top write!(buf, "
"); // in-band - match item.kind { + match *item.kind { clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items), clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => { item_function(buf, cx, item, f) @@ -2149,7 +2149,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl ); } - match myitem.kind { + match *myitem.kind { clean::ExternCrateItem(ref name, ref src) => { use crate::html::format::anchor; @@ -2185,7 +2185,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl continue; } - let unsafety_flag = match myitem.kind { + let unsafety_flag = match *myitem.kind { clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func) if func.header.unsafety == hir::Unsafety::Unsafe => { @@ -2624,7 +2624,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } for (pos, m) in provided.iter().enumerate() { render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); - match m.kind { + match *m.kind { clean::MethodItem(ref inner, _) if !inner.generics.where_predicates.is_empty() => { @@ -3051,7 +3051,7 @@ fn render_assoc_item( where_clause = WhereClause { gens: g, indent, end_newline } ) } - match item.kind { + match *item.kind { clean::StrippedItem(..) => {} clean::TyMethodItem(ref m) => { method(w, item, m.header, &m.generics, &m.decl, link, parent, cx) @@ -3098,7 +3098,7 @@ fn item_struct( let mut fields = s .fields .iter() - .filter_map(|f| match f.kind { + .filter_map(|f| match *f.kind { clean::StructFieldItem(ref ty) => Some((f, ty)), _ => None, }) @@ -3148,7 +3148,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni let mut fields = s .fields .iter() - .filter_map(|f| match f.kind { + .filter_map(|f| match *f.kind { clean::StructFieldItem(ref ty) => Some((f, ty)), _ => None, }) @@ -3201,7 +3201,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum for v in &e.variants { write!(w, " "); let name = v.name.as_ref().unwrap(); - match v.kind { + match *v.kind { clean::VariantItem(ref var) => match var.kind { clean::VariantKind::CLike => write!(w, "{}", name), clean::VariantKind::Tuple(ref tys) => { @@ -3251,7 +3251,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum id = id, name = variant.name.as_ref().unwrap() ); - if let clean::VariantItem(ref var) = variant.kind { + if let clean::VariantItem(ref var) = *variant.kind { if let clean::VariantKind::Tuple(ref tys) = var.kind { write!(w, "("); for (i, ty) in tys.iter().enumerate() { @@ -3268,7 +3268,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum document_non_exhaustive(w, variant); use crate::clean::{Variant, VariantKind}; - if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = variant.kind { + if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = *variant.kind + { let variant_id = cx.derive_id(format!( "{}.{}.fields", ItemType::Variant, @@ -3282,7 +3283,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum ); for field in &s.fields { use crate::clean::StructFieldItem; - if let StructFieldItem(ref ty) = field.kind { + if let StructFieldItem(ref ty) = *field.kind { let id = cx.derive_id(format!( "variant.{}.field.{}", variant.name.as_ref().unwrap(), @@ -3379,7 +3380,7 @@ fn render_struct( let mut has_visible_fields = false; write!(w, " {{"); for field in fields { - if let clean::StructFieldItem(ref ty) = field.kind { + if let clean::StructFieldItem(ref ty) = *field.kind { write!( w, "\n{} {}{}: {},", @@ -3410,7 +3411,7 @@ fn render_struct( if i > 0 { write!(w, ", "); } - match field.kind { + match *field.kind { clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"), clean::StructFieldItem(ref ty) => { write!(w, "{}{}", field.visibility.print_with_space(cx.tcx()), ty.print()) @@ -3457,7 +3458,7 @@ fn render_union( write!(w, " {{\n{}", tab); for field in fields { - if let clean::StructFieldItem(ref ty) = field.kind { + if let clean::StructFieldItem(ref ty) = *field.kind { write!( w, " {}{}: {},\n{}", @@ -3619,7 +3620,7 @@ fn render_deref_methods( .inner_impl() .items .iter() - .find_map(|item| match item.kind { + .find_map(|item| match *item.kind { clean::TypedefItem(ref t, true) => Some(match *t { clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), _ => (&t.type_, &t.type_), @@ -3641,7 +3642,7 @@ fn render_deref_methods( } fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { - let self_type_opt = match item.kind { + let self_type_opt = match *item.kind { clean::MethodItem(ref method, _) => method.decl.self_type(), clean::TyMethodItem(ref method) => method.decl.self_type(), _ => None, @@ -3692,7 +3693,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { )); let t_did = impl_.trait_.def_id().unwrap(); for it in &impl_.items { - if let clean::TypedefItem(ref tydef, _) = it.kind { + if let clean::TypedefItem(ref tydef, _) = *it.kind { out.push_str(" "); assoc_type( &mut out, @@ -3764,7 +3765,7 @@ fn render_impl( fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute); if show_def_docs { for it in &i.inner_impl().items { - if let clean::TypedefItem(ref tydef, _) = it.kind { + if let clean::TypedefItem(ref tydef, _) = *it.kind { write!(w, " "); assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None), ""); write!(w, ";"); @@ -3846,7 +3847,7 @@ fn render_impl( } else { (true, " hidden") }; - match item.kind { + match *item.kind { clean::MethodItem(..) | clean::TyMethodItem(_) => { // Only render when the method is not static or we allow static methods if render_method_item { @@ -4123,7 +4124,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache: write!( buffer, "

{}{}

", - match it.kind { + match *it.kind { clean::StructItem(..) => "Struct ", clean::TraitItem(..) => "Trait ", clean::PrimitiveItem(..) => "Primitive Type ", @@ -4163,7 +4164,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache: it.name.as_ref().expect("crates always have a name") ); } - match it.kind { + match *it.kind { clean::StructItem(ref s) => sidebar_struct(buffer, it, s), clean::TraitItem(ref t) => sidebar_trait(buffer, it, t), clean::PrimitiveItem(_) => sidebar_primitive(buffer, it), @@ -4303,7 +4304,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { if let Some((target, real_target)) = - impl_.inner_impl().items.iter().find_map(|item| match item.kind { + impl_.inner_impl().items.iter().find_map(|item| match *item.kind { clean::TypedefItem(ref t, true) => Some(match *t { clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), _ => (&t.type_, &t.type_), @@ -4442,7 +4443,7 @@ fn get_id_for_impl_on_foreign_type(for_: &clean::Type, trait_: &clean::Type) -> } fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> { - match item.kind { + match *item.kind { clean::ItemKind::ImplItem(ref i) => { if let Some(ref trait_) = i.trait_ { Some(( @@ -4593,7 +4594,7 @@ fn sidebar_typedef(buf: &mut Buffer, it: &clean::Item) { fn get_struct_fields_name(fields: &[clean::Item]) -> String { let mut fields = fields .iter() - .filter(|f| if let clean::StructFieldItem(..) = f.kind { true } else { false }) + .filter(|f| matches!(*f.kind, clean::StructFieldItem(..))) .filter_map(|f| match f.name { Some(ref name) => { Some(format!("{name}", name = name)) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 3b7ac624ccd..e347f7f8411 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -19,9 +19,9 @@ impl JsonRenderer<'_> { let item_type = ItemType::from(&item); let deprecation = item.deprecation(self.tcx); let clean::Item { source, name, attrs, kind, visibility, def_id } = item; - match kind { + match *kind { clean::StrippedItem(_) => None, - _ => Some(Item { + kind => Some(Item { id: def_id.into(), crate_id: def_id.krate.as_u32(), name: name.map(|sym| sym.to_string()), diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index dc2bc14e7ce..df7ab9b7361 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -178,9 +178,9 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { cache: &Cache, ) -> Result<(), Error> { use clean::types::ItemKind::*; - if let ModuleItem(m) = &item.kind { + if let ModuleItem(m) = &*item.kind { for item in &m.items { - match &item.kind { + match &*item.kind { // These don't have names so they don't get added to the output by default ImportItem(_) => self.item(item.clone(), cache).unwrap(), ExternCrateItem(_, _) => self.item(item.clone(), cache).unwrap(), diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 52f6a97089b..6951b01e03d 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -187,7 +187,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> { impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { fn fold_item(&mut self, i: clean::Item) -> Option { - match i.kind { + match *i.kind { _ if !i.def_id.is_local() => { // non-local items are skipped because they can be out of the users control, // especially in the case of trait impls, which rustdoc eagerly inlines diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 60fcbe74872..9b0ae09cb3f 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -58,11 +58,11 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { // scan through included items ahead of time to splice in Deref targets to the "valid" sets for it in &new_items { - if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.kind { + if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() { let target = items .iter() - .find_map(|item| match item.kind { + .find_map(|item| match *item.kind { TypedefItem(ref t, true) => Some(&t.type_), _ => None, }) @@ -78,7 +78,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { } new_items.retain(|it| { - if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.kind { + if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind { cleaner.keep_item(for_) || trait_.as_ref().map_or(false, |t| cleaner.keep_item(t)) || blanket_impl.is_some() @@ -124,7 +124,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { } if let Some(ref mut it) = krate.module { - if let ModuleItem(Module { ref mut items, .. }) = it.kind { + if let ModuleItem(Module { ref mut items, .. }) = *it.kind { items.extend(synth.impls); items.extend(new_items); } else { diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index 1c1141e7c81..68ce73f944b 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -59,7 +59,7 @@ impl crate::doctest::Tester for Tests { crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool { if matches!( - item.kind, + *item.kind, clean::StructFieldItem(_) | clean::VariantItem(_) | clean::AssocConstItem(_, _) diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 6b59eb8cf28..5694ce27de8 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -41,7 +41,7 @@ impl<'a> DocFolder for Stripper<'a> { if i.attrs.lists(sym::doc).has_word(sym::hidden) { debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name); // use a dedicated hidden item for given item type if any - match i.kind { + match *i.kind { clean::StructFieldItem(..) | clean::ModuleItem(..) => { // We need to recurse into stripped modules to // strip things like impl methods but when doing so diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 444fd593ec9..f872e403ab0 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -13,7 +13,7 @@ crate struct Stripper<'a> { impl<'a> DocFolder for Stripper<'a> { fn fold_item(&mut self, i: Item) -> Option { - match i.kind { + match *i.kind { clean::StrippedItem(..) => { // We need to recurse into stripped modules to strip things // like impl methods but when doing so we must not add any @@ -86,7 +86,7 @@ impl<'a> DocFolder for Stripper<'a> { clean::KeywordItem(..) => {} } - let fastreturn = match i.kind { + let fastreturn = match *i.kind { // nothing left to do for traits (don't want to filter their // methods out, visibility controlled by the trait) clean::TraitItem(..) => true, @@ -121,7 +121,7 @@ crate struct ImplStripper<'a> { impl<'a> DocFolder for ImplStripper<'a> { fn fold_item(&mut self, i: Item) -> Option { - if let clean::ImplItem(ref imp) = i.kind { + if let clean::ImplItem(ref imp) = *i.kind { // emptied none trait impls can be stripped if imp.trait_.is_none() && imp.items.is_empty() { return None; @@ -160,7 +160,7 @@ crate struct ImportStripper; impl DocFolder for ImportStripper { fn fold_item(&mut self, i: Item) -> Option { - match i.kind { + match *i.kind { clean::ExternCrateItem(..) | clean::ImportItem(..) if !i.visibility.is_public() => None, _ => Some(self.fold_item_recur(i)), } -- cgit 1.4.1-3-g733a5 From ddf82636c6b2d42a1fe9d25b51ec9b006043f529 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 16:52:20 +0100 Subject: bootstrap: convert build-manifest to use the new Tarball struct --- src/bootstrap/dist.rs | 109 ++++++++--------------------------------- src/bootstrap/lib.rs | 1 + src/bootstrap/tarball.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 88 deletions(-) create mode 100644 src/bootstrap/tarball.rs (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index fcbde9c438c..0ec896ed211 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -19,6 +19,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::TargetSelection; +use crate::tarball::{OverlayKind, Tarball}; use crate::tool::{self, Tool}; use crate::util::{exe, is_dylib, timeit}; use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}; @@ -2517,68 +2518,36 @@ impl Step for RustDev { builder.info(&format!("Dist RustDev ({})", target)); let _time = timeit(builder); - let src = builder.src.join("src/llvm-project/llvm"); - let name = pkgname(builder, "rust-dev"); - - let tmp = tmpdir(builder); - let image = tmp.join("rust-dev-image"); - drop(fs::remove_dir_all(&image)); - // Prepare the image directory - let dst_bindir = image.join("bin"); - t!(fs::create_dir_all(&dst_bindir)); + let mut tarball = Tarball::new(builder, "rust-dev", &target.triple); + tarball.set_overlay(OverlayKind::LLVM); let src_bindir = builder.llvm_out(target).join("bin"); - let install_bin = - |name| builder.install(&src_bindir.join(exe(name, target)), &dst_bindir, 0o755); - install_bin("llvm-config"); - install_bin("llvm-ar"); - install_bin("llvm-objdump"); - install_bin("llvm-profdata"); - install_bin("llvm-bcanalyzer"); - install_bin("llvm-cov"); - install_bin("llvm-dwp"); - builder.install(&builder.llvm_filecheck(target), &dst_bindir, 0o755); + for bin in &[ + "llvm-config", + "llvm-ar", + "llvm-objdump", + "llvm-profdata", + "llvm-bcanalyzer", + "llvm-cov", + "llvm-dwp", + ] { + tarball.add_file(src_bindir.join(exe(bin, target)), "bin", 0o755); + } + tarball.add_file(&builder.llvm_filecheck(target), "bin", 0o755); // Copy the include directory as well; needed mostly to build // librustc_llvm properly (e.g., llvm-config.h is in here). But also // just broadly useful to be able to link against the bundled LLVM. - builder.cp_r(&builder.llvm_out(target).join("include"), &image.join("include")); + tarball.add_dir(&builder.llvm_out(target).join("include"), "."); // Copy libLLVM.so to the target lib dir as well, so the RPATH like // `$ORIGIN/../lib` can find it. It may also be used as a dependency // of `rustc-dev` to support the inherited `-lLLVM` when using the // compiler libraries. - maybe_install_llvm(builder, target, &image.join("lib")); - - // Prepare the overlay - let overlay = tmp.join("rust-dev-overlay"); - drop(fs::remove_dir_all(&overlay)); - builder.create_dir(&overlay); - builder.install(&src.join("README.txt"), &overlay, 0o644); - builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644); - builder.create(&overlay.join("version"), &builder.rust_version()); + maybe_install_llvm(builder, target, &tarball.image_dir().join("lib")); - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=rust-dev-installed.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=rust-dev"); - - builder.run(&mut cmd); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) + Some(tarball.generate()) } } @@ -2607,45 +2576,9 @@ impl Step for BuildManifest { fn run(self, builder: &Builder<'_>) -> PathBuf { let build_manifest = builder.tool_exe(Tool::BuildManifest); - let name = pkgname(builder, "build-manifest"); - let tmp = tmpdir(builder); - - // Prepare the image. - let image = tmp.join("build-manifest-image"); - let image_bin = image.join("bin"); - let _ = fs::remove_dir_all(&image); - t!(fs::create_dir_all(&image_bin)); - builder.install(&build_manifest, &image_bin, 0o755); - - // Prepare the overlay. - let overlay = tmp.join("build-manifest-overlay"); - let _ = fs::remove_dir_all(&overlay); - builder.create_dir(&overlay); - builder.create(&overlay.join("version"), &builder.rust_version()); - for file in &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"] { - builder.install(&builder.src.join(file), &overlay, 0o644); - } - - // Create the final tarball. - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=build-manifest installed.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, self.target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=build-manifest"); - - builder.run(&mut cmd); - distdir(builder).join(format!("{}-{}.tar.gz", name, self.target.triple)) + let tarball = Tarball::new(builder, "build-manifest", &self.target.triple); + tarball.add_file(&build_manifest, "bin", 0o755); + tarball.generate() } } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index ece9bdc7a64..3b51bf272fc 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -142,6 +142,7 @@ mod native; mod run; mod sanity; mod setup; +mod tarball; mod test; mod tool; mod toolstate; diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs new file mode 100644 index 00000000000..728d1344349 --- /dev/null +++ b/src/bootstrap/tarball.rs @@ -0,0 +1,124 @@ +use std::path::{Path, PathBuf}; + +use build_helper::t; + +use crate::builder::Builder; + +#[derive(Copy, Clone)] +pub(crate) enum OverlayKind { + Rust, + LLVM, +} + +impl OverlayKind { + fn included_files(&self) -> &[&str] { + match self { + OverlayKind::Rust => &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"], + OverlayKind::LLVM => { + &["src/llvm-project/llvm/LICENSE.TXT", "src/llvm-project/llvm/README.txt"] + } + } + } +} + +pub(crate) struct Tarball<'a> { + builder: &'a Builder<'a>, + + pkgname: String, + component: String, + target: String, + overlay: OverlayKind, + + temp_dir: PathBuf, + image_dir: PathBuf, + overlay_dir: PathBuf, + work_dir: PathBuf, +} + +impl<'a> Tarball<'a> { + pub(crate) fn new(builder: &'a Builder<'a>, component: &str, target: &str) -> Self { + let pkgname = crate::dist::pkgname(builder, component); + + let temp_dir = builder.out.join("tmp").join("tarball").join(component); + let _ = std::fs::remove_dir_all(&temp_dir); + + let image_dir = temp_dir.join("image"); + let overlay_dir = temp_dir.join("overlay"); + let work_dir = temp_dir.join("work"); + + Self { + builder, + + pkgname, + component: component.into(), + target: target.into(), + overlay: OverlayKind::Rust, + + temp_dir, + image_dir, + overlay_dir, + work_dir, + } + } + + pub(crate) fn set_overlay(&mut self, overlay: OverlayKind) { + self.overlay = overlay; + } + + pub(crate) fn image_dir(&self) -> &Path { + t!(std::fs::create_dir_all(&self.image_dir)); + &self.image_dir + } + + pub(crate) fn add_file(&self, src: impl AsRef, destdir: impl AsRef, perms: u32) { + // create_dir_all fails to create `foo/bar/.`, so when the destination is "." this simply + // uses the base directory as the destination directory. + let destdir = if destdir.as_ref() == Path::new(".") { + self.image_dir.clone() + } else { + self.image_dir.join(destdir.as_ref()) + }; + + t!(std::fs::create_dir_all(&destdir)); + self.builder.install(src.as_ref(), &destdir, perms); + } + + pub(crate) fn add_dir(&self, src: impl AsRef, destdir: impl AsRef) { + t!(std::fs::create_dir_all(destdir.as_ref())); + self.builder.cp_r( + src.as_ref(), + &self.image_dir.join(destdir.as_ref()).join(src.as_ref().file_name().unwrap()), + ); + } + + pub(crate) fn generate(self) -> PathBuf { + t!(std::fs::create_dir_all(&self.overlay_dir)); + self.builder.create(&self.overlay_dir.join("version"), &self.builder.rust_version()); + for file in self.overlay.included_files() { + self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644); + } + + let distdir = crate::dist::distdir(self.builder); + let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller); + cmd.arg("generate") + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg(format!("--success-message={} installed.", self.component)) + .arg("--image-dir") + .arg(self.image_dir) + .arg("--work-dir") + .arg(self.work_dir) + .arg("--output-dir") + .arg(&distdir) + .arg("--non-installed-overlay") + .arg(self.overlay_dir) + .arg(format!("--package-name={}-{}", self.pkgname, self.target)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg(format!("--component-name={}", self.component)); + self.builder.run(&mut cmd); + + t!(std::fs::remove_dir_all(&self.temp_dir)); + + distdir.join(format!("{}-{}.tar.gz", self.pkgname, self.target)) + } +} -- cgit 1.4.1-3-g733a5 From 7be85701cda29bbe715e462be856a61aed5bd4b4 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 17:47:48 +0100 Subject: bootstrap: convert llvm-tools to use Tarball --- src/bootstrap/dist.rs | 44 +++++++------------------------------------- src/bootstrap/lib.rs | 4 ---- src/bootstrap/tarball.rs | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 0ec896ed211..9b0a6e6e19d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2431,56 +2431,26 @@ impl Step for LlvmTools { builder.info(&format!("Dist LlvmTools ({})", target)); let _time = timeit(builder); - let src = builder.src.join("src/llvm-project/llvm"); - let name = pkgname(builder, "llvm-tools"); - let tmp = tmpdir(builder); - let image = tmp.join("llvm-tools-image"); - drop(fs::remove_dir_all(&image)); + let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple); + tarball.set_overlay(OverlayKind::LLVM); + tarball.is_preview(true); // Prepare the image directory let src_bindir = builder.llvm_out(target).join("bin"); - let dst_bindir = image.join("lib/rustlib").join(&*target.triple).join("bin"); - t!(fs::create_dir_all(&dst_bindir)); + let dst_bindir = format!("lib/rustlib/{}/bin", target.triple); for tool in LLVM_TOOLS { let exe = src_bindir.join(exe(tool, target)); - builder.install(&exe, &dst_bindir, 0o755); + tarball.add_file(&exe, &dst_bindir, 0o755); } // Copy libLLVM.so to the target lib dir as well, so the RPATH like // `$ORIGIN/../lib` can find it. It may also be used as a dependency // of `rustc-dev` to support the inherited `-lLLVM` when using the // compiler libraries. - maybe_install_llvm_target(builder, target, &image); - - // Prepare the overlay - let overlay = tmp.join("llvm-tools-overlay"); - drop(fs::remove_dir_all(&overlay)); - builder.create_dir(&overlay); - builder.install(&src.join("README.txt"), &overlay, 0o644); - builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644); - builder.create(&overlay.join("version"), &builder.llvm_tools_vers()); - - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=llvm-tools-installed.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=llvm-tools-preview"); + maybe_install_llvm_target(builder, target, tarball.image_dir()); - builder.run(&mut cmd); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) + Some(tarball.generate()) } } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 3b51bf272fc..a47ddfbcc1f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1069,10 +1069,6 @@ impl Build { self.package_vers(&self.version) } - fn llvm_tools_vers(&self) -> String { - self.rust_version() - } - fn llvm_link_tools_dynamically(&self, target: TargetSelection) -> bool { target.contains("linux-gnu") || target.contains("apple-darwin") } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 728d1344349..2c110a7fb24 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -33,6 +33,8 @@ pub(crate) struct Tarball<'a> { image_dir: PathBuf, overlay_dir: PathBuf, work_dir: PathBuf, + + is_preview: bool, } impl<'a> Tarball<'a> { @@ -58,6 +60,8 @@ impl<'a> Tarball<'a> { image_dir, overlay_dir, work_dir, + + is_preview: false, } } @@ -65,6 +69,10 @@ impl<'a> Tarball<'a> { self.overlay = overlay; } + pub(crate) fn is_preview(&mut self, is: bool) { + self.is_preview = is; + } + pub(crate) fn image_dir(&self) -> &Path { t!(std::fs::create_dir_all(&self.image_dir)); &self.image_dir @@ -98,6 +106,11 @@ impl<'a> Tarball<'a> { self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644); } + let mut component_name = self.component.clone(); + if self.is_preview { + component_name.push_str("-preview"); + } + let distdir = crate::dist::distdir(self.builder); let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller); cmd.arg("generate") @@ -114,7 +127,7 @@ impl<'a> Tarball<'a> { .arg(self.overlay_dir) .arg(format!("--package-name={}-{}", self.pkgname, self.target)) .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg(format!("--component-name={}", self.component)); + .arg(format!("--component-name={}", component_name)); self.builder.run(&mut cmd); t!(std::fs::remove_dir_all(&self.temp_dir)); -- cgit 1.4.1-3-g733a5 From c768ce138427b1844c1f6594daba9c0e33928032 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 22:20:45 +0100 Subject: bootstrap: convert rust-docs to use Tarball --- src/bootstrap/dist.rs | 45 +++++++++++---------------------------------- src/bootstrap/tarball.rs | 19 ++++++++++++------- 2 files changed, 23 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 9b0a6e6e19d..26a621c41ca 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -55,7 +55,7 @@ pub struct Docs { } impl Step for Docs { - type Output = PathBuf; + type Output = Option; const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -67,13 +67,10 @@ impl Step for Docs { } /// Builds the `rust-docs` installer component. - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> Option { let host = self.host; - - let name = pkgname(builder, "rust-docs"); - if !builder.config.docs { - return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple)); + return None; } builder.default_doc(None); @@ -81,34 +78,14 @@ impl Step for Docs { builder.info(&format!("Dist docs ({})", host)); let _time = timeit(builder); - let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple)); - let _ = fs::remove_dir_all(&image); + let dest = "share/doc/rust/html"; - let dst = image.join("share/doc/rust/html"); - t!(fs::create_dir_all(&dst)); - let src = builder.doc_out(host); - builder.cp_r(&src, &dst); - builder.install(&builder.src.join("src/doc/robots.txt"), &dst, 0o644); - - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust-Documentation") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-documentation-is-installed.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, host.triple)) - .arg("--component-name=rust-docs") - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rust/html"); - builder.run(&mut cmd); - builder.remove_dir(&image); + let mut tarball = Tarball::new(builder, "rust-docs", &host.triple); + tarball.set_product_name("Rust Documentation"); + tarball.add_dir(&builder.doc_out(host), dest); + tarball.add_file(&builder.src.join("src/doc/robots.txt"), dest, 0o644); - distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple)) + Some(tarball.generate()) } } @@ -1826,7 +1803,7 @@ impl Step for Extended { tarballs.extend(llvm_tools_installer); tarballs.push(analysis_installer); tarballs.push(std_installer); - if builder.config.docs { + if let Some(docs_installer) = docs_installer { tarballs.push(docs_installer); } if target.contains("pc-windows-gnu") { @@ -2509,7 +2486,7 @@ impl Step for RustDev { // Copy the include directory as well; needed mostly to build // librustc_llvm properly (e.g., llvm-config.h is in here). But also // just broadly useful to be able to link against the bundled LLVM. - tarball.add_dir(&builder.llvm_out(target).join("include"), "."); + tarball.add_dir(&builder.llvm_out(target).join("include"), "include"); // Copy libLLVM.so to the target lib dir as well, so the RPATH like // `$ORIGIN/../lib` can find it. It may also be used as a dependency diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 2c110a7fb24..50d58d00a66 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -27,6 +27,7 @@ pub(crate) struct Tarball<'a> { pkgname: String, component: String, target: String, + product_name: String, overlay: OverlayKind, temp_dir: PathBuf, @@ -54,6 +55,7 @@ impl<'a> Tarball<'a> { pkgname, component: component.into(), target: target.into(), + product_name: "Rust".into(), overlay: OverlayKind::Rust, temp_dir, @@ -69,6 +71,10 @@ impl<'a> Tarball<'a> { self.overlay = overlay; } + pub(crate) fn set_product_name(&mut self, name: &str) { + self.product_name = name.into(); + } + pub(crate) fn is_preview(&mut self, is: bool) { self.is_preview = is; } @@ -91,12 +97,11 @@ impl<'a> Tarball<'a> { self.builder.install(src.as_ref(), &destdir, perms); } - pub(crate) fn add_dir(&self, src: impl AsRef, destdir: impl AsRef) { - t!(std::fs::create_dir_all(destdir.as_ref())); - self.builder.cp_r( - src.as_ref(), - &self.image_dir.join(destdir.as_ref()).join(src.as_ref().file_name().unwrap()), - ); + pub(crate) fn add_dir(&self, src: impl AsRef, dest: impl AsRef) { + let dest = self.image_dir.join(dest.as_ref()); + + t!(std::fs::create_dir_all(&dest)); + self.builder.cp_r(src.as_ref(), &dest); } pub(crate) fn generate(self) -> PathBuf { @@ -114,7 +119,7 @@ impl<'a> Tarball<'a> { let distdir = crate::dist::distdir(self.builder); let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller); cmd.arg("generate") - .arg("--product-name=Rust") + .arg(format!("--product-name={}", self.product_name)) .arg("--rel-manifest-dir=rustlib") .arg(format!("--success-message={} installed.", self.component)) .arg("--image-dir") -- cgit 1.4.1-3-g733a5 From 8ca46fc7a83734c9622f11f25d16b82316f44bcc Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 22:24:34 +0100 Subject: bootstrap: convert rustc-docs to use Tarball --- src/bootstrap/dist.rs | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 26a621c41ca..5a9c82c52a6 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -95,7 +95,7 @@ pub struct RustcDocs { } impl Step for RustcDocs { - type Output = PathBuf; + type Output = Option; const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -107,47 +107,21 @@ impl Step for RustcDocs { } /// Builds the `rustc-docs` installer component. - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> Option { let host = self.host; - - let name = pkgname(builder, "rustc-docs"); - if !builder.config.compiler_docs { - return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple)); + return None; } builder.default_doc(None); - - let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple)); - let _ = fs::remove_dir_all(&image); - - let dst = image.join("share/doc/rust/html/rustc"); - t!(fs::create_dir_all(&dst)); - let src = builder.compiler_doc_out(host); - builder.cp_r(&src, &dst); - - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rustc-Documentation") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rustc-documentation-is-installed.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, host.triple)) - .arg("--component-name=rustc-docs") - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rust/html/rustc"); - builder.info(&format!("Dist compiler docs ({})", host)); let _time = timeit(builder); - builder.run(&mut cmd); - builder.remove_dir(&image); - distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple)) + let mut tarball = Tarball::new(builder, "rustc-docs", &host.triple); + tarball.set_product_name("Rustc Documentation"); + tarball.add_dir(&builder.compiler_doc_out(host), "share/doc/rust/html/rustc"); + + Some(tarball.generate()) } } -- cgit 1.4.1-3-g733a5 From 82d9eaa54d3a60edc2dd664355e390ec9aa36fa5 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 22:29:33 +0100 Subject: bootstrap: convert rust-mingw to use Tarball --- src/bootstrap/dist.rs | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 5a9c82c52a6..cee8c411fa1 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -297,41 +297,23 @@ impl Step for Mingw { /// without any extra installed software (e.g., we bundle gcc, libraries, etc). fn run(self, builder: &Builder<'_>) -> Option { let host = self.host; - if !host.contains("pc-windows-gnu") { return None; } builder.info(&format!("Dist mingw ({})", host)); let _time = timeit(builder); - let name = pkgname(builder, "rust-mingw"); - let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple)); - let _ = fs::remove_dir_all(&image); - t!(fs::create_dir_all(&image)); + + let mut tarball = Tarball::new(builder, "rust-mingw", &host.triple); + tarball.set_product_name("Rust MinGW"); // The first argument is a "temporary directory" which is just // thrown away (this contains the runtime DLLs included in the rustc package // above) and the second argument is where to place all the MinGW components // (which is what we want). - make_win_dist(&tmpdir(builder), &image, host, &builder); + make_win_dist(&tmpdir(builder), tarball.image_dir(), host, &builder); - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust-MinGW") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-MinGW-is-installed.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, host.triple)) - .arg("--component-name=rust-mingw") - .arg("--legacy-manifest-dirs=rustlib,cargo"); - builder.run(&mut cmd); - t!(fs::remove_dir_all(&image)); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple))) + Some(tarball.generate()) } } -- cgit 1.4.1-3-g733a5 From 0a2e1c5a2c85ff27f2677aa7db1c2deacf34242d Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 22:42:52 +0100 Subject: bootstrap: convert rustc to use Tarball --- src/bootstrap/dist.rs | 60 +++++++----------------------------------------- src/bootstrap/tarball.rs | 3 +++ 2 files changed, 11 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index cee8c411fa1..db792886c16 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -341,30 +341,13 @@ impl Step for Rustc { let compiler = self.compiler; let host = self.compiler.host; - let name = pkgname(builder, "rustc"); - let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple)); - let _ = fs::remove_dir_all(&image); - let overlay = tmpdir(builder).join(format!("{}-{}-overlay", name, host.triple)); - let _ = fs::remove_dir_all(&overlay); + builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host.triple)); + let _time = timeit(builder); - // Prepare the rustc "image", what will actually end up getting installed - prepare_image(builder, compiler, &image); + let tarball = Tarball::new(builder, "rustc", &host.triple); - // Prepare the overlay which is part of the tarball but won't actually be - // installed - let cp = |file: &str| { - builder.install(&builder.src.join(file), &overlay, 0o644); - }; - cp("COPYRIGHT"); - cp("LICENSE-APACHE"); - cp("LICENSE-MIT"); - cp("README.md"); - // tiny morsel of metadata is used by rust-packaging - let version = builder.rust_version(); - builder.create(&overlay.join("version"), &version); - if let Some(sha) = builder.rust_sha() { - builder.create(&overlay.join("git-commit-hash"), &sha); - } + // Prepare the rustc "image", what will actually end up getting installed + prepare_image(builder, compiler, tarball.image_dir()); // On MinGW we've got a few runtime DLL dependencies that we need to // include. The first argument to this script is where to put these DLLs @@ -377,38 +360,11 @@ impl Step for Rustc { // install will *also* include the rust-mingw package, which also needs // licenses, so to be safe we just include it here in all MinGW packages. if host.contains("pc-windows-gnu") { - make_win_dist(&image, &tmpdir(builder), host, builder); - - let dst = image.join("share/doc"); - t!(fs::create_dir_all(&dst)); - builder.cp_r(&builder.src.join("src/etc/third-party"), &dst); + make_win_dist(tarball.image_dir(), &tmpdir(builder), host, builder); + tarball.add_dir(builder.src.join("src/etc/third-party"), "share/doc"); } - // Finally, wrap everything up in a nice tarball! - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-roll.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, host.triple)) - .arg("--component-name=rustc") - .arg("--legacy-manifest-dirs=rustlib,cargo"); - - builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host.triple)); - let _time = timeit(builder); - builder.run(&mut cmd); - builder.remove_dir(&image); - builder.remove_dir(&overlay); - - return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple)); + return tarball.generate(); fn prepare_image(builder: &Builder<'_>, compiler: Compiler, image: &Path) { let host = compiler.host; diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 50d58d00a66..294b69c85f4 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -107,6 +107,9 @@ impl<'a> Tarball<'a> { pub(crate) fn generate(self) -> PathBuf { t!(std::fs::create_dir_all(&self.overlay_dir)); self.builder.create(&self.overlay_dir.join("version"), &self.builder.rust_version()); + if let Some(sha) = self.builder.rust_sha() { + self.builder.create(&self.overlay_dir.join("git-commit-hash"), &sha); + } for file in self.overlay.included_files() { self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644); } -- cgit 1.4.1-3-g733a5 From fd4515cb3f8a8e21d3640ffa8f2b3040a381b87c Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 22:50:38 +0100 Subject: bootstrap: refactor showing the "dist" info --- src/bootstrap/dist.rs | 21 --------------------- src/bootstrap/tarball.rs | 7 +++++-- 2 files changed, 5 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index db792886c16..0e00649fc03 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -72,19 +72,14 @@ impl Step for Docs { if !builder.config.docs { return None; } - builder.default_doc(None); - builder.info(&format!("Dist docs ({})", host)); - let _time = timeit(builder); - let dest = "share/doc/rust/html"; let mut tarball = Tarball::new(builder, "rust-docs", &host.triple); tarball.set_product_name("Rust Documentation"); tarball.add_dir(&builder.doc_out(host), dest); tarball.add_file(&builder.src.join("src/doc/robots.txt"), dest, 0o644); - Some(tarball.generate()) } } @@ -112,15 +107,11 @@ impl Step for RustcDocs { if !builder.config.compiler_docs { return None; } - builder.default_doc(None); - builder.info(&format!("Dist compiler docs ({})", host)); - let _time = timeit(builder); let mut tarball = Tarball::new(builder, "rustc-docs", &host.triple); tarball.set_product_name("Rustc Documentation"); tarball.add_dir(&builder.compiler_doc_out(host), "share/doc/rust/html/rustc"); - Some(tarball.generate()) } } @@ -301,9 +292,6 @@ impl Step for Mingw { return None; } - builder.info(&format!("Dist mingw ({})", host)); - let _time = timeit(builder); - let mut tarball = Tarball::new(builder, "rust-mingw", &host.triple); tarball.set_product_name("Rust MinGW"); @@ -341,9 +329,6 @@ impl Step for Rustc { let compiler = self.compiler; let host = self.compiler.host; - builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host.triple)); - let _time = timeit(builder); - let tarball = Tarball::new(builder, "rustc", &host.triple); // Prepare the rustc "image", what will actually end up getting installed @@ -2318,9 +2303,6 @@ impl Step for LlvmTools { } } - builder.info(&format!("Dist LlvmTools ({})", target)); - let _time = timeit(builder); - let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple); tarball.set_overlay(OverlayKind::LLVM); tarball.is_preview(true); @@ -2375,9 +2357,6 @@ impl Step for RustDev { } } - builder.info(&format!("Dist RustDev ({})", target)); - let _time = timeit(builder); - let mut tarball = Tarball::new(builder, "rust-dev", &target.triple); tarball.set_overlay(OverlayKind::LLVM); diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 294b69c85f4..f99b6f30192 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -114,13 +114,17 @@ impl<'a> Tarball<'a> { self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644); } + let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller); + + self.builder.info(&format!("Dist {} ({})", self.component, self.target)); + let _time = crate::util::timeit(self.builder); + let mut component_name = self.component.clone(); if self.is_preview { component_name.push_str("-preview"); } let distdir = crate::dist::distdir(self.builder); - let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller); cmd.arg("generate") .arg(format!("--product-name={}", self.product_name)) .arg("--rel-manifest-dir=rustlib") @@ -137,7 +141,6 @@ impl<'a> Tarball<'a> { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg(format!("--component-name={}", component_name)); self.builder.run(&mut cmd); - t!(std::fs::remove_dir_all(&self.temp_dir)); distdir.join(format!("{}-{}.tar.gz", self.pkgname, self.target)) -- cgit 1.4.1-3-g733a5 From 79f60fbd0410d1cfcbc4ddc8cba7bb11e1dd65ba Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 26 Nov 2020 22:54:35 +0100 Subject: bootstrap: convert rust-std to use Tarball --- src/bootstrap/dist.rs | 38 ++++++++------------------------------ src/bootstrap/tarball.rs | 10 ++++++++++ 2 files changed, 18 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 0e00649fc03..98f2b28918a 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -559,7 +559,7 @@ pub struct Std { } impl Step for Std { - type Output = PathBuf; + type Output = Option; const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -577,46 +577,24 @@ impl Step for Std { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> Option { let compiler = self.compiler; let target = self.target; - let name = pkgname(builder, "rust-std"); - let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)); if skip_host_target_lib(builder, compiler) { - return archive; + return None; } builder.ensure(compile::Std { compiler, target }); - let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple)); - let _ = fs::remove_dir_all(&image); + let mut tarball = Tarball::new(builder, "rust-std", &target.triple); + tarball.include_target_in_component_name(true); let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); let stamp = compile::libstd_stamp(builder, compiler_to_use, target); - copy_target_libs(builder, target, &image, &stamp); - - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=std-is-standing-at-the-ready.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg(format!("--component-name=rust-std-{}", target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo"); + copy_target_libs(builder, target, &tarball.image_dir(), &stamp); - builder - .info(&format!("Dist std stage{} ({} -> {})", compiler.stage, &compiler.host, target)); - let _time = timeit(builder); - builder.run(&mut cmd); - builder.remove_dir(&image); - archive + Some(tarball.generate()) } } @@ -1699,7 +1677,7 @@ impl Step for Extended { tarballs.extend(rustfmt_installer.clone()); tarballs.extend(llvm_tools_installer); tarballs.push(analysis_installer); - tarballs.push(std_installer); + tarballs.push(std_installer.expect("missing std")); if let Some(docs_installer) = docs_installer { tarballs.push(docs_installer); } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index f99b6f30192..bde437723bb 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -35,6 +35,7 @@ pub(crate) struct Tarball<'a> { overlay_dir: PathBuf, work_dir: PathBuf, + include_target_in_component_name: bool, is_preview: bool, } @@ -63,6 +64,7 @@ impl<'a> Tarball<'a> { overlay_dir, work_dir, + include_target_in_component_name: false, is_preview: false, } } @@ -75,6 +77,10 @@ impl<'a> Tarball<'a> { self.product_name = name.into(); } + pub(crate) fn include_target_in_component_name(&mut self, include: bool) { + self.include_target_in_component_name = include; + } + pub(crate) fn is_preview(&mut self, is: bool) { self.is_preview = is; } @@ -123,6 +129,10 @@ impl<'a> Tarball<'a> { if self.is_preview { component_name.push_str("-preview"); } + if self.include_target_in_component_name { + component_name.push('-'); + component_name.push_str(&self.target); + } let distdir = crate::dist::distdir(self.builder); cmd.arg("generate") -- cgit 1.4.1-3-g733a5 From c0cadc9eb72e6147647bd1b7995851e371167f24 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 12:46:02 +0100 Subject: bootstrap: convert rustc-dev to use Tarball --- src/bootstrap/dist.rs | 56 +++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 98f2b28918a..1e0f3b96958 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -605,7 +605,7 @@ pub struct RustcDev { } impl Step for RustcDev { - type Output = PathBuf; + type Output = Option; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -624,60 +624,36 @@ impl Step for RustcDev { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> Option { let compiler = self.compiler; let target = self.target; - - let name = pkgname(builder, "rustc-dev"); - let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)); if skip_host_target_lib(builder, compiler) { - return archive; + return None; } builder.ensure(compile::Rustc { compiler, target }); - let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple)); - let _ = fs::remove_dir_all(&image); + let tarball = Tarball::new(builder, "rustc-dev", &target.triple); let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); let stamp = compile::librustc_stamp(builder, compiler_to_use, target); - copy_target_libs(builder, target, &image, &stamp); + copy_target_libs(builder, target, tarball.image_dir(), &stamp); - // Copy compiler sources. - let dst_src = image.join("lib/rustlib/rustc-src/rust"); - t!(fs::create_dir_all(&dst_src)); - - let src_files = ["Cargo.lock"]; + let src_files = &["Cargo.lock"]; // This is the reduced set of paths which will become the rustc-dev component // (essentially the compiler crates and all of their path dependencies). - copy_src_dirs(builder, &builder.src, &["compiler"], &[], &dst_src); - for file in src_files.iter() { - builder.copy(&builder.src.join(file), &dst_src.join(file)); + copy_src_dirs( + builder, + &builder.src, + &["compiler"], + &[], + &tarball.image_dir().join("lib/rustlib/rustc-src/rust"), + ); + for file in src_files { + tarball.add_file(builder.src.join(file), "lib/rustlib/rustc-src/rust", 0o644); } - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-develop.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg(format!("--component-name=rustc-dev-{}", target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo"); - - builder.info(&format!( - "Dist rustc-dev stage{} ({} -> {})", - compiler.stage, &compiler.host, target - )); - let _time = timeit(builder); - builder.run(&mut cmd); - builder.remove_dir(&image); - archive + Some(tarball.generate()) } } -- cgit 1.4.1-3-g733a5 From c4aaff65f0cac8fe4375423f36d544440e47878b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 12:52:44 +0100 Subject: bootstrap: convert rust-analysis to use Tarball --- src/bootstrap/dist.rs | 48 ++++++++++++------------------------------------ 1 file changed, 12 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 1e0f3b96958..e342c0ddf63 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -664,7 +664,7 @@ pub struct Analysis { } impl Step for Analysis { - type Output = PathBuf; + type Output = Option; const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -687,52 +687,26 @@ impl Step for Analysis { } /// Creates a tarball of save-analysis metadata, if available. - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> Option { let compiler = self.compiler; let target = self.target; assert!(builder.config.extended); - let name = pkgname(builder, "rust-analysis"); - if compiler.host != builder.config.build { - return distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)); + return None; } builder.ensure(compile::Std { compiler, target }); - - let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple)); - let src = builder .stage_out(compiler, Mode::Std) .join(target.triple) .join(builder.cargo_dir()) - .join("deps"); - - let image_src = src.join("save-analysis"); - let dst = image.join("lib/rustlib").join(target.triple).join("analysis"); - t!(fs::create_dir_all(&dst)); - builder.info(&format!("image_src: {:?}, dst: {:?}", image_src, dst)); - builder.cp_r(&image_src, &dst); - - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=save-analysis-saved.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg(format!("--component-name=rust-analysis-{}", target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo"); + .join("deps") + .join("save-analysis"); - builder.info("Dist analysis"); - let _time = timeit(builder); - builder.run(&mut cmd); - builder.remove_dir(&image); - distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)) + let mut tarball = Tarball::new(builder, "rust-analysis", &target.triple); + tarball.include_target_in_component_name(true); + tarball.add_dir(src, format!("lib/rustlib/{}/analysis", target.triple)); + Some(tarball.generate()) } } @@ -1652,7 +1626,9 @@ impl Step for Extended { tarballs.extend(miri_installer.clone()); tarballs.extend(rustfmt_installer.clone()); tarballs.extend(llvm_tools_installer); - tarballs.push(analysis_installer); + if let Some(analysis_installer) = analysis_installer { + tarballs.push(analysis_installer); + } tarballs.push(std_installer.expect("missing std")); if let Some(docs_installer) = docs_installer { tarballs.push(docs_installer); -- cgit 1.4.1-3-g733a5 From 8a711a00a7f0cd5470255a65a711d47e46d46c14 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 13:11:11 +0100 Subject: bootstrap: convert cargo to use Tarball --- src/bootstrap/dist.rs | 71 ++++++++++-------------------------------------- src/bootstrap/tarball.rs | 30 +++++++++++++++++++- 2 files changed, 44 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e342c0ddf63..7e7c7edceff 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1015,72 +1015,31 @@ impl Step for Cargo { let compiler = self.compiler; let target = self.target; + let cargo = builder.ensure(tool::Cargo { compiler, target }); let src = builder.src.join("src/tools/cargo"); let etc = src.join("src/etc"); - let release_num = builder.release_num("cargo"); - let name = pkgname(builder, "cargo"); - let version = builder.cargo_info.version(builder, &release_num); - - let tmp = tmpdir(builder); - let image = tmp.join("cargo-image"); - drop(fs::remove_dir_all(&image)); - builder.create_dir(&image); // Prepare the image directory - builder.create_dir(&image.join("share/zsh/site-functions")); - builder.create_dir(&image.join("etc/bash_completion.d")); - let cargo = builder.ensure(tool::Cargo { compiler, target }); - builder.install(&cargo, &image.join("bin"), 0o755); + let mut tarball = Tarball::new(builder, "cargo", &target.triple); + tarball.set_overlay(OverlayKind::Cargo); + + tarball.add_file(&cargo, "bin", 0o755); + tarball.add_file(src.join("README.md"), "share/doc/cargo", 0o644); + tarball.add_file(src.join("LICENSE-MIT"), "share/doc/cargo", 0o644); + tarball.add_file(src.join("LICENSE-APACHE"), "share/doc/cargo", 0o644); + tarball.add_file(src.join("LICENSE-THIRD-PARTY"), "share/doc/cargo", 0o644); + tarball.add_file(etc.join("_cargo"), "share/zsh/site-functions", 0o644); + tarball.add_renamed_file(etc.join("cargo.bashcomp.sh"), "etc/bash_completion.d", "cargo"); + tarball.add_dir(etc.join("man"), "share/man/man1"); + for dirent in fs::read_dir(cargo.parent().unwrap()).expect("read_dir") { let dirent = dirent.expect("read dir entry"); if dirent.file_name().to_str().expect("utf8").starts_with("cargo-credential-") { - builder.install(&dirent.path(), &image.join("libexec"), 0o755); + tarball.add_file(&dirent.path(), "libexec", 0o755); } } - for man in t!(etc.join("man").read_dir()) { - let man = t!(man); - builder.install(&man.path(), &image.join("share/man/man1"), 0o644); - } - builder.install(&etc.join("_cargo"), &image.join("share/zsh/site-functions"), 0o644); - builder.copy(&etc.join("cargo.bashcomp.sh"), &image.join("etc/bash_completion.d/cargo")); - let doc = image.join("share/doc/cargo"); - builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - builder.install(&src.join("LICENSE-THIRD-PARTY"), &doc, 0o644); - - // Prepare the overlay - let overlay = tmp.join("cargo-overlay"); - drop(fs::remove_dir_all(&overlay)); - builder.create_dir(&overlay); - builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644); - builder.install(&src.join("LICENSE-THIRD-PARTY"), &overlay, 0o644); - builder.create(&overlay.join("version"), &version); - - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-roll.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--component-name=cargo") - .arg("--legacy-manifest-dirs=rustlib,cargo"); - builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target)); - let _time = timeit(builder); - builder.run(&mut cmd); - distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)) + tarball.generate() } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index bde437723bb..5340995ce96 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -8,6 +8,7 @@ use crate::builder::Builder; pub(crate) enum OverlayKind { Rust, LLVM, + Cargo, } impl OverlayKind { @@ -17,6 +18,22 @@ impl OverlayKind { OverlayKind::LLVM => { &["src/llvm-project/llvm/LICENSE.TXT", "src/llvm-project/llvm/README.txt"] } + OverlayKind::Cargo => &[ + "src/tools/cargo/README.md", + "src/tools/cargo/LICENSE-MIT", + "src/tools/cargo/LICENSE-APACHE", + "src/tools/cargo/LICENSE-THIRD-PARTY", + ], + } + } + + fn version(&self, builder: &Builder<'_>) -> String { + match self { + OverlayKind::Rust => builder.rust_version(), + OverlayKind::LLVM => builder.rust_version(), + OverlayKind::Cargo => { + builder.cargo_info.version(builder, &builder.release_num("cargo")) + } } } } @@ -103,6 +120,17 @@ impl<'a> Tarball<'a> { self.builder.install(src.as_ref(), &destdir, perms); } + pub(crate) fn add_renamed_file( + &self, + src: impl AsRef, + destdir: impl AsRef, + new_name: &str, + ) { + let destdir = self.image_dir.join(destdir.as_ref()); + t!(std::fs::create_dir_all(&destdir)); + self.builder.copy(src.as_ref(), &destdir.join(new_name)); + } + pub(crate) fn add_dir(&self, src: impl AsRef, dest: impl AsRef) { let dest = self.image_dir.join(dest.as_ref()); @@ -112,7 +140,7 @@ impl<'a> Tarball<'a> { pub(crate) fn generate(self) -> PathBuf { t!(std::fs::create_dir_all(&self.overlay_dir)); - self.builder.create(&self.overlay_dir.join("version"), &self.builder.rust_version()); + self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder)); if let Some(sha) = self.builder.rust_sha() { self.builder.create(&self.overlay_dir.join("git-commit-hash"), &sha); } -- cgit 1.4.1-3-g733a5 From 521b884913b603ddbdcc1af97b772e40d4ea5f84 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 17:43:03 +0100 Subject: bootstrap: convert clippy to use Tarball --- src/bootstrap/dist.rs | 58 +++++++++--------------------------------------- src/bootstrap/tarball.rs | 9 ++++++++ 2 files changed, 19 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 7e7c7edceff..47ad8fae26b 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1256,16 +1256,6 @@ impl Step for Clippy { let target = self.target; assert!(builder.config.extended); - let src = builder.src.join("src/tools/clippy"); - let release_num = builder.release_num("clippy"); - let name = pkgname(builder, "clippy"); - let version = builder.clippy_info.version(builder, &release_num); - - let tmp = tmpdir(builder); - let image = tmp.join("clippy-image"); - drop(fs::remove_dir_all(&image)); - builder.create_dir(&image); - // Prepare the image directory // We expect clippy to build, because we've exited this step above if tool // state for clippy isn't testing. @@ -1275,45 +1265,17 @@ impl Step for Clippy { let cargoclippy = builder .ensure(tool::CargoClippy { compiler, target, extra_features: Vec::new() }) .expect("clippy expected to build - essential tool"); + let src = builder.src.join("src/tools/clippy"); - builder.install(&clippy, &image.join("bin"), 0o755); - builder.install(&cargoclippy, &image.join("bin"), 0o755); - let doc = image.join("share/doc/clippy"); - builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - - // Prepare the overlay - let overlay = tmp.join("clippy-overlay"); - drop(fs::remove_dir_all(&overlay)); - t!(fs::create_dir_all(&overlay)); - builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - builder.create(&overlay.join("version"), &version); - - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=clippy-ready-to-serve.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=clippy-preview"); - - builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target)); - let _time = timeit(builder); - builder.run(&mut cmd); - distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)) + let mut tarball = Tarball::new(builder, "clippy", &target.triple); + tarball.set_overlay(OverlayKind::Clippy); + tarball.is_preview(true); + tarball.add_file(clippy, "bin", 0o755); + tarball.add_file(cargoclippy, "bin", 0o755); + tarball.add_file(src.join("README.md"), "share/doc/clippy", 0o644); + tarball.add_file(src.join("LICENSE-APACHE"), "share/doc/clippy", 0o644); + tarball.add_file(src.join("LICENSE-MIT"), "share/doc/clippy", 0o644); + tarball.generate() } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 5340995ce96..c0c84222e7d 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -9,6 +9,7 @@ pub(crate) enum OverlayKind { Rust, LLVM, Cargo, + Clippy, } impl OverlayKind { @@ -24,6 +25,11 @@ impl OverlayKind { "src/tools/cargo/LICENSE-APACHE", "src/tools/cargo/LICENSE-THIRD-PARTY", ], + OverlayKind::Clippy => &[ + "src/tools/clippy/README.md", + "src/tools/clippy/LICENSE-APACHE", + "src/tools/clippy/LICENSE-MIT", + ], } } @@ -34,6 +40,9 @@ impl OverlayKind { OverlayKind::Cargo => { builder.cargo_info.version(builder, &builder.release_num("cargo")) } + OverlayKind::Clippy => { + builder.clippy_info.version(builder, &builder.release_num("clippy")) + } } } } -- cgit 1.4.1-3-g733a5 From 32afb3c436eb3909a636fd4fce20a1ba03cc88ec Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 17:56:22 +0100 Subject: bootstrap: simplify including licenses and readmes to tarballs --- src/bootstrap/dist.rs | 10 ++-------- src/bootstrap/tarball.rs | 10 ++++++++-- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 47ad8fae26b..aa4d518d014 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1024,13 +1024,10 @@ impl Step for Cargo { tarball.set_overlay(OverlayKind::Cargo); tarball.add_file(&cargo, "bin", 0o755); - tarball.add_file(src.join("README.md"), "share/doc/cargo", 0o644); - tarball.add_file(src.join("LICENSE-MIT"), "share/doc/cargo", 0o644); - tarball.add_file(src.join("LICENSE-APACHE"), "share/doc/cargo", 0o644); - tarball.add_file(src.join("LICENSE-THIRD-PARTY"), "share/doc/cargo", 0o644); tarball.add_file(etc.join("_cargo"), "share/zsh/site-functions", 0o644); tarball.add_renamed_file(etc.join("cargo.bashcomp.sh"), "etc/bash_completion.d", "cargo"); tarball.add_dir(etc.join("man"), "share/man/man1"); + tarball.add_legal_and_readme_to("share/doc/cargo"); for dirent in fs::read_dir(cargo.parent().unwrap()).expect("read_dir") { let dirent = dirent.expect("read dir entry"); @@ -1265,16 +1262,13 @@ impl Step for Clippy { let cargoclippy = builder .ensure(tool::CargoClippy { compiler, target, extra_features: Vec::new() }) .expect("clippy expected to build - essential tool"); - let src = builder.src.join("src/tools/clippy"); let mut tarball = Tarball::new(builder, "clippy", &target.triple); tarball.set_overlay(OverlayKind::Clippy); tarball.is_preview(true); tarball.add_file(clippy, "bin", 0o755); tarball.add_file(cargoclippy, "bin", 0o755); - tarball.add_file(src.join("README.md"), "share/doc/clippy", 0o644); - tarball.add_file(src.join("LICENSE-APACHE"), "share/doc/clippy", 0o644); - tarball.add_file(src.join("LICENSE-MIT"), "share/doc/clippy", 0o644); + tarball.add_legal_and_readme_to("share/doc/clippy"); tarball.generate() } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index c0c84222e7d..2c8f69e94b3 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -13,7 +13,7 @@ pub(crate) enum OverlayKind { } impl OverlayKind { - fn included_files(&self) -> &[&str] { + fn legal_and_readme(&self) -> &[&str] { match self { OverlayKind::Rust => &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"], OverlayKind::LLVM => { @@ -140,6 +140,12 @@ impl<'a> Tarball<'a> { self.builder.copy(src.as_ref(), &destdir.join(new_name)); } + pub(crate) fn add_legal_and_readme_to(&self, destdir: impl AsRef) { + for file in self.overlay.legal_and_readme() { + self.add_file(self.builder.src.join(file), destdir.as_ref(), 0o644); + } + } + pub(crate) fn add_dir(&self, src: impl AsRef, dest: impl AsRef) { let dest = self.image_dir.join(dest.as_ref()); @@ -153,7 +159,7 @@ impl<'a> Tarball<'a> { if let Some(sha) = self.builder.rust_sha() { self.builder.create(&self.overlay_dir.join("git-commit-hash"), &sha); } - for file in self.overlay.included_files() { + for file in self.overlay.legal_and_readme() { self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644); } -- cgit 1.4.1-3-g733a5 From 2073ea5c07ea5a83d17fb7d08f67cc55e1010aaf Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 18:03:41 +0100 Subject: bootstrap: convert miri to use Tarball --- src/bootstrap/dist.rs | 58 ++++++------------------------------------------ src/bootstrap/tarball.rs | 7 ++++++ 2 files changed, 14 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index aa4d518d014..a884e7ee2cc 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1303,19 +1303,6 @@ impl Step for Miri { let target = self.target; assert!(builder.config.extended); - let src = builder.src.join("src/tools/miri"); - let release_num = builder.release_num("miri"); - let name = pkgname(builder, "miri"); - let version = builder.miri_info.version(builder, &release_num); - - let tmp = tmpdir(builder); - let image = tmp.join("miri-image"); - drop(fs::remove_dir_all(&image)); - builder.create_dir(&image); - - // Prepare the image directory - // We expect miri to build, because we've exited this step above if tool - // state for miri isn't testing. let miri = builder .ensure(tool::Miri { compiler, target, extra_features: Vec::new() }) .or_else(|| { @@ -1329,44 +1316,13 @@ impl Step for Miri { None })?; - builder.install(&miri, &image.join("bin"), 0o755); - builder.install(&cargomiri, &image.join("bin"), 0o755); - let doc = image.join("share/doc/miri"); - builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - - // Prepare the overlay - let overlay = tmp.join("miri-overlay"); - drop(fs::remove_dir_all(&overlay)); - t!(fs::create_dir_all(&overlay)); - builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - builder.create(&overlay.join("version"), &version); - - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=miri-ready-to-serve.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=miri-preview"); - - builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target)); - let _time = timeit(builder); - builder.run(&mut cmd); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) + let mut tarball = Tarball::new(builder, "miri", &target.triple); + tarball.set_overlay(OverlayKind::Miri); + tarball.is_preview(true); + tarball.add_file(miri, "bin", 0o755); + tarball.add_file(cargomiri, "bin", 0o755); + tarball.add_legal_and_readme_to("share/doc/miri"); + Some(tarball.generate()) } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 2c8f69e94b3..0e705a93902 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -10,6 +10,7 @@ pub(crate) enum OverlayKind { LLVM, Cargo, Clippy, + Miri, } impl OverlayKind { @@ -30,6 +31,11 @@ impl OverlayKind { "src/tools/clippy/LICENSE-APACHE", "src/tools/clippy/LICENSE-MIT", ], + OverlayKind::Miri => &[ + "src/tools/miri/README.md", + "src/tools/miri/LICENSE-APACHE", + "src/tools/miri/LICENSE-MIT", + ], } } @@ -43,6 +49,7 @@ impl OverlayKind { OverlayKind::Clippy => { builder.clippy_info.version(builder, &builder.release_num("clippy")) } + OverlayKind::Miri => builder.miri_info.version(builder, &builder.release_num("miri")), } } } -- cgit 1.4.1-3-g733a5 From 2b54f0de3794e5fc38f0d4eb1364cb67a041aa4f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 18:07:58 +0100 Subject: bootstrap: convert rustfmt to use Tarball --- src/bootstrap/dist.rs | 56 ++++++------------------------------------------ src/bootstrap/tarball.rs | 9 ++++++++ 2 files changed, 16 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index a884e7ee2cc..35e0aeba146 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1355,17 +1355,6 @@ impl Step for Rustfmt { let compiler = self.compiler; let target = self.target; - let src = builder.src.join("src/tools/rustfmt"); - let release_num = builder.release_num("rustfmt"); - let name = pkgname(builder, "rustfmt"); - let version = builder.rustfmt_info.version(builder, &release_num); - - let tmp = tmpdir(builder); - let image = tmp.join("rustfmt-image"); - drop(fs::remove_dir_all(&image)); - builder.create_dir(&image); - - // Prepare the image directory let rustfmt = builder .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() }) .or_else(|| { @@ -1379,44 +1368,13 @@ impl Step for Rustfmt { None })?; - builder.install(&rustfmt, &image.join("bin"), 0o755); - builder.install(&cargofmt, &image.join("bin"), 0o755); - let doc = image.join("share/doc/rustfmt"); - builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - - // Prepare the overlay - let overlay = tmp.join("rustfmt-overlay"); - drop(fs::remove_dir_all(&overlay)); - builder.create_dir(&overlay); - builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644); - builder.create(&overlay.join("version"), &version); - - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=rustfmt-ready-to-fmt.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=rustfmt-preview"); - - builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target)); - let _time = timeit(builder); - builder.run(&mut cmd); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) + let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); + tarball.set_overlay(OverlayKind::Rustfmt); + tarball.is_preview(true); + tarball.add_file(rustfmt, "bin", 0o755); + tarball.add_file(cargofmt, "bin", 0o755); + tarball.add_legal_and_readme_to("share/doc/rustfmt"); + Some(tarball.generate()) } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 0e705a93902..8543f9d4a38 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -11,6 +11,7 @@ pub(crate) enum OverlayKind { Cargo, Clippy, Miri, + Rustfmt, } impl OverlayKind { @@ -36,6 +37,11 @@ impl OverlayKind { "src/tools/miri/LICENSE-APACHE", "src/tools/miri/LICENSE-MIT", ], + OverlayKind::Rustfmt => &[ + "src/tools/rustfmt/README.md", + "src/tools/rustfmt/LICENSE-APACHE", + "src/tools/rustfmt/LICENSE-MIT", + ], } } @@ -50,6 +56,9 @@ impl OverlayKind { builder.clippy_info.version(builder, &builder.release_num("clippy")) } OverlayKind::Miri => builder.miri_info.version(builder, &builder.release_num("miri")), + OverlayKind::Rustfmt => { + builder.rustfmt_info.version(builder, &builder.release_num("rustfmt")) + } } } } -- cgit 1.4.1-3-g733a5 From cfb23e845e56718fa33b7b76d30e2edec992d659 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 18:12:17 +0100 Subject: bootstrap: convert rls to use Tarball --- src/bootstrap/dist.rs | 56 ++++++------------------------------------------ src/bootstrap/tarball.rs | 7 ++++++ 2 files changed, 13 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 35e0aeba146..c31a938c746 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1070,19 +1070,6 @@ impl Step for Rls { let target = self.target; assert!(builder.config.extended); - let src = builder.src.join("src/tools/rls"); - let release_num = builder.release_num("rls"); - let name = pkgname(builder, "rls"); - let version = builder.rls_info.version(builder, &release_num); - - let tmp = tmpdir(builder); - let image = tmp.join("rls-image"); - drop(fs::remove_dir_all(&image)); - t!(fs::create_dir_all(&image)); - - // Prepare the image directory - // We expect RLS to build, because we've exited this step above if tool - // state for RLS isn't testing. let rls = builder .ensure(tool::Rls { compiler, target, extra_features: Vec::new() }) .or_else(|| { @@ -1090,43 +1077,12 @@ impl Step for Rls { None })?; - builder.install(&rls, &image.join("bin"), 0o755); - let doc = image.join("share/doc/rls"); - builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - - // Prepare the overlay - let overlay = tmp.join("rls-overlay"); - drop(fs::remove_dir_all(&overlay)); - t!(fs::create_dir_all(&overlay)); - builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644); - builder.create(&overlay.join("version"), &version); - - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=RLS-ready-to-serve.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=rls-preview"); - - builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target.triple)); - let _time = timeit(builder); - builder.run(&mut cmd); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) + let mut tarball = Tarball::new(builder, "rls", &target.triple); + tarball.set_overlay(OverlayKind::RLS); + tarball.is_preview(true); + tarball.add_file(rls, "bin", 0o755); + tarball.add_legal_and_readme_to("share/doc/rls"); + Some(tarball.generate()) } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 8543f9d4a38..efc85a1445a 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -12,6 +12,7 @@ pub(crate) enum OverlayKind { Clippy, Miri, Rustfmt, + RLS, } impl OverlayKind { @@ -42,6 +43,11 @@ impl OverlayKind { "src/tools/rustfmt/LICENSE-APACHE", "src/tools/rustfmt/LICENSE-MIT", ], + OverlayKind::RLS => &[ + "src/tools/rls/README.md", + "src/tools/rls/LICENSE-APACHE", + "src/tools/rls/LICENSE-MIT", + ], } } @@ -59,6 +65,7 @@ impl OverlayKind { OverlayKind::Rustfmt => { builder.rustfmt_info.version(builder, &builder.release_num("rustfmt")) } + OverlayKind::RLS => builder.rls_info.version(builder, &builder.release_num("rls")), } } } -- cgit 1.4.1-3-g733a5 From 2e0a16cf0d67f61d85ff7631846e9c3c6e20c85a Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 27 Nov 2020 18:20:23 +0100 Subject: bootstrap: convert rust-analyzer to use Tarball --- src/bootstrap/dist.rs | 56 ++++++------------------------------------------ src/bootstrap/tarball.rs | 9 ++++++++ 2 files changed, 15 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c31a938c746..b1a61500a70 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1122,60 +1122,16 @@ impl Step for RustAnalyzer { return None; } - let src = builder.src.join("src/tools/rust-analyzer"); - let release_num = builder.release_num("rust-analyzer/crates/rust-analyzer"); - let name = pkgname(builder, "rust-analyzer"); - let version = builder.rust_analyzer_info.version(builder, &release_num); - - let tmp = tmpdir(builder); - let image = tmp.join("rust-analyzer-image"); - drop(fs::remove_dir_all(&image)); - builder.create_dir(&image); - - // Prepare the image directory - // We expect rust-analyer to always build, as it doesn't depend on rustc internals - // and doesn't have associated toolstate. let rust_analyzer = builder .ensure(tool::RustAnalyzer { compiler, target, extra_features: Vec::new() }) .expect("rust-analyzer always builds"); - builder.install(&rust_analyzer, &image.join("bin"), 0o755); - let doc = image.join("share/doc/rust-analyzer"); - builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - - // Prepare the overlay - let overlay = tmp.join("rust-analyzer-overlay"); - drop(fs::remove_dir_all(&overlay)); - t!(fs::create_dir_all(&overlay)); - builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); - builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); - builder.create(&overlay.join("version"), &version); - - // Generate the installer tarball - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=rust-analyzer-ready-to-serve.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=rust-analyzer-preview"); - - builder.info(&format!("Dist rust-analyzer stage{} ({})", compiler.stage, target)); - let _time = timeit(builder); - builder.run(&mut cmd); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))) + let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple); + tarball.set_overlay(OverlayKind::RustAnalyzer); + tarball.is_preview(true); + tarball.add_file(rust_analyzer, "bin", 0o755); + tarball.add_legal_and_readme_to("share/doc/rust-analyzer"); + Some(tarball.generate()) } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index efc85a1445a..8a23d36346e 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -13,6 +13,7 @@ pub(crate) enum OverlayKind { Miri, Rustfmt, RLS, + RustAnalyzer, } impl OverlayKind { @@ -48,6 +49,11 @@ impl OverlayKind { "src/tools/rls/LICENSE-APACHE", "src/tools/rls/LICENSE-MIT", ], + OverlayKind::RustAnalyzer => &[ + "src/tools/rust-analyzer/README.md", + "src/tools/rust-analyzer/LICENSE-APACHE", + "src/tools/rust-analyzer/LICENSE-MIT", + ], } } @@ -66,6 +72,9 @@ impl OverlayKind { builder.rustfmt_info.version(builder, &builder.release_num("rustfmt")) } OverlayKind::RLS => builder.rls_info.version(builder, &builder.release_num("rls")), + OverlayKind::RustAnalyzer => builder + .rust_analyzer_info + .version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")), } } } -- cgit 1.4.1-3-g733a5 From 1906c42962b1f2bef084474e09b211e48ed2bda7 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 30 Nov 2020 13:25:34 +0100 Subject: bootstrap: convert rust-src to use Tarball --- src/bootstrap/dist.rs | 30 +++--------------------------- src/bootstrap/tarball.rs | 31 +++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index b1a61500a70..c89b378f820 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -814,9 +814,7 @@ impl Step for Src { /// Creates the `rust-src` installer component fn run(self, builder: &Builder<'_>) -> PathBuf { - let name = pkgname(builder, "rust-src"); - let image = tmpdir(builder).join(format!("{}-image", name)); - let _ = fs::remove_dir_all(&image); + let tarball = Tarball::new_targetless(builder, "rust-src"); // A lot of tools expect the rust-src component to be entirely in this directory, so if you // change that (e.g. by adding another directory `lib/rustlib/src/foo` or @@ -825,8 +823,7 @@ impl Step for Src { // // NOTE: if you update the paths here, you also should update the "virtual" path // translation code in `imported_source_files` in `src/librustc_metadata/rmeta/decoder.rs` - let dst_src = image.join("lib/rustlib/src/rust"); - t!(fs::create_dir_all(&dst_src)); + let dst_src = tarball.image_dir().join("lib/rustlib/src/rust"); let src_files = ["Cargo.lock"]; // This is the reduced set of paths which will become the rust-src component @@ -846,28 +843,7 @@ impl Step for Src { builder.copy(&builder.src.join(file), &dst_src.join(file)); } - // Create source tarball in rust-installer format - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Awesome-Source.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}", name)) - .arg("--component-name=rust-src") - .arg("--legacy-manifest-dirs=rustlib,cargo"); - - builder.info("Dist src"); - let _time = timeit(builder); - builder.run(&mut cmd); - - builder.remove_dir(&image); - distdir(builder).join(&format!("{}.tar.gz", name)) + tarball.generate() } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 8a23d36346e..27769cab5af 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -84,7 +84,7 @@ pub(crate) struct Tarball<'a> { pkgname: String, component: String, - target: String, + target: Option, product_name: String, overlay: OverlayKind, @@ -99,6 +99,14 @@ pub(crate) struct Tarball<'a> { impl<'a> Tarball<'a> { pub(crate) fn new(builder: &'a Builder<'a>, component: &str, target: &str) -> Self { + Self::new_inner(builder, component, Some(target.into())) + } + + pub(crate) fn new_targetless(builder: &'a Builder<'a>, component: &str) -> Self { + Self::new_inner(builder, component, None) + } + + fn new_inner(builder: &'a Builder<'a>, component: &str, target: Option) -> Self { let pkgname = crate::dist::pkgname(builder, component); let temp_dir = builder.out.join("tmp").join("tarball").join(component); @@ -113,7 +121,7 @@ impl<'a> Tarball<'a> { pkgname, component: component.into(), - target: target.into(), + target, product_name: "Rust".into(), overlay: OverlayKind::Rust, @@ -197,7 +205,14 @@ impl<'a> Tarball<'a> { let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller); - self.builder.info(&format!("Dist {} ({})", self.component, self.target)); + let package_name = if let Some(target) = &self.target { + self.builder.info(&format!("Dist {} ({})", self.component, target)); + format!("{}-{}", self.pkgname, target) + } else { + self.builder.info(&format!("Dist {}", self.component)); + self.pkgname.clone() + }; + let _time = crate::util::timeit(self.builder); let mut component_name = self.component.clone(); @@ -206,7 +221,11 @@ impl<'a> Tarball<'a> { } if self.include_target_in_component_name { component_name.push('-'); - component_name.push_str(&self.target); + component_name.push_str( + &self + .target + .expect("include_target_in_component_name used in a targetless tarball"), + ); } let distdir = crate::dist::distdir(self.builder); @@ -222,12 +241,12 @@ impl<'a> Tarball<'a> { .arg(&distdir) .arg("--non-installed-overlay") .arg(self.overlay_dir) - .arg(format!("--package-name={}-{}", self.pkgname, self.target)) + .arg(format!("--package-name={}", package_name)) .arg("--legacy-manifest-dirs=rustlib,cargo") .arg(format!("--component-name={}", component_name)); self.builder.run(&mut cmd); t!(std::fs::remove_dir_all(&self.temp_dir)); - distdir.join(format!("{}-{}.tar.gz", self.pkgname, self.target)) + distdir.join(format!("{}.tar.gz", package_name)) } } -- cgit 1.4.1-3-g733a5 From 48924ab7088802123a64af77e5201ddfc1f1a733 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 2 Dec 2020 13:29:45 +0100 Subject: bootstrap: convert rust to use Tarball --- src/bootstrap/dist.rs | 43 +++--------------------- src/bootstrap/tarball.rs | 85 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 65 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c89b378f820..a68f1398817 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1314,21 +1314,7 @@ impl Step for Extended { let std_installer = builder.ensure(Std { compiler: builder.compiler(stage, target), target }); - let tmp = tmpdir(builder); - let overlay = tmp.join("extended-overlay"); let etc = builder.src.join("src/etc/installer"); - let work = tmp.join("work"); - - let _ = fs::remove_dir_all(&overlay); - builder.install(&builder.src.join("COPYRIGHT"), &overlay, 0o644); - builder.install(&builder.src.join("LICENSE-APACHE"), &overlay, 0o644); - builder.install(&builder.src.join("LICENSE-MIT"), &overlay, 0o644); - let version = builder.rust_version(); - builder.create(&overlay.join("version"), &version); - if let Some(sha) = builder.rust_sha() { - builder.create(&overlay.join("git-commit-hash"), &sha); - } - builder.install(&etc.join("README.md"), &overlay, 0o644); // When rust-std package split from rustc, we needed to ensure that during // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering @@ -1353,31 +1339,12 @@ impl Step for Extended { if target.contains("pc-windows-gnu") { tarballs.push(mingw_installer.unwrap()); } - let mut input_tarballs = tarballs[0].as_os_str().to_owned(); - for tarball in &tarballs[1..] { - input_tarballs.push(","); - input_tarballs.push(tarball); - } - builder.info("building combined installer"); - let mut cmd = rust_installer(builder); - cmd.arg("combine") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-roll.") - .arg("--work-dir") - .arg(&work) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", pkgname(builder, "rust"), target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--input-tarballs") - .arg(input_tarballs) - .arg("--non-installed-overlay") - .arg(&overlay); - let time = timeit(&builder); - builder.run(&mut cmd); - drop(time); + let mut tarball = Tarball::new(builder, "rust", &target.triple); + let work = tarball.persist_work_dir(); + tarball.combine(&tarballs); + + let tmp = tmpdir(builder).join("combined-tarball"); let mut license = String::new(); license += &builder.read(&builder.src.join("COPYRIGHT")); diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 27769cab5af..b4146450596 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -1,4 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::{ + path::{Path, PathBuf}, + process::Command, +}; use build_helper::t; @@ -95,6 +98,7 @@ pub(crate) struct Tarball<'a> { include_target_in_component_name: bool, is_preview: bool, + delete_temp_dir: bool, } impl<'a> Tarball<'a> { @@ -132,6 +136,7 @@ impl<'a> Tarball<'a> { include_target_in_component_name: false, is_preview: false, + delete_temp_dir: true, } } @@ -193,7 +198,53 @@ impl<'a> Tarball<'a> { self.builder.cp_r(src.as_ref(), &dest); } + pub(crate) fn persist_work_dir(&mut self) -> PathBuf { + self.delete_temp_dir = false; + self.work_dir.clone() + } + pub(crate) fn generate(self) -> PathBuf { + let mut component_name = self.component.clone(); + if self.is_preview { + component_name.push_str("-preview"); + } + if self.include_target_in_component_name { + component_name.push('-'); + component_name.push_str( + &self + .target + .as_ref() + .expect("include_target_in_component_name used in a targetless tarball"), + ); + } + + self.run(|this, cmd| { + cmd.arg("generate") + .arg("--image-dir") + .arg(&this.image_dir) + .arg("--non-installed-overlay") + .arg(&this.overlay_dir) + .arg(format!("--component-name={}", &component_name)); + }) + } + + pub(crate) fn combine(self, tarballs: &[PathBuf]) { + let mut input_tarballs = tarballs[0].as_os_str().to_os_string(); + for tarball in &tarballs[1..] { + input_tarballs.push(","); + input_tarballs.push(tarball); + } + + self.run(|this, cmd| { + cmd.arg("combine") + .arg("--input-tarballs") + .arg(input_tarballs) + .arg("--non-installed-overlay") + .arg(&this.overlay_dir); + }); + } + + fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> PathBuf { t!(std::fs::create_dir_all(&self.overlay_dir)); self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder)); if let Some(sha) = self.builder.rust_sha() { @@ -215,37 +266,21 @@ impl<'a> Tarball<'a> { let _time = crate::util::timeit(self.builder); - let mut component_name = self.component.clone(); - if self.is_preview { - component_name.push_str("-preview"); - } - if self.include_target_in_component_name { - component_name.push('-'); - component_name.push_str( - &self - .target - .expect("include_target_in_component_name used in a targetless tarball"), - ); - } - let distdir = crate::dist::distdir(self.builder); - cmd.arg("generate") + build_cli(&self, &mut cmd); + cmd.arg("--rel-manifest-dir=rustlib") + .arg("--legacy-manifest-dirs=rustlib,cargo") .arg(format!("--product-name={}", self.product_name)) - .arg("--rel-manifest-dir=rustlib") .arg(format!("--success-message={} installed.", self.component)) - .arg("--image-dir") - .arg(self.image_dir) + .arg(format!("--package-name={}", package_name)) .arg("--work-dir") .arg(self.work_dir) .arg("--output-dir") - .arg(&distdir) - .arg("--non-installed-overlay") - .arg(self.overlay_dir) - .arg(format!("--package-name={}", package_name)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg(format!("--component-name={}", component_name)); + .arg(&distdir); self.builder.run(&mut cmd); - t!(std::fs::remove_dir_all(&self.temp_dir)); + if self.delete_temp_dir { + t!(std::fs::remove_dir_all(&self.temp_dir)); + } distdir.join(format!("{}.tar.gz", package_name)) } -- cgit 1.4.1-3-g733a5 From f18335edb2917a310b69a522e6f3fde30af3d419 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 7 Dec 2020 11:49:22 +0100 Subject: bootstrap: convert rustc-src to use Tarball --- src/bootstrap/dist.rs | 34 ++-------------------- src/bootstrap/tarball.rs | 73 ++++++++++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index a68f1398817..258483bf134 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -37,10 +37,6 @@ pub fn tmpdir(builder: &Builder<'_>) -> PathBuf { builder.out.join("tmp/dist") } -fn rust_installer(builder: &Builder<'_>) -> Command { - builder.tool_cmd(Tool::RustInstaller) -} - fn missing_tool(tool_name: &str, skip: bool) { if skip { println!("Unable to build {}, skipping dist", tool_name) @@ -867,11 +863,8 @@ impl Step for PlainSourceTarball { /// Creates the plain source tarball fn run(self, builder: &Builder<'_>) -> PathBuf { - // Make sure that the root folder of tarball has the correct name - let plain_name = format!("{}-src", pkgname(builder, "rustc")); - let plain_dst_src = tmpdir(builder).join(&plain_name); - let _ = fs::remove_dir_all(&plain_dst_src); - t!(fs::create_dir_all(&plain_dst_src)); + let tarball = Tarball::new(builder, "rustc", "src"); + let plain_dst_src = tarball.image_dir(); // This is the set of root paths which will become part of the source package let src_files = [ @@ -914,28 +907,7 @@ impl Step for PlainSourceTarball { builder.run(&mut cmd); } - // Create plain source tarball - let plain_name = format!("rustc-{}-src", builder.rust_package_vers()); - let mut tarball = distdir(builder).join(&format!("{}.tar.gz", plain_name)); - tarball.set_extension(""); // strip .gz - tarball.set_extension(""); // strip .tar - if let Some(dir) = tarball.parent() { - builder.create_dir(&dir); - } - builder.info("running installer"); - let mut cmd = rust_installer(builder); - cmd.arg("tarball") - .arg("--input") - .arg(&plain_name) - .arg("--output") - .arg(&tarball) - .arg("--work-dir=.") - .current_dir(tmpdir(builder)); - - builder.info("Create plain source tarball"); - let _time = timeit(builder); - builder.run(&mut cmd); - distdir(builder).join(&format!("{}.tar.gz", plain_name)) + tarball.bare() } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index b4146450596..5d73a655427 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -94,7 +94,6 @@ pub(crate) struct Tarball<'a> { temp_dir: PathBuf, image_dir: PathBuf, overlay_dir: PathBuf, - work_dir: PathBuf, include_target_in_component_name: bool, is_preview: bool, @@ -113,12 +112,14 @@ impl<'a> Tarball<'a> { fn new_inner(builder: &'a Builder<'a>, component: &str, target: Option) -> Self { let pkgname = crate::dist::pkgname(builder, component); - let temp_dir = builder.out.join("tmp").join("tarball").join(component); + let mut temp_dir = builder.out.join("tmp").join("tarball"); + if let Some(target) = &target { + temp_dir = temp_dir.join(target); + } let _ = std::fs::remove_dir_all(&temp_dir); let image_dir = temp_dir.join("image"); let overlay_dir = temp_dir.join("overlay"); - let work_dir = temp_dir.join("work"); Self { builder, @@ -132,7 +133,6 @@ impl<'a> Tarball<'a> { temp_dir, image_dir, overlay_dir, - work_dir, include_target_in_component_name: false, is_preview: false, @@ -200,7 +200,7 @@ impl<'a> Tarball<'a> { pub(crate) fn persist_work_dir(&mut self) -> PathBuf { self.delete_temp_dir = false; - self.work_dir.clone() + self.temp_dir.clone() } pub(crate) fn generate(self) -> PathBuf { @@ -222,9 +222,8 @@ impl<'a> Tarball<'a> { cmd.arg("generate") .arg("--image-dir") .arg(&this.image_dir) - .arg("--non-installed-overlay") - .arg(&this.overlay_dir) .arg(format!("--component-name={}", &component_name)); + this.non_bare_args(cmd); }) } @@ -236,14 +235,41 @@ impl<'a> Tarball<'a> { } self.run(|this, cmd| { - cmd.arg("combine") - .arg("--input-tarballs") - .arg(input_tarballs) - .arg("--non-installed-overlay") - .arg(&this.overlay_dir); + cmd.arg("combine").arg("--input-tarballs").arg(input_tarballs); + this.non_bare_args(cmd); }); } + pub(crate) fn bare(self) -> PathBuf { + self.run(|this, cmd| { + cmd.arg("tarball") + .arg("--input") + .arg(&this.image_dir) + .arg("--output") + .arg(crate::dist::distdir(this.builder).join(this.package_name())); + }) + } + + fn package_name(&self) -> String { + if let Some(target) = &self.target { + format!("{}-{}", self.pkgname, target) + } else { + self.pkgname.clone() + } + } + + fn non_bare_args(&self, cmd: &mut Command) { + cmd.arg("--rel-manifest-dir=rustlib") + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg(format!("--product-name={}", self.product_name)) + .arg(format!("--success-message={} installed.", self.component)) + .arg(format!("--package-name={}", self.package_name())) + .arg("--non-installed-overlay") + .arg(&self.overlay_dir) + .arg("--output-dir") + .arg(crate::dist::distdir(self.builder)); + } + fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> PathBuf { t!(std::fs::create_dir_all(&self.overlay_dir)); self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder)); @@ -256,32 +282,17 @@ impl<'a> Tarball<'a> { let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller); - let package_name = if let Some(target) = &self.target { - self.builder.info(&format!("Dist {} ({})", self.component, target)); - format!("{}-{}", self.pkgname, target) - } else { - self.builder.info(&format!("Dist {}", self.component)); - self.pkgname.clone() - }; - + let package_name = self.package_name(); + self.builder.info(&format!("Dist {}", package_name)); let _time = crate::util::timeit(self.builder); - let distdir = crate::dist::distdir(self.builder); build_cli(&self, &mut cmd); - cmd.arg("--rel-manifest-dir=rustlib") - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg(format!("--product-name={}", self.product_name)) - .arg(format!("--success-message={} installed.", self.component)) - .arg(format!("--package-name={}", package_name)) - .arg("--work-dir") - .arg(self.work_dir) - .arg("--output-dir") - .arg(&distdir); + cmd.arg("--work-dir").arg(&self.temp_dir); self.builder.run(&mut cmd); if self.delete_temp_dir { t!(std::fs::remove_dir_all(&self.temp_dir)); } - distdir.join(format!("{}.tar.gz", package_name)) + crate::dist::distdir(self.builder).join(format!("{}.tar.gz", package_name)) } } -- cgit 1.4.1-3-g733a5 From ae12a0c200da9a97d80d074e20bf4180fe4671b5 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 7 Dec 2020 17:23:26 +0100 Subject: bootstrap: avoid producing the rust tarball during dry runs --- src/bootstrap/dist.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 258483bf134..dddb9527ea1 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1288,6 +1288,11 @@ impl Step for Extended { let etc = builder.src.join("src/etc/installer"); + // Avoid producing tarballs during a dry run. + if builder.config.dry_run { + return; + } + // When rust-std package split from rustc, we needed to ensure that during // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering // the std files during uninstall. To do this ensure that rustc comes -- cgit 1.4.1-3-g733a5 From 2c081769b09a876ecd3e9854f8cffc022ddc6b13 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 21 Dec 2020 18:04:58 +0100 Subject: bootstrap: use the normal compiler to build std --- src/bootstrap/dist.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index dddb9527ea1..6d9ee60f952 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1283,8 +1283,7 @@ impl Step for Extended { let analysis_installer = builder.ensure(Analysis { compiler, target }); let docs_installer = builder.ensure(Docs { host: target }); - let std_installer = - builder.ensure(Std { compiler: builder.compiler(stage, target), target }); + let std_installer = builder.ensure(Std { compiler, target }); let etc = builder.src.join("src/etc/installer"); -- cgit 1.4.1-3-g733a5 From 8736731f70be86b169a0dcc6a1900ccc05d2db85 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 23 Dec 2020 19:40:45 +0100 Subject: bootstrap: convert reproducible-artifacts to use Tarball --- src/bootstrap/dist.rs | 45 ++++----------------------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6d9ee60f952..0a79d09b27f 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2034,47 +2034,10 @@ impl Step for ReproducibleArtifacts { } fn run(self, builder: &Builder<'_>) -> Self::Output { - let name = pkgname(builder, "reproducible-artifacts"); - let tmp = tmpdir(builder); + let path = builder.config.rust_profile_use.as_ref()?; - // Prepare the image. - let image = tmp.join("reproducible-artifacts-image"); - let _ = fs::remove_dir_all(&image); - - if let Some(path) = &builder.config.rust_profile_use { - builder.install(std::path::Path::new(path), &image, 0o644); - } else { - return None; - } - - // Prepare the overlay. - let overlay = tmp.join("reproducible-artifacts-overlay"); - let _ = fs::remove_dir_all(&overlay); - builder.create_dir(&overlay); - builder.create(&overlay.join("version"), &builder.rust_version()); - for file in &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"] { - builder.install(&builder.src.join(file), &overlay, 0o644); - } - - // Create the final tarball. - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=reproducible-artifacts installed.") - .arg("--image-dir") - .arg(&image) - .arg("--work-dir") - .arg(&tmpdir(builder)) - .arg("--output-dir") - .arg(&distdir(builder)) - .arg("--non-installed-overlay") - .arg(&overlay) - .arg(format!("--package-name={}-{}", name, self.target.triple)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=reproducible-artifacts"); - - builder.run(&mut cmd); - Some(distdir(builder).join(format!("{}-{}.tar.gz", name, self.target.triple))) + let tarball = Tarball::new(builder, "reproducible-artifacts", &self.target.triple); + tarball.add_file(path, ".", 0o644); + Some(tarball.generate()) } } -- cgit 1.4.1-3-g733a5 From f459b0fea5723010bf1654d8073389fd0a0263d1 Mon Sep 17 00:00:00 2001 From: Yenlin Chen <3822365+hencrice@users.noreply.github.com> Date: Wed, 23 Dec 2020 18:55:37 +0000 Subject: Addressed feedbacks Also updated the mir-opt test output files. --- compiler/rustc_mir/src/util/pretty.rs | 20 +++----------------- .../const_prop/checked_add.main.ConstProp.diff | 3 --- .../mir-opt/const_prop/indirect.main.ConstProp.diff | 3 --- .../const_prop/issue_67019.main.ConstProp.diff | 3 --- .../mutable_variable_aggregate.main.ConstProp.diff | 3 --- ...optimizes_into_variable.main.ConstProp.32bit.diff | 3 --- ...optimizes_into_variable.main.ConstProp.64bit.diff | 3 --- .../const_prop/return_place.add.ConstProp.diff | 3 --- .../tuple_literal_propagation.main.ConstProp.diff | 3 --- ...ls_removes_unused_consts.main.SimplifyLocals.diff | 3 --- 10 files changed, 3 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 9b81629400a..394eb833422 100644 --- a/compiler/rustc_mir/src/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -17,7 +17,6 @@ use rustc_middle::mir::interpret::{ }; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, TyCtxt, TyS, TypeFoldable, TypeVisitor}; use rustc_target::abi::Size; use std::ops::ControlFlow; @@ -414,22 +413,9 @@ fn use_verbose(ty: &&TyS<'tcx>) -> bool { 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) => { - // could have used `try_fold` here but it seems a bit silly that - // the accumulator is useless - let mut should_be_verbose = false; - for g_arg in g_args.iter() { - if match g_arg.unpack() { - GenericArgKind::Type(ty) => use_verbose(&ty), - GenericArgKind::Const(ty::Const { ty, val: _ }) => use_verbose(ty), - _ => false, - } { - should_be_verbose = true; - break; - } - } - should_be_verbose - } + 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, _ => true, diff --git a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff index f01676b6da8..3397ef95856 100644 --- a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff index 8c7b35887c9..9ddb34e58e5 100644 --- a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff index 492938fc206..da35bf18c71 100644 --- a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff index 204c1acecf5..12b02e90345 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff index 53ffc01ccaf..a10bac4f3ea 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff index 53ffc01ccaf..a10bac4f3ea 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff index fc8a5437232..f0e9916e630 100644 --- a/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff +++ b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff index 2de1ab19b7c..da4b135d4c6 100644 --- a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff @@ -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 -+ // ty::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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // 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 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff index 3064e92f900..34f8ca870cd 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff @@ -42,9 +42,6 @@ // mir::Constant // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12 // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(Scalar()) } - // ty::Const - // + ty: ((), ()) - // + val: Value(Scalar()) // mir::Constant // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22 // + literal: Const { ty: ((), ()), val: Value(Scalar()) } -- cgit 1.4.1-3-g733a5 From 152d4e74bec46c08e388b47f3c5693929caf377f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 23 Dec 2020 20:27:12 +0100 Subject: Update HTML DOM attribute "edition" to "data-edition" --- src/librustdoc/html/highlight.rs | 2 +- src/librustdoc/html/static/rustdoc.css | 2 +- src/test/rustdoc/codeblock-title.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 47d2707e40d..077481c8989 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -30,7 +30,7 @@ crate fn render_with_highlighting( "
ⓘ
", class, if let Some(edition_info) = edition_info { - format!(" edition=\"{}\"", edition_info) + format!(" data-edition=\"{}\"", edition_info) } else { String::new() }, diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index afc4308b68f..0b40480f738 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1098,7 +1098,7 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { content: "This example panics"; } .tooltip.edition::after { - content: "This code runs with edition " attr(edition); + content: "This code runs with edition " attr(data-edition); } .tooltip::before { diff --git a/src/test/rustdoc/codeblock-title.rs b/src/test/rustdoc/codeblock-title.rs index 1327fd67d31..140c5b3a672 100644 --- a/src/test/rustdoc/codeblock-title.rs +++ b/src/test/rustdoc/codeblock-title.rs @@ -3,7 +3,7 @@ // @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]' "ⓘ" // @has foo/fn.bar.html '//*[@class="tooltip ignore"]' "ⓘ" // @has foo/fn.bar.html '//*[@class="tooltip should_panic"]' "ⓘ" -// @has foo/fn.bar.html '//*[@edition="2018"]' "ⓘ" +// @has foo/fn.bar.html '//*[@data-edition="2018"]' "ⓘ" /// foo /// -- cgit 1.4.1-3-g733a5 From 0bfc45aa859b94cedeffcbd949f9aaad9f3ac8d8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 23 Dec 2020 12:18:15 -0800 Subject: Add libz-sys to rustc-workspace-hack. https://github.com/alexcrichton/curl-rust/pull/351 changed curl-rust to no longer enable the default features of libz-sys. Because rustfmt includes rustc-workspace-hack with the rustc-workspace-hack/all-static feature (sometimes), it ends up building libz-sys without the default features. This causes a duplicate with other packages (like rls) which enable the default features. --- Cargo.lock | 1 + src/tools/rustc-workspace-hack/Cargo.toml | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 8fbfa8d6428..3603dbe1d0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3435,6 +3435,7 @@ dependencies = [ "byteorder", "crossbeam-utils 0.7.2", "libc", + "libz-sys", "proc-macro2", "quote", "serde", diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index 11b175f9e80..1cde0e25ced 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -65,6 +65,8 @@ byteorder = { version = "1", features = ['default', 'std'] } curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true } crossbeam-utils = { version = "0.7.2", features = ["nightly"] } libc = { version = "0.2.79", features = ["align"] } +# Ensure default features of libz-sys, which are disabled in some scenarios. +libz-sys = { version = "1.1.2" } proc-macro2 = { version = "1", features = ["default"] } quote = { version = "1", features = ["default"] } serde = { version = "1.0.82", features = ['derive'] } -- cgit 1.4.1-3-g733a5 From 6dc4f7a9d430e1b7d9a2a4032905fd96677e7846 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 23 Dec 2020 15:05:06 -0500 Subject: Don't unnecessarily override attrs for Module They were never changed from the default, which you can get with `tcx.get_attrs()`. --- src/librustdoc/clean/mod.rs | 7 +------ src/librustdoc/doctree.rs | 4 +--- src/librustdoc/visit_ast.rs | 6 +----- 3 files changed, 3 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index de53ce8d95c..6982e16da87 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -218,11 +218,6 @@ impl Clean for CrateNum { impl Clean for doctree::Module<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { - // maintain a stack of mod ids, for doc comment path resolution - // but we also need to resolve the module's own docs based on whether its docs were written - // inside or outside the module, so check for that - let attrs = self.attrs.clean(cx); - let mut items: Vec = vec![]; items.extend(self.imports.iter().flat_map(|x| x.clean(cx))); items.extend(self.foreigns.iter().map(|x| x.clean(cx))); @@ -251,7 +246,7 @@ impl Clean for doctree::Module<'_> { ModuleItem(Module { is_crate: self.is_crate, items }), cx, ); - Item { attrs, source: span.clean(cx), ..what_rustc_thinks } + Item { source: span.clean(cx), ..what_rustc_thinks } } } diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index ee9a6981857..bc9f1cf8806 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -9,7 +9,6 @@ use rustc_hir as hir; crate struct Module<'hir> { crate name: Option, - crate attrs: &'hir [ast::Attribute], crate where_outer: Span, crate where_inner: Span, crate imports: Vec>, @@ -23,13 +22,12 @@ crate struct Module<'hir> { } impl Module<'hir> { - crate fn new(name: Option, attrs: &'hir [ast::Attribute]) -> Module<'hir> { + crate fn new(name: Option) -> Module<'hir> { Module { name, id: hir::CRATE_HIR_ID, where_outer: rustc_span::DUMMY_SP, where_inner: rustc_span::DUMMY_SP, - attrs, imports: Vec::new(), mods: Vec::new(), items: Vec::new(), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f9cb1d586b1..3c0aeaad43e 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -1,7 +1,6 @@ //! The Rust AST Visitor. Extracts useful information and massages it into a form //! usable for `clean`. -use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -64,7 +63,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> { let mut module = self.visit_mod_contents( krate.item.span, - krate.item.attrs, &Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public }, hir::CRATE_HIR_ID, &krate.item.module, @@ -82,13 +80,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { fn visit_mod_contents( &mut self, span: Span, - attrs: &'tcx [ast::Attribute], vis: &'tcx hir::Visibility<'_>, id: hir::HirId, m: &'tcx hir::Mod<'tcx>, name: Option, ) -> Module<'tcx> { - let mut om = Module::new(name, attrs); + let mut om = Module::new(name); om.where_outer = span; om.where_inner = m.inner; om.id = id; @@ -292,7 +289,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::ItemKind::Mod(ref m) => { om.mods.push(self.visit_mod_contents( item.span, - &item.attrs, &item.vis, item.hir_id, m, -- cgit 1.4.1-3-g733a5 From db1451c7ad08e77a17c59f6755f234ea507ead92 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Sun, 20 Dec 2020 01:34:33 -0600 Subject: rustdoc: Highlight edition-specific keywords correctly in code blocks, accounting for code block edition modifiers This is a squash of these commits: - Highlight edition-specific keywords correctly in code blocks, accounting for code block edition modifiers - Fix unit tests - Revert changes to rustc_span::symbol to prepare for merge of #80272 - Use new Symbol::is_reserved API from #80272 - Remove unused import added by accident when merging --- src/librustdoc/html/highlight.rs | 22 +++++++++++++++------- src/librustdoc/html/highlight/tests.rs | 5 +++-- src/librustdoc/html/markdown.rs | 1 + src/librustdoc/html/render/mod.rs | 1 + src/librustdoc/html/sources.rs | 7 ++++--- 5 files changed, 24 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 077481c8989..d21998bb8cf 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -12,7 +12,7 @@ use std::iter::Peekable; use rustc_lexer::{LiteralKind, TokenKind}; use rustc_span::edition::Edition; -use rustc_span::symbol::Ident; +use rustc_span::symbol::Symbol; use rustc_span::with_default_session_globals; /// Highlights `src`, returning the HTML output. @@ -21,6 +21,7 @@ crate fn render_with_highlighting( class: Option<&str>, playground_button: Option<&str>, tooltip: Option<(Option, &str)>, + edition: Edition, ) -> String { debug!("highlighting: ================\n{}\n==============", src); let mut out = String::with_capacity(src.len()); @@ -39,7 +40,7 @@ crate fn render_with_highlighting( } write_header(&mut out, class); - write_code(&mut out, &src); + write_code(&mut out, &src, edition); write_footer(&mut out, playground_button); out @@ -50,10 +51,10 @@ fn write_header(out: &mut String, class: Option<&str>) { .unwrap() } -fn write_code(out: &mut String, src: &str) { +fn write_code(out: &mut String, src: &str, edition: Edition) { // This replace allows to fix how the code source with DOS backline characters is displayed. let src = src.replace("\r\n", "\n"); - Classifier::new(&src).highlight(&mut |highlight| { + Classifier::new(&src, edition).highlight(&mut |highlight| { match highlight { Highlight::Token { text, class } => string(out, Escape(text), class), Highlight::EnterSpan { class } => enter_span(out, class), @@ -144,12 +145,19 @@ struct Classifier<'a> { in_attribute: bool, in_macro: bool, in_macro_nonterminal: bool, + edition: Edition, } impl<'a> Classifier<'a> { - fn new(src: &str) -> Classifier<'_> { + fn new(src: &str, edition: Edition) -> Classifier<'_> { let tokens = TokenIter { src }.peekable(); - Classifier { tokens, in_attribute: false, in_macro: false, in_macro_nonterminal: false } + Classifier { + tokens, + in_attribute: false, + in_macro: false, + in_macro_nonterminal: false, + edition, + } } /// Exhausts the `Classifier` writing the output into `sink`. @@ -301,7 +309,7 @@ impl<'a> Classifier<'a> { "Option" | "Result" => Class::PreludeTy, "Some" | "None" | "Ok" | "Err" => Class::PreludeVal, // Keywords are also included in the identifier set. - _ if Ident::from_str(text).is_reserved() => Class::KeyWord, + _ if Symbol::intern(text).is_reserved(|| self.edition) => Class::KeyWord, _ if self.in_macro_nonterminal => { self.in_macro_nonterminal = false; Class::MacroNonTerminal diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs index f57f52d6f08..f97c8a7ab71 100644 --- a/src/librustdoc/html/highlight/tests.rs +++ b/src/librustdoc/html/highlight/tests.rs @@ -1,5 +1,6 @@ use super::write_code; use expect_test::expect_file; +use rustc_span::edition::Edition; const STYLE: &str = r#"

"); @@ -1817,14 +1817,14 @@ fn item_path(ty: ItemType, name: &str) -> String { } } -fn full_path(cx: &Context, item: &clean::Item) -> String { +fn full_path(cx: &Context<'_>, item: &clean::Item) -> String { let mut s = cx.current.join("::"); s.push_str("::"); s.push_str(&item.name.unwrap().as_str()); s } -fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&clean::Item>) { +fn document(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, parent: Option<&clean::Item>) { if let Some(ref name) = item.name { info!("Documenting {}", name); } @@ -1835,7 +1835,7 @@ fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&cl /// Render md_text as markdown. fn render_markdown( w: &mut Buffer, - cx: &Context, + cx: &Context<'_>, md_text: &str, links: Vec, prefix: &str, @@ -1864,7 +1864,7 @@ fn render_markdown( fn document_short( w: &mut Buffer, item: &clean::Item, - cx: &Context, + cx: &Context<'_>, link: AssocItemLink<'_>, prefix: &str, is_hidden: bool, @@ -1905,7 +1905,13 @@ fn document_short( } } -fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str, is_hidden: bool) { +fn document_full( + w: &mut Buffer, + item: &clean::Item, + cx: &Context<'_>, + prefix: &str, + is_hidden: bool, +) { if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) { debug!("Doc block: =====\n{}\n=====", s); render_markdown(w, cx, &*s, item.links(), prefix, is_hidden); @@ -1926,7 +1932,7 @@ fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str, /// * Required features (through the `doc_cfg` feature) fn document_item_info( w: &mut Buffer, - cx: &Context, + cx: &Context<'_>, item: &clean::Item, is_hidden: bool, parent: Option<&clean::Item>, @@ -2030,7 +2036,7 @@ crate fn compare_names(mut lhs: &str, mut rhs: &str) -> Ordering { Ordering::Equal } -fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean::Item]) { +fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { document(w, cx, item, None); let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()).collect::>(); @@ -2272,7 +2278,11 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option) -> Vec { +fn short_item_info( + item: &clean::Item, + cx: &Context<'_>, + parent: Option<&clean::Item>, +) -> Vec { let mut extra_info = vec![]; let error_codes = cx.shared.codes; @@ -2362,7 +2372,7 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item extra_info } -fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Constant) { +fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) { write!(w, "
");
     render_attributes(w, it, false);
 
@@ -2397,7 +2407,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons
     document(w, cx, it, None)
 }
 
-fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static) {
+fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
     write!(w, "
");
     render_attributes(w, it, false);
     write!(
@@ -2411,7 +2421,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static
     document(w, cx, it, None)
 }
 
-fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Function) {
+fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
     let header_len = format!(
         "{}{}{}{}{:#}fn {}{:#}",
         it.visibility.print_with_space(),
@@ -2445,7 +2455,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
 }
 
 fn render_implementor(
-    cx: &Context,
+    cx: &Context<'_>,
     implementor: &Impl,
     parent: &clean::Item,
     w: &mut Buffer,
@@ -2482,7 +2492,7 @@ fn render_implementor(
 }
 
 fn render_impls(
-    cx: &Context,
+    cx: &Context<'_>,
     w: &mut Buffer,
     traits: &[&&Impl],
     containing_item: &clean::Item,
@@ -2541,7 +2551,7 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering {
     compare_names(&lhs, &rhs)
 }
 
-fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, cache: &Cache) {
+fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait, cache: &Cache) {
     let bounds = bounds(&t.bounds, false);
     let types = t.items.iter().filter(|m| m.is_associated_type()).collect::>();
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>();
@@ -2637,7 +2647,13 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
         write!(w, "{}Loading content...", extra_content)
     }
 
-    fn trait_item(w: &mut Buffer, cx: &Context, m: &clean::Item, t: &clean::Item, cache: &Cache) {
+    fn trait_item(
+        w: &mut Buffer,
+        cx: &Context<'_>,
+        m: &clean::Item,
+        t: &clean::Item,
+        cache: &Cache,
+    ) {
         let name = m.name.as_ref().unwrap();
         info!("Documenting {} on {:?}", name, t.name);
         let item_type = m.type_();
@@ -3040,7 +3056,13 @@ fn render_assoc_item(
     }
 }
 
-fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct, cache: &Cache) {
+fn item_struct(
+    w: &mut Buffer,
+    cx: &Context<'_>,
+    it: &clean::Item,
+    s: &clean::Struct,
+    cache: &Cache,
+) {
     wrap_into_docblock(w, |w| {
         write!(w, "
");
         render_attributes(w, it, true);
@@ -3090,7 +3112,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, cache: &Cache) {
+fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union, cache: &Cache) {
     wrap_into_docblock(w, |w| {
         write!(w, "
");
         render_attributes(w, it, true);
@@ -3136,7 +3158,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, cache: &Cache) {
+fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum, cache: &Cache) {
     wrap_into_docblock(w, |w| {
         write!(w, "
");
         render_attributes(w, it, true);
@@ -3444,7 +3466,7 @@ impl<'a> AssocItemLink<'a> {
 
 fn render_assoc_items(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     containing_item: &clean::Item,
     it: DefId,
     what: AssocItemRender<'_>,
@@ -3560,7 +3582,7 @@ fn render_assoc_items(
 
 fn render_deref_methods(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     impl_: &Impl,
     container_item: &clean::Item,
     deref_mut: bool,
@@ -3676,7 +3698,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
 
 fn render_impl(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     i: &Impl,
     parent: &clean::Item,
     link: AssocItemLink<'_>,
@@ -3770,7 +3792,7 @@ fn render_impl(
 
     fn doc_impl_item(
         w: &mut Buffer,
-        cx: &Context,
+        cx: &Context<'_>,
         item: &clean::Item,
         parent: &clean::Item,
         link: AssocItemLink<'_>,
@@ -3907,7 +3929,7 @@ fn render_impl(
 
     fn render_default_items(
         w: &mut Buffer,
-        cx: &Context,
+        cx: &Context<'_>,
         t: &clean::Trait,
         i: &clean::Impl,
         parent: &clean::Item,
@@ -3967,7 +3989,7 @@ fn render_impl(
 
 fn item_opaque_ty(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     it: &clean::Item,
     t: &clean::OpaqueTy,
     cache: &Cache,
@@ -3994,7 +4016,7 @@ fn item_opaque_ty(
 
 fn item_trait_alias(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     it: &clean::Item,
     t: &clean::TraitAlias,
     cache: &Cache,
@@ -4019,7 +4041,13 @@ fn item_trait_alias(
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef, cache: &Cache) {
+fn item_typedef(
+    w: &mut Buffer,
+    cx: &Context<'_>,
+    it: &clean::Item,
+    t: &clean::Typedef,
+    cache: &Cache,
+) {
     write!(w, "
");
     render_attributes(w, it, false);
     write!(
@@ -4040,7 +4068,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) {
+fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache: &Cache) {
     writeln!(w, "
extern {{");
     render_attributes(w, it, false);
     write!(
@@ -4055,7 +4083,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cac
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Cache) {
+fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache: &Cache) {
     let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 };
 
     if it.is_struct()
@@ -4686,7 +4714,7 @@ fn sidebar_foreign_type(buf: &mut Buffer, it: &clean::Item) {
     }
 }
 
-fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro) {
+fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) {
     wrap_into_docblock(w, |w| {
         w.write_str(&highlight::render_with_highlighting(
             t.source.clone(),
@@ -4698,7 +4726,7 @@ fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro)
     document(w, cx, it, None)
 }
 
-fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::ProcMacro) {
+fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
     let name = it.name.as_ref().expect("proc-macros always have names");
     match m.kind {
         MacroKind::Bang => {
@@ -4728,12 +4756,12 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr
     document(w, cx, it, None)
 }
 
-fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) {
+fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache: &Cache) {
     document(w, cx, it, None);
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) {
+fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
     document(w, cx, it, None)
 }
 
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index b6c3300906b..87934c8a0e5 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -15,7 +15,7 @@ use std::path::{Component, Path, PathBuf};
 
 crate fn render(
     dst: &Path,
-    scx: &mut SharedContext,
+    scx: &mut SharedContext<'_>,
     krate: clean::Crate,
 ) -> Result {
     info!("emitting source files");
@@ -26,14 +26,14 @@ crate fn render(
 }
 
 /// Helper struct to render all source code to HTML pages
-struct SourceCollector<'a> {
-    scx: &'a mut SharedContext,
+struct SourceCollector<'a, 'tcx> {
+    scx: &'a mut SharedContext<'tcx>,
 
     /// Root destination to place all HTML output into
     dst: PathBuf,
 }
 
-impl<'a> DocFolder for SourceCollector<'a> {
+impl DocFolder for SourceCollector<'_, '_> {
     fn fold_item(&mut self, item: clean::Item) -> Option {
         // If we're not rendering sources, there's nothing to do.
         // If we're including source files, and we haven't seen this file yet,
@@ -69,9 +69,9 @@ impl<'a> DocFolder for SourceCollector<'a> {
     }
 }
 
-impl<'a> SourceCollector<'a> {
+impl SourceCollector<'_, '_> {
     fn sess(&self) -> &Session {
-        &self.scx.sess
+        &self.scx.tcx.sess
     }
 
     /// Renders the given filename into its corresponding HTML source file.
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 809cfb9d743..c362b9d2b96 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -14,7 +14,7 @@ use crate::formats::item_type::ItemType;
 use crate::json::types::*;
 use crate::json::JsonRenderer;
 
-impl JsonRenderer {
+impl JsonRenderer<'_> {
     pub(super) fn convert_item(&self, item: clean::Item) -> Option {
         let item_type = ItemType::from(&item);
         let clean::Item {
@@ -57,10 +57,10 @@ impl JsonRenderer {
     }
 
     fn convert_span(&self, span: clean::Span) -> Option {
-        match span.filename(&self.sess) {
+        match span.filename(self.sess()) {
             rustc_span::FileName::Real(name) => {
-                let hi = span.hi(&self.sess);
-                let lo = span.lo(&self.sess);
+                let hi = span.hi(self.sess());
+                let lo = span.lo(self.sess());
                 Some(Span {
                     filename: match name {
                         rustc_span::RealFileName::Named(path) => path,
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 3d970918407..dc2bc14e7ce 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -13,7 +13,6 @@ use std::path::PathBuf;
 use std::rc::Rc;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lrc;
 use rustc_middle::ty;
 use rustc_session::Session;
 use rustc_span::edition::Edition;
@@ -26,8 +25,8 @@ use crate::formats::FormatRenderer;
 use crate::html::render::cache::ExternalLocation;
 
 #[derive(Clone)]
-crate struct JsonRenderer {
-    sess: Lrc,
+crate struct JsonRenderer<'tcx> {
+    tcx: ty::TyCtxt<'tcx>,
     /// A mapping of IDs that contains all local items for this crate which gets output as a top
     /// level field of the JSON blob.
     index: Rc>>,
@@ -35,7 +34,11 @@ crate struct JsonRenderer {
     out_path: PathBuf,
 }
 
-impl JsonRenderer {
+impl JsonRenderer<'_> {
+    fn sess(&self) -> &Session {
+        self.tcx.sess
+    }
+
     fn get_trait_implementors(
         &mut self,
         id: rustc_span::def_id::DefId,
@@ -121,19 +124,19 @@ impl JsonRenderer {
     }
 }
 
-impl FormatRenderer for JsonRenderer {
+impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
     fn init(
         krate: clean::Crate,
         options: RenderOptions,
         _render_info: RenderInfo,
         _edition: Edition,
         _cache: &mut Cache,
-        tcx: ty::TyCtxt<'_>,
+        tcx: ty::TyCtxt<'tcx>,
     ) -> Result<(Self, clean::Crate), Error> {
         debug!("Initializing json renderer");
         Ok((
             JsonRenderer {
-                sess: tcx.sess,
+                tcx,
                 index: Rc::new(RefCell::new(FxHashMap::default())),
                 out_path: options.output,
             },
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index caa0706fd2b..2d3b4f87068 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -64,6 +64,7 @@ use std::process;
 
 use rustc_driver::abort_on_err;
 use rustc_errors::ErrorReported;
+use rustc_interface::interface;
 use rustc_middle::ty;
 use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup};
 use rustc_session::getopts;
@@ -468,13 +469,13 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes
     }
 }
 
-fn run_renderer(
+fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
     krate: clean::Crate,
     renderopts: config::RenderOptions,
     render_info: config::RenderInfo,
     diag: &rustc_errors::Handler,
     edition: rustc_span::edition::Edition,
-    tcx: ty::TyCtxt<'_>,
+    tcx: ty::TyCtxt<'tcx>,
 ) -> MainResult {
     match formats::run_format::(krate, renderopts, render_info, &diag, edition, tcx) {
         Ok(_) => Ok(()),
@@ -577,7 +578,7 @@ fn main_options(options: config::Options) -> MainResult {
                 let diag = core::new_handler(error_format, None, &debugging_options);
                 match output_format {
                     None | Some(config::OutputFormat::Html) => sess.time("render_html", || {
-                        run_renderer::(
+                        run_renderer::>(
                             krate,
                             render_opts,
                             render_info,
@@ -587,7 +588,7 @@ fn main_options(options: config::Options) -> MainResult {
                         )
                     }),
                     Some(config::OutputFormat::Json) => sess.time("render_json", || {
-                        run_renderer::(
+                        run_renderer::>(
                             krate,
                             render_opts,
                             render_info,
-- 
cgit 1.4.1-3-g733a5


From 789c902914e66285b36987a4f397d06ac50fed9e Mon Sep 17 00:00:00 2001
From: Joshua Nelson 
Date: Wed, 16 Dec 2020 16:02:15 -0500
Subject: Fix error with `--cfg parallel_compiler`

Apparently expansion() really does return Rc, not Lrc
---
 src/librustdoc/core.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 3b789dfd66f..7e85342ac7d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -410,7 +410,7 @@ crate fn create_resolver<'a>(
     externs: config::Externs,
     queries: &Queries<'a>,
     sess: &Session,
-) -> Lrc> {
+) -> Rc> {
     let extern_names: Vec = externs
         .iter()
         .filter(|(_, entry)| entry.add_prelude)
-- 
cgit 1.4.1-3-g733a5


From b421f2e8e94e578ed200dde235b7510b6a7014ba Mon Sep 17 00:00:00 2001
From: Joshua Nelson 
Date: Wed, 16 Dec 2020 16:22:11 -0500
Subject: TODO -> FIXME

---
 src/librustdoc/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 2d3b4f87068..0275a6ecd09 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -524,7 +524,7 @@ fn main_options(options: config::Options) -> MainResult {
 
     let default_passes = options.default_passes;
     let output_format = options.output_format;
-    // TODO: fix this clone (especially render_options)
+    // FIXME: fix this clone (especially render_options)
     let externs = options.externs.clone();
     let manual_passes = options.manual_passes.clone();
     let render_options = options.render_options.clone();
-- 
cgit 1.4.1-3-g733a5


From 0c2f76a4bf515a9c1bdb930ffb7f32b7ba6bd726 Mon Sep 17 00:00:00 2001
From: Joshua Nelson 
Date: Thu, 17 Dec 2020 11:40:02 -0500
Subject: Fix rebase conflict

---
 src/librustdoc/lib.rs | 4 ----
 1 file changed, 4 deletions(-)

(limited to 'src')

diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 0275a6ecd09..72f1b817d5d 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -558,10 +558,6 @@ fn main_options(options: config::Options) -> MainResult {
                 });
                 info!("finished with rustc");
 
-                if let Some(name) = crate_name {
-                    krate.name = name
-                }
-
                 krate.version = crate_version;
 
                 if show_coverage {
-- 
cgit 1.4.1-3-g733a5


From 88dc58fc9bb3dddccb99fc0e9f7a917c2052f8d0 Mon Sep 17 00:00:00 2001
From: David Wood 
Date: Thu, 17 Dec 2020 16:06:24 +0000
Subject: Revert "cg_llvm: `fewer_names` in `uncached_llvm_type`"

This reverts commit fa01ce802f1b403a2140fd945b43af86ec3998a1.
---
 compiler/rustc_codegen_llvm/src/type_of.rs | 10 +---------
 src/test/ui/issues/issue-75763.rs          |  3 ++-
 2 files changed, 3 insertions(+), 10 deletions(-)

(limited to 'src')

diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 8ea4768f77d..0876907e119 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -40,9 +40,7 @@ fn uncached_llvm_type<'a, 'tcx>(
         // FIXME(eddyb) producing readable type names for trait objects can result
         // in problematically distinct types due to HRTB and subtyping (see #47638).
         // ty::Dynamic(..) |
-        ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str
-            if !cx.sess().fewer_names() =>
-        {
+        ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str => {
             let mut name = with_no_trimmed_paths(|| layout.ty.to_string());
             if let (&ty::Adt(def, _), &Variants::Single { index }) =
                 (layout.ty.kind(), &layout.variants)
@@ -58,12 +56,6 @@ fn uncached_llvm_type<'a, 'tcx>(
             }
             Some(name)
         }
-        ty::Adt(..) => {
-            // If `Some` is returned then a named struct is created in LLVM. Name collisions are
-            // avoided by LLVM (with increasing suffixes). If rustc doesn't generate names then that
-            // can improve perf.
-            Some(String::new())
-        }
         _ => None,
     };
 
diff --git a/src/test/ui/issues/issue-75763.rs b/src/test/ui/issues/issue-75763.rs
index 2fd9f9a60de..c311de05a1c 100644
--- a/src/test/ui/issues/issue-75763.rs
+++ b/src/test/ui/issues/issue-75763.rs
@@ -1,4 +1,5 @@
-// build-pass
+// ignore-test
+// FIXME(const_generics): This test causes an ICE after reverting #76030.
 
 #![allow(incomplete_features)]
 #![feature(const_generics)]
-- 
cgit 1.4.1-3-g733a5


From 44e226ceb753075b44bcaadf349b1d1b6a23ad8d Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Thu, 17 Dec 2020 14:02:09 +0100
Subject: Continue String to Symbol conversion in rustdoc

---
 src/librustdoc/clean/auto_trait.rs  | 14 +++++++-------
 src/librustdoc/clean/inline.rs      |  8 ++++----
 src/librustdoc/clean/mod.rs         | 25 ++++++++++++-------------
 src/librustdoc/clean/types.rs       | 32 +++++++++++++++++---------------
 src/librustdoc/clean/utils.rs       |  2 +-
 src/librustdoc/html/format.rs       | 17 ++++++++---------
 src/librustdoc/html/render/cache.rs | 14 +++++++-------
 src/librustdoc/html/render/mod.rs   | 12 ++++++------
 src/librustdoc/json/conversions.rs  | 19 ++++++++++++-------
 9 files changed, 74 insertions(+), 69 deletions(-)

(limited to 'src')

diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 72603f00697..40c59ed1e0b 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -61,10 +61,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                             .params
                             .iter()
                             .filter_map(|param| match param.kind {
-                                ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
+                                ty::GenericParamDefKind::Lifetime => Some(param.name),
                                 _ => None,
                             })
-                            .map(|name| (name.clone(), Lifetime(name)))
+                            .map(|name| (name, Lifetime(name)))
                             .collect();
                         let lifetime_predicates = self.handle_lifetimes(®ion_data, &names_map);
                         let new_generics = self.param_env_to_generics(
@@ -145,21 +145,21 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     fn get_lifetime(
         &self,
         region: Region<'_>,
-        names_map: &FxHashMap,
+        names_map: &FxHashMap,
     ) -> Lifetime {
         self.region_name(region)
             .map(|name| {
                 names_map.get(&name).unwrap_or_else(|| {
-                    panic!("Missing lifetime with name {:?} for {:?}", name, region)
+                    panic!("Missing lifetime with name {:?} for {:?}", name.as_str(), region)
                 })
             })
             .unwrap_or(&Lifetime::statik())
             .clone()
     }
 
-    fn region_name(&self, region: Region<'_>) -> Option {
+    fn region_name(&self, region: Region<'_>) -> Option {
         match region {
-            &ty::ReEarlyBound(r) => Some(r.name.to_string()),
+            &ty::ReEarlyBound(r) => Some(r.name),
             _ => None,
         }
     }
@@ -177,7 +177,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     fn handle_lifetimes<'cx>(
         &self,
         regions: &RegionConstraintData<'cx>,
-        names_map: &FxHashMap,
+        names_map: &FxHashMap,
     ) -> Vec {
         // Our goal is to 'flatten' the list of constraints by eliminating
         // all intermediate RegionVids. At the end, all constraints should
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 7bb8e5e8cfc..3cff5fa07b1 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -486,13 +486,13 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet)
                         const_stability: None,
                         deprecation: None,
                         kind: clean::ImportItem(clean::Import::new_simple(
-                            item.ident.to_string(),
+                            item.ident.name,
                             clean::ImportSource {
                                 path: clean::Path {
                                     global: false,
                                     res: item.res,
                                     segments: vec![clean::PathSegment {
-                                        name: clean::PrimitiveType::from(p).as_str().to_string(),
+                                        name: clean::PrimitiveType::from(p).as_sym(),
                                         args: clean::GenericArgs::AngleBracketed {
                                             args: Vec::new(),
                                             bindings: Vec::new(),
@@ -562,11 +562,11 @@ fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind
                     .collect::()
             );
 
-            clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from).clean(cx) })
+            clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
         }
         LoadedMacro::ProcMacro(ext) => clean::ProcMacroItem(clean::ProcMacro {
             kind: ext.macro_kind(),
-            helpers: ext.helper_attrs.clean(cx),
+            helpers: ext.helper_attrs,
         }),
     }
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2105ec0b0ba..43272aeda61 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -379,7 +379,7 @@ impl Clean for hir::Lifetime {
             }
             _ => {}
         }
-        Lifetime(self.name.ident().to_string())
+        Lifetime(self.name.ident().name)
     }
 }
 
@@ -397,9 +397,9 @@ impl Clean for hir::GenericParam<'_> {
                     for bound in bounds {
                         s.push_str(&format!(" + {}", bound.name.ident()));
                     }
-                    Lifetime(s)
+                    Lifetime(Symbol::intern(&s))
                 } else {
-                    Lifetime(self.name.ident().to_string())
+                    Lifetime(self.name.ident().name)
                 }
             }
             _ => panic!(),
@@ -423,16 +423,16 @@ impl Clean for hir::ConstArg {
 
 impl Clean for ty::GenericParamDef {
     fn clean(&self, _cx: &DocContext<'_>) -> Lifetime {
-        Lifetime(self.name.to_string())
+        Lifetime(self.name)
     }
 }
 
 impl Clean> for ty::RegionKind {
-    fn clean(&self, cx: &DocContext<'_>) -> Option {
+    fn clean(&self, _cx: &DocContext<'_>) -> Option {
         match *self {
             ty::ReStatic => Some(Lifetime::statik()),
-            ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name.to_string())),
-            ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))),
+            ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name)),
+            ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)),
 
             ty::ReLateBound(..)
             | ty::ReFree(..)
@@ -897,7 +897,7 @@ fn clean_fn_or_proc_macro(
                     }
                 }
             }
-            ProcMacroItem(ProcMacro { kind, helpers: helpers.clean(cx) })
+            ProcMacroItem(ProcMacro { kind, helpers })
         }
         None => {
             let mut func = (sig, generics, body_id).clean(cx);
@@ -1914,7 +1914,7 @@ impl Clean for hir::GenericArgs<'_> {
 
 impl Clean for hir::PathSegment<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
-        PathSegment { name: self.ident.name.clean(cx), args: self.generic_args().clean(cx) }
+        PathSegment { name: self.ident.name, args: self.generic_args().clean(cx) }
     }
 }
 
@@ -2132,7 +2132,6 @@ fn clean_extern_crate(
             return items;
         }
     }
-    let path = orig_name.map(|x| x.to_string());
     // FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
     vec![Item {
         name: None,
@@ -2143,7 +2142,7 @@ fn clean_extern_crate(
         stability: None,
         const_stability: None,
         deprecation: None,
-        kind: ExternCrateItem(name.clean(cx), path),
+        kind: ExternCrateItem(name, orig_name),
     }]
 }
 
@@ -2215,7 +2214,7 @@ impl Clean> for doctree::Import<'_> {
                         const_stability: None,
                         deprecation: None,
                         kind: ImportItem(Import::new_simple(
-                            self.name.clean(cx),
+                            self.name,
                             resolve_use_source(cx, path),
                             false,
                         )),
@@ -2223,7 +2222,7 @@ impl Clean> for doctree::Import<'_> {
                     return items;
                 }
             }
-            Import::new_simple(name.clean(cx), resolve_use_source(cx, path), true)
+            Import::new_simple(name, resolve_use_source(cx, path), true)
         };
 
         vec![Item {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 9bade5ad2ec..4920e6fd6f1 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -295,7 +295,7 @@ impl Item {
 
 #[derive(Clone, Debug)]
 crate enum ItemKind {
-    ExternCrateItem(String, Option),
+    ExternCrateItem(Symbol, Option),
     ImportItem(Import),
     StructItem(Struct),
     UnionItem(Union),
@@ -877,21 +877,19 @@ impl GenericBound {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct Lifetime(pub String);
+crate struct Lifetime(pub Symbol);
 
 impl Lifetime {
-    crate fn get_ref<'a>(&'a self) -> &'a str {
-        let Lifetime(ref s) = *self;
-        let s: &'a str = s;
-        s
+    crate fn get_ref(&self) -> SymbolStr {
+        self.0.as_str()
     }
 
     crate fn statik() -> Lifetime {
-        Lifetime("'static".to_string())
+        Lifetime(kw::StaticLifetime)
     }
 
     crate fn elided() -> Lifetime {
-        Lifetime("'_".to_string())
+        Lifetime(kw::UnderscoreLifetime)
     }
 }
 
@@ -1675,13 +1673,17 @@ crate struct Path {
 }
 
 impl Path {
-    crate fn last_name(&self) -> &str {
+    crate fn last(&self) -> Symbol {
+        self.segments.last().expect("segments were empty").name
+    }
+
+    crate fn last_name(&self) -> SymbolStr {
         self.segments.last().expect("segments were empty").name.as_str()
     }
 
     crate fn whole_name(&self) -> String {
         String::from(if self.global { "::" } else { "" })
-            + &self.segments.iter().map(|s| s.name.clone()).collect::>().join("::")
+            + &self.segments.iter().map(|s| s.name.to_string()).collect::>().join("::")
     }
 }
 
@@ -1700,7 +1702,7 @@ crate enum GenericArgs {
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct PathSegment {
-    crate name: String,
+    crate name: Symbol,
     crate args: GenericArgs,
 }
 
@@ -1777,7 +1779,7 @@ crate struct Import {
 }
 
 impl Import {
-    crate fn new_simple(name: String, source: ImportSource, should_be_displayed: bool) -> Self {
+    crate fn new_simple(name: Symbol, source: ImportSource, should_be_displayed: bool) -> Self {
         Self { kind: ImportKind::Simple(name), source, should_be_displayed }
     }
 
@@ -1789,7 +1791,7 @@ impl Import {
 #[derive(Clone, Debug)]
 crate enum ImportKind {
     // use source as str;
-    Simple(String),
+    Simple(Symbol),
     // use source::*;
     Glob,
 }
@@ -1803,13 +1805,13 @@ crate struct ImportSource {
 #[derive(Clone, Debug)]
 crate struct Macro {
     crate source: String,
-    crate imported_from: Option,
+    crate imported_from: Option,
 }
 
 #[derive(Clone, Debug)]
 crate struct ProcMacro {
     crate kind: MacroKind,
-    crate helpers: Vec,
+    crate helpers: Vec,
 }
 
 /// An type binding on an associated type (e.g., `A = Bar` in `Foo` or
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index ec922b182e2..1ae2e5de82c 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -153,7 +153,7 @@ pub(super) fn external_path(
         global: false,
         res: Res::Err,
         segments: vec![PathSegment {
-            name: name.to_string(),
+            name,
             args: external_generic_args(cx, trait_did, has_self, bindings, substs),
         }],
     }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index c49c4892237..f80346aa50b 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -308,7 +308,7 @@ impl<'a> fmt::Display for WhereClause<'a> {
 }
 
 impl clean::Lifetime {
-    crate fn print(&self) -> &str {
+    crate fn print(&self) -> impl fmt::Display + '_ {
         self.get_ref()
     }
 }
@@ -445,11 +445,10 @@ impl clean::GenericArgs {
 impl clean::PathSegment {
     crate fn print(&self) -> impl fmt::Display + '_ {
         display_fn(move |f| {
-            f.write_str(&self.name)?;
             if f.alternate() {
-                write!(f, "{:#}", self.args.print())
+                write!(f, "{}{:#}", self.name, self.args.print())
             } else {
-                write!(f, "{}", self.args.print())
+                write!(f, "{}{}", self.name, self.args.print())
             }
         })
     }
@@ -544,7 +543,7 @@ fn resolved_path(
                 last.name.to_string()
             }
         } else {
-            anchor(did, &last.name).to_string()
+            anchor(did, &*last.name.as_str()).to_string()
         };
         write!(w, "{}{}", path, last.args.print())?;
     }
@@ -1159,11 +1158,11 @@ impl PrintWithSpace for hir::Mutability {
 impl clean::Import {
     crate fn print(&self) -> impl fmt::Display + '_ {
         display_fn(move |f| match self.kind {
-            clean::ImportKind::Simple(ref name) => {
-                if *name == self.source.path.last_name() {
+            clean::ImportKind::Simple(name) => {
+                if name == self.source.path.last() {
                     write!(f, "use {};", self.source.print())
                 } else {
-                    write!(f, "use {} as {};", self.source.print(), *name)
+                    write!(f, "use {} as {};", self.source.print(), name)
                 }
             }
             clean::ImportKind::Glob => {
@@ -1187,7 +1186,7 @@ impl clean::ImportSource {
                 }
                 let name = self.path.last_name();
                 if let hir::def::Res::PrimTy(p) = self.path.res {
-                    primitive_link(f, PrimitiveType::from(p), name)?;
+                    primitive_link(f, PrimitiveType::from(p), &*name)?;
                 } else {
                     write!(f, "{}", name)?;
                 }
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 80f54d8e161..94a8b3fef47 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
 use std::path::Path;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 use serde::Serialize;
 
 use crate::clean::types::GetDefId;
@@ -191,12 +191,12 @@ fn get_index_type(clean_type: &clean::Type) -> RenderType {
     RenderType {
         ty: clean_type.def_id(),
         idx: None,
-        name: get_index_type_name(clean_type, true).map(|s| s.to_ascii_lowercase()),
+        name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()),
         generics: get_generics(clean_type),
     }
 }
 
-fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option {
+fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option {
     match *clean_type {
         clean::ResolvedPath { ref path, .. } => {
             let segments = &path.segments;
@@ -206,10 +206,10 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
                 clean_type, accept_generic
             )
             });
-            Some(path_segment.name.clone())
+            Some(path_segment.name)
         }
-        clean::Generic(s) if accept_generic => Some(s.to_string()),
-        clean::Primitive(ref p) => Some(format!("{:?}", p)),
+        clean::Generic(s) if accept_generic => Some(s),
+        clean::Primitive(ref p) => Some(p.as_sym()),
         clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_, accept_generic),
         // FIXME: add all from clean::Type.
         _ => None,
@@ -222,7 +222,7 @@ fn get_generics(clean_type: &clean::Type) -> Option> {
             .iter()
             .filter_map(|t| {
                 get_index_type_name(t, false).map(|name| Generic {
-                    name: name.to_ascii_lowercase(),
+                    name: name.as_str().to_ascii_lowercase(),
                     defid: t.def_id(),
                     idx: None,
                 })
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 00294878fe5..1e888e83e19 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2137,14 +2137,14 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                         w,
                         "{}extern crate {} as {};",
                         myitem.visibility.print_with_space(),
-                        anchor(myitem.def_id, src),
+                        anchor(myitem.def_id, &*src.as_str()),
                         name
                     ),
                     None => write!(
                         w,
                         "{}extern crate {};",
                         myitem.visibility.print_with_space(),
-                        anchor(myitem.def_id, name)
+                        anchor(myitem.def_id, &*name.as_str())
                     ),
                 }
                 write!(w, "");
@@ -2444,7 +2444,7 @@ fn render_implementor(
     implementor: &Impl,
     parent: &clean::Item,
     w: &mut Buffer,
-    implementor_dups: &FxHashMap<&str, (DefId, bool)>,
+    implementor_dups: &FxHashMap,
     aliases: &[String],
     cache: &Cache,
 ) {
@@ -2455,7 +2455,7 @@ fn render_implementor(
         | clean::BorrowedRef {
             type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
             ..
-        } => implementor_dups[path.last_name()].1,
+        } => implementor_dups[&path.last()].1,
         _ => false,
     };
     render_impl(
@@ -2704,7 +2704,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
     if let Some(implementors) = cache.implementors.get(&it.def_id) {
         // The DefId is for the first Type found with that name. The bool is
         // if any Types with the same name but different DefId have been found.
-        let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap::default();
+        let mut implementor_dups: FxHashMap = FxHashMap::default();
         for implementor in implementors {
             match implementor.inner_impl().for_ {
                 clean::ResolvedPath { ref path, did, is_generic: false, .. }
@@ -2713,7 +2713,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                     ..
                 } => {
                     let &mut (prev_did, ref mut has_duplicates) =
-                        implementor_dups.entry(path.last_name()).or_insert((did, false));
+                        implementor_dups.entry(path.last()).or_insert((did, false));
                     if prev_did != did {
                         *has_duplicates = true;
                     }
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 809cfb9d743..9dc27e3411d 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -120,7 +120,7 @@ impl From for GenericArg {
     fn from(arg: clean::GenericArg) -> Self {
         use clean::GenericArg::*;
         match arg {
-            Lifetime(l) => GenericArg::Lifetime(l.0),
+            Lifetime(l) => GenericArg::Lifetime(l.0.to_string()),
             Type(t) => GenericArg::Type(t.into()),
             Const(c) => GenericArg::Const(c.into()),
         }
@@ -163,7 +163,9 @@ impl From for ItemEnum {
         use clean::ItemKind::*;
         match item {
             ModuleItem(m) => ItemEnum::ModuleItem(m.into()),
-            ExternCrateItem(c, a) => ItemEnum::ExternCrateItem { name: c, rename: a },
+            ExternCrateItem(c, a) => {
+                ItemEnum::ExternCrateItem { name: c.to_string(), rename: a.map(|x| x.to_string()) }
+            }
             ImportItem(i) => ItemEnum::ImportItem(i.into()),
             StructItem(s) => ItemEnum::StructItem(s.into()),
             UnionItem(u) => ItemEnum::StructItem(u.into()),
@@ -302,7 +304,7 @@ impl From for WherePredicate {
                 bounds: bounds.into_iter().map(Into::into).collect(),
             },
             RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
-                lifetime: lifetime.0,
+                lifetime: lifetime.0.to_string(),
                 bounds: bounds.into_iter().map(Into::into).collect(),
             },
             EqPredicate { lhs, rhs } => {
@@ -323,7 +325,7 @@ impl From for GenericBound {
                     modifier: modifier.into(),
                 }
             }
-            Outlives(lifetime) => GenericBound::Outlives(lifetime.0),
+            Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()),
         }
     }
 }
@@ -365,7 +367,7 @@ impl From for Type {
                 type_: Box::new((*type_).into()),
             },
             BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef {
-                lifetime: lifetime.map(|l| l.0),
+                lifetime: lifetime.map(|l| l.0.to_string()),
                 mutable: mutability == ast::Mutability::Mut,
                 type_: Box::new((*type_).into()),
             },
@@ -503,7 +505,7 @@ impl From for Import {
         match import.kind {
             Simple(s) => Import {
                 span: import.source.path.whole_name(),
-                name: s,
+                name: s.to_string(),
                 id: import.source.did.map(Into::into),
                 glob: false,
             },
@@ -519,7 +521,10 @@ impl From for Import {
 
 impl From for ProcMacro {
     fn from(mac: clean::ProcMacro) -> Self {
-        ProcMacro { kind: mac.kind.into(), helpers: mac.helpers }
+        ProcMacro {
+            kind: mac.kind.into(),
+            helpers: mac.helpers.iter().map(|x| x.to_string()).collect(),
+        }
     }
 }
 
-- 
cgit 1.4.1-3-g733a5


From 419d3ae02849d47899f8fc221d37b05ac24f4efd Mon Sep 17 00:00:00 2001
From: Aaron Hill 
Date: Tue, 20 Oct 2020 16:31:54 -0400
Subject: Prefer regions with an `external_name` in
 `approx_universal_upper_bound`

Fixes #75785

When displaying a MIR borrowcheck error, we may need to find an upper
bound for a region, which gives us a region to point to in the error
message. However, a region might outlive multiple distinct universal
regions, in which case the only upper bound is 'static

To try to display a meaningful error message, we compute an
'approximate' upper bound by picking one of the universal regions.
Currently, we pick the region with the lowest index - however, this
caused us to produce a suboptimal error message in issue #75785

This PR `approx_universal_upper_bound` to prefer regions with an
`external_name`. This causes us to prefer regions from function
arguments/upvars, which seems to lead to a nicer error message in some
cases.
---
 .../rustc_mir/src/borrow_check/region_infer/mod.rs     | 18 +++++++++++++++++-
 .../issue-74072-lifetime-name-annotations.stderr       |  2 +-
 .../async-await/issue-75785-confusing-named-region.rs  | 13 +++++++++++++
 .../issue-75785-confusing-named-region.stderr          | 15 +++++++++++++++
 4 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/async-await/issue-75785-confusing-named-region.rs
 create mode 100644 src/test/ui/async-await/issue-75785-confusing-named-region.stderr

(limited to 'src')

diff --git a/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
index 3586be2804d..9d45f6fd0d3 100644
--- a/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
@@ -1145,8 +1145,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
             let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
             debug!("approx_universal_upper_bound: ur={:?} lub={:?} new_lub={:?}", ur, lub, new_lub);
+            // The upper bound of two non-static regions is static: this
+            // means we know nothing about the relationship between these
+            // two regions. Pick a 'better' one to use when constructing
+            // a diagnostic
             if ur != static_r && lub != static_r && new_lub == static_r {
-                lub = std::cmp::min(ur, lub);
+                // Prefer the region with an `external_name` - this
+                // indicates that the region is early-bound, so working with
+                // it can produce a nicer error.
+                if self.region_definition(ur).external_name.is_some() {
+                    lub = ur;
+                } else if self.region_definition(lub).external_name.is_some() {
+                    // Leave lub unchanged
+                } else {
+                    // If we get here, we don't have any reason to prefer
+                    // one region over the other. Just pick the
+                    // one with the lower index for now.
+                    lub = std::cmp::min(ur, lub);
+                }
             } else {
                 lub = new_lub;
             }
diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
index 123c3192cff..b96cab9f0f5 100644
--- a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
+++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
@@ -2,7 +2,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5
    |
 LL | pub async fn async_fn(x: &mut i32) -> &i32 {
-   |                                       - let's call the lifetime of this reference `'1`
+   |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
    |             --- borrow of `*x` occurs here
 LL |     *x += 1;
diff --git a/src/test/ui/async-await/issue-75785-confusing-named-region.rs b/src/test/ui/async-await/issue-75785-confusing-named-region.rs
new file mode 100644
index 00000000000..452614087be
--- /dev/null
+++ b/src/test/ui/async-await/issue-75785-confusing-named-region.rs
@@ -0,0 +1,13 @@
+// edition:2018
+//
+// Regression test for issue #75785
+// Tests that we don't point to a confusing named
+// region when emitting a diagnostic
+
+pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
+    let y = &*x;
+    *x += 1; //~ ERROR cannot assign to
+    (&32, y)
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
new file mode 100644
index 00000000000..3b731d9c60a
--- /dev/null
+++ b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
@@ -0,0 +1,15 @@
+error[E0506]: cannot assign to `*x` because it is borrowed
+  --> $DIR/issue-75785-confusing-named-region.rs:9:5
+   |
+LL | pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
+   |                          - let's call the lifetime of this reference `'1`
+LL |     let y = &*x;
+   |             --- borrow of `*x` occurs here
+LL |     *x += 1;
+   |     ^^^^^^^ assignment to borrowed `*x` occurs here
+LL |     (&32, y)
+   |     -------- returning this value requires that `*x` is borrowed for `'1`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0506`.
-- 
cgit 1.4.1-3-g733a5


From 3e31ffda973d2fe8e314378a98d0b4633fce9485 Mon Sep 17 00:00:00 2001
From: Matthew Jasper 
Date: Thu, 17 Dec 2020 20:16:10 +0000
Subject: Revert change to evaluation order

This change breaks some code and doesn't appear to enable any new code.
---
 .../src/traits/select/confirmation.rs              |  6 ++--
 src/test/ui/traits/impl-evaluation-order.rs        | 39 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)
 create mode 100644 src/test/ui/traits/impl-evaluation-order.rs

(limited to 'src')

diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index ed22d5849e2..c40d781e17c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -336,7 +336,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn vtable_impl(
         &mut self,
         impl_def_id: DefId,
-        mut substs: Normalized<'tcx, SubstsRef<'tcx>>,
+        substs: Normalized<'tcx, SubstsRef<'tcx>>,
         cause: ObligationCause<'tcx>,
         recursion_depth: usize,
         param_env: ty::ParamEnv<'tcx>,
@@ -358,9 +358,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // relying on projections in the impl-trait-ref.
         //
         // e.g., `impl> Foo<::T> for V`
-        substs.obligations.append(&mut impl_obligations);
+        impl_obligations.extend(substs.obligations);
 
-        ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: substs.obligations }
+        ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: impl_obligations }
     }
 
     fn confirm_object_candidate(
diff --git a/src/test/ui/traits/impl-evaluation-order.rs b/src/test/ui/traits/impl-evaluation-order.rs
new file mode 100644
index 00000000000..57809d89aa6
--- /dev/null
+++ b/src/test/ui/traits/impl-evaluation-order.rs
@@ -0,0 +1,39 @@
+// Regression test for #79902
+
+// Check that evaluation (which is used to determine whether to copy a type in
+// MIR building) evaluates bounds from normalizing an impl after evaluating
+// any bounds on the impl.
+
+// check-pass
+
+trait A {
+    type B;
+}
+trait M {}
+
+struct G(*const T, *const U);
+
+impl Clone for G {
+    fn clone(&self) -> Self {
+        G { ..*self }
+    }
+}
+
+impl Copy for G
+where
+    T: A,
+    U: A,
+{
+}
+
+impl A for () {
+    type B = ();
+}
+
+fn is_m(_: T) {}
+
+fn main() {
+    let x = G(&(), &());
+    drop(x);
+    drop(x);
+}
-- 
cgit 1.4.1-3-g733a5


From dea13632a8e8f90febe3de17c740498285397936 Mon Sep 17 00:00:00 2001
From: Aaron Hill 
Date: Thu, 17 Dec 2020 15:25:55 -0500
Subject: Suppress `CONST_ITEM_MUTATION` lint if a dereference occurs anywhere

Fixes #79971
---
 .../rustc_mir/src/transform/check_const_item_mutation.rs |  8 +++++---
 src/test/ui/lint/lint-const-item-mutation.rs             |  8 ++++++++
 src/test/ui/lint/lint-const-item-mutation.stderr         | 16 ++++++++--------
 3 files changed, 21 insertions(+), 11 deletions(-)

(limited to 'src')

diff --git a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs
index a8457043278..e2d50ba034a 100644
--- a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs
+++ b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs
@@ -66,12 +66,14 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> {
         location: Location,
         decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b>,
     ) {
-        // Don't lint on borrowing/assigning to a dereference
-        // e.g:
+        // Don't lint on borrowing/assigning when a dereference is involved.
+        // If we 'leave' the temporary via a dereference, we must
+        // be modifying something else
         //
         // `unsafe { *FOO = 0; *BAR.field = 1; }`
         // `unsafe { &mut *FOO }`
-        if !matches!(place.projection.last(), Some(PlaceElem::Deref)) {
+        // `unsafe { (*ARRAY)[0] = val; }
+        if !place.projection.iter().any(|p| matches!(p, PlaceElem::Deref)) {
             let source_info = self.body.source_info(location);
             let lint_root = self.body.source_scopes[source_info.scope]
                 .local_data
diff --git a/src/test/ui/lint/lint-const-item-mutation.rs b/src/test/ui/lint/lint-const-item-mutation.rs
index ef55f31593b..4bf5e0a9e21 100644
--- a/src/test/ui/lint/lint-const-item-mutation.rs
+++ b/src/test/ui/lint/lint-const-item-mutation.rs
@@ -30,6 +30,8 @@ const MUTABLE: Mutable = Mutable { msg: "" };
 const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
 const VEC: Vec = Vec::new();
 const PTR: *mut () = 1 as *mut _;
+const PTR_TO_ARRAY: *mut [u32; 4] = 0x12345678 as _;
+const ARRAY_OF_PTR: [*mut u32; 1] = [1 as *mut _];
 
 fn main() {
     ARRAY[0] = 5; //~ WARN attempting to modify
@@ -55,4 +57,10 @@ fn main() {
     // Test that we don't warn when converting a raw pointer
     // into a mutable reference
     unsafe { &mut *PTR };
+
+    // Test that we don't warn when there's a dereference involved.
+    // If we ever 'leave' the const via a deference, we're going
+    // to end up modifying something other than the temporary
+    unsafe { (*PTR_TO_ARRAY)[0] = 1 };
+    unsafe { *ARRAY_OF_PTR[0] = 25; }
 }
diff --git a/src/test/ui/lint/lint-const-item-mutation.stderr b/src/test/ui/lint/lint-const-item-mutation.stderr
index ae95abc72f3..74505eeb987 100644
--- a/src/test/ui/lint/lint-const-item-mutation.stderr
+++ b/src/test/ui/lint/lint-const-item-mutation.stderr
@@ -1,5 +1,5 @@
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:35:5
+  --> $DIR/lint-const-item-mutation.rs:37:5
    |
 LL |     ARRAY[0] = 5;
    |     ^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL | const ARRAY: [u8; 1] = [25];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:36:5
+  --> $DIR/lint-const-item-mutation.rs:38:5
    |
 LL |     MY_STRUCT.field = false;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:37:5
+  --> $DIR/lint-const-item-mutation.rs:39:5
    |
 LL |     MY_STRUCT.inner_array[0] = 'b';
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,7 +39,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:38:5
+  --> $DIR/lint-const-item-mutation.rs:40:5
    |
 LL |     MY_STRUCT.use_mut();
    |     ^^^^^^^^^^^^^^^^^^^
@@ -58,7 +58,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:39:5
+  --> $DIR/lint-const-item-mutation.rs:41:5
    |
 LL |     &mut MY_STRUCT;
    |     ^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:40:5
+  --> $DIR/lint-const-item-mutation.rs:42:5
    |
 LL |     (&mut MY_STRUCT).use_mut();
    |     ^^^^^^^^^^^^^^^^
@@ -86,7 +86,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:52:5
+  --> $DIR/lint-const-item-mutation.rs:54:5
    |
 LL |     MUTABLE2.msg = "wow";
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:53:5
+  --> $DIR/lint-const-item-mutation.rs:55:5
    |
 LL |     VEC.push(0);
    |     ^^^^^^^^^^^
-- 
cgit 1.4.1-3-g733a5


From d6f1787447e1132d929efbb5b772be232e336c23 Mon Sep 17 00:00:00 2001
From: Camelid 
Date: Thu, 17 Dec 2020 13:51:20 -0800
Subject: Don't allow `const` to begin a nonterminal

Thanks to Vadim Petrochenkov who [told me what the fix was][z]!

[z]: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/finding.20which.20macro.20rule.20to.20use/near/220240422
---
 compiler/rustc_parse/src/parser/nonterminal.rs |  2 ++
 src/test/ui/inline-const/macro-with-const.rs   | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+)
 create mode 100644 src/test/ui/inline-const/macro-with-const.rs

(limited to 'src')

diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index c007f96a798..76ad5acd530 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -27,6 +27,8 @@ impl<'a> Parser<'a> {
                 token.can_begin_expr()
                 // This exception is here for backwards compatibility.
                 && !token.is_keyword(kw::Let)
+                // This exception is here for backwards compatibility.
+                && !token.is_keyword(kw::Const)
             }
             NonterminalKind::Ty => token.can_begin_type(),
             NonterminalKind::Ident => get_macro_ident(token).is_some(),
diff --git a/src/test/ui/inline-const/macro-with-const.rs b/src/test/ui/inline-const/macro-with-const.rs
new file mode 100644
index 00000000000..e7393166d8d
--- /dev/null
+++ b/src/test/ui/inline-const/macro-with-const.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+macro_rules! exp {
+    (const $n:expr) => {
+        $n
+    };
+}
+
+macro_rules! stmt {
+    (exp $e:expr) => {
+        $e
+    };
+    (exp $($t:tt)+) => {
+        exp!($($t)+)
+    };
+}
+
+fn main() {
+    stmt!(exp const 1);
+}
-- 
cgit 1.4.1-3-g733a5


From b11b705e52c534300565fa9a44fa4630a896ae5b Mon Sep 17 00:00:00 2001
From: Nixon Enraght-Moony 
Date: Thu, 17 Dec 2020 22:06:00 +0000
Subject: Add test for issue #74824

---
 .../ui/generic-associated-types/issue-74824.rs     | 27 ++++++++++++++++++++++
 .../ui/generic-associated-types/issue-74824.stderr | 27 ++++++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 src/test/ui/generic-associated-types/issue-74824.rs
 create mode 100644 src/test/ui/generic-associated-types/issue-74824.stderr

(limited to 'src')

diff --git a/src/test/ui/generic-associated-types/issue-74824.rs b/src/test/ui/generic-associated-types/issue-74824.rs
new file mode 100644
index 00000000000..00761a97d00
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74824.rs
@@ -0,0 +1,27 @@
+#![feature(generic_associated_types)]
+#![feature(associated_type_defaults)]
+#![allow(incomplete_features)]
+
+use std::ops::Deref;
+
+trait UnsafeCopy {
+    type Copy: Copy = Box;
+    //~^ ERROR the trait bound `Box: Copy` is not satisfied
+    //~^^ ERROR the trait bound `T: Clone` is not satisfied
+    fn copy(x: &Self::Copy) -> Self::Copy {
+        *x
+    }
+}
+
+impl UnsafeCopy for T {}
+
+fn main() {
+    let b = Box::new(42usize);
+    let copy = <()>::copy(&b);
+
+    let raw_b = Box::deref(&b) as *const _;
+    let raw_copy = Box::deref(©) as *const _;
+
+    // assert the addresses.
+    assert_eq!(raw_b, raw_copy);
+}
diff --git a/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr
new file mode 100644
index 00000000000..34a2c1932eb
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74824.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `Box: Copy` is not satisfied
+  --> $DIR/issue-74824.rs:8:5
+   |
+LL |     type Copy: Copy = Box;
+   |     ^^^^^^^^^^^^^^----^^^^^^^^^^
+   |     |             |
+   |     |             required by this bound in `UnsafeCopy::Copy`
+   |     the trait `Copy` is not implemented for `Box`
+
+error[E0277]: the trait bound `T: Clone` is not satisfied
+  --> $DIR/issue-74824.rs:8:5
+   |
+LL |     type Copy: Copy = Box;
+   |     ^^^^^^^^^^^^^^----^^^^^^^^^^
+   |     |             |
+   |     |             required by this bound in `UnsafeCopy::Copy`
+   |     the trait `Clone` is not implemented for `T`
+   |
+   = note: required because of the requirements on the impl of `Clone` for `Box`
+help: consider restricting type parameter `T`
+   |
+LL |     type Copy: Copy = Box;
+   |                ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
-- 
cgit 1.4.1-3-g733a5


From 57266f1df6e9168f262b208f4a2ee62ebdaf9ad2 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez 
Date: Fri, 18 Dec 2020 12:05:51 +0100
Subject: Continue String to Symbol conversion in rustdoc

---
 src/librustdoc/clean/blanket_impl.rs | 2 +-
 src/librustdoc/clean/inline.rs       | 2 +-
 src/librustdoc/clean/mod.rs          | 4 ++--
 src/librustdoc/clean/types.rs        | 2 +-
 src/librustdoc/html/render/mod.rs    | 4 ++--
 src/librustdoc/json/conversions.rs   | 5 ++++-
 6 files changed, 11 insertions(+), 8 deletions(-)

(limited to 'src')

diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 33b5e84c5e0..22496065afd 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -103,7 +103,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     .cx
                     .tcx
                     .provided_trait_methods(trait_def_id)
-                    .map(|meth| meth.ident.to_string())
+                    .map(|meth| meth.ident.name)
                     .collect();
 
                 impls.push(Item {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 3cff5fa07b1..783be6c8243 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -427,7 +427,7 @@ crate fn build_impl(
 
     let provided = trait_
         .def_id()
-        .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect())
+        .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
         .unwrap_or_default();
 
     debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2809e85761d..07255168d06 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2065,9 +2065,9 @@ fn clean_impl(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec {
         build_deref_target_impls(cx, &items, &mut ret);
     }
 
-    let provided: FxHashSet = trait_
+    let provided: FxHashSet = trait_
         .def_id()
-        .map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect())
+        .map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
         .unwrap_or_default();
 
     let for_ = for_.clean(cx);
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 52d023c83cb..cd6eccea532 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1762,7 +1762,7 @@ crate enum ImplPolarity {
 crate struct Impl {
     crate unsafety: hir::Unsafety,
     crate generics: Generics,
-    crate provided_trait_methods: FxHashSet,
+    crate provided_trait_methods: FxHashSet,
     crate trait_: Option,
     crate for_: Type,
     crate items: Vec,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 62dac717968..d55c8f38912 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2966,7 +2966,7 @@ fn render_assoc_item(
             AssocItemLink::GotoSource(did, provided_methods) => {
                 // We're creating a link from an impl-item to the corresponding
                 // trait-item and need to map the anchored type accordingly.
-                let ty = if provided_methods.contains(&*name.as_str()) {
+                let ty = if provided_methods.contains(&name) {
                     ItemType::Method
                 } else {
                     ItemType::TyMethod
@@ -3429,7 +3429,7 @@ fn render_union(
 #[derive(Copy, Clone)]
 enum AssocItemLink<'a> {
     Anchor(Option<&'a str>),
-    GotoSource(DefId, &'a FxHashSet),
+    GotoSource(DefId, &'a FxHashSet),
 }
 
 impl<'a> AssocItemLink<'a> {
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 9dc27e3411d..020b7787174 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -440,7 +440,10 @@ impl From for Impl {
         Impl {
             is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe,
             generics: generics.into(),
-            provided_trait_methods: provided_trait_methods.into_iter().collect(),
+            provided_trait_methods: provided_trait_methods
+                .into_iter()
+                .map(|x| x.to_string())
+                .collect(),
             trait_: trait_.map(Into::into),
             for_: for_.into(),
             items: ids(items),
-- 
cgit 1.4.1-3-g733a5


From 1523f67f16cb65da740d20b9853ce7f267579a7d Mon Sep 17 00:00:00 2001
From: Joshua Nelson 
Date: Wed, 16 Dec 2020 15:54:05 -0500
Subject: Calculate stability, const_stability, and deprecation on-demand

Previously, they would always be calculated ahead of time, which bloated
the size of `clean::Item`.
---
 src/librustdoc/clean/auto_trait.rs   |  3 --
 src/librustdoc/clean/blanket_impl.rs |  3 --
 src/librustdoc/clean/inline.rs       |  3 --
 src/librustdoc/clean/mod.rs          |  9 ----
 src/librustdoc/clean/types.rs        | 34 ++++++++------
 src/librustdoc/html/render/mod.rs    | 90 +++++++++++++++++++++---------------
 src/librustdoc/json/conversions.rs   | 13 +-----
 7 files changed, 75 insertions(+), 80 deletions(-)

(limited to 'src')

diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 40c59ed1e0b..96d19e8e17d 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -123,9 +123,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     attrs: Default::default(),
                     visibility: Inherited,
                     def_id: self.cx.next_def_id(param_env_def_id.krate),
-                    stability: None,
-                    const_stability: None,
-                    deprecation: None,
                     kind: ImplItem(Impl {
                         unsafety: hir::Unsafety::Normal,
                         generics: new_generics,
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 33b5e84c5e0..0ecd71d008f 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -112,9 +112,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     attrs: Default::default(),
                     visibility: Inherited,
                     def_id: self.cx.next_def_id(impl_def_id.krate),
-                    stability: None,
-                    const_stability: None,
-                    deprecation: None,
                     kind: ImplItem(Impl {
                         unsafety: hir::Unsafety::Normal,
                         generics: (
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 3cff5fa07b1..fd30d62ea1f 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -482,9 +482,6 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet)
                         source: clean::Span::dummy(),
                         def_id: DefId::local(CRATE_DEF_INDEX),
                         visibility: clean::Public,
-                        stability: None,
-                        const_stability: None,
-                        deprecation: None,
                         kind: clean::ImportItem(clean::Import::new_simple(
                             item.ident.name,
                             clean::ImportSource {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2809e85761d..0d3bfd26f96 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2139,9 +2139,6 @@ fn clean_extern_crate(
         source: krate.span.clean(cx),
         def_id: crate_def_id,
         visibility: krate.vis.clean(cx),
-        stability: None,
-        const_stability: None,
-        deprecation: None,
         kind: ExternCrateItem(name, orig_name),
     }]
 }
@@ -2210,9 +2207,6 @@ impl Clean> for doctree::Import<'_> {
                         source: self.span.clean(cx),
                         def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
                         visibility: self.vis.clean(cx),
-                        stability: None,
-                        const_stability: None,
-                        deprecation: None,
                         kind: ImportItem(Import::new_simple(
                             self.name,
                             resolve_use_source(cx, path),
@@ -2231,9 +2225,6 @@ impl Clean> for doctree::Import<'_> {
             source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
-            stability: None,
-            const_stability: None,
-            deprecation: None,
             kind: ImportItem(inner),
         }]
     }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 52d023c83cb..9cff129993d 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -86,9 +86,6 @@ crate struct Item {
     crate visibility: Visibility,
     crate kind: ItemKind,
     crate def_id: DefId,
-    crate stability: Option,
-    crate deprecation: Option,
-    crate const_stability: Option,
 }
 
 impl fmt::Debug for Item {
@@ -102,13 +99,23 @@ impl fmt::Debug for Item {
             .field("kind", &self.kind)
             .field("visibility", &self.visibility)
             .field("def_id", def_id)
-            .field("stability", &self.stability)
-            .field("deprecation", &self.deprecation)
             .finish()
     }
 }
 
 impl Item {
+    crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx Stability> {
+        if self.is_fake() { None } else { tcx.lookup_stability(self.def_id) }
+    }
+
+    crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ConstStability> {
+        if self.is_fake() { None } else { tcx.lookup_const_stability(self.def_id) }
+    }
+
+    crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option {
+        if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id) }
+    }
+
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
     crate fn doc_value(&self) -> Option<&str> {
@@ -150,9 +157,6 @@ impl Item {
             source: source.clean(cx),
             attrs: cx.tcx.get_attrs(def_id).clean(cx),
             visibility: cx.tcx.visibility(def_id).clean(cx),
-            stability: cx.tcx.lookup_stability(def_id).cloned(),
-            deprecation: cx.tcx.lookup_deprecation(def_id),
-            const_stability: cx.tcx.lookup_const_stability(def_id).cloned(),
         }
     }
 
@@ -236,8 +240,8 @@ impl Item {
         }
     }
 
-    crate fn stability_class(&self) -> Option {
-        self.stability.as_ref().and_then(|ref s| {
+    crate fn stability_class(&self, tcx: TyCtxt<'_>) -> Option {
+        self.stability(tcx).as_ref().and_then(|ref s| {
             let mut classes = Vec::with_capacity(2);
 
             if s.level.is_unstable() {
@@ -245,7 +249,7 @@ impl Item {
             }
 
             // FIXME: what about non-staged API items that are deprecated?
-            if self.deprecation.is_some() {
+            if self.deprecation(tcx).is_some() {
                 classes.push("deprecated");
             }
 
@@ -253,15 +257,15 @@ impl Item {
         })
     }
 
-    crate fn stable_since(&self) -> Option {
-        match self.stability?.level {
+    crate fn stable_since(&self, tcx: TyCtxt<'_>) -> Option {
+        match self.stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since.as_str()),
             StabilityLevel::Unstable { .. } => None,
         }
     }
 
-    crate fn const_stable_since(&self) -> Option {
-        match self.const_stability?.level {
+    crate fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option {
+        match self.const_stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since.as_str()),
             StabilityLevel::Unstable { .. } => None,
         }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 67ccc3d4cf8..75c32481286 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -164,7 +164,7 @@ crate struct SharedContext<'tcx> {
     playground: Option,
 }
 
-impl Context<'_> {
+impl<'tcx> Context<'tcx> {
     fn path(&self, filename: &str) -> PathBuf {
         // We use splitn vs Path::extension here because we might get a filename
         // like `style.min.css` and we want to process that into
@@ -176,6 +176,10 @@ impl Context<'_> {
         self.dst.join(&filename)
     }
 
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.shared.tcx
+    }
+
     fn sess(&self) -> &Session {
         &self.shared.tcx.sess
     }
@@ -1708,8 +1712,8 @@ fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Ca
     write!(buf, "

"); render_stability_since_raw( buf, - item.stable_since().as_deref(), - item.const_stable_since().as_deref(), + item.stable_since(cx.tcx()).as_deref(), + item.const_stable_since(cx.tcx()).as_deref(), None, None, ); @@ -2061,14 +2065,20 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl } } - fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering { + fn cmp( + i1: &clean::Item, + i2: &clean::Item, + idx1: usize, + idx2: usize, + tcx: TyCtxt<'_>, + ) -> Ordering { let ty1 = i1.type_(); let ty2 = i2.type_(); if ty1 != ty2 { return (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2)); } - let s1 = i1.stability.as_ref().map(|s| s.level); - let s2 = i2.stability.as_ref().map(|s| s.level); + let s1 = i1.stability(tcx).as_ref().map(|s| s.level); + let s2 = i2.stability(tcx).as_ref().map(|s| s.level); if let (Some(a), Some(b)) = (s1, s2) { match (a.is_stable(), b.is_stable()) { (true, true) | (false, false) => {} @@ -2082,7 +2092,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl } if cx.shared.sort_modules_alphabetically { - indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); + indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2, cx.tcx())); } // This call is to remove re-export duplicates in cases such as: // @@ -2184,7 +2194,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl _ => "", }; - let stab = myitem.stability_class(); + let stab = myitem.stability_class(cx.tcx()); let add = if stab.is_some() { " " } else { "" }; let doc_value = myitem.doc_value().unwrap_or(""); @@ -2196,7 +2206,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl {stab_tags}{docs}\ ", name = *myitem.name.as_ref().unwrap(), - stab_tags = extra_info_tags(myitem, item), + stab_tags = extra_info_tags(myitem, item, cx.tcx()), docs = MarkdownSummaryLine(doc_value, &myitem.links()).into_string(), class = myitem.type_(), add = add, @@ -2220,7 +2230,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl /// Render the stability, deprecation and portability tags that are displayed in the item's summary /// at the module level. -fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String { +fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) -> String { let mut tags = String::new(); fn tag_html(class: &str, title: &str, contents: &str) -> String { @@ -2228,7 +2238,7 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String { } // The trailing space after each tag is to space it properly against the rest of the docs. - if let Some(depr) = &item.deprecation { + if let Some(depr) = &item.deprecation(tcx) { let mut message = "Deprecated"; if !stability::deprecation_in_effect( depr.is_since_rustc_version, @@ -2241,7 +2251,10 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String { // The "rustc_private" crates are permanently unstable so it makes no sense // to render "unstable" everywhere. - if item.stability.as_ref().map(|s| s.level.is_unstable() && s.feature != sym::rustc_private) + if item + .stability(tcx) + .as_ref() + .map(|s| s.level.is_unstable() && s.feature != sym::rustc_private) == Some(true) { tags += &tag_html("unstable", "", "Experimental"); @@ -2287,7 +2300,7 @@ fn short_item_info( let error_codes = cx.shared.codes; if let Some(Deprecation { note, since, is_since_rustc_version, suggestion: _ }) = - item.deprecation + item.deprecation(cx.tcx()) { // We display deprecation messages for #[deprecated] and #[rustc_deprecated] // but only display the future-deprecation messages for #[rustc_deprecated]. @@ -2327,7 +2340,7 @@ fn short_item_info( // Render unstable items. But don't render "rustc_private" crates (internal compiler crates). // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere. if let Some((StabilityLevel::Unstable { reason, issue, .. }, feature)) = item - .stability + .stability(cx.tcx()) .as_ref() .filter(|stab| stab.feature != sym::rustc_private) .map(|stab| (stab.level, stab.feature)) @@ -2480,8 +2493,8 @@ fn render_implementor( parent, AssocItemLink::Anchor(None), RenderMode::Normal, - implementor.impl_item.stable_since().as_deref(), - implementor.impl_item.const_stable_since().as_deref(), + implementor.impl_item.stable_since(cx.tcx()).as_deref(), + implementor.impl_item.const_stable_since(cx.tcx()).as_deref(), false, Some(use_absolute), false, @@ -2511,8 +2524,8 @@ fn render_impls( containing_item, assoc_link, RenderMode::Normal, - containing_item.stable_since().as_deref(), - containing_item.const_stable_since().as_deref(), + containing_item.stable_since(cx.tcx()).as_deref(), + containing_item.const_stable_since(cx.tcx()).as_deref(), true, None, false, @@ -2661,7 +2674,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra write!(w, "

", id = id,); render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl); write!(w, ""); - render_stability_since(w, m, t); + render_stability_since(w, m, t, cx.tcx()); write_srclink(cx, m, w, cache); write!(w, "

"); document(w, cx, m, Some(t)); @@ -2768,8 +2781,8 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra it, assoc_link, RenderMode::Normal, - implementor.impl_item.stable_since().as_deref(), - implementor.impl_item.const_stable_since().as_deref(), + implementor.impl_item.stable_since(cx.tcx()).as_deref(), + implementor.impl_item.const_stable_since(cx.tcx()).as_deref(), false, None, true, @@ -2950,13 +2963,18 @@ fn render_stability_since_raw( } } -fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: &clean::Item) { +fn render_stability_since( + w: &mut Buffer, + item: &clean::Item, + containing_item: &clean::Item, + tcx: TyCtxt<'_>, +) { render_stability_since_raw( w, - item.stable_since().as_deref(), - item.const_stable_since().as_deref(), - containing_item.stable_since().as_deref(), - containing_item.const_stable_since().as_deref(), + item.stable_since(tcx).as_deref(), + item.const_stable_since(tcx).as_deref(), + containing_item.stable_since(tcx).as_deref(), + containing_item.const_stable_since(tcx).as_deref(), ) } @@ -3149,7 +3167,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni shortty = ItemType::StructField, ty = ty.print() ); - if let Some(stability_class) = field.stability_class() { + if let Some(stability_class) = field.stability_class(cx.tcx()) { write!(w, "", stab = stability_class); } document(w, cx, field, Some(it)); @@ -3279,7 +3297,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum } write!(w, ""); } - render_stability_since(w, variant, it); + render_stability_since(w, variant, it, cx.tcx()); } } render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) @@ -3510,8 +3528,8 @@ fn render_assoc_items( containing_item, AssocItemLink::Anchor(None), render_mode, - containing_item.stable_since().as_deref(), - containing_item.const_stable_since().as_deref(), + containing_item.stable_since(cx.tcx()).as_deref(), + containing_item.const_stable_since(cx.tcx()).as_deref(), true, None, false, @@ -3758,8 +3776,8 @@ fn render_impl( write!(w, "
", id); render_stability_since_raw( w, - i.impl_item.stable_since().as_deref(), - i.impl_item.const_stable_since().as_deref(), + i.impl_item.stable_since(cx.tcx()).as_deref(), + i.impl_item.const_stable_since(cx.tcx()).as_deref(), outer_version, outer_const_version, ); @@ -3831,8 +3849,8 @@ fn render_impl( write!(w, ""); render_stability_since_raw( w, - item.stable_since().as_deref(), - item.const_stable_since().as_deref(), + item.stable_since(cx.tcx()).as_deref(), + item.const_stable_since(cx.tcx()).as_deref(), outer_version, outer_const_version, ); @@ -3853,8 +3871,8 @@ fn render_impl( write!(w, ""); render_stability_since_raw( w, - item.stable_since().as_deref(), - item.const_stable_since().as_deref(), + item.stable_since(cx.tcx()).as_deref(), + item.const_stable_since(cx.tcx()).as_deref(), outer_version, outer_const_version, ); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 99587f4ec64..ef490086ed0 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -17,17 +17,8 @@ use crate::json::JsonRenderer; impl JsonRenderer<'_> { pub(super) fn convert_item(&self, item: clean::Item) -> Option { let item_type = ItemType::from(&item); - let clean::Item { - source, - name, - attrs, - kind, - visibility, - def_id, - stability: _, - const_stability: _, - deprecation, - } = item; + let deprecation = item.deprecation(self.tcx); + let clean::Item { source, name, attrs, kind, visibility, def_id } = item; match kind { clean::StrippedItem(_) => None, _ => Some(Item { -- cgit 1.4.1-3-g733a5 From 74498c17e0d7ba29dd33e7765234ea75929b6aa7 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 16 Dec 2020 09:03:33 -0800 Subject: Update cargo --- Cargo.lock | 60 +++++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 3 +++ src/bootstrap/dist.rs | 6 ++++++ src/bootstrap/tool.rs | 37 +++++++++++++++++++++++++++++-- src/tools/cargo | 2 +- 5 files changed, 101 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 9fef7fc1e35..fcfd23f2dae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,35 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "cargo-credential" +version = "0.1.0" + +[[package]] +name = "cargo-credential-1password" +version = "0.1.0" +dependencies = [ + "cargo-credential", + "serde", + "serde_json", +] + +[[package]] +name = "cargo-credential-macos-keychain" +version = "0.1.0" +dependencies = [ + "cargo-credential", + "security-framework", +] + +[[package]] +name = "cargo-credential-wincred" +version = "0.1.0" +dependencies = [ + "cargo-credential", + "winapi 0.3.9", +] + [[package]] name = "cargo-miri" version = "0.1.0" @@ -4442,6 +4471,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "security-framework" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.9.0" @@ -4489,18 +4541,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.115" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.115" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index e1a36d88086..204c92045b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,9 @@ members = [ "src/tools/rust-installer", "src/tools/rust-demangler", "src/tools/cargo", + "src/tools/cargo/crates/credential/cargo-credential-1password", + "src/tools/cargo/crates/credential/cargo-credential-macos-keychain", + "src/tools/cargo/crates/credential/cargo-credential-wincred", "src/tools/rustdoc", "src/tools/rls", "src/tools/rustfmt", diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 360e51ed2bb..46110b71153 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1247,6 +1247,12 @@ impl Step for Cargo { builder.create_dir(&image.join("etc/bash_completion.d")); let cargo = builder.ensure(tool::Cargo { compiler, target }); builder.install(&cargo, &image.join("bin"), 0o755); + for dirent in fs::read_dir(cargo.parent().unwrap()).expect("read_dir") { + let dirent = dirent.expect("read dir entry"); + if dirent.file_name().to_str().expect("utf8").starts_with("cargo-credential-") { + builder.install(&dirent.path(), &image.join("libexec"), 0o755); + } + } for man in t!(etc.join("man").read_dir()) { let man = t!(man); builder.install(&man.path(), &image.join("share/man/man1"), 0o644); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 290e3744852..dc786249d99 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -563,7 +563,7 @@ impl Step for Cargo { } fn run(self, builder: &Builder<'_>) -> PathBuf { - builder + let cargo_bin_path = builder .ensure(ToolBuild { compiler: self.compiler, target: self.target, @@ -574,7 +574,40 @@ impl Step for Cargo { source_type: SourceType::Submodule, extra_features: Vec::new(), }) - .expect("expected to build -- essential tool") + .expect("expected to build -- essential tool"); + + let build_cred = |name, path| { + // These credential helpers are currently experimental. + // Any build failures will be ignored. + let _ = builder.ensure(ToolBuild { + compiler: self.compiler, + target: self.target, + tool: name, + mode: Mode::ToolRustc, + path, + is_optional_tool: true, + source_type: SourceType::Submodule, + extra_features: Vec::new(), + }); + }; + + if self.target.contains("windows") { + build_cred( + "cargo-credential-wincred", + "src/tools/cargo/crates/credential/cargo-credential-wincred", + ); + } + if self.target.contains("apple-darwin") { + build_cred( + "cargo-credential-macos-keychain", + "src/tools/cargo/crates/credential/cargo-credential-macos-keychain", + ); + } + build_cred( + "cargo-credential-1password", + "src/tools/cargo/crates/credential/cargo-credential-1password", + ); + cargo_bin_path } } diff --git a/src/tools/cargo b/src/tools/cargo index d274fcf862b..a3c2627fbc2 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d274fcf862b89264fa2c6b917b15230705257317 +Subproject commit a3c2627fbc2f5391c65ba45ab53b81bf71fa323c -- cgit 1.4.1-3-g733a5 From 2309783a0b65163041b03dce04d7df85dcabc2cd Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 17 Dec 2020 00:42:49 +0000 Subject: Add tests --- .../exhaustiveness-unreachable-pattern.rs | 31 ++++++++++++++++++++++ .../exhaustiveness-unreachable-pattern.stderr | 22 +++++++++++---- src/test/ui/pattern/usefulness/issue-15129.rs | 8 +++--- src/test/ui/pattern/usefulness/issue-2111.rs | 13 +++++---- src/test/ui/pattern/usefulness/issue-2111.stderr | 6 ++--- src/test/ui/pattern/usefulness/issue-56379.rs | 14 ++++++++++ src/test/ui/pattern/usefulness/issue-56379.stderr | 20 ++++++++++++++ 7 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/pattern/usefulness/issue-56379.rs create mode 100644 src/test/ui/pattern/usefulness/issue-56379.stderr (limited to 'src') diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index 512f1e283cb..178a4aa6681 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -64,6 +64,37 @@ fn main() { | 2, ..] => {} _ => {} } + // FIXME: incorrect + match &[][..] { + [true] => {} + [true //~ ERROR unreachable + | false, ..] => {} + _ => {} + } + match &[][..] { + [false] => {} + [true, ..] => {} + [true //~ ERROR unreachable + | false, ..] => {} + _ => {} + } + match (true, None) { + (true, Some(_)) => {} + (false, Some(true)) => {} + (true | false, None | Some(true // FIXME: should be unreachable + | false)) => {} + } + macro_rules! t_or_f { + () => { + (true // FIXME: should be unreachable + | false) + }; + } + match (true, None) { + (true, Some(_)) => {} + (false, Some(true)) => {} + (true | false, None | Some(t_or_f!())) => {} + } match Some(0) { Some(0) => {} Some(0 //~ ERROR unreachable diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index e968310d108..38e2369ae7d 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -95,28 +95,40 @@ LL | [1 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:69:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:70:10 + | +LL | [true + | ^^^^ + +error: unreachable pattern + --> $DIR/exhaustiveness-unreachable-pattern.rs:77:10 + | +LL | [true + | ^^^^ + +error: unreachable pattern + --> $DIR/exhaustiveness-unreachable-pattern.rs:100:14 | LL | Some(0 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:88:19 + --> $DIR/exhaustiveness-unreachable-pattern.rs:119:19 | LL | | false) => {} | ^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:96:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:127:15 | LL | | true) => {} | ^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:102:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:133:15 | LL | | true, | ^^^^ -error: aborting due to 19 previous errors +error: aborting due to 21 previous errors diff --git a/src/test/ui/pattern/usefulness/issue-15129.rs b/src/test/ui/pattern/usefulness/issue-15129.rs index ed134c175ed..bcfc32be9a4 100644 --- a/src/test/ui/pattern/usefulness/issue-15129.rs +++ b/src/test/ui/pattern/usefulness/issue-15129.rs @@ -1,17 +1,17 @@ pub enum T { T1(()), - T2(()) + T2(()), } pub enum V { V1(isize), - V2(bool) + V2(bool), } fn main() { match (T::T1(()), V::V2(true)) { - //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered + //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered (T::T1(()), V::V1(i)) => (), - (T::T2(()), V::V2(b)) => () + (T::T2(()), V::V2(b)) => (), } } diff --git a/src/test/ui/pattern/usefulness/issue-2111.rs b/src/test/ui/pattern/usefulness/issue-2111.rs index 7e5835e8697..0847045cdaa 100644 --- a/src/test/ui/pattern/usefulness/issue-2111.rs +++ b/src/test/ui/pattern/usefulness/issue-2111.rs @@ -1,12 +1,11 @@ fn foo(a: Option, b: Option) { - match (a,b) { - //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered - (Some(a), Some(b)) if a == b => { } - (Some(_), None) | - (None, Some(_)) => { } - } + match (a, b) { + //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered + (Some(a), Some(b)) if a == b => {} + (Some(_), None) | (None, Some(_)) => {} + } } fn main() { - foo(None, None); + foo(None, None); } diff --git a/src/test/ui/pattern/usefulness/issue-2111.stderr b/src/test/ui/pattern/usefulness/issue-2111.stderr index a39a479e078..f0609ccebc1 100644 --- a/src/test/ui/pattern/usefulness/issue-2111.stderr +++ b/src/test/ui/pattern/usefulness/issue-2111.stderr @@ -1,8 +1,8 @@ error[E0004]: non-exhaustive patterns: `(None, None)` not covered - --> $DIR/issue-2111.rs:2:9 + --> $DIR/issue-2111.rs:2:11 | -LL | match (a,b) { - | ^^^^^ pattern `(None, None)` not covered +LL | match (a, b) { + | ^^^^^^ pattern `(None, None)` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `(Option, Option)` diff --git a/src/test/ui/pattern/usefulness/issue-56379.rs b/src/test/ui/pattern/usefulness/issue-56379.rs new file mode 100644 index 00000000000..5454e80cdb4 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-56379.rs @@ -0,0 +1,14 @@ +enum Foo { + A(bool), + B(bool), + C(bool), +} + +fn main() { + match Foo::A(true) { + //~^ ERROR non-exhaustive patterns: `A(false)` not covered + Foo::A(true) => {} + Foo::B(true) => {} + Foo::C(true) => {} + } +} diff --git a/src/test/ui/pattern/usefulness/issue-56379.stderr b/src/test/ui/pattern/usefulness/issue-56379.stderr new file mode 100644 index 00000000000..661e0dbb439 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-56379.stderr @@ -0,0 +1,20 @@ +error[E0004]: non-exhaustive patterns: `A(false)` not covered + --> $DIR/issue-56379.rs:8:11 + | +LL | / enum Foo { +LL | | A(bool), + | | - not covered +LL | | B(bool), +LL | | C(bool), +LL | | } + | |_- `Foo` defined here +... +LL | match Foo::A(true) { + | ^^^^^^^^^^^^ pattern `A(false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. -- cgit 1.4.1-3-g733a5 From d7a6365b77e171337d4f4220ebdc618965524ecd Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 17 Dec 2020 01:07:49 +0000 Subject: Rewrite usefulness merging using `SpanSet` `SpanSet` is heavily inspired from `DefIdForest`. --- .../src/thir/pattern/check_match.rs | 2 +- .../rustc_mir_build/src/thir/pattern/usefulness.rs | 177 +++++++++++++-------- .../exhaustiveness-unreachable-pattern.rs | 2 +- .../exhaustiveness-unreachable-pattern.stderr | 8 +- 4 files changed, 122 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 97edbd83b89..2c37f7bdb45 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -402,7 +402,7 @@ fn report_arm_reachability<'p, 'tcx>( Useful(unreachables) if unreachables.is_empty() => {} // The arm is reachable, but contains unreachable subpatterns (from or-patterns). Useful(unreachables) => { - let mut unreachables: Vec<_> = unreachables.iter().flatten().copied().collect(); + let mut unreachables: Vec<_> = unreachables.iter().collect(); // Emit lints in the order in which they occur in the file. unreachables.sort_unstable(); for span in unreachables { diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 9646f7ffcf7..5af155bd746 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -311,7 +311,6 @@ use super::{Pat, PatKind}; use super::{PatternFoldable, PatternFolder}; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::OnceCell; use rustc_arena::TypedArena; @@ -626,11 +625,81 @@ impl<'p, 'tcx> FromIterator> for Matrix<'p, 'tcx> { } } +/// Represents a set of `Span`s closed under the containment relation. That is, if a `Span` is +/// contained in the set then all `Span`s contained in it are also implicitly contained in the set. +/// In particular this means that when intersecting two sets, taking the intersection of some span +/// and one of its subspans returns the subspan, whereas a simple `HashSet` would have returned an +/// empty intersection. +/// It is assumed that two spans don't overlap without one being contained in the other; in other +/// words, that the inclusion structure forms a tree and not a DAG. +/// Operations on this do not need to be fast since it's only nonempty in the diagnostic path. +#[derive(Debug, Clone, Default)] +pub(crate) struct SpanSet { + /// The minimal set of `Span`s required to represent the whole set. If A and B are `Span`s in + /// the `SpanSet`, and A is a descendant of B, then only B will be in `root_spans`. + /// Invariant: the spans are disjoint. + root_spans: Vec, +} + +impl SpanSet { + /// Creates an empty set. + fn new() -> Self { + Self::default() + } + + /// Tests whether the set is empty. + pub(crate) fn is_empty(&self) -> bool { + self.root_spans.is_empty() + } + + /// Iterate over the disjoint list of spans at the roots of this set. + pub(crate) fn iter<'a>(&'a self) -> impl Iterator + Captures<'a> { + self.root_spans.iter().copied() + } + + /// Tests whether the set contains a given Span. + fn contains(&self, span: Span) -> bool { + self.iter().any(|root_span| root_span.contains(span)) + } + + /// Add a span to the set if we know the span has no intersection in this set. + fn push_nonintersecting(&mut self, new_span: Span) { + self.root_spans.push(new_span); + } + + fn intersection_mut(&mut self, other: &Self) { + if self.is_empty() || other.is_empty() { + *self = Self::new(); + return; + } + // Those that were in `self` but not contained in `other` + let mut leftover = SpanSet::new(); + // We keep the elements in `self` that are also in `other`. + self.root_spans.retain(|span| { + let retain = other.contains(*span); + if !retain { + leftover.root_spans.push(*span); + } + retain + }); + // We keep the elements in `other` that are also in the original `self`. You might think + // this is not needed because `self` already contains the intersection. But those aren't + // just sets of things. If `self = [a]`, `other = [b]` and `a` contains `b`, then `b` + // belongs in the intersection but we didn't catch it in the filtering above. We look at + // `leftover` instead of the full original `self` to avoid duplicates. + for span in other.iter() { + if leftover.contains(span) { + self.root_spans.push(span); + } + } + } +} + #[derive(Clone, Debug)] crate enum Usefulness<'tcx> { - /// Carries, for each column in the matrix, a set of sub-branches that have been found to be - /// unreachable. Used only in the presence of or-patterns, otherwise it stays empty. - Useful(Vec>), + /// Pontentially carries a set of sub-branches that have been found to be unreachable. Used + /// only in the presence of or-patterns, otherwise it stays empty. + Useful(SpanSet), /// Carries a list of witnesses of non-exhaustiveness. UsefulWithWitness(Vec>), NotUseful, @@ -640,7 +709,7 @@ impl<'tcx> Usefulness<'tcx> { fn new_useful(preference: WitnessPreference) -> Self { match preference { ConstructWitness => UsefulWithWitness(vec![Witness(vec![])]), - LeaveOutWitness => Useful(vec![]), + LeaveOutWitness => Useful(Default::default()), } } @@ -650,22 +719,20 @@ impl<'tcx> Usefulness<'tcx> { /// When trying several branches and each returns a `Usefulness`, we need to combine the /// results together. - fn merge(usefulnesses: impl Iterator, column_count: usize) -> Self { - // If two branches have detected some unreachable sub-branches, we need to be careful. If - // they were detected in columns that are not the current one, we want to keep only the - // sub-branches that were unreachable in _all_ branches. Eg. in the following, the last - // `true` is unreachable in the second branch of the first or-pattern, but not otherwise. - // Therefore we don't want to lint that it is unreachable. - // + fn merge(usefulnesses: impl Iterator) -> Self { + // If we have detected some unreachable sub-branches, we only want to keep them when they + // were unreachable in _all_ branches. Eg. in the following, the last `true` is unreachable + // in the second branch of the first or-pattern, but not otherwise. Therefore we don't want + // to lint that it is unreachable. // ``` // match (true, true) { // (true, true) => {} // (false | true, false | true) => {} // } // ``` - // If however the sub-branches come from the current column, they come from the inside of - // the current or-pattern, and we want to keep them all. Eg. in the following, we _do_ want - // to lint that the last `false` is unreachable. + // Here however we _do_ want to lint that the last `false` is unreachable. So we don't want + // to intersect the spans that come directly from the or-pattern, since each branch of the + // or-pattern brings a new disjoint pattern. // ``` // match None { // Some(false) => {} @@ -673,35 +740,34 @@ impl<'tcx> Usefulness<'tcx> { // } // ``` - // We keep track of sub-branches separately depending on whether they come from this column - // or from others. - let mut unreachables_this_column: FxHashSet = FxHashSet::default(); - let mut unreachables_other_columns: Vec> = Vec::default(); - // Whether at least one branch is reachable. - let mut any_is_useful = false; + // Is `None` when no branch was useful. Will often be `Some(Spanset::new())` because the + // sets are only non-empty in the diagnostic path. + let mut unreachables: Option = None; + // In case of or-patterns we don't want to intersect subpatterns that come from the first + // column. Invariant: contains a list of disjoint spans. + let mut unreachables_this_column = Vec::new(); - for (u, span) in usefulnesses { + for (u, branch_span) in usefulnesses { match u { - Useful(unreachables) => { - if let Some((this_column, other_columns)) = unreachables.split_last() { - // We keep the union of unreachables found in the first column. - unreachables_this_column.extend(this_column); - // We keep the intersection of unreachables found in other columns. - if unreachables_other_columns.is_empty() { - unreachables_other_columns = other_columns.to_vec(); - } else { - unreachables_other_columns = unreachables_other_columns - .into_iter() - .zip(other_columns) - .map(|(x, y)| x.intersection(&y).copied().collect()) - .collect(); + Useful(spans) if spans.is_empty() => { + // Hot path: `spans` is only non-empty in the diagnostic path. + unreachables = Some(SpanSet::new()); + } + Useful(spans) => { + for span in spans.iter() { + if branch_span.contains(span) { + unreachables_this_column.push(span) } } - any_is_useful = true; - } - NotUseful => { - unreachables_this_column.insert(span); + if let Some(set) = &mut unreachables { + if !set.is_empty() { + set.intersection_mut(&spans); + } + } else { + unreachables = Some(spans); + } } + NotUseful => unreachables_this_column.push(branch_span), UsefulWithWitness(_) => { bug!( "encountered or-pat in the expansion of `_` during exhaustiveness checking" @@ -710,13 +776,13 @@ impl<'tcx> Usefulness<'tcx> { } } - if any_is_useful { - let mut unreachables = if unreachables_other_columns.is_empty() { - (0..column_count - 1).map(|_| FxHashSet::default()).collect() - } else { - unreachables_other_columns - }; - unreachables.push(unreachables_this_column); + if let Some(mut unreachables) = unreachables { + for span in unreachables_this_column { + // `unreachables` contained no spans from the first column, and + // `unreachables_this_column` contains only disjoint spans. Therefore it is valid + // to call `push_nonintersecting`. + unreachables.push_nonintersecting(span); + } Useful(unreachables) } else { NotUseful @@ -752,23 +818,6 @@ impl<'tcx> Usefulness<'tcx> { }; UsefulWithWitness(new_witnesses) } - Useful(mut unreachables) => { - if !unreachables.is_empty() { - // When we apply a constructor, there are `arity` columns of the matrix that - // corresponded to its arguments. All the unreachables found in these columns - // will, after `apply`, come from the first column. So we take the union of all - // the corresponding sets and put them in the first column. - // Note that `arity` may be 0, in which case we just push a new empty set. - let len = unreachables.len(); - let arity = ctor_wild_subpatterns.len(); - let mut unioned = FxHashSet::default(); - for set in unreachables.drain((len - arity)..) { - unioned.extend(set) - } - unreachables.push(unioned); - } - Useful(unreachables) - } x => x, } } @@ -926,7 +975,7 @@ fn is_useful<'p, 'tcx>( } (u, span) }); - Usefulness::merge(usefulnesses, v.len()) + Usefulness::merge(usefulnesses) } else { v.head_ctor(cx) .split(pcx, Some(hir_id)) diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index 178a4aa6681..3e242a797a2 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -81,7 +81,7 @@ fn main() { match (true, None) { (true, Some(_)) => {} (false, Some(true)) => {} - (true | false, None | Some(true // FIXME: should be unreachable + (true | false, None | Some(true //~ ERROR unreachable | false)) => {} } macro_rules! t_or_f { diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index 38e2369ae7d..ac0b34c2bd5 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -106,6 +106,12 @@ error: unreachable pattern LL | [true | ^^^^ +error: unreachable pattern + --> $DIR/exhaustiveness-unreachable-pattern.rs:84:36 + | +LL | (true | false, None | Some(true + | ^^^^ + error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:100:14 | @@ -130,5 +136,5 @@ error: unreachable pattern LL | | true, | ^^^^ -error: aborting due to 21 previous errors +error: aborting due to 22 previous errors -- cgit 1.4.1-3-g733a5 From 2d71a0b9b9871966dd1f63b4113eeecc2d6e2f6f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 17 Dec 2020 01:18:01 +0000 Subject: Keep all witnesses of non-exhaustiveness --- .../rustc_mir_build/src/thir/pattern/usefulness.rs | 64 +++++++++++++--------- src/test/ui/pattern/usefulness/issue-15129.rs | 2 +- src/test/ui/pattern/usefulness/issue-15129.stderr | 4 +- src/test/ui/pattern/usefulness/issue-2111.rs | 2 +- src/test/ui/pattern/usefulness/issue-2111.stderr | 4 +- src/test/ui/pattern/usefulness/issue-56379.rs | 2 +- src/test/ui/pattern/usefulness/issue-56379.stderr | 6 +- .../ui/pattern/usefulness/non-exhaustive-match.rs | 2 +- .../pattern/usefulness/non-exhaustive-match.stderr | 4 +- 9 files changed, 51 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 5af155bd746..02b5e0eb3b2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -713,13 +713,9 @@ impl<'tcx> Usefulness<'tcx> { } } - fn is_useful(&self) -> bool { - !matches!(*self, NotUseful) - } - /// When trying several branches and each returns a `Usefulness`, we need to combine the /// results together. - fn merge(usefulnesses: impl Iterator) -> Self { + fn merge_or_patterns(usefulnesses: impl Iterator) -> Self { // If we have detected some unreachable sub-branches, we only want to keep them when they // were unreachable in _all_ branches. Eg. in the following, the last `true` is unreachable // in the second branch of the first or-pattern, but not otherwise. Therefore we don't want @@ -789,6 +785,27 @@ impl<'tcx> Usefulness<'tcx> { } } + /// When trying several branches and each returns a `Usefulness`, we need to combine the + /// results together. + fn merge_split_constructors(usefulnesses: impl Iterator) -> Self { + // Witnesses of usefulness, if any. + let mut witnesses = Vec::new(); + + for u in usefulnesses { + match u { + Useful(..) => { + return u; + } + NotUseful => {} + UsefulWithWitness(wits) => { + witnesses.extend(wits); + } + } + } + + if !witnesses.is_empty() { UsefulWithWitness(witnesses) } else { NotUseful } + } + fn apply_constructor<'p>( self, pcx: PatCtxt<'_, 'p, 'tcx>, @@ -975,29 +992,22 @@ fn is_useful<'p, 'tcx>( } (u, span) }); - Usefulness::merge(usefulnesses) + Usefulness::merge_or_patterns(usefulnesses) } else { - v.head_ctor(cx) - .split(pcx, Some(hir_id)) - .into_iter() - .map(|ctor| { - // We cache the result of `Fields::wildcards` because it is used a lot. - let ctor_wild_subpatterns = Fields::wildcards(pcx, &ctor); - let matrix = pcx.matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns); - let v = v.pop_head_constructor(&ctor_wild_subpatterns); - let usefulness = is_useful( - pcx.cx, - &matrix, - &v, - witness_preference, - hir_id, - is_under_guard, - false, - ); - usefulness.apply_constructor(pcx, &ctor, &ctor_wild_subpatterns) - }) - .find(|result| result.is_useful()) - .unwrap_or(NotUseful) + // We split the head constructor of `v`. + let ctors = v.head_ctor(cx).split(pcx, Some(hir_id)); + // For each constructor, we compute whether there's a value that starts with it that would + // witness the usefulness of `v`. + let usefulnesses = ctors.into_iter().map(|ctor| { + // We cache the result of `Fields::wildcards` because it is used a lot. + let ctor_wild_subpatterns = Fields::wildcards(pcx, &ctor); + let matrix = pcx.matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns); + let v = v.pop_head_constructor(&ctor_wild_subpatterns); + let usefulness = + is_useful(pcx.cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false); + usefulness.apply_constructor(pcx, &ctor, &ctor_wild_subpatterns) + }); + Usefulness::merge_split_constructors(usefulnesses) }; debug!("is_useful::returns({:#?}, {:#?}) = {:?}", matrix, v, ret); ret diff --git a/src/test/ui/pattern/usefulness/issue-15129.rs b/src/test/ui/pattern/usefulness/issue-15129.rs index bcfc32be9a4..d2b72a86b74 100644 --- a/src/test/ui/pattern/usefulness/issue-15129.rs +++ b/src/test/ui/pattern/usefulness/issue-15129.rs @@ -10,7 +10,7 @@ pub enum V { fn main() { match (T::T1(()), V::V2(true)) { - //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered + //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered (T::T1(()), V::V1(i)) => (), (T::T2(()), V::V2(b)) => (), } diff --git a/src/test/ui/pattern/usefulness/issue-15129.stderr b/src/test/ui/pattern/usefulness/issue-15129.stderr index aa4434e72b5..79a77240937 100644 --- a/src/test/ui/pattern/usefulness/issue-15129.stderr +++ b/src/test/ui/pattern/usefulness/issue-15129.stderr @@ -1,8 +1,8 @@ -error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered +error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered --> $DIR/issue-15129.rs:12:11 | LL | match (T::T1(()), V::V2(true)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` not covered + | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `(T, V)` diff --git a/src/test/ui/pattern/usefulness/issue-2111.rs b/src/test/ui/pattern/usefulness/issue-2111.rs index 0847045cdaa..d27beaeffd6 100644 --- a/src/test/ui/pattern/usefulness/issue-2111.rs +++ b/src/test/ui/pattern/usefulness/issue-2111.rs @@ -1,6 +1,6 @@ fn foo(a: Option, b: Option) { match (a, b) { - //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered + //~^ ERROR: non-exhaustive patterns: `(None, None)` and `(Some(_), Some(_))` not covered (Some(a), Some(b)) if a == b => {} (Some(_), None) | (None, Some(_)) => {} } diff --git a/src/test/ui/pattern/usefulness/issue-2111.stderr b/src/test/ui/pattern/usefulness/issue-2111.stderr index f0609ccebc1..60d9b8514b7 100644 --- a/src/test/ui/pattern/usefulness/issue-2111.stderr +++ b/src/test/ui/pattern/usefulness/issue-2111.stderr @@ -1,8 +1,8 @@ -error[E0004]: non-exhaustive patterns: `(None, None)` not covered +error[E0004]: non-exhaustive patterns: `(None, None)` and `(Some(_), Some(_))` not covered --> $DIR/issue-2111.rs:2:11 | LL | match (a, b) { - | ^^^^^^ pattern `(None, None)` not covered + | ^^^^^^ patterns `(None, None)` and `(Some(_), Some(_))` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `(Option, Option)` diff --git a/src/test/ui/pattern/usefulness/issue-56379.rs b/src/test/ui/pattern/usefulness/issue-56379.rs index 5454e80cdb4..9bccccca9c2 100644 --- a/src/test/ui/pattern/usefulness/issue-56379.rs +++ b/src/test/ui/pattern/usefulness/issue-56379.rs @@ -6,7 +6,7 @@ enum Foo { fn main() { match Foo::A(true) { - //~^ ERROR non-exhaustive patterns: `A(false)` not covered + //~^ ERROR non-exhaustive patterns: `A(false)`, `B(false)` and `C(false)` not covered Foo::A(true) => {} Foo::B(true) => {} Foo::C(true) => {} diff --git a/src/test/ui/pattern/usefulness/issue-56379.stderr b/src/test/ui/pattern/usefulness/issue-56379.stderr index 661e0dbb439..6a231b868c8 100644 --- a/src/test/ui/pattern/usefulness/issue-56379.stderr +++ b/src/test/ui/pattern/usefulness/issue-56379.stderr @@ -1,16 +1,18 @@ -error[E0004]: non-exhaustive patterns: `A(false)` not covered +error[E0004]: non-exhaustive patterns: `A(false)`, `B(false)` and `C(false)` not covered --> $DIR/issue-56379.rs:8:11 | LL | / enum Foo { LL | | A(bool), | | - not covered LL | | B(bool), + | | - not covered LL | | C(bool), + | | - not covered LL | | } | |_- `Foo` defined here ... LL | match Foo::A(true) { - | ^^^^^^^^^^^^ pattern `A(false)` not covered + | ^^^^^^^^^^^^ patterns `A(false)`, `B(false)` and `C(false)` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `Foo` diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs index a28cfb579f4..4ff12aa2ff5 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs @@ -15,7 +15,7 @@ fn main() { // and `(_, _, 5_i32..=i32::MAX)` not covered (_, _, 4) => {} } - match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` not covered + match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` and `(B, B)` not covered (T::A, T::B) => {} (T::B, T::A) => {} } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr index 12412743b83..c953cd31440 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -45,11 +45,11 @@ LL | match (2, 3, 4) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `(i32, i32, i32)` -error[E0004]: non-exhaustive patterns: `(A, A)` not covered +error[E0004]: non-exhaustive patterns: `(A, A)` and `(B, B)` not covered --> $DIR/non-exhaustive-match.rs:18:11 | LL | match (T::A, T::A) { - | ^^^^^^^^^^^^ pattern `(A, A)` not covered + | ^^^^^^^^^^^^ patterns `(A, A)` and `(B, B)` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `(T, T)` -- cgit 1.4.1-3-g733a5 From 6319d737e07d732aa044864933b69a39fdbeec0a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 17 Dec 2020 01:25:53 +0000 Subject: Merge unreachable subpatterns correctly --- .../rustc_mir_build/src/thir/pattern/usefulness.rs | 31 +++++++++++++++++++--- .../exhaustiveness-unreachable-pattern.rs | 4 +-- .../exhaustiveness-unreachable-pattern.stderr | 20 +++++--------- 3 files changed, 36 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 02b5e0eb3b2..c07d4c9b8f7 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -788,13 +788,32 @@ impl<'tcx> Usefulness<'tcx> { /// When trying several branches and each returns a `Usefulness`, we need to combine the /// results together. fn merge_split_constructors(usefulnesses: impl Iterator) -> Self { + // If we have detected some unreachable sub-branches, we only want to keep them when they + // were unreachable in _all_ branches. So we take a big intersection. + + // Is `None` when no branch was useful. Will often be `Some(Spanset::new())` because the + // sets are only non-empty in the diagnostic path. + let mut unreachables: Option = None; // Witnesses of usefulness, if any. let mut witnesses = Vec::new(); for u in usefulnesses { match u { - Useful(..) => { - return u; + Useful(spans) if spans.is_empty() => { + // Once we reach the empty set, more intersections won't change the result. + return Useful(SpanSet::new()); + } + Useful(spans) => { + if let Some(unreachables) = &mut unreachables { + if !unreachables.is_empty() { + unreachables.intersection_mut(&spans); + } + if unreachables.is_empty() { + return Useful(SpanSet::new()); + } + } else { + unreachables = Some(spans); + } } NotUseful => {} UsefulWithWitness(wits) => { @@ -803,7 +822,13 @@ impl<'tcx> Usefulness<'tcx> { } } - if !witnesses.is_empty() { UsefulWithWitness(witnesses) } else { NotUseful } + if !witnesses.is_empty() { + UsefulWithWitness(witnesses) + } else if let Some(unreachables) = unreachables { + Useful(unreachables) + } else { + NotUseful + } } fn apply_constructor<'p>( diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index 3e242a797a2..184ffa85c40 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -64,11 +64,9 @@ fn main() { | 2, ..] => {} _ => {} } - // FIXME: incorrect match &[][..] { [true] => {} - [true //~ ERROR unreachable - | false, ..] => {} + [true | false, ..] => {} _ => {} } match &[][..] { diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index ac0b34c2bd5..8b1003b5514 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -95,46 +95,40 @@ LL | [1 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:70:10 + --> $DIR/exhaustiveness-unreachable-pattern.rs:75:10 | LL | [true | ^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:77:10 - | -LL | [true - | ^^^^ - -error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:84:36 + --> $DIR/exhaustiveness-unreachable-pattern.rs:82:36 | LL | (true | false, None | Some(true | ^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:100:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:98:14 | LL | Some(0 | ^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:119:19 + --> $DIR/exhaustiveness-unreachable-pattern.rs:117:19 | LL | | false) => {} | ^^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:127:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:125:15 | LL | | true) => {} | ^^^^ error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:133:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:131:15 | LL | | true, | ^^^^ -error: aborting due to 22 previous errors +error: aborting due to 21 previous errors -- cgit 1.4.1-3-g733a5 From a2fb4b95ddda1c2d622c809e63aa5e158cfb9976 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 16 Dec 2020 18:10:04 -0500 Subject: Remove `DefPath` from `Visibility` and calculate it on demand --- src/librustdoc/clean/mod.rs | 19 +++++----- src/librustdoc/clean/types.rs | 4 +-- src/librustdoc/html/format.rs | 11 +++--- src/librustdoc/html/render/mod.rs | 74 ++++++++++++++++++++++---------------- src/librustdoc/json/conversions.rs | 28 +++++++-------- 5 files changed, 75 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2809e85761d..0ce689957ca 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1775,25 +1775,28 @@ impl Clean for hir::Visibility<'_> { hir::VisibilityKind::Inherited => Visibility::Inherited, hir::VisibilityKind::Crate(_) => { let krate = DefId::local(CRATE_DEF_INDEX); - Visibility::Restricted(krate, cx.tcx.def_path(krate)) + Visibility::Restricted(krate) } hir::VisibilityKind::Restricted { ref path, .. } => { let path = path.clean(cx); let did = register_res(cx, path.res); - Visibility::Restricted(did, cx.tcx.def_path(did)) + Visibility::Restricted(did) } } } } impl Clean for ty::Visibility { - fn clean(&self, cx: &DocContext<'_>) -> Visibility { + fn clean(&self, _cx: &DocContext<'_>) -> Visibility { match *self { ty::Visibility::Public => Visibility::Public, + // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private', + // while rustdoc really does mean inherited. That means that for enum variants, such as + // `pub enum E { V }`, `V` will be marked as `Public` by `ty`, but as `Inherited` by rustdoc. + // This is the main reason `impl Clean for hir::Visibility` still exists; various parts of clean + // override `tcx.visibility` explicitly to make sure this distinction is captured. ty::Visibility::Invisible => Visibility::Inherited, - ty::Visibility::Restricted(module) => { - Visibility::Restricted(module, cx.tcx.def_path(module)) - } + ty::Visibility::Restricted(module) => Visibility::Restricted(module), } } } @@ -2303,14 +2306,14 @@ impl Clean for (&hir::MacroDef<'_>, Option) { if matchers.len() <= 1 { format!( "{}macro {}{} {{\n ...\n}}", - vis.print_with_space(), + vis.print_with_space(cx.tcx), name, matchers.iter().map(|span| span.to_src(cx)).collect::(), ) } else { format!( "{}macro {} {{\n{}}}", - vis.print_with_space(), + vis.print_with_space(cx.tcx), name, matchers .iter() diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 52d023c83cb..35917924fa6 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1569,11 +1569,11 @@ impl From for PrimitiveType { } } -#[derive(Clone, Debug)] +#[derive(Copy, Clone, Debug)] crate enum Visibility { Public, Inherited, - Restricted(DefId, rustc_hir::definitions::DefPath), + Restricted(DefId), } impl Visibility { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f80346aa50b..7b0b219570b 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -11,6 +11,7 @@ use std::fmt; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; use rustc_target::spec::abi::Abi; @@ -1084,18 +1085,18 @@ impl Function<'_> { } impl clean::Visibility { - crate fn print_with_space(&self) -> impl fmt::Display + '_ { + crate fn print_with_space<'tcx>(self, tcx: TyCtxt<'tcx>) -> impl fmt::Display + 'tcx { use rustc_span::symbol::kw; - display_fn(move |f| match *self { + display_fn(move |f| match self { clean::Public => f.write_str("pub "), clean::Inherited => Ok(()), - // If this is `pub(crate)`, `path` will be empty. - clean::Visibility::Restricted(did, _) if did.index == CRATE_DEF_INDEX => { + clean::Visibility::Restricted(did) if did.index == CRATE_DEF_INDEX => { write!(f, "pub(crate) ") } - clean::Visibility::Restricted(did, ref path) => { + clean::Visibility::Restricted(did) => { f.write_str("pub(")?; + let path = tcx.def_path(did); debug!("path={:?}", path); let first_name = path.data[0].data.get_opt_name().expect("modules are always named"); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 67ccc3d4cf8..76db0205695 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -164,7 +164,7 @@ crate struct SharedContext<'tcx> { playground: Option, } -impl Context<'_> { +impl<'tcx> Context<'tcx> { fn path(&self, filename: &str) -> PathBuf { // We use splitn vs Path::extension here because we might get a filename // like `style.min.css` and we want to process that into @@ -176,6 +176,10 @@ impl Context<'_> { self.dst.join(&filename) } + fn tcx(&self) -> TyCtxt<'tcx> { + self.shared.tcx + } + fn sess(&self) -> &Session { &self.shared.tcx.sess } @@ -2147,14 +2151,14 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl Some(ref src) => write!( w, "{}extern crate {} as {};", - myitem.visibility.print_with_space(), + myitem.visibility.print_with_space(cx.tcx()), anchor(myitem.def_id, &*src.as_str()), name ), None => write!( w, "{}extern crate {};", - myitem.visibility.print_with_space(), + myitem.visibility.print_with_space(cx.tcx()), anchor(myitem.def_id, &*name.as_str()) ), } @@ -2165,7 +2169,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl write!( w, "{}{}", - myitem.visibility.print_with_space(), + myitem.visibility.print_with_space(cx.tcx()), import.print() ); } @@ -2379,7 +2383,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean:: write!( w, "{vis}const {name}: {typ}", - vis = it.visibility.print_with_space(), + vis = it.visibility.print_with_space(cx.tcx()), name = it.name.as_ref().unwrap(), typ = c.type_.print(), ); @@ -2413,7 +2417,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St write!( w, "{vis}static {mutability}{name}: {typ}

", - vis = it.visibility.print_with_space(), + vis = it.visibility.print_with_space(cx.tcx()), mutability = s.mutability.print_with_space(), name = it.name.as_ref().unwrap(), typ = s.type_.print() @@ -2424,7 +2428,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { let header_len = format!( "{}{}{}{}{:#}fn {}{:#}", - it.visibility.print_with_space(), + it.visibility.print_with_space(cx.tcx()), f.header.constness.print_with_space(), f.header.asyncness.print_with_space(), f.header.unsafety.print_with_space(), @@ -2439,7 +2443,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: w, "{vis}{constness}{asyncness}{unsafety}{abi}fn \ {name}{generics}{decl}{spotlight}{where_clause}
", - vis = it.visibility.print_with_space(), + vis = it.visibility.print_with_space(cx.tcx()), constness = f.header.constness.print_with_space(), asyncness = f.header.asyncness.print_with_space(), unsafety = f.header.unsafety.print_with_space(), @@ -2565,7 +2569,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra write!( w, "{}{}{}trait {}{}{}", - it.visibility.print_with_space(), + it.visibility.print_with_space(cx.tcx()), t.unsafety.print_with_space(), if t.is_auto { "auto " } else { "" }, it.name.as_ref().unwrap(), @@ -2585,21 +2589,21 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra // FIXME: we should be using a derived_id for the Anchors here write!(w, "{{\n"); for t in &types { - render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait); + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); write!(w, ";\n"); } if !types.is_empty() && !consts.is_empty() { w.write_str("\n"); } for t in &consts { - render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait); + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); write!(w, ";\n"); } if !consts.is_empty() && !required.is_empty() { w.write_str("\n"); } for (pos, m) in required.iter().enumerate() { - render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait); + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); write!(w, ";\n"); if pos < required.len() - 1 { @@ -2610,7 +2614,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra w.write_str("\n"); } for (pos, m) in provided.iter().enumerate() { - render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait); + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); match m.kind { clean::MethodItem(ref inner, _) if !inner.generics.where_predicates.is_empty() => @@ -2659,7 +2663,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra let item_type = m.type_(); let id = cx.derive_id(format!("{}.{}", item_type, name)); write!(w, "

", id = id,); - render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl); + render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl, cx); write!(w, ""); render_stability_since(w, m, t); write_srclink(cx, m, w, cache); @@ -2877,12 +2881,13 @@ fn assoc_const( _default: Option<&String>, link: AssocItemLink<'_>, extra: &str, + cx: &Context<'_>, ) { write!( w, "{}{}const {}: {}", extra, - it.visibility.print_with_space(), + it.visibility.print_with_space(cx.tcx()), naive_assoc_href(it, link), it.name.as_ref().unwrap(), ty.print() @@ -2965,6 +2970,7 @@ fn render_assoc_item( item: &clean::Item, link: AssocItemLink<'_>, parent: ItemType, + cx: &Context<'_>, ) { fn method( w: &mut Buffer, @@ -2974,6 +2980,7 @@ fn render_assoc_item( d: &clean::FnDecl, link: AssocItemLink<'_>, parent: ItemType, + cx: &Context<'_>, ) { let name = meth.name.as_ref().unwrap(); let anchor = format!("#{}.{}", meth.type_(), name); @@ -2994,7 +3001,7 @@ fn render_assoc_item( }; let mut header_len = format!( "{}{}{}{}{}{:#}fn {}{:#}", - meth.visibility.print_with_space(), + meth.visibility.print_with_space(cx.tcx()), header.constness.print_with_space(), header.asyncness.print_with_space(), header.unsafety.print_with_space(), @@ -3016,7 +3023,7 @@ fn render_assoc_item( "{}{}{}{}{}{}{}fn {name}\ {generics}{decl}{spotlight}{where_clause}", if parent == ItemType::Trait { " " } else { "" }, - meth.visibility.print_with_space(), + meth.visibility.print_with_space(cx.tcx()), header.constness.print_with_space(), header.asyncness.print_with_space(), header.unsafety.print_with_space(), @@ -3032,9 +3039,11 @@ fn render_assoc_item( } match item.kind { clean::StrippedItem(..) => {} - clean::TyMethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent), + clean::TyMethodItem(ref m) => { + method(w, item, m.header, &m.generics, &m.decl, link, parent, cx) + } clean::MethodItem(ref m, _) => { - method(w, item, m.header, &m.generics, &m.decl, link, parent) + method(w, item, m.header, &m.generics, &m.decl, link, parent, cx) } clean::AssocConstItem(ref ty, ref default) => assoc_const( w, @@ -3043,6 +3052,7 @@ fn render_assoc_item( default.as_ref(), link, if parent == ItemType::Trait { " " } else { "" }, + cx, ), clean::AssocTypeItem(ref bounds, ref default) => assoc_type( w, @@ -3066,7 +3076,7 @@ fn item_struct( wrap_into_docblock(w, |w| { write!(w, "
");
         render_attributes(w, it, true);
-        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true);
+        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
         write!(w, "
") }); @@ -3116,7 +3126,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni wrap_into_docblock(w, |w| { write!(w, "
");
         render_attributes(w, it, true);
-        render_union(w, it, Some(&s.generics), &s.fields, "", true);
+        render_union(w, it, Some(&s.generics), &s.fields, "", true, cx);
         write!(w, "
") }); @@ -3165,7 +3175,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum write!( w, "{}enum {}{}{}", - it.visibility.print_with_space(), + it.visibility.print_with_space(cx.tcx()), it.name.as_ref().unwrap(), e.generics.print(), WhereClause { gens: &e.generics, indent: 0, end_newline: true } @@ -3191,7 +3201,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum write!(w, ")"); } clean::VariantKind::Struct(ref s) => { - render_struct(w, v, None, s.struct_type, &s.fields, " ", false); + render_struct(w, v, None, s.struct_type, &s.fields, " ", false, cx); } }, _ => unreachable!(), @@ -3335,11 +3345,12 @@ fn render_struct( fields: &[clean::Item], tab: &str, structhead: bool, + cx: &Context<'_>, ) { write!( w, "{}{}{}", - it.visibility.print_with_space(), + it.visibility.print_with_space(cx.tcx()), if structhead { "struct " } else { "" }, it.name.as_ref().unwrap() ); @@ -3359,7 +3370,7 @@ fn render_struct( w, "\n{} {}{}: {},", tab, - field.visibility.print_with_space(), + field.visibility.print_with_space(cx.tcx()), field.name.as_ref().unwrap(), ty.print() ); @@ -3388,7 +3399,7 @@ fn render_struct( match field.kind { clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"), clean::StructFieldItem(ref ty) => { - write!(w, "{}{}", field.visibility.print_with_space(), ty.print()) + write!(w, "{}{}", field.visibility.print_with_space(cx.tcx()), ty.print()) } _ => unreachable!(), } @@ -3416,11 +3427,12 @@ fn render_union( fields: &[clean::Item], tab: &str, structhead: bool, + cx: &Context<'_>, ) { write!( w, "{}{}{}", - it.visibility.print_with_space(), + it.visibility.print_with_space(cx.tcx()), if structhead { "union " } else { "" }, it.name.as_ref().unwrap() ); @@ -3435,7 +3447,7 @@ fn render_union( write!( w, " {}{}: {},\n{}", - field.visibility.print_with_space(), + field.visibility.print_with_space(cx.tcx()), field.name.as_ref().unwrap(), ty.print(), tab @@ -3827,7 +3839,7 @@ fn render_impl( let id = cx.derive_id(format!("{}.{}", item_type, name)); write!(w, "

", id, item_type, extra_class); write!(w, ""); - render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); + render_assoc_item(w, item, link.anchor(&id), ItemType::Impl, cx); write!(w, ""); render_stability_since_raw( w, @@ -3849,7 +3861,7 @@ fn render_impl( clean::AssocConstItem(ref ty, ref default) => { let id = cx.derive_id(format!("{}.{}", item_type, name)); write!(w, "

", id, item_type, extra_class); - assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), ""); + assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "", cx); write!(w, ""); render_stability_since_raw( w, @@ -4074,7 +4086,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache: write!( w, " {}type {};\n}}

", - it.visibility.print_with_space(), + it.visibility.print_with_space(cx.tcx()), it.name.as_ref().unwrap(), ); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 99587f4ec64..5a8b2cb5da1 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -35,7 +35,7 @@ impl JsonRenderer<'_> { crate_id: def_id.krate.as_u32(), name: name.map(|sym| sym.to_string()), source: self.convert_span(source), - visibility: visibility.into(), + visibility: self.convert_visibility(visibility), docs: attrs.collapsed_doc_value().unwrap_or_default(), links: attrs .links @@ -75,31 +75,29 @@ impl JsonRenderer<'_> { _ => None, } } -} - -impl From for Deprecation { - fn from(deprecation: rustc_attr::Deprecation) -> Self { - #[rustfmt::skip] - let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation; - Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) } - } -} -impl From for Visibility { - fn from(v: clean::Visibility) -> Self { + fn convert_visibility(&self, v: clean::Visibility) -> Visibility { use clean::Visibility::*; match v { Public => Visibility::Public, Inherited => Visibility::Default, - Restricted(did, _) if did.index == CRATE_DEF_INDEX => Visibility::Crate, - Restricted(did, path) => Visibility::Restricted { + Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate, + Restricted(did) => Visibility::Restricted { parent: did.into(), - path: path.to_string_no_crate_verbose(), + path: self.tcx.def_path(did).to_string_no_crate_verbose(), }, } } } +impl From for Deprecation { + fn from(deprecation: rustc_attr::Deprecation) -> Self { + #[rustfmt::skip] + let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation; + Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) } + } +} + impl From for GenericArgs { fn from(args: clean::GenericArgs) -> Self { use clean::GenericArgs::*; -- cgit 1.4.1-3-g733a5 From 328fcee4af7aed31343244206abb7dff25106d04 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Fri, 18 Dec 2020 13:24:55 -0500 Subject: Make BoundRegion have a kind of BoungRegionKind --- compiler/rustc_codegen_cranelift/src/abi/mod.rs | 2 +- .../src/infer/canonical/canonicalizer.rs | 3 +- .../rustc_infer/src/infer/canonical/substitute.rs | 2 +- .../rustc_infer/src/infer/error_reporting/mod.rs | 6 +- .../nice_region_error/find_anon_type.rs | 8 +-- .../error_reporting/nice_region_error/util.rs | 8 +-- .../rustc_infer/src/infer/higher_ranked/mod.rs | 4 +- compiler/rustc_infer/src/infer/mod.rs | 5 +- compiler/rustc_infer/src/infer/nll_relate/mod.rs | 2 +- compiler/rustc_middle/src/ich/impls_ty.rs | 6 +- compiler/rustc_middle/src/infer/canonical.rs | 7 ++- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_middle/src/ty/error.rs | 8 +-- compiler/rustc_middle/src/ty/fold.rs | 57 ++++++++----------- compiler/rustc_middle/src/ty/layout.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 6 +- compiler/rustc_middle/src/ty/print/pretty.rs | 18 +++--- compiler/rustc_middle/src/ty/structural_impls.rs | 8 +-- compiler/rustc_middle/src/ty/sty.rs | 32 +++++++---- compiler/rustc_middle/src/ty/util.rs | 3 +- .../rustc_mir/src/borrow_check/diagnostics/mod.rs | 4 +- .../src/borrow_check/diagnostics/region_errors.rs | 2 +- .../src/borrow_check/diagnostics/region_name.rs | 6 +- .../src/borrow_check/universal_regions.rs | 4 +- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 12 ++-- compiler/rustc_traits/src/chalk/lowering.rs | 66 ++++++++++------------ compiler/rustc_traits/src/chalk/mod.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 10 ++-- .../rustc_typeck/src/check/generator_interior.rs | 3 +- compiler/rustc_typeck/src/check/intrinsic.rs | 19 +++---- compiler/rustc_typeck/src/collect.rs | 2 +- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/clean/utils.rs | 4 +- .../escape-argument-callee.stderr | 2 +- .../closure-requirements/escape-argument.stderr | 2 +- .../propagate-approximated-fail-no-postdom.stderr | 2 +- .../propagate-approximated-ref.stderr | 2 +- ...shorter-to-static-comparing-against-free.stderr | 4 +- ...-approximated-shorter-to-static-no-bound.stderr | 2 +- ...proximated-shorter-to-static-wrong-bound.stderr | 2 +- .../propagate-approximated-val.stderr | 2 +- .../propagate-despite-same-free-region.stderr | 2 +- ...ate-fail-to-approximate-longer-no-bounds.stderr | 2 +- ...-fail-to-approximate-longer-wrong-bounds.stderr | 2 +- .../return-wrong-bound-region.stderr | 2 +- ...ty-param-closure-approximate-lower-bound.stderr | 4 +- 47 files changed, 183 insertions(+), 181 deletions(-) (limited to 'src') diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index aee274ab4a8..76e1987459f 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -64,7 +64,7 @@ pub(crate) fn fn_sig_for_fn_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx ty::Generator(_, substs, _) => { let sig = substs.as_generator().poly_sig(); - let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); + let env_region = ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrEnv }); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); let pin_did = tcx.require_lang_item(rustc_hir::LangItem::Pin, None); diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 8a60b196e5e..9002d251f12 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -625,7 +625,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); - let region = ty::ReLateBound(self.binder_index, ty::BoundRegion::BrAnon(var.as_u32())); + let br = ty::BoundRegion { kind: ty::BrAnon(var.as_u32()) }; + let region = ty::ReLateBound(self.binder_index, br); self.tcx().mk_region(region) } diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index cd4f1fa3bc3..387f480814a 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs @@ -87,6 +87,6 @@ where c => bug!("{:?} is a const but value is {:?}", bound_ct, c), }; - tcx.replace_escaping_bound_vars(value, fld_r, fld_t, fld_c).0 + tcx.replace_escaping_bound_vars(value, fld_r, fld_t, fld_c) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 18e1465c0e6..6b7edde9a67 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -165,7 +165,9 @@ fn msg_span_from_early_bound_and_free_regions( } (format!("the lifetime `{}` as defined on", br.name), sp) } - ty::ReFree(ty::FreeRegion { bound_region: ty::BoundRegion::BrNamed(_, name), .. }) => { + ty::ReFree(ty::FreeRegion { + bound_region: ty::BoundRegionKind::BrNamed(_, name), .. + }) => { let mut sp = sm.guess_head_span(tcx.hir().span(node)); if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) @@ -2279,7 +2281,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &self, var_origin: RegionVariableOrigin, ) -> DiagnosticBuilder<'tcx> { - let br_string = |br: ty::BoundRegion| { + let br_string = |br: ty::BoundRegionKind| { let mut s = match br { ty::BrNamed(_, name) => name.to_string(), _ => String::new(), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index eb1521f0565..b014b9832e7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -25,7 +25,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { pub(super) fn find_anon_type( &self, region: Region<'tcx>, - br: &ty::BoundRegion, + br: &ty::BoundRegionKind, ) -> Option<(&hir::Ty<'tcx>, &hir::FnDecl<'tcx>)> { if let Some(anon_reg) = self.tcx().is_suitable_region(region) { let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id); @@ -56,7 +56,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { fn find_component_for_bound_region( &self, arg: &'tcx hir::Ty<'tcx>, - br: &ty::BoundRegion, + br: &ty::BoundRegionKind, ) -> Option<&'tcx hir::Ty<'tcx>> { let mut nested_visitor = FindNestedTypeVisitor { tcx: self.tcx(), @@ -80,7 +80,7 @@ struct FindNestedTypeVisitor<'tcx> { tcx: TyCtxt<'tcx>, // The bound_region corresponding to the Refree(freeregion) // associated with the anonymous region we are looking for. - bound_region: ty::BoundRegion, + bound_region: ty::BoundRegionKind, // The type where the anonymous lifetime appears // for e.g., Vec<`&u8`> and <`&u8`> found_type: Option<&'tcx hir::Ty<'tcx>>, @@ -207,7 +207,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { struct TyPathVisitor<'tcx> { tcx: TyCtxt<'tcx>, found_it: bool, - bound_region: ty::BoundRegion, + bound_region: ty::BoundRegionKind, current_index: ty::DebruijnIndex, } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 61fad8863e7..17a56046a5c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -14,8 +14,8 @@ pub(super) struct AnonymousParamInfo<'tcx> { pub param: &'tcx hir::Param<'tcx>, /// The type corresponding to the anonymous region parameter. pub param_ty: Ty<'tcx>, - /// The ty::BoundRegion corresponding to the anonymous region. - pub bound_region: ty::BoundRegion, + /// The ty::BoundRegionKind corresponding to the anonymous region. + pub bound_region: ty::BoundRegionKind, /// The `Span` of the parameter type. pub param_ty_span: Span, /// Signals that the argument is the first parameter in the declaration. @@ -43,7 +43,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), ty::ReEarlyBound(ebr) => ( self.tcx().parent(ebr.def_id).unwrap(), - ty::BoundRegion::BrNamed(ebr.def_id, ebr.name), + ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region }; @@ -145,7 +145,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { pub(super) fn is_return_type_anon( &self, scope_def_id: LocalDefId, - br: ty::BoundRegion, + br: ty::BoundRegionKind, decl: &hir::FnDecl<'_>, ) -> Option { let ret_ty = self.tcx().type_of(scope_def_id); diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 39043980dc4..e794903fca3 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -77,10 +77,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // (i.e., if there are no placeholders). let next_universe = self.universe().next_universe(); - let fld_r = |br| { + let fld_r = |br: ty::BoundRegion| { self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion { universe: next_universe, - name: br, + name: br.kind, })) }; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 6affe0e5463..069f708856e 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -450,7 +450,7 @@ pub enum RegionVariableOrigin { /// Region variables created for bound regions /// in a function or method that is called - LateBoundRegion(Span, ty::BoundRegion, LateBoundRegionConversionTime), + LateBoundRegion(Span, ty::BoundRegionKind, LateBoundRegionConversionTime), UpvarRegion(ty::UpvarId, Span), @@ -1421,7 +1421,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { where T: TypeFoldable<'tcx>, { - let fld_r = |br| self.next_region_var(LateBoundRegion(span, br, lbrct)); + let fld_r = + |br: ty::BoundRegion| self.next_region_var(LateBoundRegion(span, br.kind, lbrct)); let fld_t = |_| { self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 0b2847658f7..971e0e1863b 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -176,7 +176,7 @@ where universe }); - let placeholder = ty::PlaceholderRegion { universe, name: br }; + let placeholder = ty::PlaceholderRegion { universe, name: br.kind }; delegate.next_placeholder_region(placeholder) } else { delegate.next_existential_region_var(true) diff --git a/compiler/rustc_middle/src/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs index 69bb4e23c4c..573b514e844 100644 --- a/compiler/rustc_middle/src/ich/impls_ty.rs +++ b/compiler/rustc_middle/src/ich/impls_ty.rs @@ -70,16 +70,16 @@ impl<'a> HashStable> for ty::RegionKind { ty::ReEmpty(universe) => { universe.hash_stable(hcx, hasher); } - ty::ReLateBound(db, ty::BrAnon(i)) => { + ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrAnon(i) }) => { db.hash_stable(hcx, hasher); i.hash_stable(hcx, hasher); } - ty::ReLateBound(db, ty::BrNamed(def_id, name)) => { + ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrNamed(def_id, name) }) => { db.hash_stable(hcx, hasher); def_id.hash_stable(hcx, hasher); name.hash_stable(hcx, hasher); } - ty::ReLateBound(db, ty::BrEnv) => { + ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrEnv }) => { db.hash_stable(hcx, hasher); } ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 6e5f95c4527..e106db38b2c 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -323,9 +323,10 @@ impl<'tcx> CanonicalVarValues<'tcx> { GenericArgKind::Type(..) => { tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() } - GenericArgKind::Lifetime(..) => tcx - .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))) - .into(), + GenericArgKind::Lifetime(..) => { + let br = ty::BoundRegion { kind: ty::BrAnon(i) }; + tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() + } GenericArgKind::Const(ct) => tcx .mk_const(ty::Const { ty: ct.ty, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index adf02412b96..ed91c4ffd88 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -889,7 +889,7 @@ pub struct FreeRegionInfo { // `LocalDefId` corresponding to FreeRegion pub def_id: LocalDefId, // the bound region corresponding to FreeRegion - pub boundregion: ty::BoundRegion, + pub boundregion: ty::BoundRegionKind, // checks if bound region is in Impl Item pub is_impl_item: bool, } @@ -1411,7 +1411,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } - // Returns the `DefId` and the `BoundRegion` corresponding to the given region. + // Returns the `DefId` and the `BoundRegionKind` corresponding to the given region. pub fn is_suitable_region(self, region: Region<'tcx>) -> Option { let (suitable_region_binding_scope, bound_region) = match *region { ty::ReFree(ref free_region) => { @@ -1419,7 +1419,7 @@ impl<'tcx> TyCtxt<'tcx> { } ty::ReEarlyBound(ref ebr) => ( self.parent(ebr.def_id).unwrap().expect_local(), - ty::BoundRegion::BrNamed(ebr.def_id, ebr.name), + ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region }; diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 97af927dfcb..fc02e78b2fa 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -1,6 +1,6 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::diagnostics::suggest_constraining_type_param; -use crate::ty::{self, BoundRegion, Region, Ty, TyCtxt}; +use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt}; use rustc_ast as ast; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{pluralize, DiagnosticBuilder}; @@ -42,8 +42,8 @@ pub enum TypeError<'tcx> { ArgCount, RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), - RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>), - RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>), + RegionsInsufficientlyPolymorphic(BoundRegionKind, Region<'tcx>), + RegionsOverlyPolymorphic(BoundRegionKind, Region<'tcx>), RegionsPlaceholderMismatch, Sorts(ExpectedFound>), @@ -94,7 +94,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } } - let br_string = |br: ty::BoundRegion| match br { + let br_string = |br: ty::BoundRegionKind| match br { ty::BrNamed(_, name) => format!(" {}", name), _ => String::new(), }; diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 13c8d6b2bcc..382f3708c3d 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -534,8 +534,8 @@ impl<'tcx> TyCtxt<'tcx> { /// results returned by the closure; the closure is expected to /// return a free region (relative to this binder), and hence the /// binder is removed in the return type. The closure is invoked - /// once for each unique `BoundRegion`; multiple references to the - /// same `BoundRegion` will reuse the previous result. A map is + /// once for each unique `BoundRegionKind`; multiple references to the + /// same `BoundRegionKind` will reuse the previous result. A map is /// returned at the end with each bound region and the free region /// that replaced it. /// @@ -544,7 +544,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn replace_late_bound_regions( self, value: Binder, - fld_r: F, + mut fld_r: F, ) -> (T, BTreeMap>) where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, @@ -555,7 +555,10 @@ impl<'tcx> TyCtxt<'tcx> { let fld_c = |bound_ct, ty| { self.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), ty }) }; - self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c) + let mut region_map = BTreeMap::new(); + let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br)); + let value = self.replace_escaping_bound_vars(value.skip_binder(), real_fld_r, fld_t, fld_c); + (value, region_map) } /// Replaces all escaping bound vars. The `fld_r` closure replaces escaping @@ -567,34 +570,18 @@ impl<'tcx> TyCtxt<'tcx> { mut fld_r: F, mut fld_t: G, mut fld_c: H, - ) -> (T, BTreeMap>) + ) -> T where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, G: FnMut(ty::BoundTy) -> Ty<'tcx>, H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>, T: TypeFoldable<'tcx>, { - use rustc_data_structures::fx::FxHashMap; - - let mut region_map = BTreeMap::new(); - let mut type_map = FxHashMap::default(); - let mut const_map = FxHashMap::default(); - if !value.has_escaping_bound_vars() { - (value, region_map) + value } else { - let mut real_fld_r = |br| *region_map.entry(br).or_insert_with(|| fld_r(br)); - - let mut real_fld_t = - |bound_ty| *type_map.entry(bound_ty).or_insert_with(|| fld_t(bound_ty)); - - let mut real_fld_c = - |bound_ct, ty| *const_map.entry(bound_ct).or_insert_with(|| fld_c(bound_ct, ty)); - - let mut replacer = - BoundVarReplacer::new(self, &mut real_fld_r, &mut real_fld_t, &mut real_fld_c); - let result = value.fold_with(&mut replacer); - (result, region_map) + let mut replacer = BoundVarReplacer::new(self, &mut fld_r, &mut fld_t, &mut fld_c); + value.fold_with(&mut replacer) } } @@ -604,7 +591,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn replace_bound_vars( self, value: Binder, - fld_r: F, + mut fld_r: F, fld_t: G, fld_c: H, ) -> (T, BTreeMap>) @@ -614,7 +601,10 @@ impl<'tcx> TyCtxt<'tcx> { H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>, T: TypeFoldable<'tcx>, { - self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c) + let mut region_map = BTreeMap::new(); + let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br)); + let value = self.replace_escaping_bound_vars(value.skip_binder(), real_fld_r, fld_t, fld_c); + (value, region_map) } /// Replaces any late-bound regions bound in `value` with @@ -626,7 +616,7 @@ impl<'tcx> TyCtxt<'tcx> { self.replace_late_bound_regions(value, |br| { self.mk_region(ty::ReFree(ty::FreeRegion { scope: all_outlive_scope, - bound_region: br, + bound_region: br.kind, })) }) .0 @@ -639,7 +629,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn collect_constrained_late_bound_regions( self, value: &Binder, - ) -> FxHashSet + ) -> FxHashSet where T: TypeFoldable<'tcx>, { @@ -650,7 +640,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn collect_referenced_late_bound_regions( self, value: &Binder, - ) -> FxHashSet + ) -> FxHashSet where T: TypeFoldable<'tcx>, { @@ -661,7 +651,7 @@ impl<'tcx> TyCtxt<'tcx> { self, value: &Binder, just_constraint: bool, - ) -> FxHashSet + ) -> FxHashSet where T: TypeFoldable<'tcx>, { @@ -695,7 +685,8 @@ impl<'tcx> TyCtxt<'tcx> { let mut counter = 0; Binder::bind( self.replace_late_bound_regions(sig, |_| { - let r = self.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(counter))); + let br = ty::BoundRegion { kind: ty::BrAnon(counter) }; + let r = self.mk_region(ty::ReLateBound(ty::INNERMOST, br)); counter += 1; r }) @@ -955,7 +946,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { /// into a hash set. struct LateBoundRegionsCollector { current_index: ty::DebruijnIndex, - regions: FxHashSet, + regions: FxHashSet, /// `true` if we only want regions that are known to be /// "constrained" when you equate this type with another type. In @@ -1014,7 +1005,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { if let ty::ReLateBound(debruijn, br) = *r { if debruijn == self.current_index { - self.regions.insert(br); + self.regions.insert(br.kind); } } ControlFlow::CONTINUE diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index d6b3afb3be3..b545b92c925 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2455,7 +2455,8 @@ impl<'tcx> ty::Instance<'tcx> { ty::Generator(_, substs, _) => { let sig = substs.as_generator().poly_sig(); - let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); + let br = ty::BoundRegion { kind: ty::BrEnv }; + let env_region = ty::ReLateBound(ty::INNERMOST, br); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); let pin_did = tcx.require_lang_item(LangItem::Pin, None); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7428f34153c..27a5aacb674 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -51,13 +51,13 @@ use std::ops::{ControlFlow, Range}; use std::ptr; use std::str; -pub use self::sty::BoundRegion::*; +pub use self::sty::BoundRegionKind::*; pub use self::sty::InferTy::*; pub use self::sty::RegionKind; pub use self::sty::RegionKind::*; pub use self::sty::TyKind::*; pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar}; -pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; +pub use self::sty::{BoundRegion, BoundRegionKind, EarlyBoundRegion, FreeRegion, Region}; pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig}; pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts}; pub use self::sty::{ClosureSubstsParts, GeneratorSubstsParts}; @@ -1597,7 +1597,7 @@ where } } -pub type PlaceholderRegion = Placeholder; +pub type PlaceholderRegion = Placeholder; pub type PlaceholderType = Placeholder; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 09ef69e9690..9b178d9d2bd 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -125,13 +125,13 @@ pub struct RegionHighlightMode { highlight_regions: [Option<(ty::RegionKind, usize)>; 3], /// If enabled, when printing a "free region" that originated from - /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily + /// the given `ty::BoundRegionKind`, print it as "`'1`". Free regions that would ordinarily /// have names print as normal. /// /// This is used when you have a signature like `fn foo(x: &u32, /// y: &'a u32)` and we want to give a name to the region of the /// reference `x`. - highlight_bound_region: Option<(ty::BoundRegion, usize)>, + highlight_bound_region: Option<(ty::BoundRegionKind, usize)>, } impl RegionHighlightMode { @@ -175,7 +175,7 @@ impl RegionHighlightMode { /// Highlight the given bound region. /// We can only highlight one bound region at a time. See /// the field `highlight_bound_region` for more detailed notes. - pub fn highlighting_bound_region(&mut self, br: ty::BoundRegion, number: usize) { + pub fn highlighting_bound_region(&mut self, br: ty::BoundRegionKind, number: usize) { assert!(self.highlight_bound_region.is_none()); self.highlight_bound_region = Some((br, number)); } @@ -1611,7 +1611,7 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { data.name != kw::Invalid && data.name != kw::UnderscoreLifetime } - ty::ReLateBound(_, br) + ty::ReLateBound(_, ty::BoundRegion { kind: br }) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { @@ -1690,7 +1690,7 @@ impl FmtPrinter<'_, '_, F> { return Ok(self); } } - ty::ReLateBound(_, br) + ty::ReLateBound(_, ty::BoundRegion { kind: br }) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { @@ -1779,10 +1779,10 @@ impl FmtPrinter<'_, 'tcx, F> { let mut region_index = self.region_index; let new_value = self.tcx.replace_late_bound_regions(value.clone(), |br| { let _ = start_or_continue(&mut self, "for<", ", "); - let br = match br { + let kind = match br.kind { ty::BrNamed(_, name) => { let _ = write!(self, "{}", name); - br + br.kind } ty::BrAnon(_) | ty::BrEnv => { let name = loop { @@ -1796,7 +1796,7 @@ impl FmtPrinter<'_, 'tcx, F> { ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name) } }; - self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)) + self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind })) }); start_or_continue(&mut self, "", "> ")?; @@ -1840,7 +1840,7 @@ impl FmtPrinter<'_, 'tcx, F> { struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { - if let ty::ReLateBound(_, ty::BrNamed(_, name)) = *r { + if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) = *r { self.0.insert(name); } r.super_visit_with(self) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 8af5792b3fb..7a1ca6a6c2b 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -65,7 +65,7 @@ impl fmt::Debug for ty::adjustment::Adjustment<'tcx> { } } -impl fmt::Debug for ty::BoundRegion { +impl fmt::Debug for ty::BoundRegionKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { ty::BrAnon(n) => write!(f, "BrAnon({:?})", n), @@ -308,13 +308,13 @@ TrivialTypeFoldableAndLiftImpls! { crate::traits::Reveal, crate::ty::adjustment::AutoBorrowMutability, crate::ty::AdtKind, - // Including `BoundRegion` is a *bit* dubious, but direct + // Including `BoundRegionKind` is a *bit* dubious, but direct // references to bound region appear in `ty::Error`, and aren't // really meant to be folded. In general, we can only fold a fully // general `Region`. - crate::ty::BoundRegion, + crate::ty::BoundRegionKind, crate::ty::AssocItem, - crate::ty::Placeholder, + crate::ty::Placeholder, crate::ty::ClosureKind, crate::ty::FreeRegion, crate::ty::InferTy, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 62d1dda37d6..81ee05d4b23 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -40,12 +40,12 @@ pub struct TypeAndMut<'tcx> { /// at least as big as the scope `fr.scope`". pub struct FreeRegion { pub scope: DefId, - pub bound_region: BoundRegion, + pub bound_region: BoundRegionKind, } #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] #[derive(HashStable)] -pub enum BoundRegion { +pub enum BoundRegionKind { /// An anonymous region parameter for a given fn (&T) BrAnon(u32), @@ -60,26 +60,34 @@ pub enum BoundRegion { BrEnv, } -impl BoundRegion { - pub fn is_named(&self) -> bool { - match *self { - BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime, - _ => false, - } - } +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)] +#[derive(HashStable)] +pub struct BoundRegion { + pub kind: BoundRegionKind, +} +impl BoundRegion { /// When canonicalizing, we replace unbound inference variables and free /// regions with anonymous late bound regions. This method asserts that /// we have an anonymous late bound region, which hence may refer to /// a canonical variable. pub fn assert_bound_var(&self) -> BoundVar { - match *self { - BoundRegion::BrAnon(var) => BoundVar::from_u32(var), + match self.kind { + BoundRegionKind::BrAnon(var) => BoundVar::from_u32(var), _ => bug!("bound region is not anonymous"), } } } +impl BoundRegionKind { + pub fn is_named(&self) -> bool { + match *self { + BoundRegionKind::BrNamed(_, name) => name != kw::UnderscoreLifetime, + _ => false, + } + } +} + /// N.B., if you change this, you'll probably want to change the corresponding /// AST structure in `librustc_ast/ast.rs` as well. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable, Debug)] @@ -1551,7 +1559,7 @@ impl RegionKind { pub fn has_name(&self) -> bool { match *self { RegionKind::ReEarlyBound(ebr) => ebr.has_name(), - RegionKind::ReLateBound(_, br) => br.is_named(), + RegionKind::ReLateBound(_, br) => br.kind.is_named(), RegionKind::ReFree(fr) => fr.bound_region.is_named(), RegionKind::ReStatic => true, RegionKind::ReVar(..) => false, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 25787f005aa..a64580336ad 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -503,7 +503,8 @@ impl<'tcx> TyCtxt<'tcx> { closure_substs: SubstsRef<'tcx>, ) -> Option>> { let closure_ty = self.mk_closure(closure_def_id, closure_substs); - let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); + let br = ty::BoundRegion { kind: ty::BrEnv }; + let env_region = ty::ReLateBound(ty::INNERMOST, br); let closure_kind_ty = closure_substs.as_closure().kind_ty(); let closure_kind = closure_kind_ty.to_opt_closure_kind()?; let env_ty = match closure_kind { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index 41f3edaa413..81571fd7300 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -496,7 +496,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // lifetimes without names with the value `'0`. match ty.kind() { ty::Ref( - ty::RegionKind::ReLateBound(_, br) + ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br }) | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }), _, _, @@ -517,7 +517,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let region = match ty.kind() { ty::Ref(region, _, _) => { match region { - ty::RegionKind::ReLateBound(_, br) + ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br }) | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { printer.region_highlight_mode.highlighting_bound_region(*br, counter) } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs index e22dab01517..78da43c31c0 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs @@ -138,7 +138,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// Returns `true` if a closure is inferred to be an `FnMut` closure. fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { - if let ty::BoundRegion::BrEnv = free_region.bound_region { + if let ty::BoundRegionKind::BrEnv = free_region.bound_region { if let DefiningTy::Closure(_, substs) = self.regioncx.universal_regions().defining_ty { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs index 6211cf8a9da..cbca012824f 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs @@ -281,7 +281,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } ty::ReFree(free_region) => match free_region.bound_region { - ty::BoundRegion::BrNamed(region_def_id, name) => { + ty::BoundRegionKind::BrNamed(region_def_id, name) => { // Get the span to point to, even if we don't use the name. let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP); debug!( @@ -307,7 +307,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } } - ty::BoundRegion::BrEnv => { + ty::BoundRegionKind::BrEnv => { let def_ty = self.regioncx.universal_regions().defining_ty; if let DefiningTy::Closure(_, substs) = def_ty { @@ -349,7 +349,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } } - ty::BoundRegion::BrAnon(_) => None, + ty::BoundRegionKind::BrAnon(_) => None, }, ty::ReLateBound(..) diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs index 7ad38a1f82c..c1a0d9856b7 100644 --- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs +++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs @@ -700,7 +700,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { debug!("replace_bound_regions_with_nll_infer_vars: br={:?}", br); let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: all_outlive_scope.to_def_id(), - bound_region: br, + bound_region: br.kind, })); let region_vid = self.next_nll_region_var(origin); indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid()); @@ -795,7 +795,7 @@ fn for_each_late_bound_region_defined_on<'tcx>( let region_def_id = tcx.hir().local_def_id(hir_id); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, - bound_region: ty::BoundRegion::BrNamed(region_def_id.to_def_id(), name), + bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name), })); f(liberated_region); } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 0294fb23c56..7b6e6ad0696 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -319,7 +319,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Late-bound lifetimes use indices starting at 1, // see `BinderLevel` for more details. - ty::ReLateBound(debruijn, ty::BrAnon(i)) => { + ty::ReLateBound(debruijn, ty::BoundRegion { kind: ty::BrAnon(i) }) => { let binder = &self.binders[self.binders.len() - 1 - debruijn.index()]; let depth = binder.lifetime_depths.start + i; diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index b1b9ef343d5..1893d74335a 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -648,7 +648,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked /// var bound at index `0`. For types, we use a `BoundVar` index equal to -/// the type parameter index. For regions, we use the `BoundRegion::BrNamed` +/// the type parameter index. For regions, we use the `BoundRegionKind::BrNamed` /// variant (which has a `DefId`). fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind { @@ -662,12 +662,10 @@ fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { )) .into(), - ty::GenericParamDefKind::Lifetime => tcx - .mk_region(ty::RegionKind::ReLateBound( - ty::INNERMOST, - ty::BoundRegion::BrAnon(substs.len() as u32), - )) - .into(), + ty::GenericParamDefKind::Lifetime => { + let br = ty::BoundRegion { kind: ty::BrAnon(substs.len() as u32) }; + tcx.mk_region(ty::RegionKind::ReLateBound(ty::INNERMOST, br)).into() + } ty::GenericParamDefKind::Const => tcx .mk_const(ty::Const { diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 3a747b09cd4..8aa68e533a2 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -35,9 +35,7 @@ use rustc_ast::ast; use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner}; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; -use rustc_middle::ty::{ - self, Binder, BoundRegion, Region, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor, -}; +use rustc_middle::ty::{self, Binder, Region, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_span::def_id::DefId; use chalk_ir::{FnSig, ForeignDefId}; @@ -444,15 +442,15 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t ReEarlyBound(_) => { panic!("Should have already been substituted."); } - ReLateBound(db, br) => match br { - ty::BoundRegion::BrAnon(var) => { + ReLateBound(db, br) => match br.kind { + ty::BoundRegionKind::BrAnon(var) => { chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new( chalk_ir::DebruijnIndex::new(db.as_u32()), - *var as usize, + var as usize, )) .intern(interner) } - ty::BoundRegion::BrNamed(_def_id, _name) => unimplemented!(), + ty::BoundRegionKind::BrNamed(_def_id, _name) => unimplemented!(), ty::BrEnv => unimplemented!(), }, ReFree(_) => unimplemented!(), @@ -477,13 +475,13 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime ty::RegionKind::ReLateBound( ty::DebruijnIndex::from_u32(var.debruijn.depth()), - ty::BoundRegion::BrAnon(var.index as u32), + ty::BoundRegion { kind: ty::BrAnon(var.index as u32) }, ), chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(), chalk_ir::LifetimeData::Placeholder(p) => { ty::RegionKind::RePlaceholder(ty::Placeholder { universe: ty::UniverseIndex::from_usize(p.ui.counter), - name: ty::BoundRegion::BrAnon(p.idx as u32), + name: ty::BoundRegionKind::BrAnon(p.idx as u32), }) } chalk_ir::LifetimeData::Static => ty::RegionKind::ReStatic, @@ -805,7 +803,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound } /// To collect bound vars, we have to do two passes. In the first pass, we -/// collect all `BoundRegion`s and `ty::Bound`s. In the second pass, we then +/// collect all `BoundRegionKind`s and `ty::Bound`s. In the second pass, we then /// replace `BrNamed` into `BrAnon`. The two separate passes are important, /// since we can only replace `BrNamed` with `BrAnon`s with indices *after* all /// "real" `BrAnon`s. @@ -893,14 +891,14 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { match r { - ty::ReLateBound(index, br) if *index == self.binder_index => match br { - ty::BoundRegion::BrNamed(def_id, _name) => { - if self.named_parameters.iter().find(|d| *d == def_id).is_none() { - self.named_parameters.push(*def_id); + ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind { + ty::BoundRegionKind::BrNamed(def_id, _name) => { + if self.named_parameters.iter().find(|d| **d == def_id).is_none() { + self.named_parameters.push(def_id); } } - ty::BoundRegion::BrAnon(var) => match self.parameters.entry(*var) { + ty::BoundRegionKind::BrAnon(var) => match self.parameters.entry(var) { Entry::Vacant(entry) => { entry.insert(chalk_ir::VariableKind::Lifetime); } @@ -926,7 +924,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { } } -/// This is used to replace `BoundRegion::BrNamed` with `BoundRegion::BrAnon`. +/// This is used to replace `BoundRegionKind::BrNamed` with `BoundRegionKind::BrAnon`. /// Note: we assume that we will always have room for more bound vars. (i.e. we /// won't ever hit the `u32` limit in `BrAnon`s). struct NamedBoundVarSubstitutor<'a, 'tcx> { @@ -955,20 +953,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { match r { - ty::ReLateBound(index, br) if *index == self.binder_index => match br { - ty::BoundRegion::BrNamed(def_id, _name) => { - match self.named_parameters.get(def_id) { - Some(idx) => { - return self.tcx.mk_region(RegionKind::ReLateBound( - *index, - BoundRegion::BrAnon(*idx), - )); - } - None => panic!("Missing `BrNamed`."), + ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind { + ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) { + Some(idx) => { + let new_br = ty::BoundRegion { kind: ty::BrAnon(*idx) }; + return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br)); } - } + None => panic!("Missing `BrNamed`."), + }, ty::BrEnv => unimplemented!(), - ty::BoundRegion::BrAnon(_) => {} + ty::BrAnon(_) => {} }, _ => (), }; @@ -1044,17 +1038,15 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { // FIXME(chalk) - jackh726 - this currently isn't hit in any tests. // This covers any region variables in a goal, right? ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) { - Some(idx) => self.tcx.mk_region(RegionKind::ReLateBound( - self.binder_index, - BoundRegion::BrAnon(*idx), - )), + Some(idx) => { + let br = ty::BoundRegion { kind: ty::BrAnon(*idx) }; + self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)) + } None => { let idx = self.named_regions.len() as u32; + let br = ty::BoundRegion { kind: ty::BrAnon(idx) }; self.named_regions.insert(_re.def_id, idx); - self.tcx.mk_region(RegionKind::ReLateBound( - self.binder_index, - BoundRegion::BrAnon(idx), - )) + self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)) } }, @@ -1096,7 +1088,7 @@ impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { match r { ty::RePlaceholder(p) if p.universe == self.universe_index => { - if let ty::BoundRegion::BrAnon(anon) = p.name { + if let ty::BoundRegionKind::BrAnon(anon) = p.name { self.next_anon_region_placeholder = self.next_anon_region_placeholder.max(anon); } } diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index b117e28875e..f3a55fec9e4 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -44,7 +44,7 @@ crate fn evaluate_goal<'tcx>( let reempty_placeholder = tcx.mk_region(ty::RegionKind::RePlaceholder(ty::Placeholder { universe: ty::UniverseIndex::ROOT, - name: ty::BoundRegion::BrAnon(placeholders_collector.next_anon_region_placeholder + 1), + name: ty::BoundRegionKind::BrAnon(placeholders_collector.next_anon_region_placeholder + 1), })); let mut params_substitutor = diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 693cd236299..1648c629186 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -196,11 +196,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Some(rl::Region::LateBound(debruijn, id, _)) => { let name = lifetime_name(id.expect_local()); - tcx.mk_region(ty::ReLateBound(debruijn, ty::BrNamed(id, name))) + let br = ty::BoundRegion { kind: ty::BrNamed(id, name) }; + tcx.mk_region(ty::ReLateBound(debruijn, br)) } Some(rl::Region::LateBoundAnon(debruijn, index)) => { - tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index))) + let br = ty::BoundRegion { kind: ty::BrAnon(index) }; + tcx.mk_region(ty::ReLateBound(debruijn, br)) } Some(rl::Region::EarlyBound(index, id, _)) => { @@ -2295,8 +2297,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn validate_late_bound_regions( &self, - constrained_regions: FxHashSet, - referenced_regions: FxHashSet, + constrained_regions: FxHashSet, + referenced_regions: FxHashSet, generate_err: impl Fn(&str) -> rustc_errors::DiagnosticBuilder<'tcx>, ) { for br in referenced_regions.difference(&constrained_regions) { diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 5bc40d617d0..b324e6b7f8e 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -186,7 +186,8 @@ pub fn resolve_interior<'a, 'tcx>( // which means that none of the regions inside relate to any other, even if // typeck had previously found constraints that would cause them to be related. let folded = fcx.tcx.fold_regions(erased, &mut false, |_, current_depth| { - let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter))); + let br = ty::BoundRegion { kind: ty::BrAnon(counter) }; + let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br)); counter += 1; r }); diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index e2712a30339..6bc59869318 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -116,13 +116,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let mk_va_list_ty = |mutbl| { tcx.lang_items().va_list().map(|did| { - let region = tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))); - let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); + let region = tcx + .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrAnon(0) })); + let env_region = + tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrEnv })); let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]); - ( - tcx.mk_ref(tcx.mk_region(env_region), ty::TypeAndMut { ty: va_list_ty, mutbl }), - va_list_ty, - ) + (tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty) }) }; @@ -320,12 +319,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap()); let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id; + let br = ty::BoundRegion { kind: ty::BrAnon(0) }; ( 1, - vec![tcx.mk_imm_ref( - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))), - param(0), - )], + vec![ + tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)), + ], tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())), ) } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index c70554cc627..731a4da244f 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -461,7 +461,7 @@ fn get_new_lifetime_name<'tcx>( .collect_referenced_late_bound_regions(&poly_trait_ref) .into_iter() .filter_map(|lt| { - if let ty::BoundRegion::BrNamed(_, name) = lt { + if let ty::BoundRegionKind::BrNamed(_, name) = lt { Some(name.as_str().to_string()) } else { None diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2809e85761d..9f0d111cc37 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -431,7 +431,9 @@ impl Clean> for ty::RegionKind { fn clean(&self, _cx: &DocContext<'_>) -> Option { match *self { ty::ReStatic => Some(Lifetime::statik()), - ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name)), + ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) => { + Some(Lifetime(name)) + } ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)), ty::ReLateBound(..) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 1ae2e5de82c..4d525d62c52 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -104,7 +104,9 @@ fn external_generic_args( .iter() .filter_map(|kind| match kind.unpack() { GenericArgKind::Lifetime(lt) => match lt { - ty::ReLateBound(_, ty::BrAnon(_)) => Some(GenericArg::Lifetime(Lifetime::elided())), + ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrAnon(_) }) => { + Some(GenericArg::Lifetime(Lifetime::elided())) + } _ => lt.clean(cx).map(GenericArg::Lifetime), }, GenericArgKind::Type(_) if skip_self => { diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 799ed89dcce..4e122d930fc 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) mut &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) i32)), + for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) i32)), (), ] diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr index a094fc45178..44d1d2327fc 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr @@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) mut &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32)), + for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32)), (), ] diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index c4f4facae1f..fa9f994c4fa 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -10,7 +10,7 @@ LL | | }, | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)), + for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#4r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index c1450564c45..0555f79bcb0 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>)), + for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index e7b8dff4e7e..0115f5412f2 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -10,7 +10,7 @@ LL | | }) | = note: defining type: case1::{closure#0} with closure substs [ i32, - for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>)), + for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)), (), ] @@ -49,7 +49,7 @@ LL | | }) | = note: defining type: case2::{closure#0} with closure substs [ i32, - for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>)), + for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)), (), ] = note: number of external vids: 2 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index c7e68d02dcf..e55d033d2c7 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -12,7 +12,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t1)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t2)) u32>)), + for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) u32>)), (), ] = note: late-bound region is '_#2r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index abbc76eaf4d..ac4a4579c9c 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -12,7 +12,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>)), + for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index c91b514a796..60dca1baa40 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)), + for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr index 4ddf6f8323f..cbb10eb187e 100644 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr @@ -10,7 +10,7 @@ LL | | }, | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)), + for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 6dc6f456805..f9f1d8bb6ff 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)), + for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)), (), ] = note: late-bound region is '_#2r diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 6bcada5c26c..1587c28e1be 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -11,7 +11,7 @@ LL | | }); | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>)), + for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)), (), ] = note: late-bound region is '_#3r diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index 1da6c6d2c68..44f743310b4 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -6,7 +6,7 @@ LL | expect_sig(|a, b| b); // ought to return `a` | = note: defining type: test::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32)) -> &ReLateBound(DebruijnIndex(0), BrNamed('r)) i32, + for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) i32, (), ] diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index 7c0d63c368b..dbf76cd1329 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -6,7 +6,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); | = note: defining type: generic::::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BrNamed('s)) T)), + for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) T)), (), ] = note: number of external vids: 2 @@ -31,7 +31,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); | = note: defining type: generic_fail::::{closure#0} with closure substs [ i16, - for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BrNamed('s)) T)), + for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) T)), (), ] = note: late-bound region is '_#2r -- cgit 1.4.1-3-g733a5 From 5e7095850c3577666a6b8e628760dea7cccb46b7 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 16 Dec 2020 22:36:14 -0500 Subject: More rebinds --- compiler/rustc_infer/src/infer/combine.rs | 4 +-- compiler/rustc_infer/src/infer/nll_relate/mod.rs | 2 +- compiler/rustc_middle/src/ty/_match.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 5 +-- compiler/rustc_middle/src/ty/mod.rs | 16 ++++++--- .../src/traits/error_reporting/suggestions.rs | 34 +++++++++--------- .../src/traits/object_safety.rs | 4 +-- .../rustc_trait_selection/src/traits/project.rs | 6 ++-- .../src/traits/select/confirmation.rs | 6 ++-- .../rustc_trait_selection/src/traits/select/mod.rs | 35 +++++++++--------- compiler/rustc_trait_selection/src/traits/util.rs | 8 +++-- compiler/rustc_typeck/src/astconv/mod.rs | 6 ++-- compiler/rustc_typeck/src/bounds.rs | 10 ++++-- compiler/rustc_typeck/src/check/callee.rs | 2 +- compiler/rustc_typeck/src/check/closure.rs | 42 +++++++++++----------- compiler/rustc_typeck/src/check/compare_method.rs | 5 ++- compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 7 ++-- .../rustc_typeck/src/check/generator_interior.rs | 3 +- compiler/rustc_typeck/src/check/intrinsic.rs | 36 ++++++++----------- compiler/rustc_typeck/src/collect.rs | 13 +++---- compiler/rustc_typeck/src/lib.rs | 20 ++++++----- compiler/rustc_typeck/src/outlives/mod.rs | 14 ++++---- src/librustdoc/clean/mod.rs | 18 +++++----- .../clippy_lints/src/await_holding_invalid.rs | 2 +- 24 files changed, 152 insertions(+), 148 deletions(-) (limited to 'src') diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 6a1715ef818..7770f2bd911 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -551,7 +551,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { where T: Relate<'tcx>, { - Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } fn relate_item_substs( @@ -833,7 +833,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { where T: Relate<'tcx>, { - Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 0b2847658f7..b9bd66e4b92 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -1008,6 +1008,6 @@ where self.first_free_index.shift_in(1); let result = self.relate(a.skip_binder(), a.skip_binder())?; self.first_free_index.shift_out(1); - Ok(ty::Binder::bind(result)) + Ok(a.rebind(result)) } } diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 27bccc0bcaf..a5962e3b3ba 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -118,6 +118,6 @@ impl TypeRelation<'tcx> for Match<'tcx> { where T: Relate<'tcx>, { - Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) + Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index adf02412b96..615972ae45c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -299,6 +299,7 @@ pub struct ResolvedOpaqueTy<'tcx> { /// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for /// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`. #[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)] +#[derive(TypeFoldable)] pub struct GeneratorInteriorTypeCause<'tcx> { /// Type of the captured binding. pub ty: Ty<'tcx>, @@ -423,7 +424,7 @@ pub struct TypeckResults<'tcx> { /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). - pub generator_interior_types: Vec>, + pub generator_interior_types: ty::Binder>>, /// We sometimes treat byte string literals (which are of type `&[u8; N]`) /// as `&[u8]`, depending on the pattern in which they are used. @@ -455,7 +456,7 @@ impl<'tcx> TypeckResults<'tcx> { concrete_opaque_types: Default::default(), closure_captures: Default::default(), closure_min_captures: Default::default(), - generator_interior_types: Default::default(), + generator_interior_types: ty::Binder::dummy(Default::default()), treat_byte_string_as_slice: Default::default(), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b0f02dee59b..98602d6a459 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1252,7 +1252,7 @@ impl<'tcx> Predicate<'tcx> { let pred = self.skip_binders(); let new = pred.subst(tcx, substs); if new != pred { - trait_ref.rebind(new).potentially_quantified(tcx, PredicateKind::ForAll) + ty::Binder::bind(new).potentially_quantified(tcx, PredicateKind::ForAll) } else { self } @@ -1282,6 +1282,10 @@ impl<'tcx> PolyTraitPredicate<'tcx> { // Ok to skip binder since trait `DefId` does not care about regions. self.skip_binder().def_id() } + + pub fn self_ty(self) -> ty::Binder> { + self.map_bound(|trait_ref| trait_ref.self_ty()) + } } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] @@ -1435,9 +1439,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { impl<'tcx> Predicate<'tcx> { pub fn to_opt_poly_trait_ref(self) -> Option>> { - match self.skip_binders() { + let predicate = self.bound_atom(); + match predicate.skip_binder() { PredicateAtom::Trait(t, constness) => { - Some(ConstnessAnd { constness, value: ty::Binder::bind(t.trait_ref) }) + Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) }) } PredicateAtom::Projection(..) | PredicateAtom::Subtype(..) @@ -1453,8 +1458,9 @@ impl<'tcx> Predicate<'tcx> { } pub fn to_opt_type_outlives(self) -> Option> { - match self.skip_binders() { - PredicateAtom::TypeOutlives(data) => Some(ty::Binder::bind(data)), + let predicate = self.bound_atom(); + match predicate.skip_binder() { + PredicateAtom::TypeOutlives(data) => Some(predicate.rebind(data)), PredicateAtom::Trait(..) | PredicateAtom::Projection(..) | PredicateAtom::Subtype(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5c185dc4a9f..b4b71a48ce9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1151,9 +1151,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ) -> DiagnosticBuilder<'tcx> { crate fn build_fn_sig_string<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, ) -> String { - let inputs = trait_ref.substs.type_at(1); + let inputs = trait_ref.skip_binder().substs.type_at(1); let sig = if let ty::Tuple(inputs) = inputs.kind() { tcx.mk_fn_sig( inputs.iter().map(|k| k.expect_ty()), @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { abi::Abi::Rust, ) }; - ty::Binder::bind(sig).to_string() + trait_ref.rebind(sig).to_string() } let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure(); @@ -1183,17 +1183,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if argument_is_closure { "closure" } else { "function" } ); - let found_str = format!( - "expected signature of `{}`", - build_fn_sig_string(self.tcx, found.skip_binder()) - ); + let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found)); err.span_label(span, found_str); let found_span = found_span.unwrap_or(span); - let expected_str = format!( - "found signature of `{}`", - build_fn_sig_string(self.tcx, expected_ref.skip_binder()) - ); + let expected_str = + format!("found signature of `{}`", build_fn_sig_string(self.tcx, expected_ref)); err.span_label(found_span, expected_str); err @@ -1422,7 +1417,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // generator frame. Bound regions are preserved by // `erase_regions` and so we must also call // `erase_late_bound_regions`. - let ty_erased = self.tcx.erase_late_bound_regions(ty::Binder::bind(ty)); + let ty_erased = self.tcx.erase_late_bound_regions(ty); let ty_erased = self.tcx.erase_regions(ty_erased); let eq = ty::TyS::same_type(ty_erased, target_ty_erased); debug!( @@ -1440,7 +1435,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { interior_or_upvar_span = upvars.iter().find_map(|(upvar_id, upvar)| { let upvar_ty = typeck_results.node_type(*upvar_id); let upvar_ty = self.resolve_vars_if_possible(upvar_ty); - if ty_matches(&upvar_ty) { + if ty_matches(ty::Binder::dummy(upvar_ty)) { Some(GeneratorInteriorOrUpvar::Upvar(upvar.span)) } else { None @@ -1448,10 +1443,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }); }; - if let Some(cause) = typeck_results - .generator_interior_types - .iter() - .find(|ty::GeneratorInteriorTypeCause { ty, .. }| ty_matches(ty)) + // The generator interior types share the same binders + if let Some(cause) = + typeck_results.generator_interior_types.as_ref().skip_binder().iter().find( + |ty::GeneratorInteriorTypeCause { ty, .. }| { + ty_matches(typeck_results.generator_interior_types.rebind(ty)) + }, + ) { // Check to see if any awaited expressions have the target type. let from_awaited_ty = visitor @@ -1464,7 +1462,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { "maybe_note_obligation_cause_for_async_await: await_expr={:?}", await_expr ); - ty_matches(ty) + ty_matches(ty::Binder::dummy(ty)) }) .map(|expr| expr.span); let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause; diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8b275db89f1..8b6e30f34fd 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -418,11 +418,11 @@ fn virtual_call_violation_for_method<'tcx>( } for (i, &input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() { - if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) { + if contains_illegal_self_type_reference(tcx, trait_def_id, sig.rebind(input_ty)) { return Some(MethodViolationCode::ReferencesSelfInput(i)); } } - if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output().skip_binder()) { + if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) { return Some(MethodViolationCode::ReferencesSelfOutput); } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index df472e6ed7e..a11499e4320 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -951,7 +951,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // If we are resolving `>::Item == Type`, // start out by selecting the predicate `T as TraitRef<...>`: - let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref(); + let poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref); let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate()); let _ = selcx.infcx().commit_if_ok(|_| { let impl_source = match selcx.select(&trait_obligation) { @@ -1247,7 +1247,9 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>( ty: self_ty.discriminant_ty(tcx), }; - confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate), false) + // We get here from `poly_project_and_unify_type` which replaces bound vars + // with placeholders, so dummy is okay here. + confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) } fn confirm_fn_pointer_candidate<'cx, 'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index ab09fcfd8cc..81de6dc71f4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -259,10 +259,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> ImplSourceAutoImplData> { debug!(?obligation, ?trait_def_id, "confirm_auto_impl_candidate"); - let types = obligation.predicate.map_bound(|inner| { - let self_ty = self.infcx.shallow_resolve(inner.self_ty()); - self.constituent_types_for_ty(self_ty) - }); + let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty()); + let types = self.constituent_types_for_ty(self_ty); self.vtable_auto_impl(obligation, trait_def_id, types) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 74b6652981a..f1c86eab095 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1276,7 +1276,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // FIXME(generic_associated_types): Compare the whole projections let data_poly_trait_ref = projection_ty.map_bound(|proj| proj.trait_ref(self.tcx())); - let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref(); + let obligation_poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref); self.infcx .at(&obligation.cause, obligation.param_env) .sup(obligation_poly_trait_ref, data_poly_trait_ref) @@ -1648,8 +1648,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Bar where struct Bar { x: T, y: u32 } -> [i32, u32] /// Zed where enum Zed { A(T), B(u32) } -> [i32, u32] /// ``` - fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec> { - match *t.kind() { + fn constituent_types_for_ty(&self, t: ty::Binder>) -> ty::Binder>> { + match *t.skip_binder().kind() { ty::Uint(_) | ty::Int(_) | ty::Bool @@ -1660,7 +1660,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never - | ty::Char => Vec::new(), + | ty::Char => ty::Binder::dummy(Vec::new()), ty::Placeholder(..) | ty::Dynamic(..) @@ -1673,44 +1673,44 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => { - vec![element_ty] + t.rebind(vec![element_ty]) } - ty::Array(element_ty, _) | ty::Slice(element_ty) => vec![element_ty], + ty::Array(element_ty, _) | ty::Slice(element_ty) => t.rebind(vec![element_ty]), ty::Tuple(ref tys) => { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet - tys.iter().map(|k| k.expect_ty()).collect() + t.rebind(tys.iter().map(|k| k.expect_ty()).collect()) } ty::Closure(_, ref substs) => { let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty()); - vec![ty] + t.rebind(vec![ty]) } ty::Generator(_, ref substs, _) => { let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty()); let witness = substs.as_generator().witness(); - vec![ty].into_iter().chain(iter::once(witness)).collect() + t.rebind(vec![ty].into_iter().chain(iter::once(witness)).collect()) } ty::GeneratorWitness(types) => { - // This is sound because no regions in the witness can refer to - // the binder outside the witness. So we'll effectivly reuse - // the implicit binder around the witness. - types.skip_binder().to_vec() + debug_assert!(!types.has_escaping_bound_vars()); + types.map_bound(|types| types.to_vec()) } // For `PhantomData`, we pass `T`. - ty::Adt(def, substs) if def.is_phantom_data() => substs.types().collect(), + ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()), - ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect(), + ty::Adt(def, substs) => { + t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect()) + } ty::Opaque(def_id, substs) => { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)] + t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]) } } } @@ -1738,10 +1738,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy` types + .as_ref() .skip_binder() // binder moved -\ .iter() .flat_map(|ty| { - let ty: ty::Binder> = ty::Binder::bind(ty); // <----/ + let ty: ty::Binder> = types.rebind(ty); // <----/ self.infcx.commit_unconditionally(|_| { let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index ab4a81c7d15..8888ea2c849 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -6,7 +6,7 @@ use smallvec::SmallVec; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef}; -use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; pub use rustc_infer::traits::util::*; @@ -333,11 +333,12 @@ pub fn closure_trait_ref_and_return_type( TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), }; + debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]), }; - ty::Binder::bind((trait_ref, sig.skip_binder().output())) + sig.map_bound(|sig| (trait_ref, sig.output())) } pub fn generator_trait_ref_and_outputs( @@ -346,11 +347,12 @@ pub fn generator_trait_ref_and_outputs( self_ty: Ty<'tcx>, sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { + debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]), }; - ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty)) + sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) } pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 693cd236299..c470659e18a 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -837,9 +837,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .instantiate_lang_item_trait_ref( lang_item, span, hir_id, args, param_ty, bounds, ), - hir::GenericBound::Outlives(ref l) => { - bounds.region_bounds.push((self.ast_region_to_region(l, None), l.span)) - } + hir::GenericBound::Outlives(ref l) => bounds + .region_bounds + .push((ty::Binder::bind(self.ast_region_to_region(l, None)), l.span)), } } } diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index 497754f20e4..7ba90ad8819 100644 --- a/compiler/rustc_typeck/src/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs @@ -26,7 +26,7 @@ pub struct Bounds<'tcx> { /// A list of region bounds on the (implicit) self type. So if you /// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but /// the `T` is not explicitly included). - pub region_bounds: Vec<(ty::Region<'tcx>, Span)>, + pub region_bounds: Vec<(ty::Binder>, Span)>, /// A list of trait bounds. So if you had `T: Debug` this would be /// `T: Debug`. Note that the self-type is explicit here. @@ -68,8 +68,12 @@ impl<'tcx> Bounds<'tcx> { sized_predicate .into_iter() .chain(self.region_bounds.iter().map(|&(region_bound, span)| { - let outlives = ty::OutlivesPredicate(param_ty, region_bound); - (ty::Binder::bind(outlives).to_predicate(tcx), span) + ( + region_bound + .map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound)) + .to_predicate(tcx), + span, + ) })) .chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| { let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx); diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index ebfb401fcf3..22e287320d8 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -389,7 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // In that case, we check each argument against "error" in order to // set up all the node type bindings. ( - ty::Binder::bind(self.tcx.mk_fn_sig( + ty::Binder::dummy(self.tcx.mk_fn_sig( self.err_args(arg_exprs.len()).into_iter(), self.tcx.ty_error(), false, diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 8082a230216..7470c1a76a9 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -24,7 +24,7 @@ use std::iter; struct ExpectedSig<'tcx> { /// Span that gave us this expectation, if we know that. cause_span: Option, - sig: ty::FnSig<'tcx>, + sig: ty::PolyFnSig<'tcx>, } struct ClosureSignatures<'tcx> { @@ -174,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), ty::FnPtr(sig) => { - let expected_sig = ExpectedSig { cause_span: None, sig: sig.skip_binder() }; + let expected_sig = ExpectedSig { cause_span: None, sig }; (Some(expected_sig), Some(ty::ClosureKind::Fn)) } _ => (None, None), @@ -274,13 +274,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty); debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty); - let sig = self.tcx.mk_fn_sig( + let sig = projection.rebind(self.tcx.mk_fn_sig( input_tys.iter(), &ret_param_ty, false, hir::Unsafety::Normal, Abi::Rust, - ); + )); debug!("deduce_sig_from_projection: sig={:?}", sig); Some(ExpectedSig { cause_span, sig }) @@ -374,9 +374,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Watch out for some surprises and just ignore the // expectation if things don't see to match up with what we // expect. - if expected_sig.sig.c_variadic != decl.c_variadic { + if expected_sig.sig.c_variadic() != decl.c_variadic { return self.sig_of_closure_no_expectation(expr_def_id, decl, body); - } else if expected_sig.sig.inputs_and_output.len() != decl.inputs.len() + 1 { + } else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 { return self.sig_of_closure_with_mismatched_number_of_arguments( expr_def_id, decl, @@ -388,14 +388,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Create a `PolyFnSig`. Note the oddity that late bound // regions appearing free in `expected_sig` are now bound up // in this binder we are creating. - assert!(!expected_sig.sig.has_vars_bound_above(ty::INNERMOST)); - let bound_sig = ty::Binder::bind(self.tcx.mk_fn_sig( - expected_sig.sig.inputs().iter().cloned(), - expected_sig.sig.output(), - decl.c_variadic, - hir::Unsafety::Normal, - Abi::RustCall, - )); + assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST)); + let bound_sig = expected_sig.sig.map_bound(|sig| { + self.tcx.mk_fn_sig( + sig.inputs().iter().cloned(), + sig.output(), + sig.c_variadic, + hir::Unsafety::Normal, + Abi::RustCall, + ) + }); // `deduce_expectations_from_expected_type` introduces // late-bound lifetimes defined elsewhere, which we now @@ -428,6 +430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_map_node = hir.get_if_local(expr_def_id).unwrap(); let expected_args: Vec<_> = expected_sig .sig + .skip_binder() .inputs() .iter() .map(|ty| ArgKind::from_expected_ty(ty, None)) @@ -500,7 +503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (supplied_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars( hir_ty.span, LateBoundRegionConversionTime::FnCall, - ty::Binder::bind(supplied_ty), + supplied_sig.inputs().rebind(supplied_ty), ); // recreated from (*) above // Check that E' = S'. @@ -619,12 +622,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // where R is the return type we are expecting. This type `T` // will be our output. let output_ty = self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| { - if let ty::PredicateAtom::Projection(proj_predicate) = - obligation.predicate.skip_binders() - { + let bound_predicate = obligation.predicate.bound_atom(); + if let ty::PredicateAtom::Projection(proj_predicate) = bound_predicate.skip_binder() { self.deduce_future_output_from_projection( obligation.cause.span, - ty::Binder::bind(proj_predicate), + bound_predicate.rebind(proj_predicate), ) } else { None @@ -704,7 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { astconv.ast_ty_to_ty(&output); } - let result = ty::Binder::bind(self.tcx.mk_fn_sig( + let result = ty::Binder::dummy(self.tcx.mk_fn_sig( supplied_arguments, self.tcx.ty_error(), decl.c_variadic, diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 20090d37606..bb324d0d8bc 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -494,12 +494,11 @@ fn compare_self_type<'tcx>( ty::ImplContainer(_) => impl_trait_ref.self_ty(), ty::TraitContainer(_) => tcx.types.self_param, }; - let self_arg_ty = tcx.fn_sig(method.def_id).input(0).skip_binder(); + let self_arg_ty = tcx.fn_sig(method.def_id).input(0); let param_env = ty::ParamEnv::reveal_all(); tcx.infer_ctxt().enter(|infcx| { - let self_arg_ty = - tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_arg_ty)); + let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty); let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok(); match ExplicitSelf::determine(self_arg_ty, can_eq_self) { ExplicitSelf::ByValue => "self".to_owned(), diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index e1a2f593b8d..41a403a010e 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -764,12 +764,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .pending_obligations() .into_iter() .filter_map(move |obligation| { - match obligation.predicate.skip_binders() { + let bound_predicate = obligation.predicate.bound_atom(); + match bound_predicate.skip_binder() { ty::PredicateAtom::Projection(data) => { - Some((ty::Binder::bind(data).to_poly_trait_ref(self.tcx), obligation)) + Some((bound_predicate.rebind(data).to_poly_trait_ref(self.tcx), obligation)) } ty::PredicateAtom::Trait(data, _) => { - Some((ty::Binder::bind(data).to_poly_trait_ref(), obligation)) + Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation)) } ty::PredicateAtom::Subtype(..) => None, ty::PredicateAtom::RegionOutlives(..) => None, diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 5bc40d617d0..54710e12a74 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -204,7 +204,8 @@ pub fn resolve_interior<'a, 'tcx>( let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list)); // Store the generator types and spans into the typeck results for this generator. - visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types = type_causes; + visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types = + ty::Binder::bind(type_causes); debug!( "types in generator after region replacement {:?}, span = {:?}", diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index e2712a30339..dd629980ab4 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -23,10 +23,7 @@ fn equate_intrinsic_type<'tcx>( it: &hir::ForeignItem<'_>, def_id: DefId, n_tps: usize, - abi: Abi, - safety: hir::Unsafety, - inputs: Vec>, - output: Ty<'tcx>, + sig: ty::PolyFnSig<'tcx>, ) { match it.kind { hir::ForeignItemKind::Fn(..) => {} @@ -53,13 +50,7 @@ fn equate_intrinsic_type<'tcx>( return; } - let fty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig( - inputs.into_iter(), - output, - false, - safety, - abi, - ))); + let fty = tcx.mk_fn_ptr(sig); let cause = ObligationCause::new(it.span, it.hir_id, ObligationCauseCode::IntrinsicType); require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty); } @@ -380,7 +371,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; (n_tps, inputs, output, unsafety) }; - equate_intrinsic_type(tcx, it, def_id, n_tps, Abi::RustIntrinsic, unsafety, inputs, output) + let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic); + let sig = ty::Binder::bind(sig); + equate_intrinsic_type(tcx, it, def_id, n_tps, sig) } /// Type-check `extern "platform-intrinsic" { ... }` functions. @@ -466,14 +459,13 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) } }; - equate_intrinsic_type( - tcx, - it, - def_id, - n_tps, - Abi::PlatformIntrinsic, - hir::Unsafety::Unsafe, - inputs, + let sig = tcx.mk_fn_sig( + inputs.into_iter(), output, - ) + false, + hir::Unsafety::Unsafe, + Abi::PlatformIntrinsic, + ); + let sig = ty::Binder::dummy(sig); + equate_intrinsic_type(tcx, it, def_id, n_tps, sig) } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 3b49c73c7f2..543e39af669 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1986,11 +1986,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP } _ => bug!(), }; - let pred = ty::Binder::dummy(ty::PredicateAtom::RegionOutlives( - ty::OutlivesPredicate(r1, r2), - )); + let pred = ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2)) + .to_predicate(icx.tcx); - (pred.potentially_quantified(icx.tcx, ty::PredicateKind::ForAll), span) + (pred, span) })) } @@ -2238,10 +2237,8 @@ fn predicates_from_bound<'tcx>( } hir::GenericBound::Outlives(ref lifetime) => { let region = astconv.ast_region_to_region(lifetime, None); - let pred = ty::Binder::dummy(ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate( - param_ty, region, - ))) - .potentially_quantified(astconv.tcx(), ty::PredicateKind::ForAll); + let pred = ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(param_ty, region)) + .to_predicate(astconv.tcx()); vec![(pred, lifetime.span)] } } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 929c88455f0..dde4a62ffbf 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -226,19 +226,21 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: LocalDefId) { let expected_return_type = if tcx.lang_items().termination().is_some() { // we take the return type of the given main function, the real check is done // in `check_fn` - actual.output().skip_binder() + actual.output() } else { // standard () main return type - tcx.mk_unit() + ty::Binder::dummy(tcx.mk_unit()) }; - let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig( - iter::empty(), - expected_return_type, - false, - hir::Unsafety::Normal, - Abi::Rust, - ))); + let se_ty = tcx.mk_fn_ptr(expected_return_type.map_bound(|expected_return_type| { + tcx.mk_fn_sig( + iter::empty(), + expected_return_type, + false, + hir::Unsafety::Normal, + Abi::Rust, + ) + })); require_same_types( tcx, diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index d7c084acf50..b1f79331d5f 100644 --- a/compiler/rustc_typeck/src/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt}; +use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -89,17 +89,15 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CratePredica |(ty::OutlivesPredicate(kind1, region2), &span)| { match kind1.unpack() { GenericArgKind::Type(ty1) => Some(( - ty::Binder::dummy(ty::PredicateAtom::TypeOutlives( - ty::OutlivesPredicate(ty1, region2), - )) - .potentially_quantified(tcx, ty::PredicateKind::ForAll), + ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty1, region2)) + .to_predicate(tcx), span, )), GenericArgKind::Lifetime(region1) => Some(( - ty::Binder::dummy(ty::PredicateAtom::RegionOutlives( - ty::OutlivesPredicate(region1, region2), + ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate( + region1, region2, )) - .potentially_quantified(tcx, ty::PredicateKind::ForAll), + .to_predicate(tcx), span, )), GenericArgKind::Const(_) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2809e85761d..a5f23dac044 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -469,8 +469,9 @@ impl Clean for hir::WherePredicate<'_> { impl<'a> Clean> for ty::Predicate<'a> { fn clean(&self, cx: &DocContext<'_>) -> Option { - match self.skip_binders() { - ty::PredicateAtom::Trait(pred, _) => Some(ty::Binder::bind(pred).clean(cx)), + let bound_predicate = self.bound_atom(); + match bound_predicate.skip_binder() { + ty::PredicateAtom::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)), ty::PredicateAtom::RegionOutlives(pred) => pred.clean(cx), ty::PredicateAtom::TypeOutlives(pred) => pred.clean(cx), ty::PredicateAtom::Projection(pred) => Some(pred.clean(cx)), @@ -733,7 +734,8 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx .flat_map(|(p, _)| { let mut projection = None; let param_idx = (|| { - match p.skip_binders() { + let bound_p = p.bound_atom(); + match bound_p.skip_binder() { ty::PredicateAtom::Trait(pred, _constness) => { if let ty::Param(param) = pred.self_ty().kind() { return Some(param.index); @@ -746,7 +748,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx } ty::PredicateAtom::Projection(p) => { if let ty::Param(param) = p.projection_ty.self_ty().kind() { - projection = Some(ty::Binder::bind(p)); + projection = Some(bound_p.rebind(p)); return Some(param.index); } } @@ -1659,12 +1661,10 @@ impl<'tcx> Clean for Ty<'tcx> { .filter_map(|bound| { // Note: The substs of opaque types can contain unbound variables, // meaning that we have to use `ignore_quantifiers_with_unbound_vars` here. - let trait_ref = match bound - .bound_atom_with_opt_escaping(cx.tcx) - .skip_binder() - { + let bound_predicate = bound.bound_atom_with_opt_escaping(cx.tcx); + let trait_ref = match bound_predicate.skip_binder() { ty::PredicateAtom::Trait(tr, _constness) => { - ty::Binder::bind(tr.trait_ref) + bound_predicate.rebind(tr.trait_ref) } ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { if let Some(r) = reg.clean(cx) { diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs index 58892024ce2..cfade9cbc46 100644 --- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs +++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs @@ -99,7 +99,7 @@ impl LateLintPass<'_> for AwaitHolding { }; let def_id = cx.tcx.hir().body_owner_def_id(body_id); let typeck_results = cx.tcx.typeck(def_id); - check_interior_types(cx, &typeck_results.generator_interior_types, body.value.span); + check_interior_types(cx, &typeck_results.generator_interior_types.as_ref().skip_binder(), body.value.span); } } } -- cgit 1.4.1-3-g733a5 From 830ceaa41908bd428e36b1a804dd93c9a257aea8 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Sun, 6 Dec 2020 13:57:37 +0100 Subject: Remap instrument-coverage line numbers in doctests This uses the `SourceMap::doctest_offset_line` method to re-map line numbers from doctests. Remapping columns is not yet done. Part of issue #79417. --- compiler/rustc_mir/src/transform/coverage/mod.rs | 6 +- compiler/rustc_span/src/lib.rs | 2 +- src/librustdoc/doctest.rs | 75 +++++---- src/librustdoc/doctest/tests.rs | 69 ++++++-- src/librustdoc/html/markdown.rs | 2 +- .../run-make-fulldeps/coverage-reports/Makefile | 22 ++- .../expected_show_coverage.doctest.txt | 79 ++++++++++ .../expected_show_coverage.uses_crate.txt | 4 +- .../coverage-reports/normalize_paths.py | 10 ++ .../doctest.main.-------.InstrumentCoverage.0.html | 127 +++++++++++++++ ...n_in_doctests.-------.InstrumentCoverage.0.html | 173 +++++++++++++++++++++ .../coverage/compiletest-ignore-dir | 4 +- .../run-make-fulldeps/coverage/coverage_tools.mk | 4 +- src/test/run-make-fulldeps/coverage/doctest.rs | 66 ++++++++ .../coverage/lib/doctest_crate.rs | 9 ++ 15 files changed, 596 insertions(+), 56 deletions(-) create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports/normalize_paths.py create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage/doctest.rs create mode 100644 src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index 4590d37c182..93133e9b7f0 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -30,6 +30,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; +use rustc_span::source_map::SourceMap; use rustc_span::{CharPos, Pos, SourceFile, Span, Symbol}; /// A simple error message wrapper for `coverage::Error`s. @@ -311,7 +312,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { self.mir_body, counter_kind, self.bcb_leader_bb(bcb), - Some(make_code_region(file_name, &self.source_file, span, body_span)), + Some(make_code_region(source_map, file_name, &self.source_file, span, body_span)), ); } } @@ -489,6 +490,7 @@ fn inject_intermediate_expression(mir_body: &mut mir::Body<'tcx>, expression: Co /// Convert the Span into its file name, start line and column, and end line and column fn make_code_region( + source_map: &SourceMap, file_name: Symbol, source_file: &Lrc, span: Span, @@ -508,6 +510,8 @@ fn make_code_region( } else { source_file.lookup_file_pos(span.hi()) }; + let start_line = source_map.doctest_offset_line(&source_file.name, start_line); + let end_line = source_map.doctest_offset_line(&source_file.name, end_line); CodeRegion { file_name, start_line: start_line as u32, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index f63a73acbf4..fbef4d06709 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -182,7 +182,7 @@ impl std::fmt::Display for FileName { use FileName::*; match *self { Real(RealFileName::Named(ref path)) => write!(fmt, "{}", path.display()), - // FIXME: might be nice to display both compoments of Devirtualized. + // FIXME: might be nice to display both components of Devirtualized. // But for now (to backport fix for issue #70924), best to not // perturb diagnostics so its obvious test suite still works. Real(RealFileName::Devirtualized { ref local_path, virtual_name: _ }) => { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 37fe13c32ce..a08ded92640 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -247,9 +247,10 @@ fn run_test( edition: Edition, outdir: DirState, path: PathBuf, + test_id: &str, ) -> Result<(), TestFailure> { let (test, line_offset, supports_color) = - make_test(test, Some(cratename), as_test_harness, opts, edition); + make_test(test, Some(cratename), as_test_harness, opts, edition, Some(test_id)); let output_file = outdir.path().join("rust_out"); @@ -387,6 +388,7 @@ crate fn make_test( dont_insert_main: bool, opts: &TestOptions, edition: Edition, + test_id: Option<&str>, ) -> (String, usize, bool) { let (crate_attrs, everything_else, crates) = partition_source(s); let everything_else = everything_else.trim(); @@ -542,16 +544,40 @@ crate fn make_test( prog.push_str(everything_else); } else { let returns_result = everything_else.trim_end().ends_with("(())"); + // Give each doctest main function a unique name. + // This is for example needed for the tooling around `-Z instrument-coverage`. + let inner_fn_name = if let Some(test_id) = test_id { + format!("_doctest_main_{}", test_id) + } else { + "_inner".into() + }; let (main_pre, main_post) = if returns_result { ( - "fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {", - "}\n_inner().unwrap() }", + format!( + "fn main() {{ fn {}() -> Result<(), impl core::fmt::Debug> {{\n", + inner_fn_name + ), + format!("\n}}; {}().unwrap() }}", inner_fn_name), + ) + } else if test_id.is_some() { + ( + format!("fn main() {{ fn {}() {{\n", inner_fn_name), + format!("\n}}; {}() }}", inner_fn_name), ) } else { - ("fn main() {\n", "\n}") + ("fn main() {\n".into(), "\n}".into()) }; - prog.extend([main_pre, everything_else, main_post].iter().cloned()); + // Note on newlines: We insert a line/newline *before*, and *after* + // the doctest and adjust the `line_offset` accordingly. + // In the case of `-Z instrument-coverage`, this means that the generated + // inner `main` function spans from the doctest opening codeblock to the + // closing one. For example + // /// ``` <- start of the inner main + // /// <- code under doctest + // /// ``` <- end of the inner main line_offset += 1; + + prog.extend([&main_pre, everything_else, &main_post].iter().cloned()); } debug!("final doctest:\n{}", prog); @@ -749,28 +775,24 @@ impl Tester for Collector { _ => PathBuf::from(r"doctest.rs"), }; + // For example `module/file.rs` would become `module_file_rs` + let file = filename + .to_string() + .chars() + .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' }) + .collect::(); + let test_id = format!( + "{file}_{line}_{number}", + file = file, + line = line, + number = { + // Increases the current test number, if this file already + // exists or it creates a new entry with a test number of 0. + self.visited_tests.entry((file.clone(), line)).and_modify(|v| *v += 1).or_insert(0) + }, + ); let outdir = if let Some(mut path) = options.persist_doctests.clone() { - // For example `module/file.rs` would become `module_file_rs` - let folder_name = filename - .to_string() - .chars() - .map(|c| if c == '\\' || c == '/' || c == '.' { '_' } else { c }) - .collect::(); - - path.push(format!( - "{krate}_{file}_{line}_{number}", - krate = cratename, - file = folder_name, - line = line, - number = { - // Increases the current test number, if this file already - // exists or it creates a new entry with a test number of 0. - self.visited_tests - .entry((folder_name.clone(), line)) - .and_modify(|v| *v += 1) - .or_insert(0) - }, - )); + path.push(&test_id); std::fs::create_dir_all(&path) .expect("Couldn't create directory for doctest executables"); @@ -817,6 +839,7 @@ impl Tester for Collector { edition, outdir, path, + &test_id, ); if let Err(err) = res { diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index a024e9c72a4..7c0df673c1b 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -11,7 +11,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -26,7 +26,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -44,7 +44,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 3)); } @@ -61,7 +61,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -79,7 +79,7 @@ use std::*; assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -98,7 +98,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -115,7 +115,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -134,7 +134,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 3)); // Adding more will also bump the returned line offset. @@ -147,7 +147,7 @@ use asdf::qwop; assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 4)); } @@ -164,7 +164,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -180,7 +180,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 1)); } @@ -196,7 +196,7 @@ fn main() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); } @@ -210,7 +210,7 @@ assert_eq!(2+2, 4);"; //Ceci n'est pas une `fn main` assert_eq!(2+2, 4);" .to_string(); - let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 1)); } @@ -224,7 +224,7 @@ fn make_test_display_warnings() { assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 1)); } @@ -242,7 +242,7 @@ assert_eq!(2+2, 4); }" .to_string(); - let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 2)); let input = "extern crate hella_qwop; @@ -256,7 +256,7 @@ assert_eq!(asdf::foo, 4); }" .to_string(); - let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 3)); } @@ -274,6 +274,41 @@ test_wrapper! { }" .to_string(); - let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION); + let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION, None); assert_eq!((output, len), (expected, 1)); } + +#[test] +fn make_test_returns_result() { + // creates an inner function and unwraps it + let opts = TestOptions::default(); + let input = "use std::io; +let mut input = String::new(); +io::stdin().read_line(&mut input)?; +Ok::<(), io:Error>(())"; + let expected = "#![allow(unused)] +fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> { +use std::io; +let mut input = String::new(); +io::stdin().read_line(&mut input)?; +Ok::<(), io:Error>(()) +}; _inner().unwrap() }" + .to_string(); + let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None); + assert_eq!((output, len), (expected, 2)); +} + +#[test] +fn make_test_named_wrapper() { + // creates an inner function with a specific name + let opts = TestOptions::default(); + let input = "assert_eq!(2+2, 4);"; + let expected = "#![allow(unused)] +fn main() { fn _doctest_main_some_unique_name() { +assert_eq!(2+2, 4); +}; _doctest_main_some_unique_name() }" + .to_string(); + let (output, len, _) = + make_test(input, None, false, &opts, DEFAULT_EDITION, Some("some_unique_name")); + assert_eq!((output, len), (expected, 2)); +} diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 22096203d4c..f911a2ce3fc 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -248,7 +248,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { .join("\n"); let krate = krate.as_ref().map(|s| &**s); let (test, _, _) = - doctest::make_test(&test, krate, false, &Default::default(), edition); + doctest::make_test(&test, krate, false, &Default::default(), edition, None); let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" }; let edition_string = format!("&edition={}", edition); diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile index 5c24f909130..c4700b317ef 100644 --- a/src/test/run-make-fulldeps/coverage-reports/Makefile +++ b/src/test/run-make-fulldeps/coverage-reports/Makefile @@ -98,7 +98,7 @@ endif # Run it in order to generate some profiling data, # with `LLVM_PROFILE_FILE=` environment variable set to # output the coverage stats for this run. - LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \ + LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \ $(call RUN,$@) || \ ( \ status=$$?; \ @@ -108,9 +108,16 @@ endif ) \ ) + # Run it through rustdoc as well to cover doctests + LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \ + $(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \ + $$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/$@.rs && echo "--edition=2018" ) \ + -L "$(TMPDIR)" -Zinstrument-coverage \ + -Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@ + # Postprocess the profiling data so it can be used by the llvm-cov tool "$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \ - "$(TMPDIR)"/$@.profraw \ + "$(TMPDIR)"/$@-*.profraw \ -o "$(TMPDIR)"/$@.profdata # Generate a coverage report using `llvm-cov show`. @@ -121,8 +128,15 @@ endif --show-line-counts-or-regions \ --instr-profile="$(TMPDIR)"/$@.profdata \ $(call BIN,"$(TMPDIR)"/$@) \ - > "$(TMPDIR)"/actual_show_coverage.$@.txt \ - 2> "$(TMPDIR)"/show_coverage_stderr.$@.txt || \ + $$( \ + for file in $(TMPDIR)/rustdoc-$@/*/rust_out; \ + do \ + [[ -x $$file ]] && printf "%s %s " -object $$file; \ + done \ + ) \ + 2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \ + | "$(PYTHON)" $(BASEDIR)/normalize_paths.py \ + > "$(TMPDIR)"/actual_show_coverage.$@.txt || \ ( status=$$? ; \ >&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \ exit $$status \ diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt new file mode 100644 index 00000000000..e1731c7223c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt @@ -0,0 +1,79 @@ +../coverage/doctest.rs: + 1| |//! This test ensures that code from doctests is properly re-mapped. + 2| |//! See for more info. + 3| |//! + 4| |//! Just some random code: + 5| 1|//! ``` + 6| 1|//! if true { + 7| |//! // this is executed! + 8| 1|//! assert_eq!(1, 1); + 9| |//! } else { + 10| |//! // this is not! + 11| |//! assert_eq!(1, 2); + 12| |//! } + 13| 1|//! ``` + 14| |//! + 15| |//! doctest testing external code: + 16| |//! ``` + 17| 1|//! extern crate doctest_crate; + 18| 1|//! doctest_crate::fn_run_in_doctests(1); + 19| 1|//! ``` + 20| |//! + 21| |//! doctest returning a result: + 22| 1|//! ``` + 23| 1|//! #[derive(Debug)] + 24| 1|//! struct SomeError; + 25| 1|//! let mut res = Err(SomeError); + 26| 1|//! if res.is_ok() { + 27| 0|//! res?; + 28| 1|//! } else { + 29| 1|//! res = Ok(0); + 30| 1|//! } + 31| |//! // need to be explicit because rustdoc cant infer the return type + 32| 1|//! Ok::<(), SomeError>(()) + 33| 1|//! ``` + 34| |//! + 35| |//! doctest with custom main: + 36| |//! ``` + 37| |//! #[derive(Debug)] + 38| |//! struct SomeError; + 39| |//! + 40| |//! extern crate doctest_crate; + 41| |//! + 42| 1|//! fn doctest_main() -> Result<(), SomeError> { + 43| 1|//! doctest_crate::fn_run_in_doctests(2); + 44| 1|//! Ok(()) + 45| 1|//! } + 46| |//! + 47| |//! // this `main` is not shown as covered, as it clashes with all the other + 48| |//! // `main` functions that were automatically generated for doctests + 49| |//! fn main() -> Result<(), SomeError> { + 50| |//! doctest_main() + 51| |//! } + 52| |//! ``` + 53| | + 54| |/// doctest attached to fn testing external code: + 55| |/// ``` + 56| 1|/// extern crate doctest_crate; + 57| 1|/// doctest_crate::fn_run_in_doctests(3); + 58| 1|/// ``` + 59| |/// + 60| 1|fn main() { + 61| 1| if true { + 62| 1| assert_eq!(1, 1); + 63| | } else { + 64| | assert_eq!(1, 2); + 65| | } + 66| 1|} + +../coverage/lib/doctest_crate.rs: + 1| |/// A function run only from within doctests + 2| 3|pub fn fn_run_in_doctests(conditional: usize) { + 3| 3| match conditional { + 4| 1| 1 => assert_eq!(1, 1), // this is run, + 5| 1| 2 => assert_eq!(1, 1), // this, + 6| 1| 3 => assert_eq!(1, 1), // and this too + 7| 0| _ => assert_eq!(1, 2), // however this is not + 8| | } + 9| 3|} + diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt index e14e733fff6..4c03e950af0 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt @@ -19,12 +19,12 @@ 18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); 19| 2|} ------------------ - | used_crate::used_only_from_bin_crate_generic_function::<&str>: + | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec>: | 17| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); | 19| 1|} ------------------ - | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec>: + | used_crate::used_only_from_bin_crate_generic_function::<&str>: | 17| 1|pub fn used_only_from_bin_crate_generic_function(arg: T) { | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); | 19| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py b/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py new file mode 100644 index 00000000000..05fb412cdb6 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +import sys + +# Normalize file paths in output +for line in sys.stdin: + if line.startswith("..") and line.rstrip().endswith(".rs:"): + print(line.replace("\\", "/"), end='') + else: + print(line, end='') diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..8d074558aae --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,127 @@ + + + + +doctest.main - Coverage Spans + + + +
@0⦊fn main() ⦉@0{ + if @0⦊true⦉@0 { + @5⦊@4,6,7,8,9⦊assert_eq!(1, 1);⦉@4,6,7,8,9⦉@5 + } else { + @11⦊@10,12,13,14,15⦊assert_eq!(1, 2);⦉@10,12,13,14,15⦉@11 + } +}@16⦊‸⦉@16
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..ae119d9ca9f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html @@ -0,0 +1,173 @@ + + + + +doctest_crate.fn_run_in_doctests - Coverage Spans + + + +
@0⦊pub fn fn_run_in_doctests(conditional: usize) ⦉@0{ + match @0⦊conditional⦉@0 { + 1 => @7⦊@6,8,9,10,11⦊assert_eq!(1, 1)⦉@6,8,9,10,11⦉@7, // this is run, + 2 => @14⦊@13,15,16,17,18⦊assert_eq!(1, 1)⦉@13,15,16,17,18⦉@14, // this, + 3 => @21⦊@20,22,23,24,25⦊assert_eq!(1, 1)⦉@20,22,23,24,25⦉@21, // and this too + _ => @27⦊@26,28,29,30,31⦊assert_eq!(1, 2)⦉@26,28,29,30,31⦉@27, // however this is not + } +}@32⦊‸⦉@32
+ + diff --git a/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir b/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir index abf8df8fdc9..d1824d189e3 100644 --- a/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir +++ b/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir @@ -1,3 +1,3 @@ -# Directory "instrument-coverage" supports the tests at prefix ../instrument-coverage-* +# Directory "coverage" supports the tests at prefix ../coverage-* -# Use ./x.py [options] test src/test/run-make-fulldeps/instrument-coverage to run all related tests. +# Use ./x.py [options] test src/test/run-make-fulldeps/coverage to run all related tests. diff --git a/src/test/run-make-fulldeps/coverage/coverage_tools.mk b/src/test/run-make-fulldeps/coverage/coverage_tools.mk index 7dc485cd94d..4d340d4b1da 100644 --- a/src/test/run-make-fulldeps/coverage/coverage_tools.mk +++ b/src/test/run-make-fulldeps/coverage/coverage_tools.mk @@ -1,7 +1,7 @@ -# Common Makefile include for Rust `run-make-fulldeps/instrument-coverage-* tests. Include this +# Common Makefile include for Rust `run-make-fulldeps/coverage-* tests. Include this # file with the line: # -# -include ../instrument-coverage/coverage_tools.mk +# -include ../coverage/coverage_tools.mk -include ../tools.mk diff --git a/src/test/run-make-fulldeps/coverage/doctest.rs b/src/test/run-make-fulldeps/coverage/doctest.rs new file mode 100644 index 00000000000..e41d669bf0c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/doctest.rs @@ -0,0 +1,66 @@ +//! This test ensures that code from doctests is properly re-mapped. +//! See for more info. +//! +//! Just some random code: +//! ``` +//! if true { +//! // this is executed! +//! assert_eq!(1, 1); +//! } else { +//! // this is not! +//! assert_eq!(1, 2); +//! } +//! ``` +//! +//! doctest testing external code: +//! ``` +//! extern crate doctest_crate; +//! doctest_crate::fn_run_in_doctests(1); +//! ``` +//! +//! doctest returning a result: +//! ``` +//! #[derive(Debug)] +//! struct SomeError; +//! let mut res = Err(SomeError); +//! if res.is_ok() { +//! res?; +//! } else { +//! res = Ok(0); +//! } +//! // need to be explicit because rustdoc cant infer the return type +//! Ok::<(), SomeError>(()) +//! ``` +//! +//! doctest with custom main: +//! ``` +//! #[derive(Debug)] +//! struct SomeError; +//! +//! extern crate doctest_crate; +//! +//! fn doctest_main() -> Result<(), SomeError> { +//! doctest_crate::fn_run_in_doctests(2); +//! Ok(()) +//! } +//! +//! // this `main` is not shown as covered, as it clashes with all the other +//! // `main` functions that were automatically generated for doctests +//! fn main() -> Result<(), SomeError> { +//! doctest_main() +//! } +//! ``` + +/// doctest attached to fn testing external code: +/// ``` +/// extern crate doctest_crate; +/// doctest_crate::fn_run_in_doctests(3); +/// ``` +/// +fn main() { + if true { + assert_eq!(1, 1); + } else { + assert_eq!(1, 2); + } +} diff --git a/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs b/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs new file mode 100644 index 00000000000..c3210146d69 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs @@ -0,0 +1,9 @@ +/// A function run only from within doctests +pub fn fn_run_in_doctests(conditional: usize) { + match conditional { + 1 => assert_eq!(1, 1), // this is run, + 2 => assert_eq!(1, 1), // this, + 3 => assert_eq!(1, 1), // and this too + _ => assert_eq!(1, 2), // however this is not + } +} -- cgit 1.4.1-3-g733a5 From 1a7d00a529503ac38a6b1ae28e8e779e434e02e0 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 10 Nov 2020 18:00:53 -0600 Subject: implement edition-specific :pat behavior for 2015/18 --- compiler/rustc_expand/src/mbe/macro_parser.rs | 33 +++++++++++---- compiler/rustc_parse/src/parser/expr.rs | 8 ++-- compiler/rustc_parse/src/parser/mod.rs | 1 + compiler/rustc_parse/src/parser/nonterminal.rs | 23 +++++++++-- compiler/rustc_parse/src/parser/pat.rs | 17 ++++++-- compiler/rustc_parse/src/parser/stmt.rs | 4 +- src/test/ui/macros/macro-pat-follow-2018.rs | 15 +++++++ src/test/ui/macros/macro-pat-follow.rs | 16 ++------ .../or-patterns/or-patterns-syntactic-fail-2018.rs | 15 +++++++ .../or-patterns-syntactic-fail-2018.stderr | 20 +++++++++ .../ui/or-patterns/or-patterns-syntactic-fail.rs | 10 ----- .../or-patterns/or-patterns-syntactic-fail.stderr | 48 +++++++--------------- .../or-patterns/or-patterns-syntactic-pass-2021.rs | 14 +++++++ src/test/ui/pattern/or-pattern-macro-pat.rs | 44 ++++++++++++++++++++ 14 files changed, 193 insertions(+), 75 deletions(-) create mode 100644 src/test/ui/macros/macro-pat-follow-2018.rs create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs create mode 100644 src/test/ui/pattern/or-pattern-macro-pat.rs (limited to 'src') diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index c37f9125675..3cf2d8f8ac1 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -77,9 +77,9 @@ use TokenTreeOrTokenTreeSlice::*; use crate::mbe::{self, TokenTree}; use rustc_ast::token::{self, DocComment, Nonterminal, Token}; -use rustc_parse::parser::Parser; +use rustc_parse::parser::{OrPatNonterminalMode, Parser}; use rustc_session::parse::ParseSess; -use rustc_span::symbol::MacroRulesNormalizedIdent; +use rustc_span::{edition::Edition, symbol::MacroRulesNormalizedIdent}; use smallvec::{smallvec, SmallVec}; @@ -414,6 +414,18 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool { } } +/// In edition 2015/18, `:pat` can only match `pat` because otherwise, we have +/// breakage. As of edition 2021, `:pat` matches `top_pat`. +/// +/// See for more info. +fn or_pat_mode(edition: Edition) -> OrPatNonterminalMode { + match edition { + Edition::Edition2015 | Edition::Edition2018 => OrPatNonterminalMode::NoTopAlt, + // FIXME(mark-i-m): uncomment this when edition 2021 machinery is added. + // Edition::Edition2021 => OrPatNonterminalMode::TopPat, + } +} + /// Process the matcher positions of `cur_items` until it is empty. In the process, this will /// produce more items in `next_items`, `eof_items`, and `bb_items`. /// @@ -553,10 +565,14 @@ fn inner_parse_loop<'root, 'tt>( // We need to match a metavar with a valid ident... call out to the black-box // parser by adding an item to `bb_items`. - TokenTree::MetaVarDecl(_, _, kind) => { - // Built-in nonterminals never start with these tokens, - // so we can eliminate them from consideration. - if Parser::nonterminal_may_begin_with(kind, token) { + TokenTree::MetaVarDecl(span, _, kind) => { + // Built-in nonterminals never start with these tokens, so we can eliminate + // them from consideration. + // + // We use the span of the metavariable declaration to determine any + // edition-specific matching behavior for non-terminals. + if Parser::nonterminal_may_begin_with(kind, token, or_pat_mode(span.edition())) + { bb_items.push(item); } } @@ -717,7 +733,10 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na let mut item = bb_items.pop().unwrap(); if let TokenTree::MetaVarDecl(span, _, kind) = item.top_elts.get_tt(item.idx) { let match_cur = item.match_cur; - let nt = match parser.to_mut().parse_nonterminal(kind) { + // We use the span of the metavariable declaration to determine any + // edition-specific matching behavior for non-terminals. + let nt = match parser.to_mut().parse_nonterminal(kind, or_pat_mode(span.edition())) + { Err(mut err) => { err.span_label( span, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 4d2167442be..eed3e9947b2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1,4 +1,4 @@ -use super::pat::{GateOr, PARAM_EXPECTED}; +use super::pat::{GateOr, RecoverComma, PARAM_EXPECTED}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType}; use super::{SemiColonMode, SeqSep, TokenExpectType}; @@ -1729,7 +1729,7 @@ impl<'a> Parser<'a> { /// The `let` token has already been eaten. fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P> { let lo = self.prev_token.span; - let pat = self.parse_top_pat(GateOr::No)?; + let pat = self.parse_top_pat(GateOr::No, RecoverComma::Yes)?; self.expect(&token::Eq)?; let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| { this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) @@ -1792,7 +1792,7 @@ impl<'a> Parser<'a> { _ => None, }; - let pat = self.parse_top_pat(GateOr::Yes)?; + let pat = self.parse_top_pat(GateOr::Yes, RecoverComma::Yes)?; if !self.eat_keyword(kw::In) { self.error_missing_in_for_loop(); } @@ -1902,7 +1902,7 @@ impl<'a> Parser<'a> { pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> { let attrs = self.parse_outer_attributes()?; let lo = self.token.span; - let pat = self.parse_top_pat(GateOr::No)?; + let pat = self.parse_top_pat(GateOr::No, RecoverComma::Yes)?; let guard = if self.eat_keyword(kw::If) { let if_span = self.prev_token.span; let cond = self.parse_expr()?; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index d51a0fcbf09..e19ebb8fd2f 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -12,6 +12,7 @@ mod ty; use crate::lexer::UnmatchedBrace; pub use diagnostics::AttemptLocalParseRecovery; use diagnostics::Error; +pub use pat::OrPatNonterminalMode; pub use path::PathStyle; use rustc_ast::ptr::P; diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 76ad5acd530..a6b9ac1014e 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -4,6 +4,7 @@ use rustc_ast_pretty::pprust; use rustc_errors::PResult; use rustc_span::symbol::{kw, Ident}; +use crate::parser::pat::{GateOr, OrPatNonterminalMode, RecoverComma}; use crate::parser::{FollowedByType, Parser, PathStyle}; impl<'a> Parser<'a> { @@ -11,7 +12,11 @@ impl<'a> Parser<'a> { /// /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that /// token. Be conservative (return true) if not sure. - pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool { + pub fn nonterminal_may_begin_with( + kind: NonterminalKind, + token: &Token, + or_pat_mode: OrPatNonterminalMode, + ) -> bool { /// Checks whether the non-terminal may contain a single (non-keyword) identifier. fn may_be_ident(nt: &token::Nonterminal) -> bool { match *nt { @@ -70,6 +75,8 @@ impl<'a> Parser<'a> { token::ModSep | // path token::Lt | // path (UFCS constant) token::BinOp(token::Shl) => true, // path (double UFCS) + // leading vert `|` or-pattern + token::BinOp(token::Or) => matches!(or_pat_mode, OrPatNonterminalMode::TopPat), token::Interpolated(ref nt) => may_be_ident(nt), _ => false, }, @@ -86,7 +93,12 @@ impl<'a> Parser<'a> { } } - pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, Nonterminal> { + /// Parse a non-terminal (e.g. MBE `:pat` or `:ident`). + pub fn parse_nonterminal( + &mut self, + kind: NonterminalKind, + or_pat_mode: OrPatNonterminalMode, + ) -> PResult<'a, Nonterminal> { // Any `Nonterminal` which stores its tokens (currently `NtItem` and `NtExpr`) // needs to have them force-captured here. // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro, @@ -130,7 +142,12 @@ impl<'a> Parser<'a> { } } NonterminalKind::Pat => { - let (mut pat, tokens) = self.collect_tokens(|this| this.parse_pat(None))?; + let (mut pat, tokens) = self.collect_tokens(|this| match or_pat_mode { + OrPatNonterminalMode::TopPat => { + this.parse_top_pat(GateOr::Yes, RecoverComma::No) + } + OrPatNonterminalMode::NoTopAlt => this.parse_pat(None), + })?; // We have have eaten an NtPat, which could already have tokens if pat.tokens.is_none() { pat.tokens = tokens; diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index b62c7373800..1da371e0b72 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -26,11 +26,18 @@ pub(super) enum GateOr { /// Whether or not to recover a `,` when parsing or-patterns. #[derive(PartialEq, Copy, Clone)] -enum RecoverComma { +pub(super) enum RecoverComma { Yes, No, } +/// Used when parsing a non-terminal (see `parse_nonterminal`) to determine if `:pat` should match +/// `top_pat` or `pat`. See issue . +pub enum OrPatNonterminalMode { + TopPat, + NoTopAlt, +} + impl<'a> Parser<'a> { /// Parses a pattern. /// @@ -43,13 +50,17 @@ impl<'a> Parser<'a> { /// Entry point to the main pattern parser. /// Corresponds to `top_pat` in RFC 2535 and allows or-pattern at the top level. - pub(super) fn parse_top_pat(&mut self, gate_or: GateOr) -> PResult<'a, P> { + pub(super) fn parse_top_pat( + &mut self, + gate_or: GateOr, + rc: RecoverComma, + ) -> PResult<'a, P> { // Allow a '|' before the pats (RFCs 1925, 2530, and 2535). let gated_leading_vert = self.eat_or_separator(None) && gate_or == GateOr::Yes; let leading_vert_span = self.prev_token.span; // Parse the possibly-or-pattern. - let pat = self.parse_pat_with_or(None, gate_or, RecoverComma::Yes)?; + let pat = self.parse_pat_with_or(None, gate_or, rc)?; // If we parsed a leading `|` which should be gated, // and no other gated or-pattern has been parsed thus far, diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index e974556f43a..2942747991a 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -1,7 +1,7 @@ use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN; use super::diagnostics::{AttemptLocalParseRecovery, Error}; use super::expr::LhsExpr; -use super::pat::GateOr; +use super::pat::{GateOr, RecoverComma}; use super::path::PathStyle; use super::{BlockMode, Parser, Restrictions, SemiColonMode}; use crate::maybe_whole; @@ -185,7 +185,7 @@ impl<'a> Parser<'a> { /// Parses a local variable declaration. fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P> { let lo = self.prev_token.span; - let pat = self.parse_top_pat(GateOr::Yes)?; + let pat = self.parse_top_pat(GateOr::Yes, RecoverComma::Yes)?; let (err, ty) = if self.eat(&token::Colon) { // Save the state of the parser before parsing type normally, in case there is a `:` diff --git a/src/test/ui/macros/macro-pat-follow-2018.rs b/src/test/ui/macros/macro-pat-follow-2018.rs new file mode 100644 index 00000000000..ce2911de986 --- /dev/null +++ b/src/test/ui/macros/macro-pat-follow-2018.rs @@ -0,0 +1,15 @@ +// run-pass +// edition:2018 + +macro_rules! pat_bar { + ($p:pat | $p2:pat) => {{ + match Some(1u8) { + $p | $p2 => {} + _ => {} + } + }}; +} + +fn main() { + pat_bar!(Some(1u8) | None); +} diff --git a/src/test/ui/macros/macro-pat-follow.rs b/src/test/ui/macros/macro-pat-follow.rs index 8673cf79467..8e02789fdd8 100644 --- a/src/test/ui/macros/macro-pat-follow.rs +++ b/src/test/ui/macros/macro-pat-follow.rs @@ -3,29 +3,19 @@ macro_rules! pat_in { ($p:pat in $e:expr) => {{ let mut iter = $e.into_iter(); while let $p = iter.next() {} - }} + }}; } macro_rules! pat_if { ($p:pat if $e:expr) => {{ match Some(1u8) { - $p if $e => {}, + $p if $e => {} _ => {} } - }} -} - -macro_rules! pat_bar { - ($p:pat | $p2:pat) => {{ - match Some(1u8) { - $p | $p2 => {}, - _ => {} - } - }} + }}; } fn main() { pat_in!(Some(_) in 0..10); pat_if!(Some(x) if x > 0); - pat_bar!(Some(1u8) | None); } diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs new file mode 100644 index 00000000000..9c3c5dd360e --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs @@ -0,0 +1,15 @@ +// Test that :pat doesn't accept top-level or-patterns in edition 2018. + +// edition:2018 + +#![feature(or_patterns)] + +fn main() {} + +// Test the `pat` macro fragment parser: +macro_rules! accept_pat { + ($p:pat) => {}; +} + +accept_pat!(p | q); //~ ERROR no rules expected the token `|` +accept_pat!(|p| q); //~ ERROR no rules expected the token `|` diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr new file mode 100644 index 00000000000..7dbc3087663 --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr @@ -0,0 +1,20 @@ +error: no rules expected the token `|` + --> $DIR/or-patterns-syntactic-fail-2018.rs:14:15 + | +LL | macro_rules! accept_pat { + | ----------------------- when calling this macro +... +LL | accept_pat!(p | q); + | ^ no rules expected this token in macro call + +error: no rules expected the token `|` + --> $DIR/or-patterns-syntactic-fail-2018.rs:15:13 + | +LL | macro_rules! accept_pat { + | ----------------------- when calling this macro +... +LL | accept_pat!(|p| q); + | ^ no rules expected this token in macro call + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs index d2322005652..efe90b3e3c6 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs @@ -5,16 +5,6 @@ fn main() {} -// Test the `pat` macro fragment parser: -macro_rules! accept_pat { - ($p:pat) => {} -} - -accept_pat!(p | q); //~ ERROR no rules expected the token `|` -accept_pat!(| p | q); //~ ERROR no rules expected the token `|` - -// Non-macro tests: - enum E { A, B } use E::*; diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr index 861d274ab5c..989aeb52006 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr @@ -1,53 +1,53 @@ error: an or-pattern parameter must be wrapped in parenthesis - --> $DIR/or-patterns-syntactic-fail.rs:27:13 + --> $DIR/or-patterns-syntactic-fail.rs:17:13 | LL | fn fun1(A | B: E) {} | ^^^^^ help: wrap the pattern in parenthesis: `(A | B)` error: a leading `|` is not allowed in a parameter pattern - --> $DIR/or-patterns-syntactic-fail.rs:29:13 + --> $DIR/or-patterns-syntactic-fail.rs:19:13 | LL | fn fun2(| A | B: E) {} | ^ help: remove the `|` error: an or-pattern parameter must be wrapped in parenthesis - --> $DIR/or-patterns-syntactic-fail.rs:29:15 + --> $DIR/or-patterns-syntactic-fail.rs:19:15 | LL | fn fun2(| A | B: E) {} | ^^^^^ help: wrap the pattern in parenthesis: `(A | B)` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:40:11 + --> $DIR/or-patterns-syntactic-fail.rs:30:11 | LL | let ( | A | B) = E::A; | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:41:11 + --> $DIR/or-patterns-syntactic-fail.rs:31:11 | LL | let ( | A | B,) = (E::B,); | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:42:11 + --> $DIR/or-patterns-syntactic-fail.rs:32:11 | LL | let [ | A | B ] = [E::A]; | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:43:13 + --> $DIR/or-patterns-syntactic-fail.rs:33:13 | LL | let TS( | A | B ); | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:44:17 + --> $DIR/or-patterns-syntactic-fail.rs:34:17 | LL | let NS { f: | A | B }; | ^ help: remove the `|` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:46:11 + --> $DIR/or-patterns-syntactic-fail.rs:36:11 | LL | let ( || A | B) = E::A; | ^^ help: remove the `||` @@ -55,7 +55,7 @@ LL | let ( || A | B) = E::A; = note: alternatives in or-patterns are separated with `|`, not `||` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:47:11 + --> $DIR/or-patterns-syntactic-fail.rs:37:11 | LL | let [ || A | B ] = [E::A]; | ^^ help: remove the `||` @@ -63,7 +63,7 @@ LL | let [ || A | B ] = [E::A]; = note: alternatives in or-patterns are separated with `|`, not `||` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:48:13 + --> $DIR/or-patterns-syntactic-fail.rs:38:13 | LL | let TS( || A | B ); | ^^ help: remove the `||` @@ -71,33 +71,15 @@ LL | let TS( || A | B ); = note: alternatives in or-patterns are separated with `|`, not `||` error: a leading `|` is only allowed in a top-level pattern - --> $DIR/or-patterns-syntactic-fail.rs:49:17 + --> $DIR/or-patterns-syntactic-fail.rs:39:17 | LL | let NS { f: || A | B }; | ^^ help: remove the `||` | = note: alternatives in or-patterns are separated with `|`, not `||` -error: no rules expected the token `|` - --> $DIR/or-patterns-syntactic-fail.rs:13:15 - | -LL | macro_rules! accept_pat { - | ----------------------- when calling this macro -... -LL | accept_pat!(p | q); - | ^ no rules expected this token in macro call - -error: no rules expected the token `|` - --> $DIR/or-patterns-syntactic-fail.rs:14:13 - | -LL | macro_rules! accept_pat { - | ----------------------- when calling this macro -... -LL | accept_pat!(| p | q); - | ^ no rules expected this token in macro call - error[E0369]: no implementation for `E | ()` - --> $DIR/or-patterns-syntactic-fail.rs:23:22 + --> $DIR/or-patterns-syntactic-fail.rs:13:22 | LL | let _ = |A | B: E| (); | ----^ -- () @@ -107,7 +89,7 @@ LL | let _ = |A | B: E| (); = note: an implementation of `std::ops::BitOr` might be missing for `E` error[E0308]: mismatched types - --> $DIR/or-patterns-syntactic-fail.rs:51:36 + --> $DIR/or-patterns-syntactic-fail.rs:41:36 | LL | let recovery_witness: String = 0; | ------ ^ @@ -116,7 +98,7 @@ LL | let recovery_witness: String = 0; | | help: try using a conversion method: `0.to_string()` | expected due to this -error: aborting due to 16 previous errors +error: aborting due to 14 previous errors Some errors have detailed explanations: E0308, E0369. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs new file mode 100644 index 00000000000..f0ce7597aee --- /dev/null +++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs @@ -0,0 +1,14 @@ +// Tests that :pat in macros in edition 2021 allows top-level or-patterns. + +// run-pass +// ignore-test +// edition:2021 +// FIXME(mark-i-m): unignore when 2021 machinery is in place. + +macro_rules! accept_pat { + ($p:pat) => {}; +} + +accept_pat!(p | q); + +fn main() {} diff --git a/src/test/ui/pattern/or-pattern-macro-pat.rs b/src/test/ui/pattern/or-pattern-macro-pat.rs new file mode 100644 index 00000000000..8749407675b --- /dev/null +++ b/src/test/ui/pattern/or-pattern-macro-pat.rs @@ -0,0 +1,44 @@ +// run-pass +// edition:2021 +// ignore-test +// FIXME(mark-i-m): enable this test again when 2021 machinery is available + +#![feature(or_patterns)] + +use Foo::*; + +#[derive(Eq, PartialEq, Debug)] +enum Foo { + A(u64), + B(u64), + C, + D, +} + +macro_rules! foo { + ($orpat:pat, $val:expr) => { + match $val { + x @ ($orpat) => x, // leading vert would not be allowed in $orpat + _ => B(0xDEADBEEFu64), + } + }; +} + +macro_rules! bar { + ($orpat:pat, $val:expr) => { + match $val { + $orpat => 42, // leading vert allowed here + _ => 0xDEADBEEFu64, + } + }; +} + +fn main() { + // Test or-pattern. + let y = foo!(A(_)|B(_), A(32)); + assert_eq!(y, A(32)); + + // Leading vert in or-pattern. + let y = bar!(|C| D, C); + assert_eq!(y, 42u64); +} -- cgit 1.4.1-3-g733a5 From 5b6c175566e55e29c0d2c39cb0dab2119ac40c82 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 19 Dec 2020 17:48:31 +0000 Subject: Tweak diagnostics --- .../rustc_mir_build/src/thir/pattern/deconstruct_pat.rs | 5 ++--- .../integer-ranges/overlapping_range_endpoints.stderr | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 5b1dbabe9a1..94083289cab 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -309,9 +309,7 @@ impl IntRange { pcx.span, |lint| { let mut err = lint.build("multiple patterns overlap on their endpoints"); - err.span_label(pcx.span, "... with this range"); for (int_range, span) in overlaps { - // Use the real type for user display of the ranges: err.span_label( span, &format!( @@ -320,7 +318,8 @@ impl IntRange { ), ); } - err.note("this is likely to be a mistake"); + err.span_label(pcx.span, "... with this range"); + err.note("you likely meant to write mutually exclusive ranges"); err.emit(); }, ); diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index 045c487873a..24c0419e1dd 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(overlapping_range_endpoints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:16:22 @@ -21,7 +21,7 @@ LL | m!(0u8, 30..=40, 20..=30); | | | this range overlaps on `30_u8`... | - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:19:22 @@ -31,7 +31,7 @@ LL | m!(0u8, 20.. 30, 29..=40); | | | this range overlaps on `29_u8`... | - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:23:22 @@ -41,7 +41,7 @@ LL | m!(0u8, 20..=30, 30..=31); | | | this range overlaps on `30_u8`... | - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:27:22 @@ -51,7 +51,7 @@ LL | m!(0u8, 20..=30, 19..=20); | | | this range overlaps on `20_u8`... | - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:39:9 @@ -63,7 +63,7 @@ LL | 20..=30 => {} LL | 10..=20 => {} | ^^^^^^^ ... with this range | - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:50:16 @@ -73,7 +73,7 @@ LL | (true, 0..=10) => {} LL | (true, 10..20) => {} | ^^^^^^ ... with this range | - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:56:14 @@ -83,7 +83,7 @@ LL | Some(0..=10) => {} LL | Some(10..20) => {} | ^^^^^^ ... with this range | - = note: this is likely to be a mistake + = note: you likely meant to write mutually exclusive ranges error: aborting due to 8 previous errors -- cgit 1.4.1-3-g733a5 From f4085f0d3a4f1ff77153eabf8fa9cf6d0dafae1a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 19 Dec 2020 20:25:27 +0100 Subject: also const-check FakeRead --- .../src/transform/check_consts/validation.rs | 11 +++++------ .../const_refers_to_static_cross_crate.stderr | 5 +++++ src/test/ui/error-codes/E0396.rs | 11 +++++++++++ src/test/ui/error-codes/E0396.stderr | 20 +++++++++++++++++++- 4 files changed, 40 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index d00038f345c..90688ebbd0a 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -722,17 +722,16 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { trace!("visit_statement: statement={:?} location={:?}", statement, location); - match statement.kind { - StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } => { - self.super_statement(statement, location); - } + self.super_statement(statement, location); + match statement.kind { StatementKind::LlvmInlineAsm { .. } => { - self.super_statement(statement, location); self.check_op(ops::InlineAsm); } - StatementKind::FakeRead(..) + StatementKind::Assign(..) + | StatementKind::SetDiscriminant { .. } + | StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag { .. } diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index 52662ef9eaf..b65e50eb9f4 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -146,6 +146,11 @@ help: skipping check that does not even have a feature gate | LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:32:20 + | +LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check for `const_panic` feature --> $DIR/const_refers_to_static_cross_crate.rs:32:77 | diff --git a/src/test/ui/error-codes/E0396.rs b/src/test/ui/error-codes/E0396.rs index b32853e483d..58ed3c2c722 100644 --- a/src/test/ui/error-codes/E0396.rs +++ b/src/test/ui/error-codes/E0396.rs @@ -5,5 +5,16 @@ const REG_ADDR: *const u8 = 0x5f3759df as *const u8; const VALUE: u8 = unsafe { *REG_ADDR }; //~^ ERROR dereferencing raw pointers in constants is unstable +const unsafe fn unreachable() -> ! { + use std::convert::Infallible; + + const INFALLIBLE: *const Infallible = [].as_ptr(); + match *INFALLIBLE {} + //~^ ERROR dereferencing raw pointers in constant functions is unstable + + const BAD: () = unsafe { match *INFALLIBLE {} }; + //~^ ERROR dereferencing raw pointers in constants is unstable +} + fn main() { } diff --git a/src/test/ui/error-codes/E0396.stderr b/src/test/ui/error-codes/E0396.stderr index 7d2544f939f..20dad1b983c 100644 --- a/src/test/ui/error-codes/E0396.stderr +++ b/src/test/ui/error-codes/E0396.stderr @@ -7,6 +7,24 @@ LL | const VALUE: u8 = unsafe { *REG_ADDR }; = note: see issue #51911 for more information = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable -error: aborting due to previous error +error[E0658]: dereferencing raw pointers in constant functions is unstable + --> $DIR/E0396.rs:12:11 + | +LL | match *INFALLIBLE {} + | ^^^^^^^^^^^ + | + = note: see issue #51911 for more information + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable + +error[E0658]: dereferencing raw pointers in constants is unstable + --> $DIR/E0396.rs:15:36 + | +LL | const BAD: () = unsafe { match *INFALLIBLE {} }; + | ^^^^^^^^^^^ + | + = note: see issue #51911 for more information + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From 74bd2eae3335e74663d25a6a2142bc904007a499 Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Sun, 20 Dec 2020 00:21:42 +0100 Subject: impl Default for LangString, replacing all_false by default --- src/librustdoc/html/markdown.rs | 20 ++++++++------- src/librustdoc/html/markdown/tests.rs | 48 +++++++++++++---------------------- 2 files changed, 29 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 22096203d4c..82982a1b43e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -204,7 +204,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { CodeBlockKind::Fenced(ref lang) => { LangString::parse_without_check(&lang, self.check_error_codes, false) } - CodeBlockKind::Indented => LangString::all_false(), + CodeBlockKind::Indented => Default::default(), }; if !parse_result.rust { return Some(Event::Start(Tag::CodeBlock(kind))); @@ -665,7 +665,7 @@ crate fn find_testable_code( let block_info = match kind { CodeBlockKind::Fenced(ref lang) => { if lang.is_empty() { - LangString::all_false() + Default::default() } else { LangString::parse( lang, @@ -675,7 +675,7 @@ crate fn find_testable_code( ) } } - CodeBlockKind::Indented => LangString::all_false(), + CodeBlockKind::Indented => Default::default(), }; if !block_info.rust { continue; @@ -778,14 +778,14 @@ crate enum Ignore { Some(Vec), } -impl LangString { - fn all_false() -> LangString { - LangString { +impl Default for LangString { + fn default() -> Self { + Self { original: String::new(), should_panic: false, no_run: false, ignore: Ignore::None, - rust: true, // NB This used to be `notrust = false` + rust: true, test_harness: false, compile_fail: false, error_codes: Vec::new(), @@ -793,7 +793,9 @@ impl LangString { edition: None, } } +} +impl LangString { fn parse_without_check( string: &str, allow_error_code_check: ErrorCodes, @@ -811,7 +813,7 @@ impl LangString { let allow_error_code_check = allow_error_code_check.as_bool(); let mut seen_rust_tags = false; let mut seen_other_tags = false; - let mut data = LangString::all_false(); + let mut data = LangString::default(); let mut ignores = vec![]; data.original = string.to_owned(); @@ -1233,7 +1235,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec { let syntax = syntax.as_ref(); let lang_string = if syntax.is_empty() { - LangString::all_false() + Default::default() } else { LangString::parse(&*syntax, ErrorCodes::Yes, false, Some(extra_info)) }; diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 75ff3c5af2f..9da3072ec28 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -56,71 +56,59 @@ fn test_lang_string_parse() { assert_eq!(LangString::parse(s, ErrorCodes::Yes, true, None), lg) } - t(LangString::all_false()); - t(LangString { original: "rust".into(), ..LangString::all_false() }); - t(LangString { original: "sh".into(), rust: false, ..LangString::all_false() }); - t(LangString { original: "ignore".into(), ignore: Ignore::All, ..LangString::all_false() }); + t(Default::default()); + t(LangString { original: "rust".into(), ..Default::default() }); + t(LangString { original: "sh".into(), rust: false, ..Default::default() }); + t(LangString { original: "ignore".into(), ignore: Ignore::All, ..Default::default() }); t(LangString { original: "ignore-foo".into(), ignore: Ignore::Some(vec!["foo".to_string()]), - ..LangString::all_false() - }); - t(LangString { - original: "should_panic".into(), - should_panic: true, - ..LangString::all_false() - }); - t(LangString { original: "no_run".into(), no_run: true, ..LangString::all_false() }); - t(LangString { - original: "test_harness".into(), - test_harness: true, - ..LangString::all_false() + ..Default::default() }); + t(LangString { original: "should_panic".into(), should_panic: true, ..Default::default() }); + t(LangString { original: "no_run".into(), no_run: true, ..Default::default() }); + t(LangString { original: "test_harness".into(), test_harness: true, ..Default::default() }); t(LangString { original: "compile_fail".into(), no_run: true, compile_fail: true, - ..LangString::all_false() - }); - t(LangString { original: "allow_fail".into(), allow_fail: true, ..LangString::all_false() }); - t(LangString { - original: "{.no_run .example}".into(), - no_run: true, - ..LangString::all_false() + ..Default::default() }); + t(LangString { original: "allow_fail".into(), allow_fail: true, ..Default::default() }); + t(LangString { original: "{.no_run .example}".into(), no_run: true, ..Default::default() }); t(LangString { original: "{.sh .should_panic}".into(), should_panic: true, rust: false, - ..LangString::all_false() + ..Default::default() }); - t(LangString { original: "{.example .rust}".into(), ..LangString::all_false() }); + t(LangString { original: "{.example .rust}".into(), ..Default::default() }); t(LangString { original: "{.test_harness .rust}".into(), test_harness: true, - ..LangString::all_false() + ..Default::default() }); t(LangString { original: "text, no_run".into(), no_run: true, rust: false, - ..LangString::all_false() + ..Default::default() }); t(LangString { original: "text,no_run".into(), no_run: true, rust: false, - ..LangString::all_false() + ..Default::default() }); t(LangString { original: "edition2015".into(), edition: Some(Edition::Edition2015), - ..LangString::all_false() + ..Default::default() }); t(LangString { original: "edition2018".into(), edition: Some(Edition::Edition2018), - ..LangString::all_false() + ..Default::default() }); } -- cgit 1.4.1-3-g733a5 From b76c9be7f5fa10b95fe4f872400b4388b67a4733 Mon Sep 17 00:00:00 2001 From: William Bain Date: Sat, 19 Dec 2020 16:52:19 -0500 Subject: Handle desugaring in impl trait bound suggestion --- .../src/traits/error_reporting/suggestions.rs | 18 ++++-------- .../suggestions/impl-trait-with-missing-bounds.rs | 8 ++++++ .../impl-trait-with-missing-bounds.stderr | 17 ++++++++++- ...3-impl-trait-with-missing-bounds-on-async-fn.rs | 32 +++++++++++++++++++++ ...pl-trait-with-missing-bounds-on-async-fn.stderr | 33 ++++++++++++++++++++++ 5 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs create mode 100644 src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr (limited to 'src') diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index b4b71a48ce9..79fea83a667 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -254,27 +254,21 @@ fn suggest_restriction( let pred = trait_ref.without_const().to_predicate(tcx).to_string(); let pred = pred.replace(&impl_trait_str, &type_param_name); let mut sugg = vec![ + // Find the last of the generic parameters contained within the span of + // the generics match generics .params .iter() - .filter(|p| match p.kind { - hir::GenericParamKind::Type { - synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), - .. - } => false, - _ => true, - }) - .last() + .map(|p| p.bounds_span().unwrap_or(p.span)) + .filter(|&span| generics.span.contains(span) && span.desugaring_kind().is_none()) + .max_by_key(|span| span.hi()) { // `fn foo(t: impl Trait)` // ^ suggest `` here None => (generics.span, format!("<{}>", type_param)), // `fn foo(t: impl Trait)` // ^^^ suggest `` here - Some(param) => ( - param.bounds_span().unwrap_or(param.span).shrink_to_hi(), - format!(", {}", type_param), - ), + Some(span) => (span.shrink_to_hi(), format!(", {}", type_param)), }, // `fn foo(t: impl Trait)` // ^ suggest `where ::A: Bound` diff --git a/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs b/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs index d401328077a..949b2360071 100644 --- a/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs +++ b/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs @@ -39,6 +39,14 @@ fn bak(constraints: impl Iterator + std::fmt::Debug) { } } +#[rustfmt::skip] +fn baw<>(constraints: impl Iterator) { + for constraint in constraints { + qux(constraint); +//~^ ERROR `::Item` doesn't implement `Debug` + } +} + fn qux(_: impl std::fmt::Debug) {} fn main() {} diff --git a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr index 099eb1c9d00..0de3b9aec19 100644 --- a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr +++ b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr @@ -73,6 +73,21 @@ help: introduce a type parameter with a trait bound instead of using `impl Trait LL | fn bak(constraints: I) where ::Item: Debug { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error[E0277]: `::Item` doesn't implement `Debug` + --> $DIR/impl-trait-with-missing-bounds.rs:45:13 + | +LL | qux(constraint); + | ^^^^^^^^^^ `::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` +... +LL | fn qux(_: impl std::fmt::Debug) {} + | --------------- required by this bound in `qux` + | + = help: the trait `Debug` is not implemented for `::Item` +help: introduce a type parameter with a trait bound instead of using `impl Trait` + | +LL | fn baw(constraints: I) where ::Item: Debug { + | ^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs new file mode 100644 index 00000000000..3cd6d336e13 --- /dev/null +++ b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs @@ -0,0 +1,32 @@ +// Regression test: if we suggest replacing an `impl Trait` argument to an async +// fn with a named type parameter in order to add bounds, the suggested function +// signature should be well-formed. +// +// edition:2018 + +trait Foo { + type Bar; + fn bar(&self) -> Self::Bar; +} + +async fn run(_: &(), foo: impl Foo) -> std::io::Result<()> { + let bar = foo.bar(); + assert_is_send(&bar); +//~^ ERROR: `::Bar` cannot be sent between threads safely + + Ok(()) +} + +// Test our handling of cases where there is a generic parameter list in the +// source, but only synthetic generic parameters +async fn run2< >(_: &(), foo: impl Foo) -> std::io::Result<()> { + let bar = foo.bar(); + assert_is_send(&bar); +//~^ ERROR: `::Bar` cannot be sent between threads safely + + Ok(()) +} + +fn assert_is_send(_: &T) {} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr new file mode 100644 index 00000000000..9404c3bb583 --- /dev/null +++ b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr @@ -0,0 +1,33 @@ +error[E0277]: `::Bar` cannot be sent between threads safely + --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:14:20 + | +LL | assert_is_send(&bar); + | ^^^^ `::Bar` cannot be sent between threads safely +... +LL | fn assert_is_send(_: &T) {} + | ---- required by this bound in `assert_is_send` + | + = help: the trait `Send` is not implemented for `::Bar` +help: introduce a type parameter with a trait bound instead of using `impl Trait` + | +LL | async fn run(_: &(), foo: F) -> std::io::Result<()> where ::Bar: Send { + | ^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `::Bar` cannot be sent between threads safely + --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:24:20 + | +LL | assert_is_send(&bar); + | ^^^^ `::Bar` cannot be sent between threads safely +... +LL | fn assert_is_send(_: &T) {} + | ---- required by this bound in `assert_is_send` + | + = help: the trait `Send` is not implemented for `::Bar` +help: introduce a type parameter with a trait bound instead of using `impl Trait` + | +LL | async fn run2(_: &(), foo: F) -> std::io::Result<()> where ::Bar: Send { + | ^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5 From e628fcfcb591ce78673d2736ebe936873ea5111d Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Sun, 20 Dec 2020 02:49:18 +0000 Subject: Skip `dsymutil` by default for compiler bootstrap `dsymutil` adds time to builds on Apple platforms for no clear benefit, and also makes it more difficult for debuggers to find debug info. The compiler currently defaults to running `dsymutil` to preserve its historical default, but when compiling the compiler itself, we skip it by default since we know it's safe to do so in that case. --- config.toml.example | 8 ++++++++ src/bootstrap/builder.rs | 13 +++++++++++++ src/bootstrap/config.rs | 3 +++ 3 files changed, 24 insertions(+) (limited to 'src') diff --git a/config.toml.example b/config.toml.example index 5b045d4e32d..b1fb8904ca9 100644 --- a/config.toml.example +++ b/config.toml.example @@ -426,6 +426,14 @@ changelog-seen = 2 # FIXME(#61117): Some tests fail when this option is enabled. #debuginfo-level-tests = 0 +# Whether to run `dsymutil` on Apple platforms to gather debug info into .dSYM +# bundles. `dsymutil` adds time to builds for no clear benefit, and also makes +# it more difficult for debuggers to find debug info. The compiler currently +# defaults to running `dsymutil` to preserve its historical default, but when +# compiling the compiler itself, we skip it by default since we know it's safe +# to do so in that case. +#run-dsymutil = false + # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE) #backtrace = true diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 9af79e20630..ab0c4a5c31b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1126,6 +1126,19 @@ impl<'a> Builder<'a> { }, ); + // `dsymutil` adds time to builds on Apple platforms for no clear benefit, and also makes + // it more difficult for debuggers to find debug info. The compiler currently defaults to + // running `dsymutil` to preserve its historical default, but when compiling the compiler + // itself, we skip it by default since we know it's safe to do so in that case. + // See https://github.com/rust-lang/rust/issues/79361 for more info on this flag. + if target.contains("apple") { + if self.config.rust_run_dsymutil { + rustflags.arg("-Zrun-dsymutil=yes"); + } else { + rustflags.arg("-Zrun-dsymutil=no"); + } + } + if self.config.cmd.bless() { // Bless `expect!` tests. cargo.env("UPDATE_EXPECT", "1"); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index fb2c6d1f92a..ece8a7494b5 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -123,6 +123,7 @@ pub struct Config { pub rust_debuginfo_level_std: u32, pub rust_debuginfo_level_tools: u32, pub rust_debuginfo_level_tests: u32, + pub rust_run_dsymutil: bool, pub rust_rpath: bool, pub rustc_parallel: bool, pub rustc_default_linker: Option, @@ -466,6 +467,7 @@ struct Rust { debuginfo_level_std: Option, debuginfo_level_tools: Option, debuginfo_level_tests: Option, + run_dsymutil: Option, backtrace: Option, incremental: Option, parallel_compiler: Option, @@ -830,6 +832,7 @@ impl Config { debuginfo_level_std = rust.debuginfo_level_std; debuginfo_level_tools = rust.debuginfo_level_tools; debuginfo_level_tests = rust.debuginfo_level_tests; + config.rust_run_dsymutil = rust.run_dsymutil.unwrap_or(false); optimize = rust.optimize; ignore_git = rust.ignore_git; set(&mut config.rust_new_symbol_mangling, rust.new_symbol_mangling); -- cgit 1.4.1-3-g733a5 From f9fa3fe65f561001535b069ed1f55c202758588c Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Sun, 20 Dec 2020 10:00:32 +0100 Subject: add an attribute to inner doctest fn --- src/librustdoc/doctest.rs | 7 ++++--- src/librustdoc/doctest/tests.rs | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a08ded92640..7313c761eae 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -551,17 +551,18 @@ crate fn make_test( } else { "_inner".into() }; + let inner_attr = if test_id.is_some() { "#[allow(non_snake_case)] " } else { "" }; let (main_pre, main_post) = if returns_result { ( format!( - "fn main() {{ fn {}() -> Result<(), impl core::fmt::Debug> {{\n", - inner_fn_name + "fn main() {{ {}fn {}() -> Result<(), impl core::fmt::Debug> {{\n", + inner_attr, inner_fn_name ), format!("\n}}; {}().unwrap() }}", inner_fn_name), ) } else if test_id.is_some() { ( - format!("fn main() {{ fn {}() {{\n", inner_fn_name), + format!("fn main() {{ {}fn {}() {{\n", inner_attr, inner_fn_name), format!("\n}}; {}() }}", inner_fn_name), ) } else { diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index 7c0df673c1b..1aea85e9970 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -304,11 +304,11 @@ fn make_test_named_wrapper() { let opts = TestOptions::default(); let input = "assert_eq!(2+2, 4);"; let expected = "#![allow(unused)] -fn main() { fn _doctest_main_some_unique_name() { +fn main() { #[allow(non_snake_case)] fn _doctest_main__some_unique_name() { assert_eq!(2+2, 4); -}; _doctest_main_some_unique_name() }" +}; _doctest_main__some_unique_name() }" .to_string(); let (output, len, _) = - make_test(input, None, false, &opts, DEFAULT_EDITION, Some("some_unique_name")); + make_test(input, None, false, &opts, DEFAULT_EDITION, Some("_some_unique_name")); assert_eq!((output, len), (expected, 2)); } -- cgit 1.4.1-3-g733a5 From a33f6ac9a0b124f3373cd0fd2063bfadf4242e5d Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Sun, 20 Dec 2020 16:18:34 +0800 Subject: Fix ICE on suggesting calling function --- compiler/rustc_typeck/src/check/_match.rs | 2 +- compiler/rustc_typeck/src/check/op.rs | 9 ++++++++- src/test/compile-fail/issue-77910-1.rs | 11 +++++++++++ src/test/compile-fail/issue-77910-2.rs | 9 +++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/issue-77910-1.rs create mode 100644 src/test/compile-fail/issue-77910-2.rs (limited to 'src') diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 3106f19cf86..6467e044079 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -31,7 +31,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => (false, false, false), }; - // Type check the descriminant and get its type. + // Type check the discriminant and get its type. let scrutinee_ty = if force_scrutinee_bool { // Here we want to ensure: // diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 854bc70108f..6305bafcd94 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -504,7 +504,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } // We're emitting a suggestion, so we can just ignore regions - let fn_sig = self.tcx.fn_sig(def_id).skip_binder(); + // FIXME: Instead of exiting early when encountering bound vars in + // the function signature, consider keeping the binder here and + // propagating it downwards. + let fn_sig = if let Some(fn_sig) = self.tcx.fn_sig(def_id).no_bound_vars() { + fn_sig + } else { + return false; + }; let other_ty = if let FnDef(def_id, _) = *other_ty.kind() { if !self.tcx.has_typeck_results(def_id) { diff --git a/src/test/compile-fail/issue-77910-1.rs b/src/test/compile-fail/issue-77910-1.rs new file mode 100644 index 00000000000..d786e335859 --- /dev/null +++ b/src/test/compile-fail/issue-77910-1.rs @@ -0,0 +1,11 @@ +fn foo(s: &i32) -> &i32 { + let xs; + xs +} +fn main() { + let y; + // we shouldn't ice with the bound var here. + assert_eq!(foo, y); + //~^ ERROR binary operation `==` cannot be applied to type + //~| ERROR `for<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug` +} diff --git a/src/test/compile-fail/issue-77910-2.rs b/src/test/compile-fail/issue-77910-2.rs new file mode 100644 index 00000000000..2bb48d36576 --- /dev/null +++ b/src/test/compile-fail/issue-77910-2.rs @@ -0,0 +1,9 @@ +fn foo(s: &i32) -> &i32 { + let xs; + xs +} +fn main() { + let y; + if foo == y {} + //~^ ERROR binary operation `==` cannot be applied to type +} -- cgit 1.4.1-3-g733a5 From b05ab18aec28c5025212ad44a202072ed2f610d7 Mon Sep 17 00:00:00 2001 From: Thomas Bahn Date: Sat, 19 Dec 2020 23:13:50 +0100 Subject: Fix pretty printing an AST representing `&(mut ident)` `PatKind::Ref(PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..), ..)` is an AST representing `&(mut ident)`. It was errorneously printed as `&mut ident` which reparsed into a syntactically different AST. This affected help diagnostics in the parser. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 10 +++++++++- src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs | 9 +++++++++ .../ui/pattern/issue-80186-mut-binding-help-suggestion.stderr | 10 ++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs create mode 100644 src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr (limited to 'src') diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index fdb129d9e2a..dcb6e115eda 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2420,7 +2420,15 @@ impl<'a> State<'a> { if mutbl == ast::Mutability::Mut { self.s.word("mut "); } - self.print_pat(inner); + if let PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Mut), ..) = + inner.kind + { + self.popen(); + self.print_pat(inner); + self.pclose(); + } else { + self.print_pat(inner); + } } PatKind::Lit(ref e) => self.print_expr(&**e), PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { diff --git a/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs new file mode 100644 index 00000000000..a5e9b1db546 --- /dev/null +++ b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs @@ -0,0 +1,9 @@ +// Regression test for correct pretty-printing of an AST representing `&(mut x)` in help +// suggestion diagnostic. + +fn main() { + let mut &x = &0; + //~^ ERROR `mut` must be attached to each individual binding + //~| HELP add `mut` to each binding + //~| SUGGESTION &(mut x) +} diff --git a/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr new file mode 100644 index 00000000000..75b6c163b2c --- /dev/null +++ b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr @@ -0,0 +1,10 @@ +error: `mut` must be attached to each individual binding + --> $DIR/issue-80186-mut-binding-help-suggestion.rs:5:9 + | +LL | let mut &x = &0; + | ^^^^^^ help: add `mut` to each binding: `&(mut x)` + | + = note: `mut` may be followed by `variable` and `variable @ pattern` + +error: aborting due to previous error + -- cgit 1.4.1-3-g733a5 From f8d4883dbebf71348abe1134c6f26d48a36256b9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 21 Nov 2020 18:05:29 +0100 Subject: add test that repeating non-Copy constants works --- .../rfc-2203-const-array-repeat-exprs/const-repeat.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs (limited to 'src') diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs new file mode 100644 index 00000000000..11611a94918 --- /dev/null +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs @@ -0,0 +1,13 @@ +// check-pass + +// Repeating a *constant* of non-Copy type (not just a constant expression) is already stable. + +const EMPTY: Vec = Vec::new(); + +pub fn bar() -> [Vec; 2] { + [EMPTY; 2] +} + +fn main() { + let x = bar(); +} -- cgit 1.4.1-3-g733a5 From 7f3e18cc2b24214e10df5434972f4f7cd461fa98 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 28 Nov 2020 17:32:48 +0100 Subject: make sure [CONST; N] drops N times --- .../rfc-2203-const-array-repeat-exprs/const-repeat.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs index 11611a94918..65d02317d34 100644 --- a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs +++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs @@ -1,4 +1,4 @@ -// check-pass +// run-pass // Repeating a *constant* of non-Copy type (not just a constant expression) is already stable. @@ -8,6 +8,20 @@ pub fn bar() -> [Vec; 2] { [EMPTY; 2] } +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + panic!("BOOM!"); + } +} + +const BOOM: Bomb = Bomb; + fn main() { - let x = bar(); + let _x = bar(); + + // Make sure the destructor does not get called for empty arrays. `[CONST; N]` should + // instantiate (and then later drop) the const exactly `N` times. + let _x = [BOOM; 0]; } -- cgit 1.4.1-3-g733a5 From 00bb2935fcfb54dcd2b770ff451bd0a4c97738a0 Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Sun, 20 Dec 2020 23:39:25 +0800 Subject: Move test from compile-fail to ui/binop --- src/test/compile-fail/issue-77910-1.rs | 11 ----------- src/test/compile-fail/issue-77910-2.rs | 9 --------- src/test/ui/binop/issue-77910-1.rs | 11 +++++++++++ src/test/ui/binop/issue-77910-1.stderr | 26 ++++++++++++++++++++++++++ src/test/ui/binop/issue-77910-2.rs | 9 +++++++++ src/test/ui/binop/issue-77910-2.stderr | 11 +++++++++++ 6 files changed, 57 insertions(+), 20 deletions(-) delete mode 100644 src/test/compile-fail/issue-77910-1.rs delete mode 100644 src/test/compile-fail/issue-77910-2.rs create mode 100644 src/test/ui/binop/issue-77910-1.rs create mode 100644 src/test/ui/binop/issue-77910-1.stderr create mode 100644 src/test/ui/binop/issue-77910-2.rs create mode 100644 src/test/ui/binop/issue-77910-2.stderr (limited to 'src') diff --git a/src/test/compile-fail/issue-77910-1.rs b/src/test/compile-fail/issue-77910-1.rs deleted file mode 100644 index d786e335859..00000000000 --- a/src/test/compile-fail/issue-77910-1.rs +++ /dev/null @@ -1,11 +0,0 @@ -fn foo(s: &i32) -> &i32 { - let xs; - xs -} -fn main() { - let y; - // we shouldn't ice with the bound var here. - assert_eq!(foo, y); - //~^ ERROR binary operation `==` cannot be applied to type - //~| ERROR `for<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug` -} diff --git a/src/test/compile-fail/issue-77910-2.rs b/src/test/compile-fail/issue-77910-2.rs deleted file mode 100644 index 2bb48d36576..00000000000 --- a/src/test/compile-fail/issue-77910-2.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn foo(s: &i32) -> &i32 { - let xs; - xs -} -fn main() { - let y; - if foo == y {} - //~^ ERROR binary operation `==` cannot be applied to type -} diff --git a/src/test/ui/binop/issue-77910-1.rs b/src/test/ui/binop/issue-77910-1.rs new file mode 100644 index 00000000000..d786e335859 --- /dev/null +++ b/src/test/ui/binop/issue-77910-1.rs @@ -0,0 +1,11 @@ +fn foo(s: &i32) -> &i32 { + let xs; + xs +} +fn main() { + let y; + // we shouldn't ice with the bound var here. + assert_eq!(foo, y); + //~^ ERROR binary operation `==` cannot be applied to type + //~| ERROR `for<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug` +} diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr new file mode 100644 index 00000000000..e48d3e19996 --- /dev/null +++ b/src/test/ui/binop/issue-77910-1.stderr @@ -0,0 +1,26 @@ +error[E0369]: binary operation `==` cannot be applied to type `for<'r> fn(&'r i32) -> &'r i32 {foo}` + --> $DIR/issue-77910-1.rs:8:5 + | +LL | assert_eq!(foo, y); + | ^^^^^^^^^^^^^^^^^^^ + | | + | for<'r> fn(&'r i32) -> &'r i32 {foo} + | _ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `for<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug` + --> $DIR/issue-77910-1.rs:8:5 + | +LL | assert_eq!(foo, y); + | ^^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}` + = note: required because of the requirements on the impl of `Debug` for `&for<'r> fn(&'r i32) -> &'r i32 {foo}` + = note: required by `std::fmt::Debug::fmt` + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0369. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/binop/issue-77910-2.rs b/src/test/ui/binop/issue-77910-2.rs new file mode 100644 index 00000000000..2bb48d36576 --- /dev/null +++ b/src/test/ui/binop/issue-77910-2.rs @@ -0,0 +1,9 @@ +fn foo(s: &i32) -> &i32 { + let xs; + xs +} +fn main() { + let y; + if foo == y {} + //~^ ERROR binary operation `==` cannot be applied to type +} diff --git a/src/test/ui/binop/issue-77910-2.stderr b/src/test/ui/binop/issue-77910-2.stderr new file mode 100644 index 00000000000..5477a5762a8 --- /dev/null +++ b/src/test/ui/binop/issue-77910-2.stderr @@ -0,0 +1,11 @@ +error[E0369]: binary operation `==` cannot be applied to type `for<'r> fn(&'r i32) -> &'r i32 {foo}` + --> $DIR/issue-77910-2.rs:7:12 + | +LL | if foo == y {} + | --- ^^ - _ + | | + | for<'r> fn(&'r i32) -> &'r i32 {foo} + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. -- cgit 1.4.1-3-g733a5 From fbc9d50d752ab298aea2844d236095b198e96fe6 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Sun, 20 Dec 2020 17:16:02 +0000 Subject: make sure installer only creates directories in DESTDIR Fixes #80238 Signed-off-by: Yuxuan Shui --- src/bootstrap/install.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 074f5cd73f3..8f2b128b368 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -73,12 +73,7 @@ fn install_sh( let docdir_default = datadir_default.join("doc/rust"); let libdir_default = PathBuf::from("lib"); let mandir_default = datadir_default.join("man"); - let prefix = builder.config.prefix.as_ref().map_or(prefix_default, |p| { - fs::create_dir_all(p) - .unwrap_or_else(|err| panic!("could not create {}: {}", p.display(), err)); - fs::canonicalize(p) - .unwrap_or_else(|err| panic!("could not canonicalize {}: {}", p.display(), err)) - }); + let prefix = builder.config.prefix.as_ref().unwrap_or(&prefix_default); let sysconfdir = builder.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); let datadir = builder.config.datadir.as_ref().unwrap_or(&datadir_default); let docdir = builder.config.docdir.as_ref().unwrap_or(&docdir_default); @@ -103,6 +98,13 @@ fn install_sh( let libdir = add_destdir(&libdir, &destdir); let mandir = add_destdir(&mandir, &destdir); + let prefix = { + fs::create_dir_all(&prefix) + .unwrap_or_else(|err| panic!("could not create {}: {}", prefix.display(), err)); + fs::canonicalize(&prefix) + .unwrap_or_else(|err| panic!("could not canonicalize {}: {}", prefix.display(), err)) + }; + let empty_dir = builder.out.join("tmp/empty_dir"); t!(fs::create_dir_all(&empty_dir)); -- cgit 1.4.1-3-g733a5 From 77fce67733d2a1403f17b382dfbd3802003172a6 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 20 Dec 2020 18:11:11 +0000 Subject: Make recursion limit fatal in project This avoid the hang/oom from #79714 --- compiler/rustc_trait_selection/src/traits/project.rs | 9 ++++++++- src/test/ui/issues/issue-23122-2.stderr | 3 +-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a11499e4320..7fa070caa27 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -734,7 +734,14 @@ fn project_type<'cx, 'tcx>( if !selcx.tcx().sess.recursion_limit().value_within_limit(obligation.recursion_depth) { debug!("project: overflow!"); - return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow)); + match selcx.query_mode() { + super::TraitQueryMode::Standard => { + selcx.infcx().report_overflow_error(&obligation, true); + } + super::TraitQueryMode::Canonical => { + return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow)); + } + } } let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.tcx()); diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr index ce3bffe602c..ff7e884ea6f 100644 --- a/src/test/ui/issues/issue-23122-2.stderr +++ b/src/test/ui/issues/issue-23122-2.stderr @@ -1,11 +1,10 @@ -error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` +error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next` --> $DIR/issue-23122-2.rs:9:5 | LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_23122_2`) - = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 65f4f39dd8d9a1c1f4a817da36c38b30e4369f9e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Dec 2020 14:28:20 -0500 Subject: Get rid of `locate()` in markdown handling This function was unfortunate for several reasons: - It used `unsafe` because it wanted to tell whether a string came from the same *allocation* as another, not just whether it was a textual match. - It recalculated spans even though they were already available from pulldown - It sometimes *failed* to calculate the span, which meant it was always possible for the span to be `None`, even though in practice that should never happen. This commit has several cleanups: - Make the span required - Pass through the span from pulldown in the `HeadingLinks` and `Footnotes` iterators - Only add iterator bounds on the `impl Iterator`, not on `new` and the struct itself. --- src/librustdoc/html/markdown.rs | 130 +++++++++++------------ src/librustdoc/passes/collect_intra_doc_links.rs | 62 +++++------ 2 files changed, 90 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 22096203d4c..7600b63bb88 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -447,21 +447,23 @@ impl<'a, I: Iterator>> Iterator for LinkReplacer<'a, I> { } /// Make headings links with anchor IDs and build up TOC. -struct HeadingLinks<'a, 'b, 'ids, I: Iterator>> { +struct HeadingLinks<'a, 'b, 'ids, I> { inner: I, toc: Option<&'b mut TocBuilder>, - buf: VecDeque>, + buf: VecDeque<(Event<'a>, Range)>, id_map: &'ids mut IdMap, } -impl<'a, 'b, 'ids, I: Iterator>> HeadingLinks<'a, 'b, 'ids, I> { +impl<'a, 'b, 'ids, I> HeadingLinks<'a, 'b, 'ids, I> { fn new(iter: I, toc: Option<&'b mut TocBuilder>, ids: &'ids mut IdMap) -> Self { HeadingLinks { inner: iter, toc, buf: VecDeque::new(), id_map: ids } } } -impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, 'b, 'ids, I> { - type Item = Event<'a>; +impl<'a, 'b, 'ids, I: Iterator, Range)>> Iterator + for HeadingLinks<'a, 'b, 'ids, I> +{ + type Item = (Event<'a>, Range); fn next(&mut self) -> Option { if let Some(e) = self.buf.pop_front() { @@ -469,31 +471,28 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, } let event = self.inner.next(); - if let Some(Event::Start(Tag::Heading(level))) = event { + if let Some((Event::Start(Tag::Heading(level)), _)) = event { let mut id = String::new(); for event in &mut self.inner { - match &event { + match event.0 { Event::End(Tag::Heading(..)) => break, Event::Text(text) | Event::Code(text) => { id.extend(text.chars().filter_map(slugify)); } - _ => {} - } - match event { Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {} - event => self.buf.push_back(event), + _ => self.buf.push_back(event), } } let id = self.id_map.derive(id); if let Some(ref mut builder) = self.toc { let mut html_header = String::new(); - html::push_html(&mut html_header, self.buf.iter().cloned()); + html::push_html(&mut html_header, self.buf.iter().map(|(ev, _)| ev.clone())); let sec = builder.push(level as u32, html_header, id.clone()); - self.buf.push_front(Event::Html(format!("{} ", sec).into())); + self.buf.push_front((Event::Html(format!("{} ", sec).into()), 0..0)); } - self.buf.push_back(Event::Html(format!("", level).into())); + self.buf.push_back((Event::Html(format!("", level).into()), 0..0)); let start_tags = format!( "\ @@ -501,7 +500,7 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, id = id, level = level ); - return Some(Event::Html(start_tags.into())); + return Some((Event::Html(start_tags.into()), 0..0)); } event } @@ -575,15 +574,16 @@ impl<'a, I: Iterator>> Iterator for SummaryLine<'a, I> { /// Moves all footnote definitions to the end and add back links to the /// references. -struct Footnotes<'a, I: Iterator>> { +struct Footnotes<'a, I> { inner: I, footnotes: FxHashMap>, u16)>, } -impl<'a, I: Iterator>> Footnotes<'a, I> { +impl<'a, I> Footnotes<'a, I> { fn new(iter: I) -> Self { Footnotes { inner: iter, footnotes: FxHashMap::default() } } + fn get_entry(&mut self, key: &str) -> &mut (Vec>, u16) { let new_id = self.footnotes.keys().count() + 1; let key = key.to_owned(); @@ -591,23 +591,23 @@ impl<'a, I: Iterator>> Footnotes<'a, I> { } } -impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { - type Item = Event<'a>; +impl<'a, I: Iterator, Range)>> Iterator for Footnotes<'a, I> { + type Item = (Event<'a>, Range); fn next(&mut self) -> Option { loop { match self.inner.next() { - Some(Event::FootnoteReference(ref reference)) => { + Some((Event::FootnoteReference(ref reference), range)) => { let entry = self.get_entry(&reference); let reference = format!( "{0}", (*entry).1 ); - return Some(Event::Html(reference.into())); + return Some((Event::Html(reference.into()), range)); } - Some(Event::Start(Tag::FootnoteDefinition(def))) => { + Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => { let mut content = Vec::new(); - for event in &mut self.inner { + for (event, _) in &mut self.inner { if let Event::End(Tag::FootnoteDefinition(..)) = event { break; } @@ -638,7 +638,7 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { ret.push_str(""); } ret.push_str(""); - return Some(Event::Html(ret.into())); + return Some((Event::Html(ret.into()), 0..0)); } else { return None; } @@ -946,13 +946,14 @@ impl Markdown<'_> { }; let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer)); + let p = p.into_offset_iter(); let mut s = String::with_capacity(md.len() * 3 / 2); let p = HeadingLinks::new(p, None, &mut ids); - let p = LinkReplacer::new(p, links); - let p = CodeBlocks::new(p, codes, edition, playground); let p = Footnotes::new(p); + let p = LinkReplacer::new(p.map(|(ev, _)| ev), links); + let p = CodeBlocks::new(p, codes, edition, playground); html::push_html(&mut s, p); s @@ -963,7 +964,7 @@ impl MarkdownWithToc<'_> { crate fn into_string(self) -> String { let MarkdownWithToc(md, mut ids, codes, edition, playground) = self; - let p = Parser::new_ext(md, opts()); + let p = Parser::new_ext(md, opts()).into_offset_iter(); let mut s = String::with_capacity(md.len() * 3 / 2); @@ -971,8 +972,8 @@ impl MarkdownWithToc<'_> { { let p = HeadingLinks::new(p, Some(&mut toc), &mut ids); - let p = CodeBlocks::new(p, codes, edition, playground); let p = Footnotes::new(p); + let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground); html::push_html(&mut s, p); } @@ -988,19 +989,19 @@ impl MarkdownHtml<'_> { if md.is_empty() { return String::new(); } - let p = Parser::new_ext(md, opts()); + let p = Parser::new_ext(md, opts()).into_offset_iter(); // Treat inline HTML as plain text. - let p = p.map(|event| match event { - Event::Html(text) => Event::Text(text), + let p = p.map(|event| match event.0 { + Event::Html(text) => (Event::Text(text), event.1), _ => event, }); let mut s = String::with_capacity(md.len() * 3 / 2); let p = HeadingLinks::new(p, None, &mut ids); - let p = CodeBlocks::new(p, codes, edition, playground); let p = Footnotes::new(p); + let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground); html::push_html(&mut s, p); s @@ -1153,7 +1154,7 @@ crate fn plain_text_summary(md: &str) -> String { s } -crate fn markdown_links(md: &str) -> Vec<(String, Option>)> { +crate fn markdown_links(md: &str) -> Vec<(String, Range)> { if md.is_empty() { return vec![]; } @@ -1161,42 +1162,35 @@ crate fn markdown_links(md: &str) -> Vec<(String, Option>)> { let mut links = vec![]; let mut shortcut_links = vec![]; - { - let locate = |s: &str| unsafe { - let s_start = s.as_ptr(); - let s_end = s_start.add(s.len()); - let md_start = md.as_ptr(); - let md_end = md_start.add(md.len()); - if md_start <= s_start && s_end <= md_end { - let start = s_start.offset_from(md_start) as usize; - let end = s_end.offset_from(md_start) as usize; - Some(start..end) - } else { - None - } - }; - - let mut push = |link: BrokenLink<'_>| { - // FIXME: use `link.span` instead of `locate` - // (doing it now includes the `[]` as well as the text) - shortcut_links.push((link.reference.to_owned(), locate(link.reference))); - None - }; - let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push)); - - // There's no need to thread an IdMap through to here because - // the IDs generated aren't going to be emitted anywhere. - let mut ids = IdMap::new(); - let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids)); - - for ev in iter { - if let Event::Start(Tag::Link(_, dest, _)) = ev { - debug!("found link: {}", dest); - links.push(match dest { - CowStr::Borrowed(s) => (s.to_owned(), locate(s)), - s @ (CowStr::Boxed(..) | CowStr::Inlined(..)) => (s.into_string(), None), - }); + let span_for_link = |link: &str, span: Range| { + // Pulldown includes the `[]` as well as the URL. Only highlight the relevant span. + // NOTE: uses `rfind` in case the title and url are the same: `[Ok][Ok]` + match md[span.clone()].rfind(link) { + Some(start) => { + let start = span.start + start; + start..start + link.len() } + // This can happen for things other than intra-doc links, like `#1` expanded to `https://github.com/rust-lang/rust/issues/1`. + None => span, + } + }; + let mut push = |link: BrokenLink<'_>| { + let span = span_for_link(link.reference, link.span); + shortcut_links.push((link.reference.to_owned(), span)); + None + }; + let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push)); + + // There's no need to thread an IdMap through to here because + // the IDs generated aren't going to be emitted anywhere. + let mut ids = IdMap::new(); + let iter = Footnotes::new(HeadingLinks::new(p.into_offset_iter(), None, &mut ids)); + + for ev in iter { + if let Event::Start(Tag::Link(_, dest, _)) = ev.0 { + debug!("found link: {}", dest); + let span = span_for_link(&dest, ev.1); + links.push((dest.into_string(), span)); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index ea5bf94689b..a8adfe08b25 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -180,7 +180,7 @@ struct DiagnosticInfo<'a> { item: &'a Item, dox: &'a str, ori_link: &'a str, - link_range: Option>, + link_range: Range, } #[derive(Clone, Debug, Hash)] @@ -920,7 +920,7 @@ impl LinkCollector<'_, '_> { parent_node: Option, krate: CrateNum, ori_link: String, - link_range: Option>, + link_range: Range, ) -> Option { trace!("considering link '{}'", ori_link); @@ -1566,7 +1566,7 @@ fn report_diagnostic( msg: &str, item: &Item, dox: &str, - link_range: &Option>, + link_range: &Range, decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option), ) { let hir_id = match cx.as_local_hir_id(item.def_id) { @@ -1584,31 +1584,26 @@ fn report_diagnostic( cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| { let mut diag = lint.build(msg); - let span = link_range - .as_ref() - .and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs)); - - if let Some(link_range) = link_range { - if let Some(sp) = span { - diag.set_span(sp); - } else { - // blah blah blah\nblah\nblah [blah] blah blah\nblah blah - // ^ ~~~~ - // | link_range - // last_new_line_offset - let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1); - let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); - - // Print the line containing the `link_range` and manually mark it with '^'s. - diag.note(&format!( - "the link appears in this line:\n\n{line}\n\ - {indicator: , dox: &str, - link_range: Option>, + link_range: Range, kinds: SmallVec<[ResolutionFailure<'_>; 3]>, ) { report_diagnostic( @@ -1862,7 +1857,7 @@ fn anchor_failure( item: &Item, path_str: &str, dox: &str, - link_range: Option>, + link_range: Range, failure: AnchorFailure, ) { let msg = match failure { @@ -1887,7 +1882,7 @@ fn ambiguity_error( item: &Item, path_str: &str, dox: &str, - link_range: Option>, + link_range: Range, candidates: Vec, ) { let mut msg = format!("`{}` is ", path_str); @@ -1936,13 +1931,12 @@ fn suggest_disambiguator( path_str: &str, dox: &str, sp: Option, - link_range: &Option>, + link_range: &Range, ) { let suggestion = disambiguator.suggestion(); let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr()); if let Some(sp) = sp { - let link_range = link_range.as_ref().expect("must have a link range if we have a span"); let msg = if dox.bytes().nth(link_range.start) == Some(b'`') { format!("`{}`", suggestion.as_help(path_str)) } else { @@ -1961,7 +1955,7 @@ fn privacy_error( item: &Item, path_str: &str, dox: &str, - link_range: Option>, + link_range: Range, ) { let sym; let item_name = match item.name { -- cgit 1.4.1-3-g733a5 From 1e15c2fde5dd456d879b90259c414a73d5804550 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Dec 2020 14:33:58 -0500 Subject: Remove unnecessary scope --- src/librustdoc/html/markdown.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 7600b63bb88..e4a0d80674f 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1160,6 +1160,8 @@ crate fn markdown_links(md: &str) -> Vec<(String, Range)> { } let mut links = vec![]; + // Used to avoid mutable borrow issues in the `push` closure + // Probably it would be more efficient to use a `RefCell` but it doesn't seem worth the churn. let mut shortcut_links = vec![]; let span_for_link = |link: &str, span: Range| { -- cgit 1.4.1-3-g733a5 From 60d55671602fcff089a7b9199608a1b397877836 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Dec 2020 15:57:43 -0500 Subject: Fix incorrect logic when merging matches --- src/librustdoc/html/markdown.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index e4a0d80674f..0e87dd72ef1 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -474,12 +474,13 @@ impl<'a, 'b, 'ids, I: Iterator, Range)>> Iterator if let Some((Event::Start(Tag::Heading(level)), _)) = event { let mut id = String::new(); for event in &mut self.inner { - match event.0 { + match &event.0 { Event::End(Tag::Heading(..)) => break, + Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {} Event::Text(text) | Event::Code(text) => { id.extend(text.chars().filter_map(slugify)); + self.buf.push_back(event); } - Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {} _ => self.buf.push_back(event), } } -- cgit 1.4.1-3-g733a5 From 2e92b13a606ba2f073c789dfd6c33f889f04c8cf Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 20 Dec 2020 18:13:05 +0000 Subject: Prevent caching projections in the case of cycles When normalizing a projection which results in a cycle, we would cache the result of `project_type` without the nested obligations (because they're not needed for inference). This would result in the nested obligations only being handled once in fulfill, which would avoid the cycle error. Fixes #79714, a regresion from #79305 caused by the removal of `get_paranoid_cache_value_obligation`. --- compiler/rustc_infer/src/traits/project.rs | 16 ++++++++- .../rustc_trait_selection/src/traits/project.rs | 14 ++++---- .../rustc_trait_selection/src/traits/select/mod.rs | 4 +++ .../ui/associated-types/defaults-cyclic-fail-1.rs | 4 +-- .../associated-types/defaults-cyclic-fail-1.stderr | 10 +++--- .../ui/associated-types/defaults-cyclic-fail-2.rs | 4 +-- .../associated-types/defaults-cyclic-fail-2.stderr | 10 +++--- src/test/ui/associated-types/impl-wf-cycle-1.rs | 29 ++++++++++++++++ .../ui/associated-types/impl-wf-cycle-1.stderr | 39 ++++++++++++++++++++++ src/test/ui/associated-types/impl-wf-cycle-2.rs | 16 +++++++++ .../ui/associated-types/impl-wf-cycle-2.stderr | 25 ++++++++++++++ 11 files changed, 150 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/associated-types/impl-wf-cycle-1.rs create mode 100644 src/test/ui/associated-types/impl-wf-cycle-1.stderr create mode 100644 src/test/ui/associated-types/impl-wf-cycle-2.rs create mode 100644 src/test/ui/associated-types/impl-wf-cycle-2.stderr (limited to 'src') diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 65284bcee91..33bddf1dedc 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -90,6 +90,7 @@ impl ProjectionCacheKey<'tcx> { pub enum ProjectionCacheEntry<'tcx> { InProgress, Ambiguous, + Recur, Error, NormalizedTy(NormalizedTy<'tcx>), } @@ -143,7 +144,12 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { "ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}", key, value ); - let fresh_key = self.map().insert(key, ProjectionCacheEntry::NormalizedTy(value)); + let mut map = self.map(); + if let Some(ProjectionCacheEntry::Recur) = map.get(&key) { + debug!("Not overwriting Recur"); + return; + } + let fresh_key = map.insert(key, ProjectionCacheEntry::NormalizedTy(value)); assert!(!fresh_key, "never started projecting `{:?}`", key); } @@ -197,6 +203,14 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { assert!(!fresh, "never started projecting `{:?}`", key); } + /// Indicates that while trying to normalize `key`, `key` was required to + /// be normalized again. Selection or evaluation should eventually report + /// an error here. + pub fn recur(&mut self, key: ProjectionCacheKey<'tcx>) { + let fresh = self.map().insert(key, ProjectionCacheEntry::Recur); + assert!(!fresh, "never started projecting `{:?}`", key); + } + /// Indicates that trying to normalize `key` resulted in /// error. pub fn error(&mut self, key: ProjectionCacheKey<'tcx>) { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 7fa070caa27..fa0526445c1 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -496,12 +496,6 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( return Ok(None); } Err(ProjectionCacheEntry::InProgress) => { - // If while normalized A::B, we are asked to normalize - // A::B, just return A::B itself. This is a conservative - // answer, in the sense that A::B *is* clearly equivalent - // to A::B, though there may be a better value we can - // find. - // Under lazy normalization, this can arise when // bootstrapping. That is, imagine an environment with a // where-clause like `A::B == u32`. Now, if we are asked @@ -512,6 +506,14 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( debug!("found cache entry: in-progress"); + // Cache that normalizing this projection resulted in a cycle. This + // should ensure that, unless this happens within a snapshot that's + // rolled back, fulfillment or evaluation will notice the cycle. + + infcx.inner.borrow_mut().projection_cache().recur(cache_key); + return Err(InProgress); + } + Err(ProjectionCacheEntry::Recur) => { return Err(InProgress); } Err(ProjectionCacheEntry::NormalizedTy(ty)) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f1c86eab095..a8f81445b03 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -291,6 +291,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx.tcx } + pub(super) fn query_mode(&self) -> TraitQueryMode { + self.query_mode + } + /////////////////////////////////////////////////////////////////////////// // Selection // diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-1.rs b/src/test/ui/associated-types/defaults-cyclic-fail-1.rs index afb2b3df716..61ef013236e 100644 --- a/src/test/ui/associated-types/defaults-cyclic-fail-1.rs +++ b/src/test/ui/associated-types/defaults-cyclic-fail-1.rs @@ -24,13 +24,13 @@ impl Tr for u32 { // ...but not in an impl that redefines one of the types. impl Tr for bool { type A = Box; - //~^ ERROR type mismatch resolving `::B == _` + //~^ ERROR overflow evaluating the requirement `::B == _` } // (the error is shown twice for some reason) impl Tr for usize { type B = &'static Self::A; - //~^ ERROR type mismatch resolving `::A == _` + //~^ ERROR overflow evaluating the requirement `::A == _` } fn main() { diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr b/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr index ae7150d47ca..5e98520b411 100644 --- a/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr +++ b/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr @@ -1,15 +1,15 @@ -error[E0271]: type mismatch resolving `::B == _` +error[E0275]: overflow evaluating the requirement `::B == _` --> $DIR/defaults-cyclic-fail-1.rs:26:5 | LL | type A = Box; - | ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size + | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0271]: type mismatch resolving `::A == _` +error[E0275]: overflow evaluating the requirement `::A == _` --> $DIR/defaults-cyclic-fail-1.rs:32:5 | LL | type B = &'static Self::A; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-2.rs b/src/test/ui/associated-types/defaults-cyclic-fail-2.rs index ba4bb0d5a29..e91c9f2d29a 100644 --- a/src/test/ui/associated-types/defaults-cyclic-fail-2.rs +++ b/src/test/ui/associated-types/defaults-cyclic-fail-2.rs @@ -25,13 +25,13 @@ impl Tr for u32 { impl Tr for bool { type A = Box; - //~^ ERROR type mismatch resolving `::B == _` + //~^ ERROR overflow evaluating the requirement `::B == _` } // (the error is shown twice for some reason) impl Tr for usize { type B = &'static Self::A; - //~^ ERROR type mismatch resolving `::A == _` + //~^ ERROR overflow evaluating the requirement `::A == _` } fn main() { diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr b/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr index 0dfbac2dec5..c538805f858 100644 --- a/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr +++ b/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr @@ -1,15 +1,15 @@ -error[E0271]: type mismatch resolving `::B == _` +error[E0275]: overflow evaluating the requirement `::B == _` --> $DIR/defaults-cyclic-fail-2.rs:27:5 | LL | type A = Box; - | ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size + | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0271]: type mismatch resolving `::A == _` +error[E0275]: overflow evaluating the requirement `::A == _` --> $DIR/defaults-cyclic-fail-2.rs:33:5 | LL | type B = &'static Self::A; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.rs b/src/test/ui/associated-types/impl-wf-cycle-1.rs new file mode 100644 index 00000000000..ba074210a2b --- /dev/null +++ b/src/test/ui/associated-types/impl-wf-cycle-1.rs @@ -0,0 +1,29 @@ +// Regression test for #79714 + +trait Baz {} +impl Baz for () {} +impl Baz for (T,) {} + +trait Fiz {} +impl Fiz for bool {} + +trait Grault { + type A; + type B; +} + +impl Grault for (T,) +where + Self::A: Baz, + Self::B: Fiz, +{ + type A = (); + //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _` + type B = bool; + //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _` +} +//~^^^^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _` + +fn main() { + let x: <(_,) as Grault>::A = (); +} diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.stderr b/src/test/ui/associated-types/impl-wf-cycle-1.stderr new file mode 100644 index 00000000000..82328048c99 --- /dev/null +++ b/src/test/ui/associated-types/impl-wf-cycle-1.stderr @@ -0,0 +1,39 @@ +error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _` + --> $DIR/impl-wf-cycle-1.rs:15:1 + | +LL | / impl Grault for (T,) +LL | | where +LL | | Self::A: Baz, +LL | | Self::B: Fiz, +... | +LL | | +LL | | } + | |_^ + | + = note: required because of the requirements on the impl of `Grault` for `(T,)` + = note: 1 redundant requirements hidden + = note: required because of the requirements on the impl of `Grault` for `(T,)` + +error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _` + --> $DIR/impl-wf-cycle-1.rs:20:5 + | +LL | type A = (); + | ^^^^^^^^^^^^ + | + = note: required because of the requirements on the impl of `Grault` for `(T,)` + = note: 1 redundant requirements hidden + = note: required because of the requirements on the impl of `Grault` for `(T,)` + +error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _` + --> $DIR/impl-wf-cycle-1.rs:22:5 + | +LL | type B = bool; + | ^^^^^^^^^^^^^^ + | + = note: required because of the requirements on the impl of `Grault` for `(T,)` + = note: 1 redundant requirements hidden + = note: required because of the requirements on the impl of `Grault` for `(T,)` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.rs b/src/test/ui/associated-types/impl-wf-cycle-2.rs new file mode 100644 index 00000000000..6fccc54f229 --- /dev/null +++ b/src/test/ui/associated-types/impl-wf-cycle-2.rs @@ -0,0 +1,16 @@ +// Regression test for #79714 + +trait Grault { + type A; +} + +impl Grault for (T,) +where + Self::A: Copy, +{ + type A = (); + //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _` +} +//~^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _` + +fn main() {} diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.stderr b/src/test/ui/associated-types/impl-wf-cycle-2.stderr new file mode 100644 index 00000000000..5cd18a33adf --- /dev/null +++ b/src/test/ui/associated-types/impl-wf-cycle-2.stderr @@ -0,0 +1,25 @@ +error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _` + --> $DIR/impl-wf-cycle-2.rs:7:1 + | +LL | / impl Grault for (T,) +LL | | where +LL | | Self::A: Copy, +LL | | { +LL | | type A = (); +LL | | +LL | | } + | |_^ + | + = note: required because of the requirements on the impl of `Grault` for `(T,)` + +error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _` + --> $DIR/impl-wf-cycle-2.rs:11:5 + | +LL | type A = (); + | ^^^^^^^^^^^^ + | + = note: required because of the requirements on the impl of `Grault` for `(T,)` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. -- cgit 1.4.1-3-g733a5 From 8cfaf94a61bead79e3675b981a8563c2f36f04e9 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 20 Dec 2020 16:10:28 -0600 Subject: update rustfmt to v1.4.30 --- Cargo.lock | 4 ++-- src/tools/rustfmt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index fcfd23f2dae..596a9413e1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4396,7 +4396,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.29" +version = "1.4.30" dependencies = [ "annotate-snippets 0.6.1", "anyhow", @@ -5342,7 +5342,7 @@ dependencies = [ "chrono", "lazy_static", "matchers", - "parking_lot 0.11.0", + "parking_lot 0.9.0", "regex", "serde", "serde_json", diff --git a/src/tools/rustfmt b/src/tools/rustfmt index 70ce18255f4..acd94866fd0 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit 70ce18255f429caf0d75ecfed8c1464535ee779b +Subproject commit acd94866fd0ff5eacb7e184ae21c19e5440fc5fb -- cgit 1.4.1-3-g733a5 From 087101e285895b8bce94a16a90f7e7a3d938c3da Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Mon, 21 Dec 2020 12:05:10 +0100 Subject: make path normalization compatible with mac python2 --- src/test/run-make-fulldeps/coverage-reports/normalize_paths.py | 2 ++ 1 file changed, 2 insertions(+) mode change 100644 => 100755 src/test/run-make-fulldeps/coverage-reports/normalize_paths.py (limited to 'src') diff --git a/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py b/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py old mode 100644 new mode 100755 index 05fb412cdb6..e5777ad2512 --- a/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py +++ b/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + import sys # Normalize file paths in output -- cgit 1.4.1-3-g733a5 From a272d621bc7a2ca61d704fbe531dc532d49ab402 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 18 Dec 2020 17:32:26 +0100 Subject: Implemented a compiler diagnostic for move async mistake Ran the tidy check Following the diagnostic guide better Diagnostic generation is now relegated to its own function in the diagnostics module. Added tests Fixed the ui test --- compiler/rustc_parse/src/parser/diagnostics.rs | 18 ++++++++++++++++++ compiler/rustc_parse/src/parser/expr.rs | 18 ++++++++++++++---- .../incorrect-move-async-order-issue-79694.fixed | 8 ++++++++ .../parser/incorrect-move-async-order-issue-79694.rs | 8 ++++++++ .../incorrect-move-async-order-issue-79694.stderr | 13 +++++++++++++ 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed create mode 100644 src/test/ui/parser/incorrect-move-async-order-issue-79694.rs create mode 100644 src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr (limited to 'src') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 350a372a684..98c7b9a63a5 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1912,4 +1912,22 @@ impl<'a> Parser<'a> { *self = snapshot; Err(err) } + + /// Get the diagnostics for the cases where `move async` is found. + /// + /// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword + pub(super) fn incorrect_move_async_order_found( + &self, + move_async_span: Span, + ) -> DiagnosticBuilder<'a> { + let mut err = + self.struct_span_err(move_async_span, "the order of `move` and `async` is incorrect"); + err.span_suggestion_verbose( + move_async_span, + "try switching the order", + "async move".to_owned(), + Applicability::MaybeIncorrect, + ); + err + } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 93be478fc8c..7d0d4f30137 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1603,7 +1603,7 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::async_closure, span); } - let capture_clause = self.parse_capture_clause(); + let capture_clause = self.parse_capture_clause()?; let decl = self.parse_fn_block_decl()?; let decl_hi = self.prev_token.span; let body = match decl.output { @@ -1626,8 +1626,18 @@ impl<'a> Parser<'a> { } /// Parses an optional `move` prefix to a closure-like construct. - fn parse_capture_clause(&mut self) -> CaptureBy { - if self.eat_keyword(kw::Move) { CaptureBy::Value } else { CaptureBy::Ref } + fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> { + if self.eat_keyword(kw::Move) { + // Check for `move async` and recover + if self.check_keyword(kw::Async) { + let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo); + Err(self.incorrect_move_async_order_found(move_async_span)) + } else { + Ok(CaptureBy::Value) + } + } else { + Ok(CaptureBy::Ref) + } } /// Parses the `|arg, arg|` header of a closure. @@ -2018,7 +2028,7 @@ impl<'a> Parser<'a> { fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P> { let lo = self.token.span; self.expect_keyword(kw::Async)?; - let capture_clause = self.parse_capture_clause(); + let capture_clause = self.parse_capture_clause()?; let (iattrs, body) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs); let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body); diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed b/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed new file mode 100644 index 00000000000..055800d23b6 --- /dev/null +++ b/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed @@ -0,0 +1,8 @@ +// run-rustfix +// edition:2018 + +// Regression test for issue 79694 + +fn main() { + let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect +} diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs b/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs new file mode 100644 index 00000000000..e8be16516d6 --- /dev/null +++ b/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs @@ -0,0 +1,8 @@ +// run-rustfix +// edition:2018 + +// Regression test for issue 79694 + +fn main() { + let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect +} diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr b/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr new file mode 100644 index 00000000000..2add9fb33c7 --- /dev/null +++ b/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr @@ -0,0 +1,13 @@ +error: the order of `move` and `async` is incorrect + --> $DIR/incorrect-move-async-order-issue-79694.rs:7:13 + | +LL | let _ = move async { }; + | ^^^^^^^^^^ + | +help: try switching the order + | +LL | let _ = async move { }; + | ^^^^^^^^^^ + +error: aborting due to previous error + -- cgit 1.4.1-3-g733a5 From dffa1e241289f1c98f8a6e4757c00305592e7794 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Mon, 21 Dec 2020 17:40:39 +0100 Subject: Remove redundant test --- src/test/rustdoc-ui/reference-link-has-one-warning.rs | 6 ------ src/test/rustdoc-ui/reference-link-has-one-warning.stderr | 10 ---------- 2 files changed, 16 deletions(-) delete mode 100644 src/test/rustdoc-ui/reference-link-has-one-warning.rs delete mode 100644 src/test/rustdoc-ui/reference-link-has-one-warning.stderr (limited to 'src') diff --git a/src/test/rustdoc-ui/reference-link-has-one-warning.rs b/src/test/rustdoc-ui/reference-link-has-one-warning.rs deleted file mode 100644 index 21cb7eb9040..00000000000 --- a/src/test/rustdoc-ui/reference-link-has-one-warning.rs +++ /dev/null @@ -1,6 +0,0 @@ -// ignore-test -// check-pass - -/// docs [label][with#anchor#error] -//~^ WARNING has an issue with the link anchor -pub struct S; diff --git a/src/test/rustdoc-ui/reference-link-has-one-warning.stderr b/src/test/rustdoc-ui/reference-link-has-one-warning.stderr deleted file mode 100644 index a1eeb60f178..00000000000 --- a/src/test/rustdoc-ui/reference-link-has-one-warning.stderr +++ /dev/null @@ -1,10 +0,0 @@ -warning: `[with#anchor#error]` has an issue with the link anchor. - --> $DIR/reference-link-has-one-warning.rs:3:18 - | -LL | /// docs [label][with#anchor#error] - | ^^^^^^^^^^^^^^^^^ only one `#` is allowed in a link - | - = note: `#[warn(broken_intra_doc_links)]` on by default - -warning: 1 warning emitted - -- cgit 1.4.1-3-g733a5 From aec3575aa7d6903fbff2140b37b65961836d47dc Mon Sep 17 00:00:00 2001 From: pierwill Date: Mon, 21 Dec 2020 14:17:53 -0800 Subject: Rename rustc_middle::lint::LintSource Rename rustc_middle::lint::LintSource to rustc_middle::lint::LintLevelSource. --- compiler/rustc_lint/src/levels.rs | 20 ++++++++-------- compiler/rustc_middle/src/lint.rs | 32 ++++++++++++------------- compiler/rustc_middle/src/ty/context.rs | 4 ++-- src/librustdoc/passes/calculate_doc_coverage.rs | 4 ++-- src/librustdoc/passes/doc_test_lints.rs | 4 ++-- 5 files changed, 32 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 3e22eba15aa..410bd06850e 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -12,7 +12,7 @@ use rustc_hir::{intravisit, HirId}; use rustc_middle::hir::map::Map; use rustc_middle::lint::LevelSource; use rustc_middle::lint::LintDiagnosticBuilder; -use rustc_middle::lint::{struct_lint_level, LintLevelMap, LintLevelSets, LintSet, LintSource}; +use rustc_middle::lint::{struct_lint_level, LintLevelMap, LintLevelSets, LintSet, LintLevelSource}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::{builtin, Level, Lint, LintId}; @@ -91,7 +91,7 @@ impl<'s> LintLevelsBuilder<'s> { }; for id in ids { self.check_gated_lint(id, DUMMY_SP); - let src = LintSource::CommandLine(lint_flag_val, orig_level); + let src = LintLevelSource::CommandLine(lint_flag_val, orig_level); specs.insert(id, (level, src)); } } @@ -128,19 +128,19 @@ impl<'s> LintLevelsBuilder<'s> { ); diag_builder.span_label(src.span(), "overruled by previous forbid"); match old_src { - LintSource::Default => { + LintLevelSource::Default => { diag_builder.note(&format!( "`forbid` lint level is the default for {}", id.to_string() )); } - LintSource::Node(_, forbid_source_span, reason) => { + LintLevelSource::Node(_, forbid_source_span, reason) => { diag_builder.span_label(forbid_source_span, "`forbid` level set here"); if let Some(rationale) = reason { diag_builder.note(&rationale.as_str()); } } - LintSource::CommandLine(_, _) => { + LintLevelSource::CommandLine(_, _) => { diag_builder.note("`forbid` lint level was set on command line"); } } @@ -276,7 +276,7 @@ impl<'s> LintLevelsBuilder<'s> { let name = meta_item.path.segments.last().expect("empty lint name").ident.name; match store.check_lint_name(&name.as_str(), tool_name) { CheckLintNameResult::Ok(ids) => { - let src = LintSource::Node(name, li.span(), reason); + let src = LintLevelSource::Node(name, li.span(), reason); for &id in ids { self.check_gated_lint(id, attr.span); self.insert_spec(&mut specs, id, (level, src)); @@ -287,7 +287,7 @@ impl<'s> LintLevelsBuilder<'s> { match result { Ok(ids) => { let complete_name = &format!("{}::{}", tool_name.unwrap(), name); - let src = LintSource::Node( + let src = LintLevelSource::Node( Symbol::intern(complete_name), li.span(), reason, @@ -324,7 +324,7 @@ impl<'s> LintLevelsBuilder<'s> { }, ); - let src = LintSource::Node( + let src = LintLevelSource::Node( Symbol::intern(&new_lint_name), li.span(), reason, @@ -403,7 +403,7 @@ impl<'s> LintLevelsBuilder<'s> { } let (lint_attr_name, lint_attr_span) = match *src { - LintSource::Node(name, span, _) => (name, span), + LintLevelSource::Node(name, span, _) => (name, span), _ => continue, }; @@ -460,7 +460,7 @@ impl<'s> LintLevelsBuilder<'s> { } /// Find the lint level for a lint. - pub fn lint_level(&self, lint: &'static Lint) -> (Level, LintSource) { + pub fn lint_level(&self, lint: &'static Lint) -> (Level, LintLevelSource) { self.sets.get_lint_level(lint, self.cur, None, self.sess) } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index a61d37cc90e..2dbb84970d1 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -13,7 +13,7 @@ use rustc_span::{symbol, Span, Symbol, DUMMY_SP}; /// How a lint level was set. #[derive(Clone, Copy, PartialEq, Eq, HashStable)] -pub enum LintSource { +pub enum LintLevelSource { /// Lint is at the default level as declared /// in rustc or a plugin. Default, @@ -27,25 +27,25 @@ pub enum LintSource { CommandLine(Symbol, Level), } -impl LintSource { +impl LintLevelSource { pub fn name(&self) -> Symbol { match *self { - LintSource::Default => symbol::kw::Default, - LintSource::Node(name, _, _) => name, - LintSource::CommandLine(name, _) => name, + LintLevelSource::Default => symbol::kw::Default, + LintLevelSource::Node(name, _, _) => name, + LintLevelSource::CommandLine(name, _) => name, } } pub fn span(&self) -> Span { match *self { - LintSource::Default => DUMMY_SP, - LintSource::Node(_, span, _) => span, - LintSource::CommandLine(_, _) => DUMMY_SP, + LintLevelSource::Default => DUMMY_SP, + LintLevelSource::Node(_, span, _) => span, + LintLevelSource::CommandLine(_, _) => DUMMY_SP, } } } -pub type LevelSource = (Level, LintSource); +pub type LevelSource = (Level, LintLevelSource); pub struct LintLevelSets { pub list: Vec, @@ -113,7 +113,7 @@ impl LintLevelSets { id: LintId, mut idx: u32, aux: Option<&FxHashMap>, - ) -> (Option, LintSource) { + ) -> (Option, LintLevelSource) { if let Some(specs) = aux { if let Some(&(level, src)) = specs.get(&id) { return (Some(level), src); @@ -125,7 +125,7 @@ impl LintLevelSets { if let Some(&(level, src)) = specs.get(&id) { return (Some(level), src); } - return (None, LintSource::Default); + return (None, LintLevelSource::Default); } LintSet::Node { ref specs, parent } => { if let Some(&(level, src)) = specs.get(&id) { @@ -213,7 +213,7 @@ pub fn struct_lint_level<'s, 'd>( sess: &'s Session, lint: &'static Lint, level: Level, - src: LintSource, + src: LintLevelSource, span: Option, decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>) + 'd, ) { @@ -223,7 +223,7 @@ pub fn struct_lint_level<'s, 'd>( sess: &'s Session, lint: &'static Lint, level: Level, - src: LintSource, + src: LintLevelSource, span: Option, decorate: Box FnOnce(LintDiagnosticBuilder<'b>) + 'd>, ) { @@ -274,14 +274,14 @@ pub fn struct_lint_level<'s, 'd>( let name = lint.name_lower(); match src { - LintSource::Default => { + LintLevelSource::Default => { sess.diag_note_once( &mut err, DiagnosticMessageId::from(lint), &format!("`#[{}({})]` on by default", level.as_str(), name), ); } - LintSource::CommandLine(lint_flag_val, orig_level) => { + LintLevelSource::CommandLine(lint_flag_val, orig_level) => { let flag = match orig_level { Level::Warn => "-W", Level::Deny => "-D", @@ -310,7 +310,7 @@ pub fn struct_lint_level<'s, 'd>( ); } } - LintSource::Node(lint_attr_name, src, reason) => { + LintLevelSource::Node(lint_attr_name, src, reason) => { if let Some(rationale) = reason { err.note(&rationale.as_str()); } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4205e2ca5aa..9b944f202a9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -5,7 +5,7 @@ use crate::dep_graph::{self, DepGraph, DepKind, DepNode, DepNodeExt}; use crate::hir::exports::ExportMap; use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; -use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintSource}; +use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource}; use crate::middle; use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata}; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; @@ -2559,7 +2559,7 @@ impl<'tcx> TyCtxt<'tcx> { self, lint: &'static Lint, mut id: hir::HirId, - ) -> (Level, LintSource) { + ) -> (Level, LintLevelSource) { let sets = self.lint_levels(LOCAL_CRATE); loop { if let Some(pair) = sets.level_and_source(lint, id, self.sess) { diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 52f6a97089b..af5121d6b1b 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -5,7 +5,7 @@ use crate::html::markdown::{find_testable_code, ErrorCodes}; use crate::passes::doc_test_lints::{should_have_doc_example, Tests}; use crate::passes::Pass; use rustc_lint::builtin::MISSING_DOCS; -use rustc_middle::lint::LintSource; +use rustc_middle::lint::LintLevelSource; use rustc_session::lint; use rustc_span::symbol::sym; use rustc_span::FileName; @@ -254,7 +254,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> { // `missing_docs` is allow-by-default, so don't treat this as ignoring the item // unless the user had an explicit `allow` let should_have_docs = - level != lint::Level::Allow || matches!(source, LintSource::Default); + level != lint::Level::Allow || matches!(source, LintLevelSource::Default); debug!("counting {:?} {:?} in {}", i.type_(), i.name, filename); self.items.entry(filename).or_default().count_item( has_docs, diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index 1c1141e7c81..17d2847913d 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -9,7 +9,7 @@ use crate::clean::*; use crate::core::DocContext; use crate::fold::DocFolder; use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString}; -use rustc_middle::lint::LintSource; +use rustc_middle::lint::LintLevelSource; use rustc_session::lint; crate const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass { @@ -77,7 +77,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local()); let (level, source) = cx.tcx.lint_level_at_node(lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id); - level != lint::Level::Allow || matches!(source, LintSource::Default) + level != lint::Level::Allow || matches!(source, LintLevelSource::Default) } crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { -- cgit 1.4.1-3-g733a5 From 163f5da322f7e62216532735c67813060eacc8de Mon Sep 17 00:00:00 2001 From: pierwill Date: Mon, 21 Dec 2020 17:18:48 -0800 Subject: Add installation commands to `x` tool README --- src/tools/x/README.md | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/tools/x/README.md b/src/tools/x/README.md index 3b3cf2847c2..80bf02e8a0e 100644 --- a/src/tools/x/README.md +++ b/src/tools/x/README.md @@ -1,3 +1,10 @@ # x `x` invokes `x.py` from any subdirectory. + +To install, run the following commands: + +``` +$ cd rust/src/tools/x/ +$ cargo install --path . +``` -- cgit 1.4.1-3-g733a5 From 1339c813906a33530b1ef2770141fecc03ec9452 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 21 Dec 2020 19:00:49 -0800 Subject: Update books --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/doc/book b/src/doc/book index a190438d77d..5bb44f8b5b0 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit a190438d77d28041f24da4f6592e287fab073a61 +Subproject commit 5bb44f8b5b0aa105c8b22602e9b18800484afa21 diff --git a/src/doc/nomicon b/src/doc/nomicon index d8383b65f79..a5a48441d41 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit d8383b65f7948c2ca19191b3b4bd709b403aaf45 +Subproject commit a5a48441d411f61556b57d762b03d6874afe575d diff --git a/src/doc/reference b/src/doc/reference index a8afdca5d07..b278478b766 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit a8afdca5d0715b2257b6f8b9a032fd4dd7dae855 +Subproject commit b278478b766178491a8b6f67afa4bcd6b64d977a diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 236c734a2cb..1cce0737d6a 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 236c734a2cb323541b3394f98682cb981b9ec086 +Subproject commit 1cce0737d6a7d3ceafb139b4a206861fb1dcb2ab -- cgit 1.4.1-3-g733a5 From 828d4ace4dee856b376fa44cc095d490ee799c30 Mon Sep 17 00:00:00 2001 From: Linus Färnstrand Date: Fri, 20 Nov 2020 22:27:50 +0100 Subject: Migrate standard library away from compare_and_swap --- library/core/tests/atomic.rs | 6 +++--- library/std/src/sync/mpsc/blocking.rs | 6 +++++- library/std/src/sync/mpsc/oneshot.rs | 14 +++++++++++--- library/std/src/sync/mpsc/shared.rs | 11 +++++++++-- library/std/src/sync/mpsc/stream.rs | 9 ++++++--- library/std/src/sync/once.rs | 16 +++++++++++----- library/std/src/sys/sgx/abi/mod.rs | 8 ++++---- library/std/src/sys/sgx/waitqueue/spin_mutex.rs | 2 +- library/std/src/sys/windows/mutex.rs | 6 +++--- library/std/src/sys_common/condvar/check.rs | 6 +++--- library/std/src/sys_common/thread_local_key.rs | 8 ++++---- library/std/src/sys_common/thread_parker/futex.rs | 2 +- src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs | 7 ++++++- src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs | 7 ++++++- src/test/ui/array-slice-vec/nested-vec-3.rs | 7 ++++++- 15 files changed, 79 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index 75528ebb54e..2d1e4496aee 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -4,11 +4,11 @@ use core::sync::atomic::*; #[test] fn bool_() { let a = AtomicBool::new(false); - assert_eq!(a.compare_and_swap(false, true, SeqCst), false); - assert_eq!(a.compare_and_swap(false, true, SeqCst), true); + assert_eq!(a.compare_exchange(false, true, SeqCst, SeqCst), Ok(false)); + assert_eq!(a.compare_exchange(false, true, SeqCst, SeqCst), Err(true)); a.store(false, SeqCst); - assert_eq!(a.compare_and_swap(false, true, SeqCst), false); + assert_eq!(a.compare_exchange(false, true, SeqCst, SeqCst), Ok(false)); } #[test] diff --git a/library/std/src/sync/mpsc/blocking.rs b/library/std/src/sync/mpsc/blocking.rs index d34de6a4fac..4c852b8ee81 100644 --- a/library/std/src/sync/mpsc/blocking.rs +++ b/library/std/src/sync/mpsc/blocking.rs @@ -36,7 +36,11 @@ pub fn tokens() -> (WaitToken, SignalToken) { impl SignalToken { pub fn signal(&self) -> bool { - let wake = !self.inner.woken.compare_and_swap(false, true, Ordering::SeqCst); + let wake = self + .inner + .woken + .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) + .is_ok(); if wake { self.inner.thread.unpark(); } diff --git a/library/std/src/sync/mpsc/oneshot.rs b/library/std/src/sync/mpsc/oneshot.rs index 75f5621fa12..3dcf03f579a 100644 --- a/library/std/src/sync/mpsc/oneshot.rs +++ b/library/std/src/sync/mpsc/oneshot.rs @@ -129,7 +129,7 @@ impl Packet { let ptr = unsafe { signal_token.cast_to_usize() }; // race with senders to enter the blocking state - if self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) == EMPTY { + if self.state.compare_exchange(EMPTY, ptr, Ordering::SeqCst, Ordering::SeqCst).is_ok() { if let Some(deadline) = deadline { let timed_out = !wait_token.wait_max_until(deadline); // Try to reset the state @@ -161,7 +161,12 @@ impl Packet { // the state changes under our feet we'd rather just see that state // change. DATA => { - self.state.compare_and_swap(DATA, EMPTY, Ordering::SeqCst); + let _ = self.state.compare_exchange( + DATA, + EMPTY, + Ordering::SeqCst, + Ordering::SeqCst, + ); match (&mut *self.data.get()).take() { Some(data) => Ok(data), None => unreachable!(), @@ -264,7 +269,10 @@ impl Packet { // If we've got a blocked thread, then use an atomic to gain ownership // of it (may fail) - ptr => self.state.compare_and_swap(ptr, EMPTY, Ordering::SeqCst), + ptr => self + .state + .compare_exchange(ptr, EMPTY, Ordering::SeqCst, Ordering::SeqCst) + .unwrap_or_else(|x| x), }; // Now that we've got ownership of our state, figure out what to do diff --git a/library/std/src/sync/mpsc/shared.rs b/library/std/src/sync/mpsc/shared.rs index 898654f21f2..0c32e636a56 100644 --- a/library/std/src/sync/mpsc/shared.rs +++ b/library/std/src/sync/mpsc/shared.rs @@ -385,8 +385,15 @@ impl Packet { self.port_dropped.store(true, Ordering::SeqCst); let mut steals = unsafe { *self.steals.get() }; while { - let cnt = self.cnt.compare_and_swap(steals, DISCONNECTED, Ordering::SeqCst); - cnt != DISCONNECTED && cnt != steals + match self.cnt.compare_exchange( + steals, + DISCONNECTED, + Ordering::SeqCst, + Ordering::SeqCst, + ) { + Ok(_) => false, + Err(old) => old != DISCONNECTED, + } } { // See the discussion in 'try_recv' for why we yield // control of this thread. diff --git a/library/std/src/sync/mpsc/stream.rs b/library/std/src/sync/mpsc/stream.rs index 9f7c1af8951..a652f24c58a 100644 --- a/library/std/src/sync/mpsc/stream.rs +++ b/library/std/src/sync/mpsc/stream.rs @@ -322,12 +322,15 @@ impl Packet { // (because there is a bounded number of senders). let mut steals = unsafe { *self.queue.consumer_addition().steals.get() }; while { - let cnt = self.queue.producer_addition().cnt.compare_and_swap( + match self.queue.producer_addition().cnt.compare_exchange( steals, DISCONNECTED, Ordering::SeqCst, - ); - cnt != DISCONNECTED && cnt != steals + Ordering::SeqCst, + ) { + Ok(_) => false, + Err(old) => old != DISCONNECTED, + } } { while self.queue.pop().is_some() { steals += 1; diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index de5ddf1daf2..9a17d121db1 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -65,7 +65,7 @@ // must do so with Release ordering to make the result available. // - `wait` inserts `Waiter` nodes as a pointer in `state_and_queue`, and // needs to make the nodes available with Release ordering. The load in -// its `compare_and_swap` can be Relaxed because it only has to compare +// its `compare_exchange` can be Relaxed because it only has to compare // the atomic, not to read other data. // - `WaiterQueue::Drop` must see the `Waiter` nodes, so it must load // `state_and_queue` with Acquire ordering. @@ -395,12 +395,13 @@ impl Once { } POISONED | INCOMPLETE => { // Try to register this thread as the one RUNNING. - let old = self.state_and_queue.compare_and_swap( + let exchange_result = self.state_and_queue.compare_exchange( state_and_queue, RUNNING, Ordering::Acquire, + Ordering::Acquire, ); - if old != state_and_queue { + if let Err(old) = exchange_result { state_and_queue = old; continue; } @@ -452,8 +453,13 @@ fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) { // Try to slide in the node at the head of the linked list, making sure // that another thread didn't just replace the head of the linked list. - let old = state_and_queue.compare_and_swap(current_state, me | RUNNING, Ordering::Release); - if old != current_state { + let exchange_result = state_and_queue.compare_exchange( + current_state, + me | RUNNING, + Ordering::Release, + Ordering::Relaxed, + ); + if let Err(old) = exchange_result { current_state = old; continue; } diff --git a/library/std/src/sys/sgx/abi/mod.rs b/library/std/src/sys/sgx/abi/mod.rs index a0eb12c3d15..a5e45303476 100644 --- a/library/std/src/sys/sgx/abi/mod.rs +++ b/library/std/src/sys/sgx/abi/mod.rs @@ -36,20 +36,20 @@ unsafe extern "C" fn tcs_init(secondary: bool) { } // Try to atomically swap UNINIT with BUSY. The returned state can be: - match RELOC_STATE.compare_and_swap(UNINIT, BUSY, Ordering::Acquire) { + match RELOC_STATE.compare_exchange(UNINIT, BUSY, Ordering::Acquire, Ordering::Acquire) { // This thread just obtained the lock and other threads will observe BUSY - UNINIT => { + Ok(_) => { reloc::relocate_elf_rela(); RELOC_STATE.store(DONE, Ordering::Release); } // We need to wait until the initialization is done. - BUSY => { + Err(BUSY) => { while RELOC_STATE.load(Ordering::Acquire) == BUSY { core::hint::spin_loop(); } } // Initialization is done. - DONE => {} + Err(DONE) => {} _ => unreachable!(), } } diff --git a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs index d99ce895da5..9140041c584 100644 --- a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs +++ b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs @@ -42,7 +42,7 @@ impl SpinMutex { #[inline(always)] pub fn try_lock(&self) -> Option> { - if !self.lock.compare_and_swap(false, true, Ordering::Acquire) { + if self.lock.compare_exchange(false, true, Ordering::Acquire, Ordering::Acquire).is_ok() { Some(SpinMutexGuard { mutex: self }) } else { None diff --git a/library/std/src/sys/windows/mutex.rs b/library/std/src/sys/windows/mutex.rs index fa51b006c34..d4cc56d4cb3 100644 --- a/library/std/src/sys/windows/mutex.rs +++ b/library/std/src/sys/windows/mutex.rs @@ -123,9 +123,9 @@ impl Mutex { let inner = box Inner { remutex: ReentrantMutex::uninitialized(), held: Cell::new(false) }; inner.remutex.init(); let inner = Box::into_raw(inner); - match self.lock.compare_and_swap(0, inner as usize, Ordering::SeqCst) { - 0 => inner, - n => { + match self.lock.compare_exchange(0, inner as usize, Ordering::SeqCst, Ordering::SeqCst) { + Ok(_) => inner, + Err(n) => { Box::from_raw(inner).remutex.destroy(); n as *const _ } diff --git a/library/std/src/sys_common/condvar/check.rs b/library/std/src/sys_common/condvar/check.rs index fecb732b910..1578a2de60c 100644 --- a/library/std/src/sys_common/condvar/check.rs +++ b/library/std/src/sys_common/condvar/check.rs @@ -23,9 +23,9 @@ impl SameMutexCheck { } pub fn verify(&self, mutex: &MovableMutex) { let addr = mutex.raw() as *const mutex_imp::Mutex as usize; - match self.addr.compare_and_swap(0, addr, Ordering::SeqCst) { - 0 => {} // Stored the address - n if n == addr => {} // Lost a race to store the same address + match self.addr.compare_exchange(0, addr, Ordering::SeqCst, Ordering::SeqCst) { + Ok(_) => {} // Stored the address + Err(n) if n == addr => {} // Lost a race to store the same address _ => panic!("attempted to use a condition variable with two mutexes"), } } diff --git a/library/std/src/sys_common/thread_local_key.rs b/library/std/src/sys_common/thread_local_key.rs index dbcb7b36265..32cd5641665 100644 --- a/library/std/src/sys_common/thread_local_key.rs +++ b/library/std/src/sys_common/thread_local_key.rs @@ -168,7 +168,7 @@ impl StaticKey { return key; } - // POSIX allows the key created here to be 0, but the compare_and_swap + // POSIX allows the key created here to be 0, but the compare_exchange // below relies on using 0 as a sentinel value to check who won the // race to set the shared TLS key. As far as I know, there is no // guaranteed value that cannot be returned as a posix_key_create key, @@ -186,11 +186,11 @@ impl StaticKey { key2 }; rtassert!(key != 0); - match self.key.compare_and_swap(0, key as usize, Ordering::SeqCst) { + match self.key.compare_exchange(0, key as usize, Ordering::SeqCst, Ordering::SeqCst) { // The CAS succeeded, so we've created the actual key - 0 => key as usize, + Ok(_) => key as usize, // If someone beat us to the punch, use their key instead - n => { + Err(n) => { imp::destroy(key); n } diff --git a/library/std/src/sys_common/thread_parker/futex.rs b/library/std/src/sys_common/thread_parker/futex.rs index a5d4927dcc5..0132743b244 100644 --- a/library/std/src/sys_common/thread_parker/futex.rs +++ b/library/std/src/sys_common/thread_parker/futex.rs @@ -49,7 +49,7 @@ impl Parker { // Wait for something to happen, assuming it's still set to PARKED. futex_wait(&self.state, PARKED, None); // Change NOTIFIED=>EMPTY and return in that case. - if self.state.compare_and_swap(NOTIFIED, EMPTY, Acquire) == NOTIFIED { + if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Acquire).is_ok() { return; } else { // Spurious wake up. We loop to try again. diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs index d4858932815..c8559d24728 100644 --- a/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs +++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs @@ -17,7 +17,12 @@ impl Drop for D { fn drop(&mut self) { println!("Dropping {}", self.0); let old = LOG.load(Ordering::SeqCst); - LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst); + let _ = LOG.compare_exchange( + old, + old << 4 | self.0 as usize, + Ordering::SeqCst, + Ordering::SeqCst + ); } } diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs index e8a5b00a55b..e75051caabc 100644 --- a/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs +++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs @@ -17,7 +17,12 @@ impl Drop for D { fn drop(&mut self) { println!("Dropping {}", self.0); let old = LOG.load(Ordering::SeqCst); - LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst); + let _ = LOG.compare_exchange( + old, + old << 4 | self.0 as usize, + Ordering::SeqCst, + Ordering::SeqCst + ); } } diff --git a/src/test/ui/array-slice-vec/nested-vec-3.rs b/src/test/ui/array-slice-vec/nested-vec-3.rs index 52b892dbcdf..96497a53d30 100644 --- a/src/test/ui/array-slice-vec/nested-vec-3.rs +++ b/src/test/ui/array-slice-vec/nested-vec-3.rs @@ -18,7 +18,12 @@ impl Drop for D { fn drop(&mut self) { println!("Dropping {}", self.0); let old = LOG.load(Ordering::SeqCst); - LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst); + let _ = LOG.compare_exchange( + old, + old << 4 | self.0 as usize, + Ordering::SeqCst, + Ordering::SeqCst, + ); } } -- cgit 1.4.1-3-g733a5 From 9414f0b833734c344e795d590e9a845ce437c908 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 19 Dec 2020 16:29:38 -0500 Subject: Revert "Remove missing_fragment_specifier lint" This reverts commit 5ba961018c482e050af908de60e4f8bd1a00f0ae. --- compiler/rustc_lint_defs/src/builtin.rs | 17 +++++++++++++++++ src/doc/rustc/src/lints/listing/deny-by-default.md | 3 --- 2 files changed, 17 insertions(+), 3 deletions(-) delete mode 100644 src/doc/rustc/src/lints/listing/deny-by-default.md (limited to 'src') diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 6a48b8f4dfb..de5253a84cc 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1227,6 +1227,22 @@ declare_lint! { }; } +declare_lint! { + /// The missing_fragment_specifier warning is issued when an unused pattern in a + /// `macro_rules!` macro definition has a meta-variable (e.g. `$e`) that is not + /// followed by a fragment specifier (e.g. `:expr`). + /// + /// This warning can always be fixed by removing the unused pattern in the + /// `macro_rules!` macro definition. + pub MISSING_FRAGMENT_SPECIFIER, + Deny, + "detects missing fragment specifiers in unused `macro_rules!` patterns", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #40107 ", + edition: None, + }; +} + declare_lint! { /// The `late_bound_lifetime_arguments` lint detects generic lifetime /// arguments in path segments with late bound lifetime parameters. @@ -2827,6 +2843,7 @@ declare_lint_pass! { CONST_ITEM_MUTATION, SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, + MISSING_FRAGMENT_SPECIFIER, LATE_BOUND_LIFETIME_ARGUMENTS, ORDER_DEPENDENT_TRAIT_OBJECTS, COHERENCE_LEAK_CHECK, diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md deleted file mode 100644 index 3c1452d6467..00000000000 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ /dev/null @@ -1,3 +0,0 @@ -# Deny-by-default lints - -This file is auto-generated by the lint-docs script. -- cgit 1.4.1-3-g733a5 From f1eb88b28a84b0533ddd036a60bb5b8acbffabb2 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 19 Dec 2020 16:30:56 -0500 Subject: Revert "Promote missing_fragment_specifier to hard error" This reverts commit 02eae432e7476a0686633a8c2b7cb1d5aab1bd2c. --- compiler/rustc_expand/src/mbe.rs | 2 +- compiler/rustc_expand/src/mbe/macro_parser.rs | 20 +++++++++++++++++--- compiler/rustc_expand/src/mbe/macro_rules.rs | 15 ++++++++------- compiler/rustc_expand/src/mbe/quoted.rs | 11 +++++++---- compiler/rustc_interface/src/passes.rs | 19 ++++++++++++++++++- compiler/rustc_session/src/parse.rs | 2 ++ src/test/ui/lint/expansion-time.rs | 4 ++++ src/test/ui/lint/expansion-time.stderr | 22 ++++++++++++++++++---- src/test/ui/macros/issue-39404.rs | 1 + src/test/ui/macros/issue-39404.stderr | 4 ++++ src/test/ui/macros/macro-match-nonterminal.rs | 1 + src/test/ui/macros/macro-match-nonterminal.stderr | 4 ++++ src/test/ui/parser/macro/issue-33569.rs | 1 - src/test/ui/parser/macro/issue-33569.stderr | 16 +++++----------- 14 files changed, 90 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index eb4aab116f0..cbc4d14a65a 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -84,7 +84,7 @@ enum TokenTree { /// e.g., `$var` MetaVar(Span, Ident), /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros. - MetaVarDecl(Span, Ident /* name to bind */, NonterminalKind), + MetaVarDecl(Span, Ident /* name to bind */, Option), } impl TokenTree { diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 3cf2d8f8ac1..0c44f5fe9e1 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -378,6 +378,11 @@ fn nameize>( n_rec(sess, next_m, res.by_ref(), ret_val)?; } } + TokenTree::MetaVarDecl(span, _, None) => { + if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { + return Err((span, "missing fragment specifier".to_string())); + } + } TokenTree::MetaVarDecl(sp, bind_name, _) => match ret_val .entry(MacroRulesNormalizedIdent::new(bind_name)) { @@ -446,6 +451,7 @@ fn or_pat_mode(edition: Edition) -> OrPatNonterminalMode { /// /// A `ParseResult`. Note that matches are kept track of through the items generated. fn inner_parse_loop<'root, 'tt>( + sess: &ParseSess, cur_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>, next_items: &mut Vec>, eof_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>, @@ -563,9 +569,16 @@ fn inner_parse_loop<'root, 'tt>( }))); } + // We need to match a metavar (but the identifier is invalid)... this is an error + TokenTree::MetaVarDecl(span, _, None) => { + if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { + return Error(span, "missing fragment specifier".to_string()); + } + } + // We need to match a metavar with a valid ident... call out to the black-box // parser by adding an item to `bb_items`. - TokenTree::MetaVarDecl(span, _, kind) => { + TokenTree::MetaVarDecl(span, _, Some(kind)) => { // Built-in nonterminals never start with these tokens, so we can eliminate // them from consideration. // @@ -640,6 +653,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na // parsing from the black-box parser done. The result is that `next_items` will contain a // bunch of possible next matcher positions in `next_items`. match inner_parse_loop( + parser.sess, &mut cur_items, &mut next_items, &mut eof_items, @@ -701,7 +715,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na let nts = bb_items .iter() .map(|item| match item.top_elts.get_tt(item.idx) { - TokenTree::MetaVarDecl(_, bind, kind) => format!("{} ('{}')", kind, bind), + TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind), _ => panic!(), }) .collect::>() @@ -731,7 +745,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na assert_eq!(bb_items.len(), 1); let mut item = bb_items.pop().unwrap(); - if let TokenTree::MetaVarDecl(span, _, kind) = item.top_elts.get_tt(item.idx) { + if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) { let match_cur = item.match_cur; // We use the span of the metavariable declaration to determine any // edition-specific matching behavior for non-terminals. diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 66463eeb907..89d375b257d 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -401,7 +401,7 @@ pub fn compile_declarative_macro( let diag = &sess.parse_sess.span_diagnostic; let lhs_nm = Ident::new(sym::lhs, def.span); let rhs_nm = Ident::new(sym::rhs, def.span); - let tt_spec = NonterminalKind::TT; + let tt_spec = Some(NonterminalKind::TT); // Parse the macro_rules! invocation let (macro_rules, body) = match &def.kind { @@ -578,7 +578,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { TokenTree::Sequence(span, ref seq) => { if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| match *seq_tt { - TokenTree::MetaVarDecl(_, _, NonterminalKind::Vis) => true, + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true, TokenTree::Sequence(_, ref sub_seq) => { sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne @@ -961,7 +961,7 @@ fn check_matcher_core( // Now `last` holds the complete set of NT tokens that could // end the sequence before SUFFIX. Check that every one works with `suffix`. for token in &last.tokens { - if let TokenTree::MetaVarDecl(_, name, kind) = *token { + if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token { for next_token in &suffix_first.tokens { match is_in_follow(next_token, kind) { IsInFollow::Yes => {} @@ -1019,7 +1019,7 @@ fn check_matcher_core( } fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool { - if let mbe::TokenTree::MetaVarDecl(_, _, kind) = *tok { + if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok { frag_can_be_followed_by_any(kind) } else { // (Non NT's can always be followed by anything in matchers.) @@ -1123,7 +1123,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { } _ => IsInFollow::No(TOKENS), }, - TokenTree::MetaVarDecl(_, _, NonterminalKind::Block) => IsInFollow::Yes, + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } } @@ -1158,7 +1158,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { TokenTree::MetaVarDecl( _, _, - NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path, + Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path), ) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } @@ -1171,7 +1171,8 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { match *tt { mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token), mbe::TokenTree::MetaVar(_, name) => format!("${}", name), - mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name), _ => panic!( "{}", "unexpected mbe::TokenTree::{Sequence or Delimited} \ diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 48db532c78f..01b11bb979d 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -3,7 +3,7 @@ use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream; -use rustc_ast::NodeId; +use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, Ident}; @@ -73,7 +73,7 @@ pub(super) fn parse( .emit(); token::NonterminalKind::Ident }); - result.push(TokenTree::MetaVarDecl(span, ident, kind)); + result.push(TokenTree::MetaVarDecl(span, ident, Some(kind))); continue; } _ => token.span, @@ -83,8 +83,11 @@ pub(super) fn parse( } tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp), }; - sess.span_diagnostic.struct_span_err(span, "missing fragment specifier").emit(); - continue; + if node_id != DUMMY_NODE_ID { + // Macros loaded from other crates have dummy node ids. + sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id); + } + result.push(TokenTree::MetaVarDecl(span, ident, None)); } // Not a metavar or no matchers allowed, so just return the tree diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c13d26c79d7..a8c8690b9e7 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -29,6 +29,7 @@ use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode}; +use rustc_session::lint; use rustc_session::output::{filename_for_input, filename_for_metadata}; use rustc_session::search_paths::PathKind; use rustc_session::Session; @@ -306,11 +307,27 @@ fn configure_and_expand_inner<'a>( ecx.check_unused_macros(); }); + let mut missing_fragment_specifiers: Vec<_> = ecx + .sess + .parse_sess + .missing_fragment_specifiers + .borrow() + .iter() + .map(|(span, node_id)| (*span, *node_id)) + .collect(); + missing_fragment_specifiers.sort_unstable_by_key(|(span, _)| *span); + + let recursion_limit_hit = ecx.reduced_recursion_limit.is_some(); + + for (span, node_id) in missing_fragment_specifiers { + let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER; + let msg = "missing fragment specifier"; + resolver.lint_buffer().buffer_lint(lint, node_id, span, msg); + } if cfg!(windows) { env::set_var("PATH", &old_path); } - let recursion_limit_hit = ecx.reduced_recursion_limit.is_some(); if recursion_limit_hit { // If we hit a recursion limit, exit early to avoid later passes getting overwhelmed // with a large AST diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 66c3738fb5b..b1a48342417 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -119,6 +119,7 @@ pub struct ParseSess { pub unstable_features: UnstableFeatures, pub config: CrateConfig, pub edition: Edition, + pub missing_fragment_specifiers: Lock>, /// Places where raw identifiers were used. This is used for feature-gating raw identifiers. pub raw_identifier_spans: Lock>, /// Used to determine and report recursive module inclusions. @@ -152,6 +153,7 @@ impl ParseSess { unstable_features: UnstableFeatures::from_environment(None), config: FxHashSet::default(), edition: ExpnId::root().expn_data().edition, + missing_fragment_specifiers: Default::default(), raw_identifier_spans: Lock::new(Vec::new()), included_mod_stack: Lock::new(vec![]), source_map, diff --git a/src/test/ui/lint/expansion-time.rs b/src/test/ui/lint/expansion-time.rs index a9c7ac363b0..f23c7cb0dca 100644 --- a/src/test/ui/lint/expansion-time.rs +++ b/src/test/ui/lint/expansion-time.rs @@ -5,6 +5,10 @@ macro_rules! foo { ( $($i:ident)* ) => { $($i)+ }; //~ WARN meta-variable repeats with different Kleene operator } +#[warn(missing_fragment_specifier)] +macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier + //~| WARN this was previously accepted + #[warn(soft_unstable)] mod benches { #[bench] //~ WARN use of unstable library feature 'test' diff --git a/src/test/ui/lint/expansion-time.stderr b/src/test/ui/lint/expansion-time.stderr index 24e2733064e..b0fc1f8e5ee 100644 --- a/src/test/ui/lint/expansion-time.stderr +++ b/src/test/ui/lint/expansion-time.stderr @@ -12,14 +12,28 @@ note: the lint level is defined here LL | #[warn(meta_variable_misuse)] | ^^^^^^^^^^^^^^^^^^^^ +warning: missing fragment specifier + --> $DIR/expansion-time.rs:9:19 + | +LL | macro_rules! m { ($i) => {} } + | ^^ + | +note: the lint level is defined here + --> $DIR/expansion-time.rs:8:8 + | +LL | #[warn(missing_fragment_specifier)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 + warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable - --> $DIR/expansion-time.rs:10:7 + --> $DIR/expansion-time.rs:14:7 | LL | #[bench] | ^^^^^ | note: the lint level is defined here - --> $DIR/expansion-time.rs:8:8 + --> $DIR/expansion-time.rs:12:8 | LL | #[warn(soft_unstable)] | ^^^^^^^^^^^^^ @@ -33,10 +47,10 @@ LL | 2 | ^ | note: the lint level is defined here - --> $DIR/expansion-time.rs:25:8 + --> $DIR/expansion-time.rs:29:8 | LL | #[warn(incomplete_include)] | ^^^^^^^^^^^^^^^^^^ -warning: 3 warnings emitted +warning: 4 warnings emitted diff --git a/src/test/ui/macros/issue-39404.rs b/src/test/ui/macros/issue-39404.rs index 054958ba00b..2229f2c3900 100644 --- a/src/test/ui/macros/issue-39404.rs +++ b/src/test/ui/macros/issue-39404.rs @@ -2,5 +2,6 @@ macro_rules! m { ($i) => {} } //~^ ERROR missing fragment specifier +//~| WARN previously accepted fn main() {} diff --git a/src/test/ui/macros/issue-39404.stderr b/src/test/ui/macros/issue-39404.stderr index 645f06e59d8..d2f2a823c2a 100644 --- a/src/test/ui/macros/issue-39404.stderr +++ b/src/test/ui/macros/issue-39404.stderr @@ -3,6 +3,10 @@ error: missing fragment specifier | LL | macro_rules! m { ($i) => {} } | ^^ + | + = note: `#[deny(missing_fragment_specifier)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 error: aborting due to previous error diff --git a/src/test/ui/macros/macro-match-nonterminal.rs b/src/test/ui/macros/macro-match-nonterminal.rs index 6b023e41372..b23e5c71c03 100644 --- a/src/test/ui/macros/macro-match-nonterminal.rs +++ b/src/test/ui/macros/macro-match-nonterminal.rs @@ -2,6 +2,7 @@ macro_rules! test { ($a, $b) => { //~^ ERROR missing fragment //~| ERROR missing fragment + //~| WARN this was previously accepted () }; } diff --git a/src/test/ui/macros/macro-match-nonterminal.stderr b/src/test/ui/macros/macro-match-nonterminal.stderr index 334d62812cd..674ce3434aa 100644 --- a/src/test/ui/macros/macro-match-nonterminal.stderr +++ b/src/test/ui/macros/macro-match-nonterminal.stderr @@ -9,6 +9,10 @@ error: missing fragment specifier | LL | ($a, $b) => { | ^^ + | + = note: `#[deny(missing_fragment_specifier)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs index cf81f0480a2..80e2d7c6545 100644 --- a/src/test/ui/parser/macro/issue-33569.rs +++ b/src/test/ui/parser/macro/issue-33569.rs @@ -2,7 +2,6 @@ macro_rules! foo { { $+ } => { //~ ERROR expected identifier, found `+` //~^ ERROR missing fragment specifier $(x)(y) //~ ERROR expected one of: `*`, `+`, or `?` - //~^ ERROR attempted to repeat an expression containing no syntax variables } } diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr index f54efaa6996..b4d38d3ce48 100644 --- a/src/test/ui/parser/macro/issue-33569.stderr +++ b/src/test/ui/parser/macro/issue-33569.stderr @@ -4,23 +4,17 @@ error: expected identifier, found `+` LL | { $+ } => { | ^ -error: missing fragment specifier - --> $DIR/issue-33569.rs:2:8 - | -LL | { $+ } => { - | ^ - error: expected one of: `*`, `+`, or `?` --> $DIR/issue-33569.rs:4:13 | LL | $(x)(y) | ^^^ -error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth - --> $DIR/issue-33569.rs:4:10 +error: missing fragment specifier + --> $DIR/issue-33569.rs:2:8 | -LL | $(x)(y) - | ^^^ +LL | { $+ } => { + | ^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -- cgit 1.4.1-3-g733a5 From 64afdedfb87d471dcf1b757cea5f4b0b570176c1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 20 Dec 2020 23:37:24 +0100 Subject: Rework beautify_doc_string so that it returns a Symbol instead of a String --- compiler/rustc_ast/src/util/comments.rs | 58 ++++++++++++++------------- compiler/rustc_ast/src/util/comments/tests.rs | 14 +++---- compiler/rustc_save_analysis/src/lib.rs | 2 +- src/librustdoc/clean/types.rs | 2 +- 4 files changed, 39 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs index e97c8cc4562..5d994c90379 100644 --- a/compiler/rustc_ast/src/util/comments.rs +++ b/compiler/rustc_ast/src/util/comments.rs @@ -25,9 +25,8 @@ pub struct Comment { /// Makes a doc string more presentable to users. /// Used by rustdoc and perhaps other tools, but not by rustc. -pub fn beautify_doc_string(data: Symbol) -> String { - /// remove whitespace-only lines from the start/end of lines - fn vertical_trim(lines: Vec) -> Vec { +pub fn beautify_doc_string(data: Symbol) -> Symbol { + fn get_vertical_trim(lines: &[&str]) -> Option<(usize, usize)> { let mut i = 0; let mut j = lines.len(); // first line of all-stars should be omitted @@ -47,55 +46,58 @@ pub fn beautify_doc_string(data: Symbol) -> String { j -= 1; } - lines[i..j].to_vec() + if i != 0 || j != lines.len() { Some((i, j)) } else { None } } - /// remove a "[ \t]*\*" block from each line, if possible - fn horizontal_trim(lines: Vec) -> Vec { + fn get_horizontal_trim(lines: &[&str]) -> Option { let mut i = usize::MAX; - let mut can_trim = true; let mut first = true; - for line in &lines { + for line in lines { for (j, c) in line.chars().enumerate() { if j > i || !"* \t".contains(c) { - can_trim = false; - break; + return None; } if c == '*' { if first { i = j; first = false; } else if i != j { - can_trim = false; + return None; } break; } } if i >= line.len() { - can_trim = false; - } - if !can_trim { - break; + return None; } } + Some(i) + } - if can_trim { - lines.iter().map(|line| (&line[i + 1..line.len()]).to_string()).collect() + let data_s = data.as_str(); + if data_s.contains('\n') { + let mut lines = data_s.lines().collect::>(); + let mut changes = false; + let lines = if let Some((i, j)) = get_vertical_trim(&lines) { + changes = true; + // remove whitespace-only lines from the start/end of lines + &mut lines[i..j] } else { - lines + &mut lines + }; + if let Some(horizontal) = get_horizontal_trim(&lines) { + changes = true; + // remove a "[ \t]*\*" block from each line, if possible + for line in lines.iter_mut() { + *line = &line[horizontal + 1..]; + } + } + if changes { + return Symbol::intern(&lines.join("\n")); } } - - let data = data.as_str(); - if data.contains('\n') { - let lines = data.lines().map(|s| s.to_string()).collect::>(); - let lines = vertical_trim(lines); - let lines = horizontal_trim(lines); - lines.join("\n") - } else { - data.to_string() - } + data } /// Returns `None` if the first `col` chars of `s` contain a non-whitespace char. diff --git a/compiler/rustc_ast/src/util/comments/tests.rs b/compiler/rustc_ast/src/util/comments/tests.rs index e19198f863b..98ab653e45f 100644 --- a/compiler/rustc_ast/src/util/comments/tests.rs +++ b/compiler/rustc_ast/src/util/comments/tests.rs @@ -6,7 +6,7 @@ fn test_block_doc_comment_1() { with_default_session_globals(|| { let comment = "\n * Test \n ** Test\n * Test\n"; let stripped = beautify_doc_string(Symbol::intern(comment)); - assert_eq!(stripped, " Test \n* Test\n Test"); + assert_eq!(stripped.as_str(), " Test \n* Test\n Test"); }) } @@ -15,7 +15,7 @@ fn test_block_doc_comment_2() { with_default_session_globals(|| { let comment = "\n * Test\n * Test\n"; let stripped = beautify_doc_string(Symbol::intern(comment)); - assert_eq!(stripped, " Test\n Test"); + assert_eq!(stripped.as_str(), " Test\n Test"); }) } @@ -24,7 +24,7 @@ fn test_block_doc_comment_3() { with_default_session_globals(|| { let comment = "\n let a: *i32;\n *a = 5;\n"; let stripped = beautify_doc_string(Symbol::intern(comment)); - assert_eq!(stripped, " let a: *i32;\n *a = 5;"); + assert_eq!(stripped.as_str(), " let a: *i32;\n *a = 5;"); }) } @@ -32,12 +32,12 @@ fn test_block_doc_comment_3() { fn test_line_doc_comment() { with_default_session_globals(|| { let stripped = beautify_doc_string(Symbol::intern(" test")); - assert_eq!(stripped, " test"); + assert_eq!(stripped.as_str(), " test"); let stripped = beautify_doc_string(Symbol::intern("! test")); - assert_eq!(stripped, "! test"); + assert_eq!(stripped.as_str(), "! test"); let stripped = beautify_doc_string(Symbol::intern("test")); - assert_eq!(stripped, "test"); + assert_eq!(stripped.as_str(), "test"); let stripped = beautify_doc_string(Symbol::intern("!test")); - assert_eq!(stripped, "!test"); + assert_eq!(stripped.as_str(), "!test"); }) } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index eed9f2eb74d..056c0b3d9d5 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -825,7 +825,7 @@ impl<'tcx> SaveContext<'tcx> { for attr in attrs { if let Some(val) = attr.doc_str() { // FIXME: Should save-analysis beautify doc strings itself or leave it to users? - result.push_str(&beautify_doc_string(val)); + result.push_str(&beautify_doc_string(val).as_str()); result.push('\n'); } else if self.tcx.sess.check_name(attr, sym::doc) { if let Some(meta_list) = attr.meta_item_list() { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cd6eccea532..632aad75c26 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -617,7 +617,7 @@ impl Attributes { let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| { if let Some(value) = attr.doc_str() { trace!("got doc_str={:?}", value); - let value = beautify_doc_string(value); + let value = beautify_doc_string(value).to_string(); let kind = if attr.is_doc_comment() { DocFragmentKind::SugaredDoc } else { -- cgit 1.4.1-3-g733a5 From 42b77c709e98f8f75498e1b57eac20756f6c6ead Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 14 Nov 2020 21:50:53 +0000 Subject: Add some tests --- src/test/ui/pattern/usefulness/consts-opaque.rs | 39 ++++++++++++-- .../ui/pattern/usefulness/consts-opaque.stderr | 60 +++++++++++++--------- 2 files changed, 71 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/test/ui/pattern/usefulness/consts-opaque.rs b/src/test/ui/pattern/usefulness/consts-opaque.rs index f87f96e34fc..ca4fcd85bb6 100644 --- a/src/test/ui/pattern/usefulness/consts-opaque.rs +++ b/src/test/ui/pattern/usefulness/consts-opaque.rs @@ -25,10 +25,6 @@ enum Baz { impl Eq for Baz {} const BAZ: Baz = Baz::Baz1; -type Quux = fn(usize, usize) -> usize; -fn quux(a: usize, b: usize) -> usize { a + b } -const QUUX: Quux = quux; - fn main() { match FOO { FOO => {} @@ -106,9 +102,44 @@ fn main() { //~^ ERROR unreachable pattern } + type Quux = fn(usize, usize) -> usize; + fn quux(a: usize, b: usize) -> usize { a + b } + const QUUX: Quux = quux; + match QUUX { QUUX => {} QUUX => {} _ => {} } + + #[derive(PartialEq, Eq)] + struct Wrap(T); + const WRAPQUUX: Wrap = Wrap(quux); + + match WRAPQUUX { + WRAPQUUX => {} + WRAPQUUX => {} + Wrap(_) => {} + } + + match WRAPQUUX { + Wrap(_) => {} + WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer + //~^ ERROR unreachable pattern + } + + #[derive(PartialEq, Eq)] + enum WhoKnows { + Yay(T), + Nope, + }; + const WHOKNOWSQUUX: WhoKnows = WhoKnows::Yay(quux); + + match WHOKNOWSQUUX { + WHOKNOWSQUUX => {} + WhoKnows::Yay(_) => {} + WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer + //~^ ERROR unreachable pattern + WhoKnows::Nope => {} + } } diff --git a/src/test/ui/pattern/usefulness/consts-opaque.stderr b/src/test/ui/pattern/usefulness/consts-opaque.stderr index f10166d5a35..68451043cf5 100644 --- a/src/test/ui/pattern/usefulness/consts-opaque.stderr +++ b/src/test/ui/pattern/usefulness/consts-opaque.stderr @@ -1,11 +1,11 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:34:9 + --> $DIR/consts-opaque.rs:30:9 | LL | FOO => {} | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:36:9 + --> $DIR/consts-opaque.rs:32:9 | LL | _ => {} // should not be emitting unreachable warning | ^ @@ -17,19 +17,19 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:41:9 + --> $DIR/consts-opaque.rs:37:9 | LL | FOO_REF => {} | ^^^^^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:43:9 + --> $DIR/consts-opaque.rs:39:9 | LL | Foo(_) => {} // should not be emitting unreachable warning | ^^^^^^ warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:49:9 + --> $DIR/consts-opaque.rs:45:9 | LL | FOO_REF_REF => {} | ^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | FOO_REF_REF => {} = note: for more information, see issue #62411 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:57:9 + --> $DIR/consts-opaque.rs:53:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:57:9 + --> $DIR/consts-opaque.rs:53:9 | LL | Bar => {} | --- matches any value @@ -53,7 +53,7 @@ LL | BAR => {} // should not be emitting unreachable warning | ^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:60:9 + --> $DIR/consts-opaque.rs:56:9 | LL | Bar => {} | --- matches any value @@ -62,19 +62,19 @@ LL | _ => {} | ^ unreachable pattern error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:65:9 + --> $DIR/consts-opaque.rs:61:9 | LL | BAR => {} | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:67:9 + --> $DIR/consts-opaque.rs:63:9 | LL | Bar => {} // should not be emitting unreachable warning | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:69:9 + --> $DIR/consts-opaque.rs:65:9 | LL | Bar => {} // should not be emitting unreachable warning | --- matches any value @@ -83,76 +83,88 @@ LL | _ => {} | ^ unreachable pattern error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:74:9 + --> $DIR/consts-opaque.rs:70:9 | LL | BAR => {} | ^^^ error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:76:9 + --> $DIR/consts-opaque.rs:72:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:76:9 + --> $DIR/consts-opaque.rs:72:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:79:9 + --> $DIR/consts-opaque.rs:75:9 | LL | _ => {} // should not be emitting unreachable warning | ^ error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:84:9 + --> $DIR/consts-opaque.rs:80:9 | LL | BAZ => {} | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:86:9 + --> $DIR/consts-opaque.rs:82:9 | LL | Baz::Baz1 => {} // should not be emitting unreachable warning | ^^^^^^^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:88:9 + --> $DIR/consts-opaque.rs:84:9 | LL | _ => {} | ^ error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:94:9 + --> $DIR/consts-opaque.rs:90:9 | LL | BAZ => {} | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:96:9 + --> $DIR/consts-opaque.rs:92:9 | LL | _ => {} | ^ error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:101:9 + --> $DIR/consts-opaque.rs:97:9 | LL | BAZ => {} | ^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:103:9 + --> $DIR/consts-opaque.rs:99:9 | LL | Baz::Baz2 => {} // should not be emitting unreachable warning | ^^^^^^^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:105:9 + --> $DIR/consts-opaque.rs:101:9 | LL | _ => {} // should not be emitting unreachable warning | ^ -error: aborting due to 22 previous errors; 1 warning emitted +error: unreachable pattern + --> $DIR/consts-opaque.rs:127:9 + | +LL | WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer + | ^^^^^^^^ + +error: unreachable pattern + --> $DIR/consts-opaque.rs:141:9 + | +LL | WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer + | ^^^^^^^^^^^^ + +error: aborting due to 24 previous errors; 1 warning emitted -- cgit 1.4.1-3-g733a5 From 0fd4f8febf8fc0edb94481f35c44c7e9e6e1ba87 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 18 Dec 2020 23:35:44 -0500 Subject: Add a custom `Res` type - Don't make rustc_resolve::Res public; use a new type alias instead --- src/librustdoc/passes/collect_intra_doc_links.rs | 277 +++++++++++++---------- 1 file changed, 161 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index ea5bf94689b..1f1fb9754cf 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -10,17 +10,16 @@ use rustc_hir as hir; use rustc_hir::def::{ DefKind, Namespace::{self, *}, - PerNS, Res, + PerNS, }; use rustc_hir::def_id::{CrateNum, DefId}; -use rustc_middle::ty; +use rustc_middle::{bug, ty}; use rustc_resolve::ParentScope; use rustc_session::lint::{ builtin::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS}, Lint, }; use rustc_span::hygiene::MacroKind; -use rustc_span::symbol::sym; use rustc_span::symbol::Ident; use rustc_span::symbol::Symbol; use rustc_span::DUMMY_SP; @@ -28,6 +27,7 @@ use smallvec::{smallvec, SmallVec}; use std::borrow::Cow; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::mem; use std::ops::Range; @@ -61,6 +61,71 @@ impl<'a> From> for ErrorKind<'a> { } } +#[derive(Copy, Clone, Debug, Hash)] +enum Res { + Def(DefKind, DefId), + Primitive(PrimitiveType), +} + +type ResolveRes = rustc_hir::def::Res; + +impl Res { + fn descr(self) -> &'static str { + match self { + Res::Def(kind, id) => ResolveRes::Def(kind, id).descr(), + Res::Primitive(_) => "builtin type", + } + } + + fn article(self) -> &'static str { + match self { + Res::Def(kind, id) => ResolveRes::Def(kind, id).article(), + Res::Primitive(_) => "a", + } + } + + fn name(self, tcx: ty::TyCtxt<'_>) -> String { + match self { + Res::Def(_, id) => tcx.item_name(id).to_string(), + Res::Primitive(prim) => prim.as_str().to_string(), + } + } + + fn def_id(self) -> DefId { + self.opt_def_id().expect("called def_id() on a primitive") + } + + fn opt_def_id(self) -> Option { + match self { + Res::Def(_, id) => Some(id), + Res::Primitive(_) => None, + } + } + + fn as_hir_res(self) -> Option { + match self { + Res::Def(kind, id) => Some(rustc_hir::def::Res::Def(kind, id)), + // FIXME: maybe this should handle the subset of PrimitiveType that fits into hir::PrimTy? + Res::Primitive(_) => None, + } + } +} + +impl TryFrom for Res { + type Error = (); + + fn try_from(res: ResolveRes) -> Result { + use rustc_hir::def::Res::*; + match res { + Def(kind, id) => Ok(Res::Def(kind, id)), + PrimTy(prim) => Ok(Res::Primitive(PrimitiveType::from_hir(prim))), + // e.g. `#[derive]` + NonMacroAttr(..) | Err => Result::Err(()), + other => bug!("unrecognized res {:?}", other), + } + } +} + #[derive(Debug)] /// A link failed to resolve. enum ResolutionFailure<'a> { @@ -253,12 +318,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .enter_resolver(|resolver| { resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id) }) - .map(|(_, res)| res) - .unwrap_or(Res::Err); - if let Res::Err = ty_res { - return Err(no_res().into()); - } - let ty_res = ty_res.map_id(|_| panic!("unexpected node_id")); + .and_then(|(_, res)| res.try_into()) + .map_err(|()| no_res())?; + match ty_res { Res::Def(DefKind::Enum, did) => { if cx @@ -309,7 +371,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { /// lifetimes on `&'path` will work. fn resolve_primitive_associated_item( &self, - prim_ty: hir::PrimTy, + prim_ty: PrimitiveType, ns: Namespace, module_id: DefId, item_name: Symbol, @@ -317,7 +379,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ) -> Result<(Res, Option), ErrorKind<'path>> { let cx = self.cx; - PrimitiveType::from_hir(prim_ty) + prim_ty .impls(cx.tcx) .into_iter() .find_map(|&impl_| { @@ -336,21 +398,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }) .map(|out| { ( - Res::PrimTy(prim_ty), - Some(format!("{}#{}.{}", prim_ty.name(), out, item_str)), + Res::Primitive(prim_ty), + Some(format!("{}#{}.{}", prim_ty.as_str(), out, item_str)), ) }) }) .ok_or_else(|| { debug!( "returning primitive error for {}::{} in {} namespace", - prim_ty.name(), + prim_ty.as_str(), item_name, ns.descr() ); ResolutionFailure::NotResolved { module_id, - partial_res: Some(Res::PrimTy(prim_ty)), + partial_res: Some(Res::Primitive(prim_ty)), unresolved: item_str.into(), } .into() @@ -377,19 +439,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { false, ) { if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { - return Ok(res.map_id(|_| panic!("unexpected id"))); + return Ok(res.try_into().unwrap()); } } - if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) { - return Ok(res.map_id(|_| panic!("unexpected id"))); + if let Some(&res) = resolver.all_macros().get(&Symbol::intern(path_str)) { + return Ok(res.try_into().unwrap()); } debug!("resolving {} as a macro in the module {:?}", path_str, module_id); if let Ok((_, res)) = resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id) { // don't resolve builtins like `#[derive]` - if let Res::Def(..) = res { - let res = res.map_id(|_| panic!("unexpected node_id")); + if let Ok(res) = res.try_into() { return Ok(res); } } @@ -408,14 +469,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { /// Associated items will never be resolved by this function. fn resolve_path(&self, path_str: &str, ns: Namespace, module_id: DefId) -> Option { let result = self.cx.enter_resolver(|resolver| { - resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id) + resolver + .resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id) + .and_then(|(_, res)| res.try_into()) }); debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns); - match result.map(|(_, res)| res) { + match result { // resolver doesn't know about true and false so we'll have to resolve them // manually as bool - Ok(Res::Err) | Err(()) => is_bool_value(path_str, ns).map(|(_, res)| res), - Ok(res) => Some(res.map_id(|_| panic!("unexpected node_id"))), + Err(()) => is_bool_value(path_str, ns), + Ok(res) => Some(res), } } @@ -444,13 +507,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { return handle_variant(cx, res, extra_fragment); } // Not a trait item; just return what we found. - Res::PrimTy(ty) => { + Res::Primitive(ty) => { if extra_fragment.is_some() { return Err(ErrorKind::AnchorFailure( AnchorFailure::RustdocAnchorConflict(res), )); } - return Ok((res, Some(ty.name_str().to_owned()))); + return Ok((res, Some(ty.as_str().to_owned()))); } Res::Def(DefKind::Mod, _) => { return Ok((res, extra_fragment.clone())); @@ -483,7 +546,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // FIXME: are these both necessary? let ty_res = if let Some(ty_res) = resolve_primitive(&path_root, TypeNS) - .map(|(_, res)| res) .or_else(|| self.resolve_path(&path_root, TypeNS, module_id)) { ty_res @@ -502,7 +564,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }; let res = match ty_res { - Res::PrimTy(prim) => Some( + Res::Primitive(prim) => Some( self.resolve_primitive_associated_item(prim, ns, module_id, item_name, item_str), ), Res::Def( @@ -1068,9 +1130,9 @@ impl LinkCollector<'_, '_> { if matches!( disambiguator, None | Some(Disambiguator::Namespace(Namespace::TypeNS) | Disambiguator::Primitive) - ) && !matches!(res, Res::PrimTy(_)) + ) && !matches!(res, Res::Primitive(_)) { - if let Some((path, prim)) = resolve_primitive(path_str, TypeNS) { + if let Some(prim) = resolve_primitive(path_str, TypeNS) { // `prim@char` if matches!(disambiguator, Some(Disambiguator::Primitive)) { if fragment.is_some() { @@ -1085,7 +1147,7 @@ impl LinkCollector<'_, '_> { return None; } res = prim; - fragment = Some(path.as_str().to_string()); + fragment = Some(prim.name(self.cx.tcx)); } else { // `[char]` when a `char` module is in scope let candidates = vec![res, prim]; @@ -1111,8 +1173,8 @@ impl LinkCollector<'_, '_> { }; report_diagnostic(cx, BROKEN_INTRA_DOC_LINKS, &msg, &item, dox, &link_range, callback); }; - if let Res::PrimTy(..) = res { - match disambiguator { + match res { + Res::Primitive(_) => match disambiguator { Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => { Some(ItemLink { link: ori_link, link_text, did: None, fragment }) } @@ -1120,12 +1182,11 @@ impl LinkCollector<'_, '_> { report_mismatch(other, Disambiguator::Primitive); None } - } - } else { - debug!("intra-doc link to {} resolved to {:?}", path_str, res); + }, + Res::Def(kind, id) => { + debug!("intra-doc link to {} resolved to {:?}", path_str, res); - // Disallow e.g. linking to enums with `struct@` - if let Res::Def(kind, _) = res { + // Disallow e.g. linking to enums with `struct@` debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); match (self.kind_side_channel.take().map(|(kind, _)| kind).unwrap_or(kind), disambiguator) { | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const))) @@ -1144,27 +1205,26 @@ impl LinkCollector<'_, '_> { return None; } } - } - // item can be non-local e.g. when using #[doc(primitive = "pointer")] - if let Some((src_id, dst_id)) = res - .opt_def_id() - .and_then(|def_id| def_id.as_local()) - .and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id))) - { - use rustc_hir::def_id::LOCAL_CRATE; + // item can be non-local e.g. when using #[doc(primitive = "pointer")] + if let Some((src_id, dst_id)) = id + .as_local() + .and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id))) + { + use rustc_hir::def_id::LOCAL_CRATE; - let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id); - let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id); + let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id); + let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id); - if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src) - && !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst) - { - privacy_error(cx, &item, &path_str, dox, link_range); + if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src) + && !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst) + { + privacy_error(cx, &item, &path_str, dox, link_range); + } } + let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id)); + Some(ItemLink { link: ori_link, link_text, did: Some(id), fragment }) } - let id = clean::register_res(cx, res); - Some(ItemLink { link: ori_link, link_text, did: Some(id), fragment }) } } @@ -1296,16 +1356,18 @@ impl LinkCollector<'_, '_> { .and_then(|(res, fragment)| { // Constructors are picked up in the type namespace. match res { - Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => { + Res::Def(DefKind::Ctor(..), _) => { Err(ResolutionFailure::WrongNamespace(res, TypeNS)) } - _ => match (fragment, extra_fragment.clone()) { - (Some(fragment), Some(_)) => { - // Shouldn't happen but who knows? - Ok((res, Some(fragment))) + _ => { + match (fragment, extra_fragment.clone()) { + (Some(fragment), Some(_)) => { + // Shouldn't happen but who knows? + Ok((res, Some(fragment))) + } + (fragment, None) | (None, fragment) => Ok((res, fragment)), } - (fragment, None) | (None, fragment) => Ok((res, fragment)), - }, + } } }), }; @@ -1445,12 +1507,10 @@ impl Disambiguator { } } - /// WARNING: panics on `Res::Err` fn from_res(res: Res) -> Self { match res { Res::Def(kind, _) => Disambiguator::Kind(kind), - Res::PrimTy(_) => Disambiguator::Primitive, - _ => Disambiguator::Namespace(res.ns().expect("can't call `from_res` on Res::err")), + Res::Primitive(_) => Disambiguator::Primitive, } } @@ -1631,6 +1691,7 @@ fn resolution_failure( link_range: Option>, kinds: SmallVec<[ResolutionFailure<'_>; 3]>, ) { + let tcx = collector.cx.tcx; report_diagnostic( collector.cx, BROKEN_INTRA_DOC_LINKS, @@ -1639,16 +1700,9 @@ fn resolution_failure( dox, &link_range, |diag, sp| { - let item = |res: Res| { - format!( - "the {} `{}`", - res.descr(), - collector.cx.tcx.item_name(res.def_id()).to_string() - ) - }; + let item = |res: Res| format!("the {} `{}`", res.descr(), res.name(tcx),); let assoc_item_not_allowed = |res: Res| { - let def_id = res.def_id(); - let name = collector.cx.tcx.item_name(def_id); + let name = res.name(tcx); format!( "`{}` is {} {}, not a module or type, and cannot have associated items", name, @@ -1714,7 +1768,7 @@ fn resolution_failure( if let Some(module) = last_found_module { let note = if partial_res.is_some() { // Part of the link resolved; e.g. `std::io::nonexistent` - let module_name = collector.cx.tcx.item_name(module); + let module_name = tcx.item_name(module); format!("no item named `{}` in module `{}`", unresolved, module_name) } else { // None of the link resolved; e.g. `Notimported` @@ -1738,14 +1792,10 @@ fn resolution_failure( // Otherwise, it must be an associated item or variant let res = partial_res.expect("None case was handled by `last_found_module`"); - let diagnostic_name; - let (kind, name) = match res { - Res::Def(kind, def_id) => { - diagnostic_name = collector.cx.tcx.item_name(def_id).as_str(); - (Some(kind), &*diagnostic_name) - } - Res::PrimTy(ty) => (None, ty.name_str()), - _ => unreachable!("only ADTs and primitives are in scope at module level"), + let name = res.name(tcx); + let kind = match res { + Res::Def(kind, _) => Some(kind), + Res::Primitive(_) => None, }; let path_description = if let Some(kind) = kind { match kind { @@ -2003,50 +2053,45 @@ fn handle_variant( .parent(res.def_id()) .map(|parent| { let parent_def = Res::Def(DefKind::Enum, parent); - let variant = cx.tcx.expect_variant_res(res); + let variant = cx.tcx.expect_variant_res(res.as_hir_res().unwrap()); (parent_def, Some(format!("variant.{}", variant.ident.name))) }) .ok_or_else(|| ResolutionFailure::NoParentItem.into()) } -// FIXME: At this point, this is basically a copy of the PrimitiveTypeTable -const PRIMITIVES: &[(Symbol, Res)] = &[ - (sym::u8, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U8))), - (sym::u16, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U16))), - (sym::u32, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U32))), - (sym::u64, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U64))), - (sym::u128, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U128))), - (sym::usize, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::Usize))), - (sym::i8, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I8))), - (sym::i16, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I16))), - (sym::i32, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I32))), - (sym::i64, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I64))), - (sym::i128, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I128))), - (sym::isize, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::Isize))), - (sym::f32, Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F32))), - (sym::f64, Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F64))), - (sym::str, Res::PrimTy(hir::PrimTy::Str)), - (sym::bool, Res::PrimTy(hir::PrimTy::Bool)), - (sym::char, Res::PrimTy(hir::PrimTy::Char)), -]; - /// Resolve a primitive type or value. -fn resolve_primitive(path_str: &str, ns: Namespace) -> Option<(Symbol, Res)> { - is_bool_value(path_str, ns).or_else(|| { - if ns == TypeNS { - // FIXME: this should be replaced by a lookup in PrimitiveTypeTable - let maybe_primitive = Symbol::intern(path_str); - PRIMITIVES.iter().find(|x| x.0 == maybe_primitive).copied() - } else { - None - } - }) +fn resolve_primitive(path_str: &str, ns: Namespace) -> Option { + if ns != TypeNS { + return None; + } + use PrimitiveType::*; + let prim = match path_str { + "u8" => U8, + "u16" => U16, + "u32" => U32, + "u64" => U64, + "u128" => U128, + "usize" => Usize, + "i8" => I8, + "i16" => I16, + "i32" => I32, + "i64" => I64, + "i128" => I128, + "isize" => Isize, + "f32" => F32, + "f64" => F64, + "str" => Str, + "bool" | "true" | "false" => Bool, + "char" => Char, + _ => return None, + }; + Some(Res::Primitive(prim)) } /// Resolve a primitive value. -fn is_bool_value(path_str: &str, ns: Namespace) -> Option<(Symbol, Res)> { +fn is_bool_value(path_str: &str, ns: Namespace) -> Option { if ns == TypeNS && (path_str == "true" || path_str == "false") { - Some((sym::bool, Res::PrimTy(hir::PrimTy::Bool))) + Some(Res::Primitive(PrimitiveType::Bool)) } else { None } -- cgit 1.4.1-3-g733a5 From 4092891a8f2ca5947d5312e1949ecf701a4f25de Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 19 Dec 2020 01:52:43 -0500 Subject: Fix intra-doc links for non-path primitives This does *not* currently work for associated items that are auto-implemented by the compiler (e.g. `never::eq`), because they aren't present in the source code. I plan to fix this in a follow-up PR. --- src/librustdoc/passes/collect_intra_doc_links.rs | 54 ++++++++++--------- src/test/rustdoc/intra-doc/non-path-primitives.rs | 66 +++++++++++++++++++++++ 2 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 src/test/rustdoc/intra-doc/non-path-primitives.rs (limited to 'src') diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 1f1fb9754cf..b8db0d5a4d6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -475,9 +475,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }); debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns); match result { - // resolver doesn't know about true and false so we'll have to resolve them + // resolver doesn't know about true, false, and types that aren't paths (e.g. `()`) // manually as bool - Err(()) => is_bool_value(path_str, ns), + Err(()) => resolve_primitive(path_str, ns), Ok(res) => Some(res), } } @@ -1020,7 +1020,7 @@ impl LinkCollector<'_, '_> { (link.trim(), None) }; - if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !".contains(ch))) { + if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*()[]&;".contains(ch))) { return None; } @@ -1108,9 +1108,8 @@ impl LinkCollector<'_, '_> { // Sanity check to make sure we don't have any angle brackets after stripping generics. assert!(!path_str.contains(['<', '>'].as_slice())); - // The link is not an intra-doc link if it still contains commas or spaces after - // stripping generics. - if path_str.contains([',', ' '].as_slice()) { + // The link is not an intra-doc link if it still contains spaces after stripping generics. + if path_str.contains(' ') { return None; } @@ -1476,8 +1475,11 @@ impl Disambiguator { ("!", DefKind::Macro(MacroKind::Bang)), ]; for &(suffix, kind) in &suffixes { - if link.ends_with(suffix) { - return Ok((Kind(kind), link.trim_end_matches(suffix))); + if let Some(link) = link.strip_suffix(suffix) { + // Avoid turning `!` or `()` into an empty string + if !link.is_empty() { + return Ok((Kind(kind), link)); + } } } Err(()) @@ -2066,37 +2068,37 @@ fn resolve_primitive(path_str: &str, ns: Namespace) -> Option { } use PrimitiveType::*; let prim = match path_str { - "u8" => U8, - "u16" => U16, - "u32" => U32, - "u64" => U64, - "u128" => U128, - "usize" => Usize, + "isize" => Isize, "i8" => I8, "i16" => I16, "i32" => I32, "i64" => I64, "i128" => I128, - "isize" => Isize, + "usize" => Usize, + "u8" => U8, + "u16" => U16, + "u32" => U32, + "u64" => U64, + "u128" => U128, "f32" => F32, "f64" => F64, - "str" => Str, - "bool" | "true" | "false" => Bool, "char" => Char, + "bool" | "true" | "false" => Bool, + "str" => Str, + "slice" | "&[]" | "[T]" => Slice, + "array" | "[]" | "[T;N]" => Array, + "tuple" | "(,)" => Tuple, + "unit" | "()" => Unit, + "pointer" | "*" | "*const" | "*mut" => RawPointer, + "reference" | "&" | "&mut" => Reference, + "fn" => Fn, + "never" | "!" => Never, _ => return None, }; + debug!("resolved primitives {:?}", prim); Some(Res::Primitive(prim)) } -/// Resolve a primitive value. -fn is_bool_value(path_str: &str, ns: Namespace) -> Option { - if ns == TypeNS && (path_str == "true" || path_str == "false") { - Some(Res::Primitive(PrimitiveType::Bool)) - } else { - None - } -} - fn strip_generics_from_path(path_str: &str) -> Result> { let mut stripped_segments = vec![]; let mut path = path_str.chars().peekable(); diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs new file mode 100644 index 00000000000..83d081824ff --- /dev/null +++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs @@ -0,0 +1,66 @@ +// ignore-tidy-linelength +#![crate_name = "foo"] +#![deny(broken_intra_doc_links)] + +// @has foo/index.html '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'slice::rotate_left' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'X' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'Y' +//! [slice::rotate_left] +//! [X]([T]::rotate_left) +//! [Y](&[]::rotate_left) +// These don't work because markdown syntax doesn't allow it. +// [[T]::rotate_left] +//! [&[]::rotate_left] + +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'array::map' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'X' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'Y' +//! [array::map] +//! [X]([]::map) +//! [Y]([T;N]::map) +// These don't work because markdown syntax doesn't allow it. +// [Z]([T; N]::map) +//! [`[T; N]::map`] +//! [[]::map] +// [Z][] +// +// [Z]: [T; N]::map + +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' 'pointer::is_null' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*const::is_null' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*mut::is_null' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*::is_null' +//! [pointer::is_null] +//! [*const::is_null] +//! [*mut::is_null] +//! [*::is_null] + +// FIXME: Associated items on some primitives aren't working, because the impls +// are part of the compiler instead of being part of the source code. + +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.unit.html"]' 'unit' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.unit.html"]' '()' +//! [unit] +//! [()] + +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.tuple.html"]' 'tuple' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.tuple.html"]' 'X' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.tuple.html"]' '(,)' +//! [tuple] +//! [X]((,)) +//! [(,)] + +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' 'reference' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' '&' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' '&mut' +//! [reference] +//! [&] +//! [&mut] + +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.fn.html"]' 'fn' +//! [fn] + +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.never.html"]' 'never' +// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.never.html"]' '!' +//! [never] +//! [!] -- cgit 1.4.1-3-g733a5 From a448f88b6986208c0da97940c86189f78a865068 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 14 Dec 2020 13:50:59 -0500 Subject: Utilize PGO for rustc linux dist builds This implements support for applying PGO to the rustc compilation step (not standard library or any tooling, including rustdoc). Expanding PGO to more tools is not terribly difficult but will involve more work and greater CI time commitment. For the same reason of avoiding greater time commitment, this currently avoids implementing for platforms outside of x86_64-unknown-linux-gnu, though in practice it should be quite simple to extend over time to more platforms. The initial implementation is intentionally minimal here to avoid too much work investment before we start seeing wins for a subset of Rust users. The choice of workloads to profile here is somewhat arbitrary, but the general rationale was to aim for a small set that largely avoided time regressions on perf.rust-lang.org's full suite of crates. The set chosen is libcore, cargo (and its dependencies), and a few ad-hoc stress tests from perf.rlo. The stress tests are arguably the most controversial, but they benefit those cases (avoiding regressions) and do not really remove wins from other benchmarks. The primary next step after this PR lands is to implement support for PGO in LLVM. It is unclear whether we can afford a full LLVM rebuild in CI, though, so the approach taken there may need to be more staggered. rustc-only PGO seems well affordable on linux at least, giving us up to 20% wall time wins on some crates for 15 minutes of extra CI time (1 hour up from 45 minutes). The PGO data is uploaded to allow others to reuse it if attempting to reproduce the CI build or potentially, in the future, on other platforms where an off-by-one strategy is used for dist builds at minimal performance cost. --- src/bootstrap/builder.rs | 1 + src/bootstrap/compile.rs | 37 +++++++++++- src/bootstrap/config.rs | 9 +++ src/bootstrap/dist.rs | 69 ++++++++++++++++++++++ src/bootstrap/flags.rs | 7 +++ .../host-x86_64/dist-x86_64-linux/Dockerfile | 9 ++- src/ci/pgo.sh | 47 +++++++++++++++ src/tools/build-manifest/src/main.rs | 1 + 8 files changed, 176 insertions(+), 4 deletions(-) create mode 100755 src/ci/pgo.sh (limited to 'src') diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 9af79e20630..05b1035d843 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -471,6 +471,7 @@ impl<'a> Builder<'a> { dist::RustDev, dist::Extended, dist::BuildManifest, + dist::ReproducibleArtifacts, ), Kind::Install => describe!( install::Docs, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index fbebb26c746..091bd2a1c5a 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -501,6 +501,41 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build"); rustc_cargo(builder, &mut cargo, target); + if builder.config.rust_profile_use.is_some() + && builder.config.rust_profile_generate.is_some() + { + panic!("Cannot use and generate PGO profiles at the same time"); + } + + let is_collecting = if let Some(path) = &builder.config.rust_profile_generate { + if compiler.stage == 1 { + cargo.rustflag(&format!("-Cprofile-generate={}", path)); + // Apparently necessary to avoid overflowing the counters during + // a Cargo build profile + cargo.rustflag("-Cllvm-args=-vp-counters-per-site=4"); + true + } else { + false + } + } else if let Some(path) = &builder.config.rust_profile_use { + if compiler.stage == 1 { + cargo.rustflag(&format!("-Cprofile-use={}", path)); + cargo.rustflag("-Cllvm-args=-pgo-warn-missing-function"); + true + } else { + false + } + } else { + false + }; + if is_collecting { + // Ensure paths to Rust sources are relative, not absolute. + cargo.rustflag(&format!( + "-Cllvm-args=-static-func-strip-dirname-prefix={}", + builder.config.src.components().count() + )); + } + builder.info(&format!( "Building stage{} compiler artifacts ({} -> {})", compiler.stage, &compiler.host, target @@ -752,7 +787,7 @@ fn copy_codegen_backends_to_sysroot( // Here we're looking for the output dylib of the `CodegenBackend` step and // we're copying that into the `codegen-backends` folder. let dst = builder.sysroot_codegen_backends(target_compiler); - t!(fs::create_dir_all(&dst)); + t!(fs::create_dir_all(&dst), dst); if builder.config.dry_run { return; diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index fb2c6d1f92a..58dc5f7af79 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -133,6 +133,8 @@ pub struct Config { pub rust_thin_lto_import_instr_limit: Option, pub rust_remap_debuginfo: bool, pub rust_new_symbol_mangling: bool, + pub rust_profile_use: Option, + pub rust_profile_generate: Option, pub build: TargetSelection, pub hosts: Vec, @@ -494,6 +496,8 @@ struct Rust { llvm_libunwind: Option, control_flow_guard: Option, new_symbol_mangling: Option, + profile_generate: Option, + profile_use: Option, } /// TOML representation of how each build target is configured. @@ -871,6 +875,11 @@ impl Config { config.rust_codegen_units = rust.codegen_units.map(threads_from_config); config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); + config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use); + config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate); + } else { + config.rust_profile_use = flags.rust_profile_use; + config.rust_profile_generate = flags.rust_profile_generate; } if let Some(t) = toml.target { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index b1bb97cf83b..823f62fa4a3 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2664,3 +2664,72 @@ impl Step for BuildManifest { distdir(builder).join(format!("{}-{}.tar.gz", name, self.target.triple)) } } + +/// Tarball containing artifacts necessary to reproduce the build of rustc. +/// +/// Currently this is the PGO profile data. +/// +/// Should not be considered stable by end users. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct ReproducibleArtifacts { + pub target: TargetSelection, +} + +impl Step for ReproducibleArtifacts { + type Output = Option; + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("reproducible") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(ReproducibleArtifacts { target: run.target }); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let name = pkgname(builder, "reproducible-artifacts"); + let tmp = tmpdir(builder); + + // Prepare the image. + let image = tmp.join("reproducible-artifacts-image"); + let _ = fs::remove_dir_all(&image); + + if let Some(path) = &builder.config.rust_profile_use { + builder.install(std::path::Path::new(path), &image, 0o644); + } else { + return None; + } + + // Prepare the overlay. + let overlay = tmp.join("reproducible-artifacts-overlay"); + let _ = fs::remove_dir_all(&overlay); + builder.create_dir(&overlay); + builder.create(&overlay.join("version"), &builder.rust_version()); + for file in &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"] { + builder.install(&builder.src.join(file), &overlay, 0o644); + } + + // Create the final tarball. + let mut cmd = rust_installer(builder); + cmd.arg("generate") + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=reproducible-artifacts installed.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, self.target.triple)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--component-name=reproducible-artifacts"); + + builder.run(&mut cmd); + Some(distdir(builder).join(format!("{}-{}.tar.gz", name, self.target.triple))) + } +} diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 5a8096674c6..d6a45f1c170 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -68,6 +68,9 @@ pub struct Flags { pub deny_warnings: Option, pub llvm_skip_rebuild: Option, + + pub rust_profile_use: Option, + pub rust_profile_generate: Option, } pub enum Subcommand { @@ -219,6 +222,8 @@ To learn more about a subcommand, run `./x.py -h`", VALUE overrides the skip-rebuild option in config.toml.", "VALUE", ); + opts.optopt("", "rust-profile-generate", "rustc error format", "FORMAT"); + opts.optopt("", "rust-profile-use", "rustc error format", "FORMAT"); // We can't use getopt to parse the options until we have completed specifying which // options are valid, but under the current implementation, some options are conditional on @@ -674,6 +679,8 @@ Arguments: color: matches .opt_get_default("color", Color::Auto) .expect("`color` should be `always`, `never`, or `auto`"), + rust_profile_use: matches.opt_str("rust-profile-use"), + rust_profile_generate: matches.opt_str("rust-profile-generate"), } } } diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 14700aeea05..d1b4bbf7fff 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -85,6 +85,8 @@ ENV CC=clang CXX=clang++ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh +ENV PGO_HOST=x86_64-unknown-linux-gnu + ENV HOSTS=x86_64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ @@ -98,9 +100,10 @@ ENV RUST_CONFIGURE_ARGS \ --set llvm.thin-lto=true \ --set llvm.ninja=false \ --set rust.jemalloc -ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS \ - --include-default-paths \ - src/tools/build-manifest +ENV SCRIPT ../src/ci/pgo.sh python2.7 ../x.py dist \ + --host $HOSTS --target $HOSTS \ + --include-default-paths \ + src/tools/build-manifest ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs diff --git a/src/ci/pgo.sh b/src/ci/pgo.sh new file mode 100755 index 00000000000..13b8ca91f89 --- /dev/null +++ b/src/ci/pgo.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +set -euxo pipefail + +rm -rf /tmp/rustc-pgo + +python2.7 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \ + --stage 2 library/std --rust-profile-generate=/tmp/rustc-pgo + +./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \ + --crate-type=lib ../library/core/src/lib.rs + +# Download and build a single-file stress test benchmark on perf.rust-lang.org. +function pgo_perf_benchmark { + local PERF=e095f5021bf01cf3800f50b3a9f14a9683eb3e4e + local github_prefix=https://raw.githubusercontent.com/rust-lang/rustc-perf/$PERF + local name=$1 + curl -o /tmp/$name.rs $github_prefix/collector/benchmarks/$name/src/lib.rs + ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 --crate-type=lib /tmp/$name.rs +} + +pgo_perf_benchmark externs +pgo_perf_benchmark ctfe-stress-4 + +cp -pri ../src/tools/cargo /tmp/cargo + +# Build cargo (with some flags) +function pgo_cargo { + RUSTC=./build/$PGO_HOST/stage2/bin/rustc \ + ./build/$PGO_HOST/stage0/bin/cargo $@ \ + --manifest-path /tmp/cargo/Cargo.toml +} + +# Build a couple different variants of Cargo +CARGO_INCREMENTAL=1 pgo_cargo check +echo 'pub fn barbarbar() {}' >> /tmp/cargo/src/cargo/lib.rs +CARGO_INCREMENTAL=1 pgo_cargo check +touch /tmp/cargo/src/cargo/lib.rs +CARGO_INCREMENTAL=1 pgo_cargo check +pgo_cargo build --release + +# Merge the profile data we gathered +./build/$PGO_HOST/llvm/bin/llvm-profdata \ + merge -o /tmp/rustc-pgo.profdata /tmp/rustc-pgo + +# This produces the actual final set of artifacts. +$@ --rust-profile-use=/tmp/rustc-pgo.profdata diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 0462efaa9b0..73a4cbd0792 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -299,6 +299,7 @@ impl Builder { let mut package = |name, targets| self.package(name, &mut manifest.pkg, targets); package("rustc", HOSTS); package("rustc-dev", HOSTS); + package("reproducible-artifacts", HOSTS); package("rustc-docs", HOSTS); package("cargo", HOSTS); package("rust-mingw", MINGW); -- cgit 1.4.1-3-g733a5 From 5e6dc927f7a935874a08c2c3913f24295711d8f2 Mon Sep 17 00:00:00 2001 From: ThePuzzlemaker Date: Tue, 22 Dec 2020 13:25:37 -0600 Subject: Add regression test for #80179 --- src/test/ui/fn/issue-80179.rs | 27 +++++++++++++++++++++++++++ src/test/ui/fn/issue-80179.stderr | 21 +++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/test/ui/fn/issue-80179.rs create mode 100644 src/test/ui/fn/issue-80179.stderr (limited to 'src') diff --git a/src/test/ui/fn/issue-80179.rs b/src/test/ui/fn/issue-80179.rs new file mode 100644 index 00000000000..7609b1525cc --- /dev/null +++ b/src/test/ui/fn/issue-80179.rs @@ -0,0 +1,27 @@ +// Functions with a type placeholder `_` as the return type should +// show a function pointer suggestion when given a function item +// and suggest how to return closures correctly from a function. +// This is a regression test of #80179 + +fn returns_i32() -> i32 { + 0 +} + +fn returns_fn_ptr() -> _ { +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121] +//~| NOTE not allowed in type signatures +//~| HELP replace with the correct return type +//~| SUGGESTION fn() -> i32 + returns_i32 +} + +fn returns_closure() -> _ { +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121] +//~| NOTE not allowed in type signatures +//~| HELP consider using an `Fn`, `FnMut`, or `FnOnce` trait bound +//~| NOTE for more information on `Fn` traits and closure types, see +// https://doc.rust-lang.org/book/ch13-01-closures.html + || 0 +} + +fn main() {} diff --git a/src/test/ui/fn/issue-80179.stderr b/src/test/ui/fn/issue-80179.stderr new file mode 100644 index 00000000000..63571e71b34 --- /dev/null +++ b/src/test/ui/fn/issue-80179.stderr @@ -0,0 +1,21 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/issue-80179.rs:10:24 + | +LL | fn returns_fn_ptr() -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `fn() -> i32` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/issue-80179.rs:18:25 + | +LL | fn returns_closure() -> _ { + | ^ not allowed in type signatures + | + = help: consider using an `Fn`, `FnMut`, or `FnOnce` trait bound + = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. -- cgit 1.4.1-3-g733a5 From 32716814a2d9a26674503122d0b91aca39e5ab28 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Wed, 23 Dec 2020 00:00:00 +0000 Subject: Ignore proc-macros when assembling rustc libdir --- src/bootstrap/compile.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index fbebb26c746..81a5b4c8960 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -7,6 +7,7 @@ //! goes along from the output of the previous stage. use std::borrow::Cow; +use std::collections::HashSet; use std::env; use std::fs; use std::io::prelude::*; @@ -956,13 +957,26 @@ impl Step for Assemble { builder.info(&format!("Assembling stage{} compiler ({})", stage, host)); // Link in all dylibs to the libdir + let stamp = librustc_stamp(builder, build_compiler, target_compiler.host); + let proc_macros = builder + .read_stamp_file(&stamp) + .into_iter() + .filter_map(|(path, dependency_type)| { + if dependency_type == DependencyType::Host { + Some(path.file_name().unwrap().to_owned().into_string().unwrap()) + } else { + None + } + }) + .collect::>(); + let sysroot = builder.sysroot(target_compiler); let rustc_libdir = builder.rustc_libdir(target_compiler); t!(fs::create_dir_all(&rustc_libdir)); let src_libdir = builder.sysroot_libdir(build_compiler, host); for f in builder.read_dir(&src_libdir) { let filename = f.file_name().into_string().unwrap(); - if is_dylib(&filename) { + if is_dylib(&filename) && !proc_macros.contains(&filename) { builder.copy(&f.path(), &rustc_libdir.join(&filename)); } } -- cgit 1.4.1-3-g733a5 From a6d377d56560350976ccb46f33ae14ad65eb9372 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 22 Dec 2020 16:33:36 -0800 Subject: Include rustdoc in the compiler docs index. --- src/bootstrap/doc.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 8cacc2512ef..30a8229036f 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -628,6 +628,8 @@ impl Step for Rustdoc { cargo.arg("-p").arg("rustdoc"); cargo.rustdocflag("--document-private-items"); + cargo.rustdocflag("--enable-index-page"); + cargo.rustdocflag("-Zunstable-options"); builder.run(&mut cargo.into()); } } -- cgit 1.4.1-3-g733a5 From 530c33cd5fd92c17e44c692bbe7a4006d57340f8 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 22 Dec 2020 20:22:47 -0500 Subject: Fix elided lifetimes shown as `'_` on async functions --- src/librustdoc/clean/mod.rs | 25 +++++++++++++++++++++++-- src/test/rustdoc/async-fn.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 07255168d06..e7fdf76ba79 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -635,6 +635,18 @@ impl Clean for hir::Generics<'_> { _ => false, } } + /// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`. + /// + /// See [`lifetime_to_generic_param`] in [`rustc_ast_lowering`] for more information. + /// + /// [`lifetime_to_generic_param`]: rustc_ast_lowering::LoweringContext::lifetime_to_generic_param + fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool { + match param.kind { + hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided } => true, + _ => false, + } + } + let impl_trait_params = self .params .iter() @@ -653,7 +665,7 @@ impl Clean for hir::Generics<'_> { .collect::>(); let mut params = Vec::with_capacity(self.params.len()); - for p in self.params.iter().filter(|p| !is_impl_trait(p)) { + for p in self.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { let p = p.clean(cx); params.push(p); } @@ -1433,7 +1445,16 @@ impl Clean for hir::Ty<'_> { TyKind::Never => Never, TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)), TyKind::Rptr(ref l, ref m) => { - let lifetime = if l.is_elided() { None } else { Some(l.clean(cx)) }; + // There are two times a `Fresh` lifetime can be created: + // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`. + // 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`. + // See commit 749349fc9f7b12f212bca9ba2297e463328cb701 for more information. + // Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it. + // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though; + // there's no case where it could cause the function to fail to compile. + let elided = + l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_))); + let lifetime = if elided { None } else { Some(l.clean(cx)) }; BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) } } TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index e7a7d1831f7..7a673b9f670 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -1,3 +1,4 @@ +// ignore-tidy-linelength // edition:2018 #![feature(min_const_generics)] @@ -52,3 +53,31 @@ pub trait Trait {} // @has async_fn/fn.const_generics.html // @has - '//pre[@class="rust fn"]' 'pub async fn const_generics(_: impl Trait)' pub async fn const_generics(_: impl Trait) {} + +// test that elided lifetimes are properly elided and not displayed as `'_` +// regression test for #63037 +// @has async_fn/fn.elided.html +// @has - '//pre[@class="rust fn"]' 'pub async fn elided(foo: &str) -> &str' +pub async fn elided(foo: &str) -> &str {} +// This should really be shown as written, but for implementation reasons it's difficult. +// See `impl Clean for TyKind::Rptr`. +// @has async_fn/fn.user_elided.html +// @has - '//pre[@class="rust fn"]' 'pub async fn user_elided(foo: &str) -> &str' +pub async fn user_elided(foo: &'_ str) -> &str {} +// @has async_fn/fn.static_trait.html +// @has - '//pre[@class="rust fn"]' 'pub async fn static_trait(foo: &str) -> Box' +pub async fn static_trait(foo: &str) -> Box {} +// @has async_fn/fn.lifetime_for_trait.html +// @has - '//pre[@class="rust fn"]' "pub async fn lifetime_for_trait(foo: &str) -> Box" +pub async fn lifetime_for_trait(foo: &str) -> Box {} + +struct AsyncFdReadyGuard<'a, T> { x: &'a T } + +impl Foo { + // @has async_fn/struct.Foo.html + // @has - '//h4[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator' + pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator {} + // taken from `tokio` as an example of a method that was particularly bad before + // @has - '//h4[@class="method"]' "pub async fn readable(&self) -> Result, ()>" + pub async fn readable(&self) -> Result, ()> {} +} -- cgit 1.4.1-3-g733a5 From e8a564edc0a0c19633039848c68d5f81fcfcc00d Mon Sep 17 00:00:00 2001 From: Victor Ding Date: Wed, 23 Dec 2020 12:17:45 +1100 Subject: Add a test that rustc compiles and links separately --- src/test/run-make-fulldeps/separate-link/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/run-make-fulldeps/separate-link/Makefile (limited to 'src') diff --git a/src/test/run-make-fulldeps/separate-link/Makefile b/src/test/run-make-fulldeps/separate-link/Makefile new file mode 100644 index 00000000000..060484e89f9 --- /dev/null +++ b/src/test/run-make-fulldeps/separate-link/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: + echo 'fn main(){}' | $(RUSTC) -Z no-link - + $(RUSTC) -Z link-only $(TMPDIR)/rust_out.rlink + $(call RUN,rust_out) -- cgit 1.4.1-3-g733a5 From e89801553ddbaccdeb2eac4db08900edb51ac7ff Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Tue, 22 Dec 2020 19:17:59 +0100 Subject: Revert "Pass Clippy args also trough RUSTFLAGS" --- Cargo.toml | 1 + README.md | 1 + src/driver.rs | 116 ++++++++++++++----------------------------------------- src/main.rs | 98 +++++++--------------------------------------- tests/dogfood.rs | 2 +- 5 files changed, 47 insertions(+), 171 deletions(-) (limited to 'src') diff --git a/Cargo.toml b/Cargo.toml index 7f9d22e594b..a765390c603 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ publish = false [[bin]] name = "cargo-clippy" +test = false path = "src/main.rs" [[bin]] diff --git a/README.md b/README.md index dc931963726..aaa55e11c7d 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ the lint(s) you are interested in: ```terminal cargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::... ``` +Note that if you've run clippy before, this may only take effect after you've modified a file or ran `cargo clean`. ### Specifying the minimum supported Rust version diff --git a/src/driver.rs b/src/driver.rs index 40f1b802e60..e490ee54c0b 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -1,6 +1,5 @@ #![feature(rustc_private)] #![feature(once_cell)] -#![feature(bool_to_option)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] @@ -20,7 +19,6 @@ use rustc_tools_util::VersionInfo; use std::borrow::Cow; use std::env; -use std::iter; use std::lazy::SyncLazy; use std::ops::Deref; use std::panic; @@ -49,6 +47,20 @@ fn arg_value<'a, T: Deref>( None } +#[test] +fn test_arg_value() { + let args = &["--bar=bar", "--foobar", "123", "--foo"]; + + assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None); + assert_eq!(arg_value(args, "--bar", |_| false), None); + assert_eq!(arg_value(args, "--bar", |_| true), Some("bar")); + assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar")); + assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None); + assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None); + assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123")); + assert_eq!(arg_value(args, "--foo", |_| true), None); +} + struct DefaultCallbacks; impl rustc_driver::Callbacks for DefaultCallbacks {} @@ -170,28 +182,6 @@ fn toolchain_path(home: Option, toolchain: Option) -> Option(args: &mut Vec, clippy_args: I) -where - T: AsRef, - U: AsRef + ?Sized + 'a, - I: Iterator + Clone, -{ - let args_iter = clippy_args.map(AsRef::as_ref); - let args_count = args_iter.clone().count(); - - if args_count > 0 { - if let Some(start) = args.windows(args_count).enumerate().find_map(|(current, window)| { - window - .iter() - .map(AsRef::as_ref) - .eq(args_iter.clone()) - .then_some(current) - }) { - args.drain(start..start + args_count); - } - } -} - #[allow(clippy::too_many_lines)] pub fn main() { rustc_driver::init_rustc_env_logger(); @@ -288,9 +278,20 @@ pub fn main() { args.extend(vec!["--sysroot".into(), sys_root]); }; - let clippy_args = env::var("CLIPPY_ARGS").unwrap_or_default(); - let clippy_args = clippy_args.split_whitespace(); - let no_deps = clippy_args.clone().any(|flag| flag == "--no-deps"); + let mut no_deps = false; + let clippy_args = env::var("CLIPPY_ARGS") + .unwrap_or_default() + .split("__CLIPPY_HACKERY__") + .filter_map(|s| match s { + "" => None, + "--no-deps" => { + no_deps = true; + None + }, + _ => Some(s.to_string()), + }) + .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]) + .collect::>(); // We enable Clippy if one of the following conditions is met // - IF Clippy is run on its test suite OR @@ -303,11 +304,7 @@ pub fn main() { let clippy_enabled = clippy_tests_set || (!cap_lints_allow && (!no_deps || in_primary_package)); if clippy_enabled { - remove_clippy_args(&mut args, iter::once("--no-deps")); - args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]); - } else { - // Remove all flags passed through RUSTFLAGS if Clippy is not enabled. - remove_clippy_args(&mut args, clippy_args); + args.extend(clippy_args); } let mut clippy = ClippyCallbacks; @@ -318,58 +315,3 @@ pub fn main() { rustc_driver::RunCompiler::new(&args, callbacks).run() })) } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_arg_value() { - let args = &["--bar=bar", "--foobar", "123", "--foo"]; - - assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None); - assert_eq!(arg_value(args, "--bar", |_| false), None); - assert_eq!(arg_value(args, "--bar", |_| true), Some("bar")); - assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar")); - assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None); - assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None); - assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123")); - assert_eq!(arg_value(args, "--foo", |_| true), None); - } - - #[test] - fn removes_clippy_args_from_start() { - let mut args = vec!["-D", "clippy::await_holding_lock", "--cfg", r#"feature="some_feat""#]; - let clippy_args = ["-D", "clippy::await_holding_lock"].iter(); - - remove_clippy_args(&mut args, clippy_args); - assert_eq!(args, &["--cfg", r#"feature="some_feat""#]); - } - - #[test] - fn removes_clippy_args_from_end() { - let mut args = vec!["-Zui-testing", "-A", "clippy::empty_loop", "--no-deps"]; - let clippy_args = ["-A", "clippy::empty_loop", "--no-deps"].iter(); - - remove_clippy_args(&mut args, clippy_args); - assert_eq!(args, &["-Zui-testing"]); - } - - #[test] - fn removes_clippy_args_from_middle() { - let mut args = vec!["-Zui-testing", "-W", "clippy::filter_map", "-L", "serde"]; - let clippy_args = ["-W", "clippy::filter_map"].iter(); - - remove_clippy_args(&mut args, clippy_args); - assert_eq!(args, &["-Zui-testing", "-L", "serde"]); - } - - #[test] - fn no_clippy_args_to_remove() { - let mut args = vec!["-Zui-testing", "-L", "serde"]; - let clippy_args: [&str; 0] = []; - - remove_clippy_args(&mut args, clippy_args.iter()); - assert_eq!(args, &["-Zui-testing", "-L", "serde"]); - } -} diff --git a/src/main.rs b/src/main.rs index 1c0e04689a9..ea06743394d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -#![feature(bool_to_option)] -#![feature(command_access)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] @@ -64,7 +62,7 @@ struct ClippyCmd { unstable_options: bool, cargo_subcommand: &'static str, args: Vec, - clippy_args: Option, + clippy_args: Vec, } impl ClippyCmd { @@ -101,17 +99,16 @@ impl ClippyCmd { args.insert(0, "+nightly".to_string()); } - let mut clippy_args = old_args.collect::>().join(" "); - if cargo_subcommand == "fix" && !clippy_args.contains("--no-deps") { - clippy_args = format!("{} --no-deps", clippy_args); + let mut clippy_args: Vec = old_args.collect(); + if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") { + clippy_args.push("--no-deps".into()); } - let has_args = !clippy_args.is_empty(); ClippyCmd { unstable_options, cargo_subcommand, args, - clippy_args: has_args.then_some(clippy_args), + clippy_args, } } @@ -151,24 +148,20 @@ impl ClippyCmd { .map(|p| ("CARGO_TARGET_DIR", p)) } - fn into_std_cmd(self, rustflags: Option) -> Command { + fn into_std_cmd(self) -> Command { let mut cmd = Command::new("cargo"); + let clippy_args: String = self + .clippy_args + .iter() + .map(|arg| format!("{}__CLIPPY_HACKERY__", arg)) + .collect(); cmd.env(self.path_env(), Self::path()) .envs(ClippyCmd::target_dir()) + .env("CLIPPY_ARGS", clippy_args) .arg(self.cargo_subcommand) .args(&self.args); - // HACK: pass Clippy args to the driver *also* through RUSTFLAGS. - // This guarantees that new builds will be triggered when Clippy flags change. - if let Some(clippy_args) = self.clippy_args { - cmd.env( - "RUSTFLAGS", - rustflags.map_or(clippy_args.clone(), |flags| format!("{} {}", clippy_args, flags)), - ); - cmd.env("CLIPPY_ARGS", clippy_args); - } - cmd } } @@ -179,7 +172,7 @@ where { let cmd = ClippyCmd::new(old_args); - let mut cmd = cmd.into_std_cmd(env::var("RUSTFLAGS").ok()); + let mut cmd = cmd.into_std_cmd(); let exit_status = cmd .spawn() @@ -197,7 +190,6 @@ where #[cfg(test)] mod tests { use super::ClippyCmd; - use std::ffi::OsStr; #[test] #[should_panic] @@ -212,7 +204,6 @@ mod tests { .split_whitespace() .map(ToString::to_string); let cmd = ClippyCmd::new(args); - assert_eq!("fix", cmd.cargo_subcommand); assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env()); assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options"))); @@ -224,8 +215,7 @@ mod tests { .split_whitespace() .map(ToString::to_string); let cmd = ClippyCmd::new(args); - - assert!(cmd.clippy_args.unwrap().contains("--no-deps")); + assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps")); } #[test] @@ -234,15 +224,13 @@ mod tests { .split_whitespace() .map(ToString::to_string); let cmd = ClippyCmd::new(args); - - assert_eq!(1, cmd.clippy_args.unwrap().matches("--no-deps").count()); + assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1); } #[test] fn check() { let args = "cargo clippy".split_whitespace().map(ToString::to_string); let cmd = ClippyCmd::new(args); - assert_eq!("check", cmd.cargo_subcommand); assert_eq!("RUSTC_WRAPPER", cmd.path_env()); } @@ -253,63 +241,7 @@ mod tests { .split_whitespace() .map(ToString::to_string); let cmd = ClippyCmd::new(args); - assert_eq!("check", cmd.cargo_subcommand); assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env()); } - - #[test] - fn clippy_args_into_rustflags() { - let args = "cargo clippy -- -W clippy::as_conversions" - .split_whitespace() - .map(ToString::to_string); - let cmd = ClippyCmd::new(args); - - let rustflags = None; - let cmd = cmd.into_std_cmd(rustflags); - - assert!(cmd - .get_envs() - .any(|(key, val)| key == "RUSTFLAGS" && val == Some(OsStr::new("-W clippy::as_conversions")))); - } - - #[test] - fn clippy_args_respect_existing_rustflags() { - let args = "cargo clippy -- -D clippy::await_holding_lock" - .split_whitespace() - .map(ToString::to_string); - let cmd = ClippyCmd::new(args); - - let rustflags = Some(r#"--cfg feature="some_feat""#.into()); - let cmd = cmd.into_std_cmd(rustflags); - - assert!(cmd.get_envs().any(|(key, val)| key == "RUSTFLAGS" - && val == Some(OsStr::new(r#"-D clippy::await_holding_lock --cfg feature="some_feat""#)))); - } - - #[test] - fn no_env_change_if_no_clippy_args() { - let args = "cargo clippy".split_whitespace().map(ToString::to_string); - let cmd = ClippyCmd::new(args); - - let rustflags = Some(r#"--cfg feature="some_feat""#.into()); - let cmd = cmd.into_std_cmd(rustflags); - - assert!(!cmd - .get_envs() - .any(|(key, _)| key == "RUSTFLAGS" || key == "CLIPPY_ARGS")); - } - - #[test] - fn no_env_change_if_no_clippy_args_nor_rustflags() { - let args = "cargo clippy".split_whitespace().map(ToString::to_string); - let cmd = ClippyCmd::new(args); - - let rustflags = None; - let cmd = cmd.into_std_cmd(rustflags); - - assert!(!cmd - .get_envs() - .any(|(key, _)| key == "RUSTFLAGS" || key == "CLIPPY_ARGS")) - } } diff --git a/tests/dogfood.rs b/tests/dogfood.rs index fda1413868e..052223d6d6f 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -23,7 +23,7 @@ fn dogfood_clippy() { .current_dir(root_dir) .env("CLIPPY_DOGFOOD", "1") .env("CARGO_INCREMENTAL", "0") - .arg("clippy") + .arg("clippy-preview") .arg("--all-targets") .arg("--all-features") .arg("--") -- cgit 1.4.1-3-g733a5 From ceb66ad464287d9f2232d7b81857c514a22236c0 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 22 Dec 2020 21:26:17 -0500 Subject: Add more tests --- src/librustdoc/clean/mod.rs | 2 +- src/test/rustdoc/async-fn.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e7fdf76ba79..6e4ec016aad 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1448,7 +1448,7 @@ impl Clean for hir::Ty<'_> { // There are two times a `Fresh` lifetime can be created: // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`. // 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`. - // See commit 749349fc9f7b12f212bca9ba2297e463328cb701 for more information. + // See #59286 for more information. // Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it. // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though; // there's no case where it could cause the function to fail to compile. diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index 7a673b9f670..f0fd9703915 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -49,6 +49,8 @@ impl Foo { pub async fn mut_self(mut self, mut first: usize) {} } +pub trait Pattern<'a> {} + pub trait Trait {} // @has async_fn/fn.const_generics.html // @has - '//pre[@class="rust fn"]' 'pub async fn const_generics(_: impl Trait)' @@ -70,6 +72,9 @@ pub async fn static_trait(foo: &str) -> Box {} // @has async_fn/fn.lifetime_for_trait.html // @has - '//pre[@class="rust fn"]' "pub async fn lifetime_for_trait(foo: &str) -> Box" pub async fn lifetime_for_trait(foo: &str) -> Box {} +// @has async_fn/fn.elided_in_input_trait.html +// @has - '//pre[@class="rust fn"]' "pub async fn elided_in_input_trait(t: impl Pattern<'_>)" +pub async fn elided_in_input_trait(t: impl Pattern<'_>) {} struct AsyncFdReadyGuard<'a, T> { x: &'a T } @@ -80,4 +85,14 @@ impl Foo { // taken from `tokio` as an example of a method that was particularly bad before // @has - '//h4[@class="method"]' "pub async fn readable(&self) -> Result, ()>" pub async fn readable(&self) -> Result, ()> {} + // @has - '//h4[@class="method"]' "pub async fn mut_self(&mut self)" + pub async fn mut_self(&mut self) {} } + +// test named lifetimes, just in case +// @has async_fn/fn.named.html +// @has - '//pre[@class="rust fn"]' "pub async fn named<'a, 'b>(foo: &'a str) -> &'b str" +pub async fn named<'a, 'b>(foo: &'a str) -> &'b str {} +// @has async_fn/fn.named_trait.html +// @has - '//pre[@class="rust fn"]' "pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b>" +pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b> {} -- cgit 1.4.1-3-g733a5 From 468af39ef2f689ed151018fc76c571c2c9804893 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 22 Dec 2020 19:42:03 -0800 Subject: Update cargo --- Cargo.lock | 20 ++++++++++---------- src/tools/cargo | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index fcfd23f2dae..8fbfa8d6428 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -895,9 +895,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.31" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9447ad28eee2a5cfb031c329d46bef77487244fff6a724b378885b8691a35f78" +checksum = "e268162af1a5fe89917ae25ba3b0a77c8da752bdc58e7dbb4f15b91fbd33756e" dependencies = [ "curl-sys", "libc", @@ -910,9 +910,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.34+curl-7.71.1" +version = "0.4.39+curl-7.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad4eff0be6985b7e709f64b5a541f700e9ad1407190a29f4884319eb663ed1d6" +checksum = "07a8ce861e7b68a0b394e814d7ee9f1b2750ff8bd10372c6ad3bacc10e86f874" dependencies = [ "cc", "libc", @@ -1330,9 +1330,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.12" +version = "0.13.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6f1a0238d7f8f8fd5ee642f4ebac4dbc03e03d1f78fbe7a3ede35dcf7e2224" +checksum = "186dd99cc77576e58344ad614fa9bb27bad9d048f85de3ca850c1f4e8b048260" dependencies = [ "bitflags", "libc", @@ -1345,9 +1345,9 @@ dependencies = [ [[package]] name = "git2-curl" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502d532a2d06184beb3bc869d4d90236e60934e3382c921b203fa3c33e212bd7" +checksum = "883539cb0ea94bab3f8371a98cd8e937bbe9ee7c044499184aa4c17deb643a50" dependencies = [ "curl", "git2", @@ -1759,9 +1759,9 @@ dependencies = [ [[package]] name = "libgit2-sys" -version = "0.12.14+1.1.0" +version = "0.12.16+1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f25af58e6495f7caf2919d08f212de550cfa3ed2f5e744988938ea292b9f549" +checksum = "9f91b2f931ee975a98155195be8cd82d02e8e029d7d793d2bac1b8181ac97020" dependencies = [ "cc", "libc", diff --git a/src/tools/cargo b/src/tools/cargo index a3c2627fbc2..75d5d8cffe3 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit a3c2627fbc2f5391c65ba45ab53b81bf71fa323c +Subproject commit 75d5d8cffe3464631f82dcd3c470b78dc1dda8bb -- cgit 1.4.1-3-g733a5 From 4a4426377e8f1ad61dd6d4bb3525bbf2997889b9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 13 Dec 2020 11:32:57 -0500 Subject: Box ItemKind to reduce the size of `Item` This brings the size of `Item` from ``` [src/librustdoc/lib.rs:103] std::mem::size_of::() = 680 ``` to ``` [src/librustdoc/lib.rs:103] std::mem::size_of::() = 280 ``` --- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +-- src/librustdoc/clean/types.rs | 12 +++--- src/librustdoc/clean/utils.rs | 6 +-- src/librustdoc/fold.rs | 8 ++-- src/librustdoc/formats/cache.rs | 53 +++++++++++-------------- src/librustdoc/formats/item_type.rs | 2 +- src/librustdoc/formats/mod.rs | 2 +- src/librustdoc/formats/renderer.rs | 2 +- src/librustdoc/html/render/cache.rs | 2 +- src/librustdoc/html/render/mod.rs | 53 +++++++++++++------------ src/librustdoc/json/conversions.rs | 4 +- src/librustdoc/json/mod.rs | 4 +- src/librustdoc/passes/calculate_doc_coverage.rs | 2 +- src/librustdoc/passes/collect_trait_impls.rs | 8 ++-- src/librustdoc/passes/doc_test_lints.rs | 2 +- src/librustdoc/passes/strip_hidden.rs | 2 +- src/librustdoc/passes/stripper.rs | 8 ++-- 20 files changed, 89 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 96d19e8e17d..3ca02b61063 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -123,7 +123,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { attrs: Default::default(), visibility: Inherited, def_id: self.cx.next_def_id(param_env_def_id.krate), - kind: ImplItem(Impl { + kind: box ImplItem(Impl { unsafety: hir::Unsafety::Normal, generics: new_generics, provided_trait_methods: Default::default(), diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index d99055e1145..ba3eb007e38 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { attrs: Default::default(), visibility: Inherited, def_id: self.cx.next_def_id(impl_def_id.krate), - kind: ImplItem(Impl { + kind: box ImplItem(Impl { unsafety: hir::Unsafety::Normal, generics: ( self.cx.tcx.generics_of(impl_def_id), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index be4c62d891d..c168c56d30d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -482,7 +482,7 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) source: clean::Span::dummy(), def_id: DefId::local(CRATE_DEF_INDEX), visibility: clean::Public, - kind: clean::ImportItem(clean::Import::new_simple( + kind: box clean::ImportItem(clean::Import::new_simple( item.ident.name, clean::ImportSource { path: clean::Path { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index de53ce8d95c..a81ea1630cd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2144,7 +2144,7 @@ fn clean_extern_crate( source: krate.span.clean(cx), def_id: crate_def_id, visibility: krate.vis.clean(cx), - kind: ExternCrateItem(name, orig_name), + kind: box ExternCrateItem(name, orig_name), }] } @@ -2212,7 +2212,7 @@ impl Clean> for doctree::Import<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - kind: ImportItem(Import::new_simple( + kind: box ImportItem(Import::new_simple( self.name, resolve_use_source(cx, path), false, @@ -2230,7 +2230,7 @@ impl Clean> for doctree::Import<'_> { source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(), visibility: self.vis.clean(cx), - kind: ImportItem(inner), + kind: box ImportItem(inner), }] } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 9b2003911a7..fc977704e44 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -84,7 +84,7 @@ crate struct Item { crate name: Option, crate attrs: Attributes, crate visibility: Visibility, - crate kind: ItemKind, + crate kind: Box, crate def_id: DefId, } @@ -152,7 +152,7 @@ impl Item { Item { def_id, - kind, + kind: box kind, name, source: source.clean(cx), attrs: cx.tcx.get_attrs(def_id).clean(cx), @@ -171,7 +171,7 @@ impl Item { } crate fn is_crate(&self) -> bool { - match self.kind { + match *self.kind { StrippedItem(box ModuleItem(Module { is_crate: true, .. })) | ModuleItem(Module { is_crate: true, .. }) => true, _ => false, @@ -223,14 +223,14 @@ impl Item { self.type_() == ItemType::Keyword } crate fn is_stripped(&self) -> bool { - match self.kind { + match *self.kind { StrippedItem(..) => true, ImportItem(ref i) => !i.should_be_displayed, _ => false, } } crate fn has_stripped_fields(&self) -> Option { - match self.kind { + match *self.kind { StructItem(ref _struct) => Some(_struct.fields_stripped), UnionItem(ref union) => Some(union.fields_stripped), VariantItem(Variant { kind: VariantKind::Struct(ref vstruct) }) => { @@ -281,7 +281,7 @@ impl Item { } crate fn is_default(&self) -> bool { - match self.kind { + match *self.kind { ItemKind::MethodItem(_, Some(defaultness)) => { defaultness.has_value() && !defaultness.is_final() } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 270321aaa11..2e479d25203 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -43,7 +43,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { let mut module = module.clean(cx); let mut masked_crates = FxHashSet::default(); - match module.kind { + match *module.kind { ItemKind::ModuleItem(ref module) => { for it in &module.items { // `compiler_builtins` should be masked too, but we can't apply @@ -61,7 +61,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx); { - let m = match module.kind { + let m = match *module.kind { ItemKind::ModuleItem(ref mut m) => m, _ => unreachable!(), }; @@ -338,7 +338,7 @@ crate fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut let tcx = cx.tcx; for item in items { - let target = match item.kind { + let target = match *item.kind { ItemKind::TypedefItem(ref t, true) => &t.type_, _ => continue, }; diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 285fabdc372..343c6e779c1 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -5,9 +5,9 @@ crate struct StripItem(pub Item); impl StripItem { crate fn strip(self) -> Option { match self.0 { - Item { kind: StrippedItem(..), .. } => Some(self.0), + Item { kind: box StrippedItem(..), .. } => Some(self.0), mut i => { - i.kind = StrippedItem(box i.kind); + i.kind = box StrippedItem(i.kind); Some(i) } } @@ -72,9 +72,9 @@ crate trait DocFolder: Sized { /// don't override! fn fold_item_recur(&mut self, mut item: Item) -> Item { - item.kind = match item.kind { + item.kind = box match *item.kind { StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)), - _ => self.fold_inner_recur(item.kind), + _ => self.fold_inner_recur(*item.kind), }; item } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 77a3e9fa954..899d61d8e43 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -219,7 +219,7 @@ impl DocFolder for Cache { // If this is a stripped module, // we don't want it or its children in the search index. - let orig_stripped_mod = match item.kind { + let orig_stripped_mod = match *item.kind { clean::StrippedItem(box clean::ModuleItem(..)) => { mem::replace(&mut self.stripped_mod, true) } @@ -228,7 +228,7 @@ impl DocFolder for Cache { // If the impl is from a masked crate or references something from a // masked crate then remove it completely. - if let clean::ImplItem(ref i) = item.kind { + if let clean::ImplItem(ref i) = *item.kind { if self.masked_crates.contains(&item.def_id.krate) || i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) || i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) @@ -239,12 +239,12 @@ impl DocFolder for Cache { // Propagate a trait method's documentation to all implementors of the // trait. - if let clean::TraitItem(ref t) = item.kind { + if let clean::TraitItem(ref t) = *item.kind { self.traits.entry(item.def_id).or_insert_with(|| t.clone()); } // Collect all the implementors of traits. - if let clean::ImplItem(ref i) = item.kind { + if let clean::ImplItem(ref i) = *item.kind { if let Some(did) = i.trait_.def_id() { if i.blanket_impl.is_none() { self.implementors @@ -257,7 +257,7 @@ impl DocFolder for Cache { // Index this method for searching later on. if let Some(ref s) = item.name { - let (parent, is_inherent_impl_item) = match item.kind { + let (parent, is_inherent_impl_item) = match *item.kind { clean::StrippedItem(..) => ((None, None), false), clean::AssocConstItem(..) | clean::TypedefItem(_, true) if self.parent_is_trait_impl => @@ -348,7 +348,7 @@ impl DocFolder for Cache { _ => false, }; - match item.kind { + match *item.kind { clean::StructItem(..) | clean::EnumItem(..) | clean::TypedefItem(..) @@ -387,7 +387,7 @@ impl DocFolder for Cache { // Maintain the parent stack let orig_parent_is_trait_impl = self.parent_is_trait_impl; - let parent_pushed = match item.kind { + let parent_pushed = match *item.kind { clean::TraitItem(..) | clean::EnumItem(..) | clean::ForeignTypeItem @@ -425,38 +425,33 @@ impl DocFolder for Cache { // Once we've recursively found all the generics, hoard off all the // implementations elsewhere. let item = self.fold_item_recur(item); - let ret = if let clean::Item { kind: clean::ImplItem(_), .. } = item { + let ret = if let clean::Item { kind: box clean::ImplItem(ref i), .. } = item { // Figure out the id of this impl. This may map to a // primitive rather than always to a struct/enum. // Note: matching twice to restrict the lifetime of the `i` borrow. let mut dids = FxHashSet::default(); - if let clean::Item { kind: clean::ImplItem(ref i), .. } = item { - match i.for_ { - clean::ResolvedPath { did, .. } - | clean::BorrowedRef { type_: box clean::ResolvedPath { did, .. }, .. } => { - dids.insert(did); - } - ref t => { - let did = t - .primitive_type() - .and_then(|t| self.primitive_locations.get(&t).cloned()); + match i.for_ { + clean::ResolvedPath { did, .. } + | clean::BorrowedRef { type_: box clean::ResolvedPath { did, .. }, .. } => { + dids.insert(did); + } + ref t => { + let did = + t.primitive_type().and_then(|t| self.primitive_locations.get(&t).cloned()); - if let Some(did) = did { - dids.insert(did); - } + if let Some(did) = did { + dids.insert(did); } } + } - if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) { - for bound in generics { - if let Some(did) = bound.def_id() { - dids.insert(did); - } + if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) { + for bound in generics { + if let Some(did) = bound.def_id() { + dids.insert(did); } } - } else { - unreachable!() - }; + } let impl_item = Impl { impl_item: item }; if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) { for did in dids { diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index af512e37460..ad51adf2fe3 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -60,7 +60,7 @@ impl Serialize for ItemType { impl<'a> From<&'a clean::Item> for ItemType { fn from(item: &'a clean::Item) -> ItemType { - let kind = match item.kind { + let kind = match *item.kind { clean::StrippedItem(box ref item) => item, ref kind => kind, }; diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index 55fd4948f45..58b9f5fbf0f 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -32,7 +32,7 @@ crate struct Impl { impl Impl { crate fn inner_impl(&self) -> &clean::Impl { - match self.impl_item.kind { + match *self.impl_item.kind { clean::ImplItem(ref impl_) => impl_, _ => panic!("non-impl item found in impl"), } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index fbbd3c1ccf5..e84a9853d9b 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -89,7 +89,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( } cx.mod_item_in(&item, &name, &cache)?; - let module = match item.kind { + let module = match *item.kind { clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m, _ => unreachable!(), }; diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 25fe31aab59..c408e576639 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -165,7 +165,7 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { } crate fn get_index_search_type(item: &clean::Item) -> Option { - let (all_types, ret_types) = match item.kind { + let (all_types, ret_types) = match *item.kind { clean::FunctionItem(ref f) => (&f.all_types, &f.ret_types), clean::MethodItem(ref m, _) => (&m.all_types, &m.ret_types), clean::TyMethodItem(ref m) => (&m.all_types, &m.ret_types), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 97e7c38ecb8..db1744f2853 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -633,7 +633,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { // Render sidebar-items.js used throughout this module. if !self.render_redirect_pages { - let module = match item.kind { + let module = match *item.kind { clean::StrippedItem(box clean::ModuleItem(ref m)) | clean::ModuleItem(ref m) => m, _ => unreachable!(), }; @@ -1739,7 +1739,7 @@ fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Ca write!(buf, "
"); // out-of-band write!(buf, ""); - let name = match item.kind { + let name = match *item.kind { clean::ModuleItem(ref m) => { if m.is_crate { "Crate " @@ -1788,7 +1788,7 @@ fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Ca write!(buf, "