From 3a37c95e900590eb68d80124c118c2ea788fc269 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 14 Jun 2022 12:10:34 -0700 Subject: [PATCH 1/9] rustdoc: remove tuple link on round braces This is 682889fb06591c4245422b73b005c5d8ae2d0cad but for tuples. The reasoning is the same: * This commit also changes it so that tuples with all-generic elements still link to the primitive.tuple.html page, just like slices. So there still plenty of on-ramps for anybody who doesn't know about it. * It's too hard to see when round braces are a separate link from the type inside of them. * It's too hard to click even if you do notice them. --- src/librustdoc/html/format.rs | 44 +++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 394db2d0cda6b..7a49f5d66776c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -23,6 +23,8 @@ use rustc_span::symbol::kw; use rustc_span::{sym, Symbol}; use rustc_target::spec::abi::Abi; +use itertools::Itertools; + use crate::clean::{ self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId, PrimitiveType, @@ -864,20 +866,42 @@ fn fmt_type<'cx>( match &typs[..] { &[] => primitive_link(f, PrimitiveType::Unit, "()", cx), &[ref one] => { - primitive_link(f, PrimitiveType::Tuple, "(", cx)?; - // Carry `f.alternate()` into this display w/o branching manually. - fmt::Display::fmt(&one.print(cx), f)?; - primitive_link(f, PrimitiveType::Tuple, ",)", cx) + if let clean::Generic(name) = one { + primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx) + } else { + write!(f, "(")?; + // Carry `f.alternate()` into this display w/o branching manually. + fmt::Display::fmt(&one.print(cx), f)?; + write!(f, ",)") + } } many => { - primitive_link(f, PrimitiveType::Tuple, "(", cx)?; - for (i, item) in many.iter().enumerate() { - if i != 0 { - write!(f, ", ")?; + let generic_names: Vec = many + .iter() + .filter_map(|t| match t { + clean::Generic(name) => Some(*name), + _ => None, + }) + .collect(); + let is_generic = generic_names.len() == many.len(); + if is_generic { + primitive_link( + f, + PrimitiveType::Tuple, + &format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")), + cx, + ) + } else { + write!(f, "(")?; + for (i, item) in many.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + // Carry `f.alternate()` into this display w/o branching manually. + fmt::Display::fmt(&item.print(cx), f)?; } - fmt::Display::fmt(&item.print(cx), f)?; + write!(f, ")") } - primitive_link(f, PrimitiveType::Tuple, ")", cx) } } } From c51f5081f08dacdf498115c30fa7edb19a0bb5a0 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sat, 18 Jun 2022 04:11:47 +0100 Subject: [PATCH 2/9] Skip late bound regions in GATSubstCollector #93227 liberated late bound regions when collecting GAT substs in wfcheck. It should simply skip late bound regions instead. r? @compiler-errors --- compiler/rustc_typeck/src/check/wfcheck.rs | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 2db5f5d407193..75340d35d4081 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -490,7 +490,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( // The bounds we that we would require from `to_check` let mut bounds = FxHashSet::default(); - let (regions, types) = GATSubstCollector::visit(tcx, gat_def_id.to_def_id(), to_check); + let (regions, types) = GATSubstCollector::visit(gat_def_id.to_def_id(), to_check); // If both regions and types are empty, then this GAT isn't in the // set of types we are checking, and we shouldn't try to do clause analysis @@ -664,7 +664,6 @@ fn resolve_regions_with_wf_tys<'tcx>( /// the two vectors, `regions` and `types` (depending on their kind). For each /// parameter `Pi` also track the index `i`. struct GATSubstCollector<'tcx> { - tcx: TyCtxt<'tcx>, gat: DefId, // Which region appears and which parameter index its substituted for regions: FxHashSet<(ty::Region<'tcx>, usize)>, @@ -674,16 +673,11 @@ struct GATSubstCollector<'tcx> { impl<'tcx> GATSubstCollector<'tcx> { fn visit>( - tcx: TyCtxt<'tcx>, gat: DefId, t: T, ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) { - let mut visitor = GATSubstCollector { - tcx, - gat, - regions: FxHashSet::default(), - types: FxHashSet::default(), - }; + let mut visitor = + GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() }; t.visit_with(&mut visitor); (visitor.regions, visitor.types) } @@ -692,19 +686,12 @@ impl<'tcx> GATSubstCollector<'tcx> { impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> { type BreakTy = !; - fn visit_binder>( - &mut self, - t: &ty::Binder<'tcx, T>, - ) -> ControlFlow { - self.tcx.liberate_late_bound_regions(self.gat, t.clone()).visit_with(self) - } - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Projection(p) if p.item_def_id == self.gat => { for (idx, subst) in p.substs.iter().enumerate() { match subst.unpack() { - GenericArgKind::Lifetime(lt) => { + GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => { self.regions.insert((lt, idx)); } GenericArgKind::Type(t) => { From 7952205bc8b8c890bca12430e75cc3173d49cb52 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Jun 2022 07:37:41 -0700 Subject: [PATCH 3/9] make btree not use &A: Allocator instance --- library/alloc/src/collections/btree/map.rs | 10 +++++----- library/alloc/src/collections/btree/set.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index e1124a68750ae..28068a8806096 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1644,11 +1644,11 @@ impl IntoIter { &mut self, ) -> Option, marker::KV>> { if self.length == 0 { - self.range.deallocating_end(&self.alloc); + self.range.deallocating_end(self.alloc.clone()); None } else { self.length -= 1; - Some(unsafe { self.range.deallocating_next_unchecked(&self.alloc) }) + Some(unsafe { self.range.deallocating_next_unchecked(self.alloc.clone()) }) } } @@ -1658,11 +1658,11 @@ impl IntoIter { &mut self, ) -> Option, marker::KV>> { if self.length == 0 { - self.range.deallocating_end(&self.alloc); + self.range.deallocating_end(self.alloc.clone()); None } else { self.length -= 1; - Some(unsafe { self.range.deallocating_next_back_unchecked(&self.alloc) }) + Some(unsafe { self.range.deallocating_next_back_unchecked(self.alloc.clone()) }) } } } @@ -1849,7 +1849,7 @@ where type Item = (K, V); fn next(&mut self) -> Option<(K, V)> { - self.inner.next(&mut self.pred, &self.alloc) + self.inner.next(&mut self.pred, self.alloc.clone()) } fn size_hint(&self) -> (usize, Option) { diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index bec3b9675254c..0d3fdc9019efd 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1320,7 +1320,7 @@ where fn next(&mut self) -> Option { let pred = &mut self.pred; let mut mapped_pred = |k: &T, _v: &mut ()| pred(k); - self.inner.next(&mut mapped_pred, &self.alloc).map(|(k, _)| k) + self.inner.next(&mut mapped_pred, self.alloc.clone()).map(|(k, _)| k) } fn size_hint(&self) -> (usize, Option) { From b05d71f880b77b4c9202b73dd9f6127409452f19 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Jun 2022 07:38:28 -0700 Subject: [PATCH 4/9] make std not use &A: Allocator instance --- library/std/src/alloc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index d3879273f5b03..d554ec590358f 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -187,7 +187,7 @@ impl System { old_size => unsafe { let new_ptr = self.alloc_impl(new_layout, zeroed)?; ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), old_size); - Allocator::deallocate(&self, ptr, old_layout); + Allocator::deallocate(self, ptr, old_layout); Ok(new_ptr) }, } @@ -254,7 +254,7 @@ unsafe impl Allocator for System { match new_layout.size() { // SAFETY: conditions must be upheld by the caller 0 => unsafe { - Allocator::deallocate(&self, ptr, old_layout); + Allocator::deallocate(self, ptr, old_layout); Ok(NonNull::slice_from_raw_parts(new_layout.dangling(), 0)) }, @@ -274,9 +274,9 @@ unsafe impl Allocator for System { // `new_ptr`. Thus, the call to `copy_nonoverlapping` is safe. The safety contract // for `dealloc` must be upheld by the caller. new_size => unsafe { - let new_ptr = Allocator::allocate(&self, new_layout)?; + let new_ptr = Allocator::allocate(self, new_layout)?; ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), new_size); - Allocator::deallocate(&self, ptr, old_layout); + Allocator::deallocate(self, ptr, old_layout); Ok(new_ptr) }, } From b068e6aeb75c0991927fb5751ce81e3ac2d46aec Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 18 Jun 2022 10:35:19 -0700 Subject: [PATCH 5/9] Add test cases for tuples with links --- src/test/rustdoc/tuples.link1_i32.html | 1 + src/test/rustdoc/tuples.link1_t.html | 1 + src/test/rustdoc/tuples.link2_i32.html | 1 + src/test/rustdoc/tuples.link2_t.html | 1 + src/test/rustdoc/tuples.link2_tu.html | 1 + src/test/rustdoc/tuples.link_unit.html | 1 + src/test/rustdoc/tuples.rs | 12 ++++++++++++ 7 files changed, 18 insertions(+) create mode 100644 src/test/rustdoc/tuples.link1_i32.html create mode 100644 src/test/rustdoc/tuples.link1_t.html create mode 100644 src/test/rustdoc/tuples.link2_i32.html create mode 100644 src/test/rustdoc/tuples.link2_t.html create mode 100644 src/test/rustdoc/tuples.link2_tu.html create mode 100644 src/test/rustdoc/tuples.link_unit.html diff --git a/src/test/rustdoc/tuples.link1_i32.html b/src/test/rustdoc/tuples.link1_i32.html new file mode 100644 index 0000000000000..4efde28ed52e7 --- /dev/null +++ b/src/test/rustdoc/tuples.link1_i32.html @@ -0,0 +1 @@ +pub fn tuple1(x: (i32,)) -> (i32,) \ No newline at end of file diff --git a/src/test/rustdoc/tuples.link1_t.html b/src/test/rustdoc/tuples.link1_t.html new file mode 100644 index 0000000000000..1cbaec05733b5 --- /dev/null +++ b/src/test/rustdoc/tuples.link1_t.html @@ -0,0 +1 @@ +pub fn tuple1_t<T>(x: (T,)) -> (T,) \ No newline at end of file diff --git a/src/test/rustdoc/tuples.link2_i32.html b/src/test/rustdoc/tuples.link2_i32.html new file mode 100644 index 0000000000000..77c8d81b842df --- /dev/null +++ b/src/test/rustdoc/tuples.link2_i32.html @@ -0,0 +1 @@ +pub fn tuple2(x: (i32, i32)) -> (i32, i32) \ No newline at end of file diff --git a/src/test/rustdoc/tuples.link2_t.html b/src/test/rustdoc/tuples.link2_t.html new file mode 100644 index 0000000000000..2477aa6be9d39 --- /dev/null +++ b/src/test/rustdoc/tuples.link2_t.html @@ -0,0 +1 @@ +pub fn tuple2_t<T>(x: (T, T)) -> (T, T) \ No newline at end of file diff --git a/src/test/rustdoc/tuples.link2_tu.html b/src/test/rustdoc/tuples.link2_tu.html new file mode 100644 index 0000000000000..b02f8dd8d6530 --- /dev/null +++ b/src/test/rustdoc/tuples.link2_tu.html @@ -0,0 +1 @@ +pub fn tuple2_tu<T, U>(x: (T, U)) -> (T, U) \ No newline at end of file diff --git a/src/test/rustdoc/tuples.link_unit.html b/src/test/rustdoc/tuples.link_unit.html new file mode 100644 index 0000000000000..839990e1587c6 --- /dev/null +++ b/src/test/rustdoc/tuples.link_unit.html @@ -0,0 +1 @@ +pub fn tuple0(x: ()) \ No newline at end of file diff --git a/src/test/rustdoc/tuples.rs b/src/test/rustdoc/tuples.rs index 53654abff2a8e..62e2f9e7ef244 100644 --- a/src/test/rustdoc/tuples.rs +++ b/src/test/rustdoc/tuples.rs @@ -1,8 +1,20 @@ #![crate_name = "foo"] // @has foo/fn.tuple0.html //pre 'pub fn tuple0(x: ())' +// @snapshot link_unit - '//pre[@class="rust fn"]/code' pub fn tuple0(x: ()) -> () { x } // @has foo/fn.tuple1.html //pre 'pub fn tuple1(x: (i32,)) -> (i32,)' +// @snapshot link1_i32 - '//pre[@class="rust fn"]/code' pub fn tuple1(x: (i32,)) -> (i32,) { x } // @has foo/fn.tuple2.html //pre 'pub fn tuple2(x: (i32, i32)) -> (i32, i32)' +// @snapshot link2_i32 - '//pre[@class="rust fn"]/code' pub fn tuple2(x: (i32, i32)) -> (i32, i32) { x } +// @has foo/fn.tuple1_t.html //pre 'pub fn tuple1_t(x: (T,)) -> (T,)' +// @snapshot link1_t - '//pre[@class="rust fn"]/code' +pub fn tuple1_t(x: (T,)) -> (T,) { x } +// @has foo/fn.tuple2_t.html //pre 'pub fn tuple2_t(x: (T, T)) -> (T, T)' +// @snapshot link2_t - '//pre[@class="rust fn"]/code' +pub fn tuple2_t(x: (T, T)) -> (T, T) { x } +// @has foo/fn.tuple2_tu.html //pre 'pub fn tuple2_tu(x: (T, U)) -> (T, U)' +// @snapshot link2_tu - '//pre[@class="rust fn"]/code' +pub fn tuple2_tu(x: (T, U)) -> (T, U) { x } From 29a9f36685c8da552d0d8772778ff4ec70af0032 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 18 Jun 2022 10:36:12 -0700 Subject: [PATCH 6/9] Fix bug when using `--bless` --- src/etc/htmldocck.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py index f762e38900552..70b6af717cd38 100644 --- a/src/etc/htmldocck.py +++ b/src/etc/htmldocck.py @@ -417,7 +417,7 @@ def check_snapshot(snapshot_name, actual_tree, normalize_to_text): snapshot_path = '{}.{}.{}'.format(rust_test_path[:-3], snapshot_name, 'html') try: with open(snapshot_path, 'r') as snapshot_file: - expected_str = snapshot_file.read() + expected_str = snapshot_file.read().replace("{{channel}}", channel) except FileNotFoundError: if bless: expected_str = None @@ -429,8 +429,6 @@ def check_snapshot(snapshot_name, actual_tree, normalize_to_text): else: actual_str = flatten(actual_tree) - expected_str = expected_str.replace("{{channel}}", channel) - # Conditions: # 1. Is --bless # 2. Are actual and expected tree different From cc6c774a5a5124af85c7a41c75da24681dd23681 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sat, 18 Jun 2022 22:07:14 +0100 Subject: [PATCH 7/9] Write help for unexpected =>. Fixes #98128 --- compiler/rustc_parse/src/parser/diagnostics.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index acf892cec5328..3b1903f0ee941 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -606,6 +606,8 @@ impl<'a> Parser<'a> { && expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Gt))) { err.span_label(self.prev_token.span, "maybe try to close unmatched angle bracket"); + } else if self.token == token::FatArrow { + err.help("closures are written `|a, b| a + b` and greater-than-or-equal is `>=`."); } let sp = if self.token == token::Eof { From 04f9957d5beadf198aab9c0c64592ae7a0502dc5 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 19 Jun 2022 00:24:50 +0100 Subject: [PATCH 8/9] Show => help only if operator expected. --- compiler/rustc_parse/src/parser/diagnostics.rs | 4 +++- src/test/ui/asm/x86_64/parse-error.stderr | 2 ++ src/test/ui/missing/missing-comma-in-match.stderr | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 3b1903f0ee941..20447fa07cadf 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -606,7 +606,9 @@ impl<'a> Parser<'a> { && expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Gt))) { err.span_label(self.prev_token.span, "maybe try to close unmatched angle bracket"); - } else if self.token == token::FatArrow { + } else if self.token == token::FatArrow + && expected.iter().any(|tok| matches!(tok, TokenType::Operator)) + { err.help("closures are written `|a, b| a + b` and greater-than-or-equal is `>=`."); } diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr index 1fd317a96a8a6..5c176f93a4341 100644 --- a/src/test/ui/asm/x86_64/parse-error.stderr +++ b/src/test/ui/asm/x86_64/parse-error.stderr @@ -57,6 +57,8 @@ error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` | LL | asm!("{}", in(reg) foo => bar); | ^^ expected one of 7 possible tokens + | + = help: closures are written `|a, b| a + b` and greater-than-or-equal is `>=`. error: expected a path for argument to `sym` --> $DIR/parse-error.rs:31:24 diff --git a/src/test/ui/missing/missing-comma-in-match.stderr b/src/test/ui/missing/missing-comma-in-match.stderr index fe210f697c446..58897a499e8cb 100644 --- a/src/test/ui/missing/missing-comma-in-match.stderr +++ b/src/test/ui/missing/missing-comma-in-match.stderr @@ -5,6 +5,8 @@ LL | &None => 1 | - help: missing a comma here to end this `match` arm LL | &Some(2) => { 3 } | ^^ expected one of `,`, `.`, `?`, `}`, or an operator + | + = help: closures are written `|a, b| a + b` and greater-than-or-equal is `>=`. error: aborting due to previous error From 3fb6d45af9c9e8a682da743f6d920bb5b6dd66de Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 15 Jun 2022 12:33:27 -0700 Subject: [PATCH 9/9] ENH Move --memory-init-file flag from EmLinker to asmjs target spec --- compiler/rustc_codegen_ssa/src/back/linker.rs | 2 -- .../rustc_target/src/spec/asmjs_unknown_emscripten.rs | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index ee097b5f05199..8ac5f094cf6ee 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1120,8 +1120,6 @@ impl<'a> Linker for EmLinker<'a> { OptLevel::Size => "-Os", OptLevel::SizeMin => "-Oz", }); - // Unusable until https://github.com/rust-lang/rust/issues/38454 is resolved - self.cmd.args(&["--memory-init-file", "0"]); } fn pgo_gen(&mut self) { diff --git a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs index a90c7b7bc6f07..269bf8b8bcd49 100644 --- a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs @@ -2,10 +2,10 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target}; pub fn target() -> Target { let mut target = wasm32_unknown_emscripten::target(); - target - .post_link_args - .entry(LinkerFlavor::Em) - .or_default() - .extend(vec!["-s".into(), "WASM=0".into()]); + target.post_link_args.entry(LinkerFlavor::Em).or_default().extend(vec![ + "-sWASM=0".into(), + "--memory-init-file".into(), + "0".into(), + ]); target }