From 0cac8455e6f7587228458ef5607e8d3e6f71f347 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Sun, 11 Jun 2023 22:45:04 -0400 Subject: [PATCH 1/5] Applied nits --- compiler/rustc_data_structures/src/unord.rs | 8 ++++---- compiler/rustc_incremental/src/persist/dirty_clean.rs | 10 ++++------ compiler/rustc_incremental/src/persist/fs.rs | 11 +++++------ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index e18c7b415f6cf..2b21815b687d5 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -107,6 +107,10 @@ impl> UnordItems { { UnordItems(self.0.flat_map(f)) } + + pub fn collect>>(self) -> C { + self.into() + } } impl UnordItems> { @@ -161,10 +165,6 @@ impl> UnordItems { items.sort_by_cached_key(|x| x.to_stable_hash_key(hcx)); items } - - pub fn collect>>(self) -> C { - self.into() - } } /// This is a set collection type that tries very hard to not expose diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index cbe77e7b16de8..f9cd01fd80dbb 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -198,7 +198,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { let (name, mut auto) = self.auto_labels(item_id, attr); let except = self.except(attr); let loaded_from_disk = self.loaded_from_disk(attr); - for e in except.items().map(|x| x.as_str()).into_sorted_stable_ord() { + for e in except.items().into_sorted_stable_ord() { if !auto.remove(e) { self.tcx.sess.emit_fatal(errors::AssertionAuto { span: attr.span, name, e }); } @@ -377,17 +377,15 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { continue; }; self.checked_attrs.insert(attr.id); - for label in assertion.clean.items().map(|x| x.as_str()).into_sorted_stable_ord() { + for label in assertion.clean.items().into_sorted_stable_ord() { let dep_node = DepNode::from_label_string(self.tcx, &label, def_path_hash).unwrap(); self.assert_clean(item_span, dep_node); } - for label in assertion.dirty.items().map(|x| x.as_str()).into_sorted_stable_ord() { + for label in assertion.dirty.items().into_sorted_stable_ord() { let dep_node = DepNode::from_label_string(self.tcx, &label, def_path_hash).unwrap(); self.assert_dirty(item_span, dep_node); } - for label in - assertion.loaded_from_disk.items().map(|x| x.as_str()).into_sorted_stable_ord() - { + for label in assertion.loaded_from_disk.items().into_sorted_stable_ord() { let dep_node = DepNode::from_label_string(self.tcx, &label, def_path_hash).unwrap(); self.assert_loaded_from_disk(item_span, dep_node); } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 243057b99bca2..7708deecec713 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -855,12 +855,11 @@ fn all_except_most_recent( let most_recent = deletion_candidates.items().map(|(&(timestamp, _), _)| timestamp).max(); if let Some(most_recent) = most_recent { - UnordMap::from( - deletion_candidates - .into_items() - .filter(|&((timestamp, _), _)| timestamp != most_recent) - .map(|((_, path), lock)| (path, lock)), - ) + deletion_candidates + .into_items() + .filter(|&((timestamp, _), _)| timestamp != most_recent) + .map(|((_, path), lock)| (path, lock)) + .collect() } else { UnordMap::default() } From c007293e293fce01c73928bd34ad3a901262c730 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 21 Jun 2023 17:45:38 +0300 Subject: [PATCH 2/5] resolve: Minor cleanup to `fn resolve_path_with_ribs` A single-use closure is inlined and one unnecessary enum is removed. --- compiler/rustc_resolve/src/ident.rs | 89 ++++++++++++----------------- 1 file changed, 38 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index ec0a8535e7180..e29a1626aedd2 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1459,60 +1459,47 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); } - enum FindBindingResult<'a> { - Binding(Result<&'a NameBinding<'a>, Determinacy>), - Res(Res), - } - let find_binding_in_ns = |this: &mut Self, ns| { - let binding = if let Some(module) = module { - this.resolve_ident_in_module( - module, - ident, - ns, - parent_scope, - finalize, - ignore_binding, - ) - } else if let Some(ribs) = ribs - && let Some(TypeNS | ValueNS) = opt_ns - { - match this.resolve_ident_in_lexical_scope( - ident, - ns, - parent_scope, - finalize, - &ribs[ns], - ignore_binding, - ) { - // we found a locally-imported or available item/module - Some(LexicalScopeBinding::Item(binding)) => Ok(binding), - // we found a local variable or type param - Some(LexicalScopeBinding::Res(res)) => return FindBindingResult::Res(res), - _ => Err(Determinacy::determined(finalize.is_some())), + let binding = if let Some(module) = module { + self.resolve_ident_in_module( + module, + ident, + ns, + parent_scope, + finalize, + ignore_binding, + ) + } else if let Some(ribs) = ribs && let Some(TypeNS | ValueNS) = opt_ns { + match self.resolve_ident_in_lexical_scope( + ident, + ns, + parent_scope, + finalize, + &ribs[ns], + ignore_binding, + ) { + // we found a locally-imported or available item/module + Some(LexicalScopeBinding::Item(binding)) => Ok(binding), + // we found a local variable or type param + Some(LexicalScopeBinding::Res(res)) => { + record_segment_res(self, res); + return PathResult::NonModule(PartialRes::with_unresolved_segments( + res, + path.len() - 1, + )); } - } else { - let scopes = ScopeSet::All(ns, opt_ns.is_none()); - this.early_resolve_ident_in_lexical_scope( - ident, - scopes, - parent_scope, - finalize, - finalize.is_some(), - ignore_binding, - ) - }; - FindBindingResult::Binding(binding) - }; - let binding = match find_binding_in_ns(self, ns) { - FindBindingResult::Res(res) => { - record_segment_res(self, res); - return PathResult::NonModule(PartialRes::with_unresolved_segments( - res, - path.len() - 1, - )); + _ => Err(Determinacy::determined(finalize.is_some())), } - FindBindingResult::Binding(binding) => binding, + } else { + self.early_resolve_ident_in_lexical_scope( + ident, + ScopeSet::All(ns, opt_ns.is_none()), + parent_scope, + finalize, + finalize.is_some(), + ignore_binding, + ) }; + match binding { Ok(binding) => { if segment_idx == 1 { From 6f485269632c031b6b698a8f7bf820839dca4f2b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 21 Jun 2023 17:25:19 +0200 Subject: [PATCH 3/5] Fix union fields display --- src/librustdoc/html/render/mod.rs | 5 ++--- src/librustdoc/html/templates/item_info.html | 2 +- src/librustdoc/html/templates/item_union.html | 11 ++++++----- src/librustdoc/html/templates/print_item.html | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 5bd9389a400af..c5d6771c2fdd3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -421,11 +421,10 @@ fn document<'a, 'cx: 'a>( display_fn(move |f| { document_item_info(cx, item, parent).render_into(f).unwrap(); if parent.is_none() { - write!(f, "{}", document_full_collapsible(item, cx, heading_offset))?; + write!(f, "{}", document_full_collapsible(item, cx, heading_offset)) } else { - write!(f, "{}", document_full(item, cx, heading_offset))?; + write!(f, "{}", document_full(item, cx, heading_offset)) } - Ok(()) }) } diff --git a/src/librustdoc/html/templates/item_info.html b/src/librustdoc/html/templates/item_info.html index d2ea9bdae9c65..9e65ae95e15d2 100644 --- a/src/librustdoc/html/templates/item_info.html +++ b/src/librustdoc/html/templates/item_info.html @@ -1,5 +1,5 @@ {% if !items.is_empty() %} - {# #} + {% for item in items %} {{item|safe}} {# #} {% endfor %} diff --git a/src/librustdoc/html/templates/item_union.html b/src/librustdoc/html/templates/item_union.html index a01457971c178..f6d2fa3489081 100644 --- a/src/librustdoc/html/templates/item_union.html +++ b/src/librustdoc/html/templates/item_union.html @@ -4,14 +4,15 @@ {{ self.document() | safe }} {% if self.fields_iter().peek().is_some() %} -

