about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@dend.ro>2023-11-15 09:45:17 +0200
committerLaurențiu Nicola <lnicola@dend.ro>2023-11-15 09:45:17 +0200
commit610eafe0093f11ac3cb8c8c23baa2391d3bf4a1b (patch)
tree207e18a139b3f6d7e1a4e6fda1f91bdc3e692dba
parentd45ff2484f8da763e27e72db678d44d61a22d0ef (diff)
parent76633199f4316b9c659d4ec0c102774d693cd940 (diff)
downloadrust-610eafe0093f11ac3cb8c8c23baa2391d3bf4a1b.tar.gz
rust-610eafe0093f11ac3cb8c8c23baa2391d3bf4a1b.zip
Merge commit '76633199f4316b9c659d4ec0c102774d693cd940' into sync-from-rust
-rw-r--r--crates/hir-def/src/import_map.rs6
-rw-r--r--crates/hir-ty/src/chalk_ext.rs5
-rw-r--r--crates/hir-ty/src/infer/closure.rs27
-rw-r--r--crates/hir/src/display.rs59
-rw-r--r--crates/ide-diagnostics/src/handlers/mutability_errors.rs16
-rw-r--r--crates/ide/src/hover/tests.rs61
-rw-r--r--crates/parser/src/event.rs5
7 files changed, 147 insertions, 32 deletions
diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs
index c0b507d3911..6461439bb71 100644
--- a/crates/hir-def/src/import_map.rs
+++ b/crates/hir-def/src/import_map.rs
@@ -111,7 +111,11 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
 
         let visible_items = mod_data.scope.entries().filter_map(|(name, per_ns)| {
             let per_ns = per_ns.filter_visibility(|vis| vis == Visibility::Public);
-            if per_ns.is_none() { None } else { Some((name, per_ns)) }
+            if per_ns.is_none() {
+                None
+            } else {
+                Some((name, per_ns))
+            }
         });
 
         for (name, per_ns) in visible_items {
diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs
index c0b243ea248..c9ab356854b 100644
--- a/crates/hir-ty/src/chalk_ext.rs
+++ b/crates/hir-ty/src/chalk_ext.rs
@@ -28,6 +28,7 @@ pub trait TyExt {
     fn is_unknown(&self) -> bool;
     fn contains_unknown(&self) -> bool;
     fn is_ty_var(&self) -> bool;
+    fn is_union(&self) -> bool;
 
     fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
     fn as_builtin(&self) -> Option<BuiltinType>;
@@ -96,6 +97,10 @@ impl TyExt for Ty {
         matches!(self.kind(Interner), TyKind::InferenceVar(_, _))
     }
 
+    fn is_union(&self) -> bool {
+        matches!(self.adt_id(Interner), Some(AdtId(hir_def::AdtId::UnionId(_))))
+    }
+
     fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
         match self.kind(Interner) {
             TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 0805e20447a..af74df1032c 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -735,6 +735,32 @@ impl InferenceContext<'_> {
         self.walk_expr(expr);
     }
 
+    fn restrict_precision_for_unsafe(&mut self) {
+        for capture in &mut self.current_captures {
+            let mut ty = self.table.resolve_completely(self.result[capture.place.local].clone());
+            if ty.as_raw_ptr().is_some() || ty.is_union() {
+                capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
+                capture.place.projections.truncate(0);
+                continue;
+            }
+            for (i, p) in capture.place.projections.iter().enumerate() {
+                ty = p.projected_ty(
+                    ty,
+                    self.db,
+                    |_, _, _| {
+                        unreachable!("Closure field only happens in MIR");
+                    },
+                    self.owner.module(self.db.upcast()).krate(),
+                );
+                if ty.as_raw_ptr().is_some() || ty.is_union() {
+                    capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
+                    capture.place.projections.truncate(i + 1);
+                    break;
+                }
+            }
+        }
+    }
+
     fn adjust_for_move_closure(&mut self) {
         for capture in &mut self.current_captures {
             if let Some(first_deref) =
@@ -924,6 +950,7 @@ impl InferenceContext<'_> {
                 self.result.mutated_bindings_in_closure.insert(item.place.local);
             }
         }
+        self.restrict_precision_for_unsafe();
         // closure_kind should be done before adjust_for_move_closure
         let closure_kind = self.closure_kind();
         match capture_by {
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index ac171026d5d..cf3ff62fc6c 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -1,6 +1,6 @@
 //! HirDisplay implementations for various hir types.
 use hir_def::{
-    data::adt::VariantData,
+    data::adt::{StructKind, VariantData},
     generics::{
         TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
     },
@@ -163,7 +163,40 @@ impl HirDisplay for Struct {
         write!(f, "{}", self.name(f.db).display(f.db.upcast()))?;
         let def_id = GenericDefId::AdtId(AdtId::StructId(self.id));
         write_generic_params(def_id, f)?;
+
+        let variant_data = self.variant_data(f.db);
+        if let StructKind::Tuple = variant_data.kind() {
+            f.write_char('(')?;
+            let mut it = variant_data.fields().iter().peekable();
+
+            while let Some((id, _)) = it.next() {
+                let field = Field { parent: (*self).into(), id };
+                field.ty(f.db).hir_fmt(f)?;
+                if it.peek().is_some() {
+                    f.write_str(", ")?;
+                }
+            }
+
+            f.write_str(");")?;
+        }
+
         write_where_clause(def_id, f)?;
+
+        if let StructKind::Record = variant_data.kind() {
+            let fields = self.fields(f.db);
+            if fields.is_empty() {
+                f.write_str(" {}")?;
+            } else {
+                f.write_str(" {\n")?;
+                for field in self.fields(f.db) {
+                    f.write_str("    ")?;
+                    field.hir_fmt(f)?;
+                    f.write_str(",\n")?;
+                }
+                f.write_str("}")?;
+            }
+        }
+
         Ok(())
     }
 }
@@ -176,6 +209,18 @@ impl HirDisplay for Enum {
         let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id));
         write_generic_params(def_id, f)?;
         write_where_clause(def_id, f)?;
+
+        let variants = self.variants(f.db);
+        if !variants.is_empty() {
+            f.write_str(" {\n")?;
+            for variant in variants {
+                f.write_str("    ")?;
+                variant.hir_fmt(f)?;
+                f.write_str(",\n")?;
+            }
+            f.write_str("}")?;
+        }
+
         Ok(())
     }
 }
