Unnamed repository; edit this file 'description' to name the repository.
Merge commit '76633199f4316b9c659d4ec0c102774d693cd940' into sync-from-rust
| -rw-r--r-- | crates/hir-def/src/import_map.rs | 6 | ||||
| -rw-r--r-- | crates/hir-ty/src/chalk_ext.rs | 5 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/closure.rs | 27 | ||||
| -rw-r--r-- | crates/hir/src/display.rs | 59 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/mutability_errors.rs | 16 | ||||
| -rw-r--r-- | crates/ide/src/hover/tests.rs | 61 | ||||
| -rw-r--r-- | crates/parser/src/event.rs | 5 |
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 c0b507d391..6461439bb7 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 c0b243ea24..c9ab356854 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 0805e20447..af74df1032 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 ac171026d5..cf3ff62fc6 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 ee096a100a..1875111492 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 e54bc48d55..d3d492f3fd 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 577eb0967b..e38571dd3e 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::{ |