- Fields§ +

{# #} + Fields§ {# #}

{% for (field, ty) in self.fields_iter() %} {% let name = field.name.expect("union field name") %} - - § - {{ name }}: {{ self.print_ty(ty) | safe }} + {# #} + § {# #} + {{ name }}: {{+ self.print_ty(ty) | safe }} {# #} {% if let Some(stability_class) = self.stability_field(field) %} diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index edabac9a08231..68a295ae095aa 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -1,5 +1,5 @@
{# #} -

{# #} +

{{typ}} {# The breadcrumbs of the item path, like std::string #} {% for component in path_components %} @@ -12,7 +12,7 @@

{# #} alt="Copy item path"> {# #} {# #}

{# #} - {# #} + {% if !stability_since_raw.is_empty() %} {{ stability_since_raw|safe +}} · {#+ #} {% endif %} From 805edb0a4a028d1d0f4f7f776ac8d2d36f131dd4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 21 Jun 2023 17:42:53 +0200 Subject: [PATCH 4/5] Add test to prevent regression for fields display --- tests/rustdoc-gui/fields.goml | 18 ++++++++++++++++++ tests/rustdoc-gui/src/test_docs/lib.rs | 21 +++++++++++++++++++++ tests/rustdoc/union-fields-html.rs | 11 +++++++++++ 3 files changed, 50 insertions(+) create mode 100644 tests/rustdoc-gui/fields.goml create mode 100644 tests/rustdoc/union-fields-html.rs diff --git a/tests/rustdoc-gui/fields.goml b/tests/rustdoc-gui/fields.goml new file mode 100644 index 0000000000000..b8139a2edac10 --- /dev/null +++ b/tests/rustdoc-gui/fields.goml @@ -0,0 +1,18 @@ +// This test checks that fields are displayed as expected (one by line). +go-to: "file://" + |DOC_PATH| + "/test_docs/fields/struct.Struct.html" +store-position: ("#structfield\.a", {"y": a_y}) +store-position: ("#structfield\.b", {"y": b_y}) +assert: |a_y| < |b_y| + +go-to: "file://" + |DOC_PATH| + "/test_docs/fields/union.Union.html" +store-position: ("#structfield\.a", {"y": a_y}) +store-position: ("#structfield\.b", {"y": b_y}) +assert: |a_y| < |b_y| + +go-to: "file://" + |DOC_PATH| + "/test_docs/fields/enum.Enum.html" +store-position: ("#variant\.A\.field\.a", {"y": a_y}) +store-position: ("#variant\.A\.field\.b", {"y": b_y}) +assert: |a_y| < |b_y| +store-position: ("#variant\.B\.field\.a", {"y": a_y}) +store-position: ("#variant\.B\.field\.b", {"y": b_y}) +assert: |a_y| < |b_y| diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs index 6ad1e8b4f673f..c040fa02dffeb 100644 --- a/tests/rustdoc-gui/src/test_docs/lib.rs +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -486,3 +486,24 @@ pub mod search_results { } } + +pub mod fields { + pub struct Struct { + pub a: u8, + pub b: u32, + } + pub union Union { + pub a: u8, + pub b: u32, + } + pub enum Enum { + A { + a: u8, + b: u32, + }, + B { + a: u8, + b: u32, + }, + } +} diff --git a/tests/rustdoc/union-fields-html.rs b/tests/rustdoc/union-fields-html.rs new file mode 100644 index 0000000000000..1ac01232c3e6b --- /dev/null +++ b/tests/rustdoc/union-fields-html.rs @@ -0,0 +1,11 @@ +#![crate_name = "foo"] + +// @has 'foo/union.Union.html' +// Checking that there is a whitespace after `:`. +// @has - '//*[@id="structfield.a"]/code' 'a: u8' +// @has - '//*[@id="structfield.b"]/code' 'b: u32' +pub union Union { + pub a: u8, + /// tadam + pub b: u32, +} From 7563909a28a2add4e41cb653e4d7ebd50c97bce4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 21 Jun 2023 01:57:26 +0000 Subject: [PATCH 5/5] Liberate bound vars properly when suggesting missing AFIT --- compiler/rustc_hir_analysis/src/check/mod.rs | 23 ++++++++----------- .../in-trait/suggest-missing-item.fixed | 5 +++- .../in-trait/suggest-missing-item.rs | 2 ++ .../in-trait/suggest-missing-item.stderr | 9 +++++--- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 4247869ce7603..1dfe053b21530 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -470,19 +470,16 @@ fn suggestion_signature<'tcx>( ); match assoc.kind { - ty::AssocKind::Fn => { - // We skip the binder here because the binder would deanonymize all - // late-bound regions, and we don't want method signatures to show up - // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound - // regions just fine, showing `fn(&MyType)`. - fn_sig_suggestion( - tcx, - tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(), - assoc.ident(tcx), - tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), - assoc, - ) - } + ty::AssocKind::Fn => fn_sig_suggestion( + tcx, + tcx.liberate_late_bound_regions( + assoc.def_id, + tcx.fn_sig(assoc.def_id).subst(tcx, substs), + ), + assoc.ident(tcx), + tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), + assoc, + ), ty::AssocKind::Type => { let (generics, where_clauses) = bounds_from_generic_predicates( tcx, diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed index 16c4d15ddcd60..d9f775a6c8464 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed @@ -9,11 +9,14 @@ trait Trait { async fn bar() -> i32; fn test(&self) -> impl Sized + '_; + + async fn baz(&self) -> &i32; } struct S; -impl Trait for S {fn test(&self) -> impl Sized + '_ { todo!() } +impl Trait for S {async fn baz(&self) -> &i32 { todo!() } +fn test(&self) -> impl Sized + '_ { todo!() } async fn bar() -> i32 { todo!() } async fn foo() { todo!() } } diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs index f218e6cb581e3..26979b5149b06 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs @@ -9,6 +9,8 @@ trait Trait { async fn bar() -> i32; fn test(&self) -> impl Sized + '_; + + async fn baz(&self) -> &i32; } struct S; diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr index d96641fe16335..44f98896eb384 100644 --- a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr +++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr @@ -1,5 +1,5 @@ -error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test` - --> $DIR/suggest-missing-item.rs:16:1 +error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test`, `baz` + --> $DIR/suggest-missing-item.rs:18:1 | LL | async fn foo(); | --------------- `foo` from trait @@ -9,9 +9,12 @@ LL | async fn bar() -> i32; LL | LL | fn test(&self) -> impl Sized + '_; | ---------------------------------- `test` from trait +LL | +LL | async fn baz(&self) -> &i32; + | ---------------------------- `baz` from trait ... LL | impl Trait for S {} - | ^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `test` in implementation + | ^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `test`, `baz` in implementation error: aborting due to previous error