@@ -188,6 +233,18 @@ impl HirDisplay for Union {
         let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id));
         write_generic_params(def_id, f)?;
         write_where_clause(def_id, f)?;
+
+        let fields = self.fields(f.db);
+        if !fields.is_empty() {
+            f.write_str(" {\n")?;
+            for field in self.fields(f.db) {
+                f.write_str("    ")?;
+                field.hir_fmt(f)?;
+                f.write_str(",\n")?;
+            }
+            f.write_str("}")?;
+        }
+
         Ok(())
     }
 }
diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index ee096a100aa..1875111492c 100644
--- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -1228,4 +1228,20 @@ fn foo(mut foo: Foo) {
 "#,
         );
     }
+
+    #[test]
+    fn regression_15670() {
+        check_diagnostics(
+            r#"
+//- minicore: fn
+
+pub struct A {}
+pub unsafe fn foo(a: *mut A) {
+    let mut b = || -> *mut A { &mut *a };
+      //^^^^^ 💡 warn: variable does not need to be mutable
+    let _ = b();
+}
+"#,
+        );
+    }
 }
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index e54bc48d555..d3d492f3fde 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -1136,7 +1136,9 @@ impl Thing {
                 ```
 
                 ```rust
-                struct Thing
+                struct Thing {
+                    x: u32,
+                }
                 ```
             "#]],
     );
@@ -1155,7 +1157,9 @@ impl Thing {
                 ```
 
                 ```rust
-                struct Thing
+                struct Thing {
+                    x: u32,
+                }
                 ```
             "#]],
     );
@@ -1174,7 +1178,9 @@ impl Thing {
                 ```
 
                 ```rust
-                enum Thing
+                enum Thing {
+                    A,
+                }
                 ```
             "#]],
     );
@@ -1193,7 +1199,9 @@ impl Thing {
                 ```
 
                 ```rust
-                enum Thing
+                enum Thing {
+                    A,
+                }
                 ```
             "#]],
     );
