about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_data_structures/src/unord.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs23
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs10
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs11
-rw-r--r--compiler/rustc_resolve/src/ident.rs89
-rw-r--r--src/librustdoc/html/render/mod.rs5
-rw-r--r--src/librustdoc/html/templates/item_info.html2
-rw-r--r--src/librustdoc/html/templates/item_union.html11
-rw-r--r--src/librustdoc/html/templates/print_item.html4
-rw-r--r--tests/rustdoc-gui/fields.goml18
-rw-r--r--tests/rustdoc-gui/src/test_docs/lib.rs21
-rw-r--r--tests/rustdoc/union-fields-html.rs11
-rw-r--r--tests/ui/impl-trait/in-trait/suggest-missing-item.fixed5
-rw-r--r--tests/ui/impl-trait/in-trait/suggest-missing-item.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/suggest-missing-item.stderr9
15 files changed, 134 insertions, 95 deletions
diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs
index e18c7b415f6..2b21815b687 100644
--- a/compiler/rustc_data_structures/src/unord.rs
+++ b/compiler/rustc_data_structures/src/unord.rs
@@ -107,6 +107,10 @@ impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
     {
         UnordItems(self.0.flat_map(f))
     }
+
+    pub fn collect<C: From<UnordItems<T, I>>>(self) -> C {
+        self.into()
+    }
 }
 
 impl<T> UnordItems<T, std::iter::Empty<T>> {
@@ -161,10 +165,6 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
         items.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
         items
     }
-
-    pub fn collect<C: From<UnordItems<T, I>>>(self) -> C {
-        self.into()
-    }
 }
 
 /// This is a set collection type that tries very hard to not expose
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 4247869ce76..1dfe053b215 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/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index cbe77e7b16d..f9cd01fd80d 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 243057b99bc..7708deecec7 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()
     }
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index ec0a8535e71..e29a1626aed 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 {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 5bd9389a400..c5d6771c2fd 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 d2ea9bdae9c..9e65ae95e15 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() %}
-    <span class="item-info"> {# #}
+    <span class="item-info">
         {% 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 a01457971c1..f6d2fa34890 100644
--- a/src/librustdoc/html/templates/item_union.html
+++ b/src/librustdoc/html/templates/item_union.html
@@ -4,14 +4,15 @@
 </code></pre>
 {{ self.document() | safe }}
 {% if self.fields_iter().peek().is_some() %}
-    <h2 id="fields" class="fields small-section-header">
-        Fields<a href="#fields" class="anchor">§</a>
+    <h2 id="fields" class="fields small-section-header"> {# #}
+        Fields<a href="#fields" class="anchor">§</a> {# #}
     </h2>
     {% for (field, ty) in self.fields_iter() %}
         {% let name = field.name.expect("union field name") %}
-        <span id="structfield.{{ name }}" class="{{ ItemType::StructField }} small-section-header">
-            <a href="#structfield.{{ name }}" class="anchor field">§</a>
-            <code>{{ name }}: {{ self.print_ty(ty) | safe }}</code>
+        <span id="structfield.{{ name }}" {#+ #}
+            class="{{ ItemType::StructField +}} small-section-header"> {# #}
+            <a href="#structfield.{{ name }}" class="anchor field">§</a> {# #}
+            <code>{{ name }}: {{+ self.print_ty(ty) | safe }}</code> {# #}
         </span>
         {% if let Some(stability_class) = self.stability_field(field) %}
             <span class="stab {{ stability_class }}"></span>
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
index edabac9a082..68a295ae095 100644
--- a/src/librustdoc/html/templates/print_item.html
+++ b/src/librustdoc/html/templates/print_item.html
@@ -1,5 +1,5 @@
 <div class="main-heading"> {# #}
-    <h1> {# #}
+    <h1>
         {{typ}}
         {# The breadcrumbs of the item path, like std::string #}
         {% for component in path_components %}
@@ -12,7 +12,7 @@
                 alt="Copy item path"> {# #}
         </button> {# #}
     </h1> {# #}
-    <span class="out-of-band"> {# #}
+    <span class="out-of-band">
         {% if !stability_since_raw.is_empty() %}
         {{ stability_since_raw|safe +}} · {#+ #}
         {% endif %}
diff --git a/tests/rustdoc-gui/fields.goml b/tests/rustdoc-gui/fields.goml
new file mode 100644
index 00000000000..b8139a2edac
--- /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 6ad1e8b4f67..c040fa02dff 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 00000000000..1ac01232c3e
--- /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,
+}
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 16c4d15ddcd..d9f775a6c84 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 f218e6cb581..26979b5149b 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 d96641fe163..44f98896eb3 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