From 1142112c70b705f59b7d559d9d72cdc831865158 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 14:51:08 +0200 Subject: Rename FnDef -> Fn --- crates/ra_hir_ty/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index 45bc14c37..016e689ff 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs @@ -81,7 +81,7 @@ fn check_types_impl(ra_fixture: &str, display_source: bool) { fn type_at_range(db: &TestDB, pos: FileRange) -> Ty { let file = db.parse(pos.file_id).ok().unwrap(); let expr = algo::find_node_at_range::(file.syntax(), pos.range).unwrap(); - let fn_def = expr.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); + let fn_def = expr.syntax().ancestors().find_map(ast::Fn::cast).unwrap(); let module = db.module_for_file(pos.file_id); let func = *module.child_by_source(db)[keys::FUNCTION] .get(&InFile::new(pos.file_id.into(), fn_def)) -- cgit v1.2.3 From 6f8aa75329d0a4e588e58b8f22f7932bf3d3a706 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 16:21:30 +0200 Subject: Rename RecordLit -> RecordExpr --- crates/ra_hir_ty/src/diagnostics.rs | 12 ++++++------ crates/ra_hir_ty/src/diagnostics/expr.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index 885abbaf2..f210c305a 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs @@ -29,7 +29,7 @@ pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut Diag #[derive(Debug)] pub struct NoSuchField { pub file: HirFileId, - pub field: AstPtr, + pub field: AstPtr, } impl Diagnostic for NoSuchField { @@ -47,19 +47,19 @@ impl Diagnostic for NoSuchField { } impl AstDiagnostic for NoSuchField { - type AST = ast::RecordField; + type AST = ast::RecordExprField; fn ast(&self, db: &dyn AstDatabase) -> Self::AST { let root = db.parse_or_expand(self.source().file_id).unwrap(); let node = self.source().value.to_node(&root); - ast::RecordField::cast(node).unwrap() + ast::RecordExprField::cast(node).unwrap() } } #[derive(Debug)] pub struct MissingFields { pub file: HirFileId, - pub field_list: AstPtr, + pub field_list: AstPtr, pub missed_fields: Vec, } @@ -80,12 +80,12 @@ impl Diagnostic for MissingFields { } impl AstDiagnostic for MissingFields { - type AST = ast::RecordFieldList; + type AST = ast::RecordExprFieldList; fn ast(&self, db: &dyn AstDatabase) -> Self::AST { let root = db.parse_or_expand(self.source().file_id).unwrap(); let node = self.source().value.to_node(&root); - ast::RecordFieldList::cast(node).unwrap() + ast::RecordExprFieldList::cast(node).unwrap() } } diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs index fd930eab1..f0e0f2988 100644 --- a/crates/ra_hir_ty/src/diagnostics/expr.rs +++ b/crates/ra_hir_ty/src/diagnostics/expr.rs @@ -100,8 +100,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> { if let Ok(source_ptr) = source_map.expr_syntax(id) { let root = source_ptr.file_syntax(db.upcast()); - if let ast::Expr::RecordLit(record_lit) = &source_ptr.value.to_node(&root) { - if let Some(field_list) = record_lit.record_field_list() { + if let ast::Expr::RecordExpr(record_lit) = &source_ptr.value.to_node(&root) { + if let Some(field_list) = record_lit.record_expr_field_list() { let variant_data = variant_data(db.upcast(), variant_def); let missed_fields = missed_fields .into_iter() -- cgit v1.2.3 From 797cdb00d91a221d62438b23dfd625a78163a58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Thu, 30 Jul 2020 20:37:28 +0300 Subject: Bump chalk --- crates/ra_hir_ty/src/traits/chalk.rs | 19 ++++++++----------- crates/ra_hir_ty/src/traits/chalk/mapping.rs | 22 ++++++++++++++++------ 2 files changed, 24 insertions(+), 17 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 5298dbecf..1c7065364 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -183,6 +183,7 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { .collect(), 1, ), + where_clauses: make_binders(vec![], 0), }; let num_vars = datas.num_binders; Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) }) @@ -193,15 +194,6 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { Ty::Unknown.to_chalk(self.db) } - fn force_impl_for( - &self, - _well_known: rust_ir::WellKnownTrait, - _ty: &chalk_ir::TyData, - ) -> Option { - // this method is mostly for rustc - None - } - fn is_object_safe(&self, _trait_id: chalk_ir::TraitId) -> bool { // FIXME: implement actual object safety true @@ -547,8 +539,13 @@ pub(crate) fn fn_def_datum_query( ), where_clauses, }; - let datum = - FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders), abi: () }; + let datum = FnDefDatum { + id: fn_def_id, + abi: (), + safety: chalk_ir::Safety::Safe, + variadic: sig.value.is_varargs, + binders: make_binders(bound, sig.num_binders), + }; Arc::new(datum) } diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 09d8347ca..b3e92993d 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs @@ -30,11 +30,16 @@ impl ToChalk for Ty { Ty::Apply(apply_ty) => match apply_ty.ctor { TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), - TypeCtor::FnPtr { num_args: _, is_varargs: _ } => { - // FIXME: handle is_varargs + TypeCtor::FnPtr { num_args: _, is_varargs } => { let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); - chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) - .intern(&Interner) + chalk_ir::TyData::Function(chalk_ir::FnPointer { + num_binders: 0, + abi: (), + safety: chalk_ir::Safety::Safe, + variadic: is_varargs, + substitution, + }) + .intern(&Interner) } _ => { let name = apply_ty.ctor.to_chalk(db); @@ -118,7 +123,12 @@ impl ToChalk for Ty { let parameters = from_chalk(db, opaque_ty.substitution); Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) } - chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, substitution }) => { + chalk_ir::TyData::Function(chalk_ir::FnPointer { + num_binders, + variadic, + substitution, + .. + }) => { assert_eq!(num_binders, 0); let parameters: Substs = from_chalk( db, @@ -127,7 +137,7 @@ impl ToChalk for Ty { Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16, - is_varargs: false, + is_varargs: variadic, }, parameters, }) -- cgit v1.2.3 From 14cb96ec0e6be3b99bfe4ea373c058dcbd2a4f79 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 31 Jul 2020 19:54:16 +0200 Subject: Allign RecordPat with RecordExpr --- crates/ra_hir_ty/src/diagnostics.rs | 2 +- crates/ra_hir_ty/src/diagnostics/expr.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index f210c305a..977c0525b 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs @@ -92,7 +92,7 @@ impl AstDiagnostic for MissingFields { #[derive(Debug)] pub struct MissingPatFields { pub file: HirFileId, - pub field_list: AstPtr, + pub field_list: AstPtr, pub missed_fields: Vec, } diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs index f0e0f2988..95bbf2d95 100644 --- a/crates/ra_hir_ty/src/diagnostics/expr.rs +++ b/crates/ra_hir_ty/src/diagnostics/expr.rs @@ -131,7 +131,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { if let Some(expr) = source_ptr.value.as_ref().left() { let root = source_ptr.file_syntax(db.upcast()); if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) { - if let Some(field_list) = record_pat.record_field_pat_list() { + if let Some(field_list) = record_pat.record_pat_field_list() { let variant_data = variant_data(db.upcast(), variant_def); let missed_fields = missed_fields .into_iter() -- cgit v1.2.3 From f089690a21357ca6d396bce98bf598f0954199b5 Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Thu, 6 Aug 2020 20:55:29 -0400 Subject: Account for static mut in missing unsafe diagnostic --- crates/ra_hir_ty/src/diagnostics/unsafe_check.rs | 38 ++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs index 5cc76bdce..61ffbf5d1 100644 --- a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use hir_def::{ body::Body, expr::{Expr, ExprId, UnaryOp}, + resolver::{resolver_for_expr, ResolveValueResult, ValueNs}, DefWithBodyId, }; use hir_expand::diagnostics::DiagnosticSink; @@ -70,7 +71,7 @@ pub fn unsafe_expressions( ) -> Vec { let mut unsafe_exprs = vec![]; let body = db.body(def); - walk_unsafe(&mut unsafe_exprs, db, infer, &body, body.body_expr, false); + walk_unsafe(&mut unsafe_exprs, db, infer, def, &body, body.body_expr, false); unsafe_exprs } @@ -79,6 +80,7 @@ fn walk_unsafe( unsafe_exprs: &mut Vec, db: &dyn HirDatabase, infer: &InferenceResult, + def: DefWithBodyId, body: &Body, current: ExprId, inside_unsafe_block: bool, @@ -97,6 +99,15 @@ fn walk_unsafe( } } } + Expr::Path(path) => { + let resolver = resolver_for_expr(db.upcast(), def, current); + let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path.mod_path()); + if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial { + if db.static_data(id).mutable { + unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); + } + } + } Expr::MethodCall { .. } => { if infer .method_resolution(current) @@ -112,13 +123,13 @@ fn walk_unsafe( } } Expr::Unsafe { body: child } => { - return walk_unsafe(unsafe_exprs, db, infer, body, *child, true); + return walk_unsafe(unsafe_exprs, db, infer, def, body, *child, true); } _ => {} } expr.walk_child_exprs(|child| { - walk_unsafe(unsafe_exprs, db, infer, body, child, inside_unsafe_block); + walk_unsafe(unsafe_exprs, db, infer, def, body, child, inside_unsafe_block); }); } @@ -167,6 +178,27 @@ fn main() { HasUnsafe.unsafe_fn(); } } +"#, + ); + } + + #[test] + fn missing_unsafe_diagnostic_with_static_mut() { + check_diagnostics( + r#" +struct Ty { + a: u8, +} + +static mut static_mut: Ty = Ty { a: 0 }; + +fn main() { + let x = static_mut.a; + //^^^^^^^^^^ This operation is unsafe and requires an unsafe function or block + unsafe { + let x = static_mut.a; + } +} "#, ); } -- cgit v1.2.3 From a39d503ef3ba26ec324639e22e46e1a8173b397e Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Sat, 8 Aug 2020 11:26:01 -0400 Subject: Add additional checks for union inference tests --- crates/ra_hir_ty/src/tests/simple.rs | 38 +++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 3fd7d5cd4..a2db6944d 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -334,16 +334,44 @@ fn infer_union() { bar: f32, } + fn test() { + let u = MyUnion { foo: 0 }; + unsafe { baz(u); } + let u = MyUnion { bar: 0.0 }; + unsafe { baz(u); } + } + unsafe fn baz(u: MyUnion) { let inner = u.foo; + let inner = u.bar; } "#, expect![[r#" - 61..62 'u': MyUnion - 73..99 '{ ...foo; }': () - 83..88 'inner': u32 - 91..92 'u': MyUnion - 91..96 'u.foo': u32 + 57..172 '{ ...); } }': () + 67..68 'u': MyUnion + 71..89 'MyUnio...o: 0 }': MyUnion + 86..87 '0': i32 + 95..113 'unsafe...(u); }': () + 102..113 '{ baz(u); }': () + 104..107 'baz': fn baz(MyUnion) + 104..110 'baz(u)': () + 108..109 'u': MyUnion + 122..123 'u': MyUnion + 126..146 'MyUnio... 0.0 }': MyUnion + 141..144 '0.0': f64 + 152..170 'unsafe...(u); }': () + 159..170 '{ baz(u); }': () + 161..164 'baz': fn baz(MyUnion) + 161..167 'baz(u)': () + 165..166 'u': MyUnion + 188..189 'u': MyUnion + 200..249 '{ ...bar; }': () + 210..215 'inner': u32 + 218..219 'u': MyUnion + 218..223 'u.foo': u32 + 233..238 'inner': f32 + 241..242 'u': MyUnion + 241..246 'u.bar': f32 "#]], ); } -- cgit v1.2.3 From 3bf033e54814919f2214ca4e9b73cebc5ba7d86d Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Fri, 7 Aug 2020 09:24:20 -0400 Subject: Add support for unions in inference and lowering --- crates/ra_hir_ty/src/infer.rs | 11 +++++++---- crates/ra_hir_ty/src/lower.rs | 5 ++++- crates/ra_hir_ty/src/tests/simple.rs | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 28f32a0a4..3d12039a6 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -440,6 +440,12 @@ impl<'a> InferenceContext<'a> { let ty = self.insert_type_vars(ty.subst(&substs)); forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) } + TypeNs::AdtId(AdtId::UnionId(u)) => { + let substs = Ty::substs_from_path(&ctx, path, u.into(), true); + let ty = self.db.ty(u.into()); + let ty = self.insert_type_vars(ty.subst(&substs)); + forbid_unresolved_segments((ty, Some(u.into())), unresolved) + } TypeNs::EnumVariantId(var) => { let substs = Ty::substs_from_path(&ctx, path, var.into(), true); let ty = self.db.ty(var.parent.into()); @@ -490,10 +496,7 @@ impl<'a> InferenceContext<'a> { // FIXME potentially resolve assoc type (Ty::Unknown, None) } - TypeNs::AdtId(AdtId::EnumId(_)) - | TypeNs::AdtId(AdtId::UnionId(_)) - | TypeNs::BuiltinType(_) - | TypeNs::TraitId(_) => { + TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { // FIXME diagnostic (Ty::Unknown, None) } diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 1eacc6f95..7638f167b 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -518,6 +518,7 @@ impl Ty { let (segment, generic_def) = match resolved { ValueTyDefId::FunctionId(it) => (last, Some(it.into())), ValueTyDefId::StructId(it) => (last, Some(it.into())), + ValueTyDefId::UnionId(it) => (last, Some(it.into())), ValueTyDefId::ConstId(it) => (last, Some(it.into())), ValueTyDefId::StaticId(_) => (last, None), ValueTyDefId::EnumVariantId(var) => { @@ -1148,11 +1149,12 @@ impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefI pub enum ValueTyDefId { FunctionId(FunctionId), StructId(StructId), + UnionId(UnionId), EnumVariantId(EnumVariantId), ConstId(ConstId), StaticId(StaticId), } -impl_from!(FunctionId, StructId, EnumVariantId, ConstId, StaticId for ValueTyDefId); +impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId); /// Build the declared type of an item. This depends on the namespace; e.g. for /// `struct Foo(usize)`, we have two types: The type of the struct itself, and @@ -1179,6 +1181,7 @@ pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders match def { ValueTyDefId::FunctionId(it) => type_for_fn(db, it), ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), + ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()), ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), ValueTyDefId::ConstId(it) => type_for_const(db, it), ValueTyDefId::StaticId(it) => type_for_static(db, it), diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index a2db6944d..5a7cf9455 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -350,7 +350,7 @@ fn infer_union() { 57..172 '{ ...); } }': () 67..68 'u': MyUnion 71..89 'MyUnio...o: 0 }': MyUnion - 86..87 '0': i32 + 86..87 '0': u32 95..113 'unsafe...(u); }': () 102..113 '{ baz(u); }': () 104..107 'baz': fn baz(MyUnion) @@ -358,7 +358,7 @@ fn infer_union() { 108..109 'u': MyUnion 122..123 'u': MyUnion 126..146 'MyUnio... 0.0 }': MyUnion - 141..144 '0.0': f64 + 141..144 '0.0': f32 152..170 'unsafe...(u); }': () 159..170 '{ baz(u); }': () 161..164 'baz': fn baz(MyUnion) -- cgit v1.2.3