@@ -2005,7 +2013,10 @@ fn test_hover_layout_of_enum() {
             ```
 
             ```rust
-            enum Foo // size = 16 (0x10), align = 8, niches = 254
+            enum Foo {
+                Variant1(u8, u16),
+                Variant2(i32, u8, i64),
+            } // size = 16 (0x10), align = 8, niches = 254
             ```
         "#]],
     );
@@ -2346,7 +2357,7 @@ fn main() { let s$0t = S{ f1:0 }; }
                                     focus_range: 7..8,
                                     name: "S",
                                     kind: Struct,
-                                    description: "struct S",
+                                    description: "struct S {\n    f1: u32,\n}",
                                 },
                             },
                         ],
@@ -2379,7 +2390,7 @@ fn main() { let s$0t = S{ f1:Arg(0) }; }
                                     focus_range: 24..25,
                                     name: "S",
                                     kind: Struct,
-                                    description: "struct S<T>",
+                                    description: "struct S<T> {\n    f1: T,\n}",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2392,7 +2403,7 @@ fn main() { let s$0t = S{ f1:Arg(0) }; }
                                     focus_range: 7..10,
                                     name: "Arg",
                                     kind: Struct,
-                                    description: "struct Arg",
+                                    description: "struct Arg(u32);",
                                 },
                             },
                         ],
@@ -2438,7 +2449,7 @@ fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; }
                                     focus_range: 24..25,
                                     name: "S",
                                     kind: Struct,
-                                    description: "struct S<T>",
+                                    description: "struct S<T> {\n    f1: T,\n}",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2451,7 +2462,7 @@ fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; }
                                     focus_range: 7..10,
                                     name: "Arg",
                                     kind: Struct,
-                                    description: "struct Arg",
+                                    description: "struct Arg(u32);",
                                 },
                             },
                         ],
@@ -2487,7 +2498,7 @@ fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
                                 focus_range: 7..8,
                                 name: "A",
                                 kind: Struct,
-                                description: "struct A",
+                                description: "struct A(u32);",
                             },
                         },
                         HoverGotoTypeData {
@@ -2500,7 +2511,7 @@ fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
                                 focus_range: 22..23,
                                 name: "B",
                                 kind: Struct,
-                                description: "struct B",
+                                description: "struct B(u32);",
                             },
                         },
                         HoverGotoTypeData {
@@ -2514,7 +2525,7 @@ fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
                                 name: "C",
                                 kind: Struct,
                                 container_name: "M",
-                                description: "pub struct C",
+                                description: "pub struct C(u32);",
                             },
                         },
                     ],
@@ -2704,7 +2715,7 @@ fn main() { let s$0t = foo(); }
                                     focus_range: 39..41,
                                     name: "S1",
                                     kind: Struct,
-                                    description: "struct S1",
+                                    description: "struct S1 {}",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2717,7 +2728,7 @@ fn main() { let s$0t = foo(); }
                                     focus_range: 52..54,
                                     name: "S2",
                                     kind: Struct,
-                                    description: "struct S2",
+                                    description: "struct S2 {}",
                                 },
                             },
                         ],
@@ -2808,7 +2819,7 @@ fn foo(ar$0g: &impl Foo + Bar<S>) {}
                                     focus_range: 36..37,
                                     name: "S",
                                     kind: Struct,
-                                    description: "struct S",
+                                    description: "struct S {}",
                                 },
                             },
                         ],
@@ -2908,7 +2919,7 @@ fn foo(ar$0g: &impl Foo<S>) {}
                                     focus_range: 23..24,
                                     name: "S",
                                     kind: Struct,
-                                    description: "struct S",
+                                    description: "struct S {}",
                                 },
                             },
                         ],
@@ -2945,7 +2956,7 @@ fn main() { let s$0t = foo(); }
                                     focus_range: 49..50,
                                     name: "B",
                                     kind: Struct,
-                                    description: "struct B<T>",
+                                    description: "struct B<T> {}",
                                 },
                             },
                             HoverGotoTypeData {
@@ -3034,7 +3045,7 @@ fn foo(ar$0g: &dyn Foo<S>) {}
                                     focus_range: 23..24,
                                     name: "S",
                                     kind: Struct,
-                                    description: "struct S",
+                                    description: "struct S {}",
                                 },
                             },
                         ],
@@ -3082,7 +3093,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
                                     focus_range: 50..51,
                                     name: "B",
                                     kind: Struct,
-                                    description: "struct B<T>",
+                                    description: "struct B<T> {}",
                                 },
                             },
                             HoverGotoTypeData {
@@ -3108,7 +3119,7 @@ fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
                                     focus_range: 65..66,
                                     name: "S",
                                     kind: Struct,
-                                    description: "struct S",
+                                    description: "struct S {}",
                                 },
                             },
                         ],
@@ -3335,7 +3346,7 @@ struct S$0T<const C: usize = 1, T = Foo>(T);
             ```
 
             ```rust
-            struct ST<const C: usize = 1, T = Foo>
+            struct ST<const C: usize = 1, T = Foo>(T);
             ```
         "#]],
     );
@@ -3356,7 +3367,7 @@ struct S$0T<const C: usize = {40 + 2}, T = Foo>(T);
             ```
 
             ```rust
-            struct ST<const C: usize = {const}, T = Foo>
+            struct ST<const C: usize = {const}, T = Foo>(T);
             ```
         "#]],
     );
@@ -3378,7 +3389,7 @@ struct S$0T<const C: usize = VAL, T = Foo>(T);
             ```
 
             ```rust
-            struct ST<const C: usize = VAL, T = Foo>
+            struct ST<const C: usize = VAL, T = Foo>(T);
             ```
         "#]],
     );
@@ -5935,7 +5946,7 @@ pub struct Foo(i32);
             ```
 
             ```rust
-            pub struct Foo // size = 4, align = 4
+            pub struct Foo(i32); // size = 4, align = 4
             ```
 
             ---
diff --git a/crates/parser/src/event.rs b/crates/parser/src/event.rs
index 577eb0967b4..e38571dd3ec 100644
--- a/crates/parser/src/event.rs
+++ b/crates/parser/src/event.rs
@@ -2,11 +2,6 @@
 //! It is intended to be completely decoupled from the
 //! parser, so as to allow to evolve the tree representation
 //! and the parser algorithm independently.
-//!
-//! The `TreeSink` trait is the bridge between the parser and the
-//! tree builder: the parser produces a stream of events like
-//! `start node`, `finish node`, and `FileBuilder` converts
-//! this stream to a real tree.
 use std::mem;
 
 use crate::{