diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/Cargo.toml | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics.rs | 15 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 27 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/tests.rs | 2 |
5 files changed, 36 insertions, 20 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index 2dfccd191..b0a453961 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -17,9 +17,9 @@ ena = "0.14.0" | |||
17 | log = "0.4.8" | 17 | log = "0.4.8" |
18 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
19 | scoped-tls = "1" | 19 | scoped-tls = "1" |
20 | chalk-solve = { version = "0.45", default-features = false } | 20 | chalk-solve = { version = "0.47", default-features = false } |
21 | chalk-ir = "0.45" | 21 | chalk-ir = "0.47" |
22 | chalk-recursive = "0.45" | 22 | chalk-recursive = "0.47" |
23 | 23 | ||
24 | stdx = { path = "../stdx", version = "0.0.0" } | 24 | stdx = { path = "../stdx", version = "0.0.0" } |
25 | hir_def = { path = "../hir_def", version = "0.0.0" } | 25 | hir_def = { path = "../hir_def", version = "0.0.0" } |
@@ -31,7 +31,7 @@ syntax = { path = "../syntax", version = "0.0.0" } | |||
31 | test_utils = { path = "../test_utils", version = "0.0.0" } | 31 | test_utils = { path = "../test_utils", version = "0.0.0" } |
32 | 32 | ||
33 | [dev-dependencies] | 33 | [dev-dependencies] |
34 | expect-test = "1.0" | 34 | expect-test = "1.1" |
35 | tracing = "0.1" | 35 | tracing = "0.1" |
36 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } | 36 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } |
37 | tracing-tree = { version = "0.1.4" } | 37 | tracing-tree = { version = "0.1.4" } |
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs index 14e18f5a1..c67a289f2 100644 --- a/crates/hir_ty/src/diagnostics.rs +++ b/crates/hir_ty/src/diagnostics.rs | |||
@@ -186,9 +186,10 @@ impl Diagnostic for MissingMatchArms { | |||
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | // Diagnostic: missing-ok-in-tail-expr | 189 | // Diagnostic: missing-ok-or-some-in-tail-expr |
190 | // | 190 | // |
191 | // This diagnostic is triggered if block that should return `Result` returns a value not wrapped in `Ok`. | 191 | // This diagnostic is triggered if a block that should return `Result` returns a value not wrapped in `Ok`, |
192 | // or if a block that should return `Option` returns a value not wrapped in `Some`. | ||
192 | // | 193 | // |
193 | // Example: | 194 | // Example: |
194 | // | 195 | // |
@@ -198,17 +199,19 @@ impl Diagnostic for MissingMatchArms { | |||
198 | // } | 199 | // } |
199 | // ``` | 200 | // ``` |
200 | #[derive(Debug)] | 201 | #[derive(Debug)] |
201 | pub struct MissingOkInTailExpr { | 202 | pub struct MissingOkOrSomeInTailExpr { |
202 | pub file: HirFileId, | 203 | pub file: HirFileId, |
203 | pub expr: AstPtr<ast::Expr>, | 204 | pub expr: AstPtr<ast::Expr>, |
205 | // `Some` or `Ok` depending on whether the return type is Result or Option | ||
206 | pub required: String, | ||
204 | } | 207 | } |
205 | 208 | ||
206 | impl Diagnostic for MissingOkInTailExpr { | 209 | impl Diagnostic for MissingOkOrSomeInTailExpr { |
207 | fn code(&self) -> DiagnosticCode { | 210 | fn code(&self) -> DiagnosticCode { |
208 | DiagnosticCode("missing-ok-in-tail-expr") | 211 | DiagnosticCode("missing-ok-or-some-in-tail-expr") |
209 | } | 212 | } |
210 | fn message(&self) -> String { | 213 | fn message(&self) -> String { |
211 | "wrap return expression in Ok".to_string() | 214 | format!("wrap return expression in {}", self.required) |
212 | } | 215 | } |
213 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | 216 | fn display_source(&self) -> InFile<SyntaxNodePtr> { |
214 | InFile { file_id: self.file, value: self.expr.clone().into() } | 217 | InFile { file_id: self.file, value: self.expr.clone().into() } |
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index b4e453411..a1c484fdf 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -11,8 +11,8 @@ use crate::{ | |||
11 | db::HirDatabase, | 11 | db::HirDatabase, |
12 | diagnostics::{ | 12 | diagnostics::{ |
13 | match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, | 13 | match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, |
14 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, | 14 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, |
15 | RemoveThisSemicolon, | 15 | MissingPatFields, RemoveThisSemicolon, |
16 | }, | 16 | }, |
17 | utils::variant_data, | 17 | utils::variant_data, |
18 | ApplicationTy, InferenceResult, Ty, TypeCtor, | 18 | ApplicationTy, InferenceResult, Ty, TypeCtor, |
@@ -306,27 +306,40 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
306 | }; | 306 | }; |
307 | 307 | ||
308 | let core_result_path = path![core::result::Result]; | 308 | let core_result_path = path![core::result::Result]; |
309 | let core_option_path = path![core::option::Option]; | ||
309 | 310 | ||
310 | let resolver = self.owner.resolver(db.upcast()); | 311 | let resolver = self.owner.resolver(db.upcast()); |
311 | let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) { | 312 | let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) { |
312 | Some(it) => it, | 313 | Some(it) => it, |
313 | _ => return, | 314 | _ => return, |
314 | }; | 315 | }; |
316 | let core_option_enum = match resolver.resolve_known_enum(db.upcast(), &core_option_path) { | ||
317 | Some(it) => it, | ||
318 | _ => return, | ||
319 | }; | ||
315 | 320 | ||
316 | let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); | 321 | let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); |
317 | let params = match &mismatch.expected { | 322 | let core_option_ctor = TypeCtor::Adt(AdtId::EnumId(core_option_enum)); |
323 | |||
324 | let (params, required) = match &mismatch.expected { | ||
318 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => { | 325 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => { |
319 | parameters | 326 | (parameters, "Ok".to_string()) |
327 | } | ||
328 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_option_ctor => { | ||
329 | (parameters, "Some".to_string()) | ||
320 | } | 330 | } |
321 | _ => return, | 331 | _ => return, |
322 | }; | 332 | }; |
323 | 333 | ||
324 | if params.len() == 2 && params[0] == mismatch.actual { | 334 | if params.len() > 0 && params[0] == mismatch.actual { |
325 | let (_, source_map) = db.body_with_source_map(self.owner.into()); | 335 | let (_, source_map) = db.body_with_source_map(self.owner.into()); |
326 | 336 | ||
327 | if let Ok(source_ptr) = source_map.expr_syntax(id) { | 337 | if let Ok(source_ptr) = source_map.expr_syntax(id) { |
328 | self.sink | 338 | self.sink.push(MissingOkOrSomeInTailExpr { |
329 | .push(MissingOkInTailExpr { file: source_ptr.file_id, expr: source_ptr.value }); | 339 | file: source_ptr.file_id, |
340 | expr: source_ptr.value, | ||
341 | required, | ||
342 | }); | ||
330 | } | 343 | } |
331 | } | 344 | } |
332 | } | 345 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 0e827a29e..e9e949c47 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -168,7 +168,7 @@ pub enum DisplayTarget { | |||
168 | 168 | ||
169 | impl DisplayTarget { | 169 | impl DisplayTarget { |
170 | fn is_source_code(&self) -> bool { | 170 | fn is_source_code(&self) -> bool { |
171 | matches!(self, Self::SourceCode {..}) | 171 | matches!(self, Self::SourceCode { .. }) |
172 | } | 172 | } |
173 | fn is_test(&self) -> bool { | 173 | fn is_test(&self) -> bool { |
174 | matches!(self, Self::Test) | 174 | matches!(self, Self::Test) |
@@ -595,7 +595,7 @@ impl HirDisplay for FnSig { | |||
595 | } | 595 | } |
596 | } | 596 | } |
597 | 597 | ||
598 | fn write_bounds_like_dyn_trait( | 598 | pub fn write_bounds_like_dyn_trait( |
599 | predicates: &[GenericPredicate], | 599 | predicates: &[GenericPredicate], |
600 | f: &mut HirFormatter, | 600 | f: &mut HirFormatter, |
601 | ) -> Result<(), HirDisplayError> { | 601 | ) -> Result<(), HirDisplayError> { |
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 0a400cb70..3b1675f0b 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs | |||
@@ -314,7 +314,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
314 | " | 314 | " |
315 | //- /lib.rs | 315 | //- /lib.rs |
316 | fn foo() -> i32 { | 316 | fn foo() -> i32 { |
317 | <|>1 + 1 | 317 | $01 + 1 |
318 | } | 318 | } |
319 | ", | 319 | ", |
320 | ); | 320 | ); |