Merge commit '76633199f4316b9c659d4ec0c102774d693cd940' into sync-from-rust

This commit is contained in:
Laurențiu Nicola 2023-11-15 09:45:17 +02:00
commit 610eafe009
7 changed files with 147 additions and 32 deletions

View file

@ -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 {

View file

@ -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)),

View file

@ -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 {

View file

@ -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(())
}
}

View file

@ -1225,6 +1225,22 @@ fn foo(mut foo: Foo) {
};
call_me();
}
"#,
);
}
#[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();
}
"#,
);
}

View file

@ -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
```
---

View file

@ -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::{