diff options
-rw-r--r-- | crates/hir/src/diagnostics.rs | 23 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 28 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 17 | ||||
-rw-r--r-- | crates/ide/src/diagnostics.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/diagnostics/missing_match_arms.rs | 99 |
5 files changed, 62 insertions, 108 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index 5cffef47f..1f6a70006 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs | |||
@@ -3,8 +3,6 @@ | |||
3 | //! | 3 | //! |
4 | //! This probably isn't the best way to do this -- ideally, diagnistics should | 4 | //! This probably isn't the best way to do this -- ideally, diagnistics should |
5 | //! be expressed in terms of hir types themselves. | 5 | //! be expressed in terms of hir types themselves. |
6 | use std::any::Any; | ||
7 | |||
8 | use cfg::{CfgExpr, CfgOptions}; | 6 | use cfg::{CfgExpr, CfgOptions}; |
9 | use either::Either; | 7 | use either::Either; |
10 | use hir_def::path::ModPath; | 8 | use hir_def::path::ModPath; |
@@ -157,25 +155,4 @@ pub struct MissingMatchArms { | |||
157 | pub arms: AstPtr<ast::MatchArmList>, | 155 | pub arms: AstPtr<ast::MatchArmList>, |
158 | } | 156 | } |
159 | 157 | ||
160 | #[derive(Debug)] | ||
161 | pub struct InternalBailedOut { | ||
162 | pub file: HirFileId, | ||
163 | pub pat_syntax_ptr: SyntaxNodePtr, | ||
164 | } | ||
165 | |||
166 | impl Diagnostic for InternalBailedOut { | ||
167 | fn code(&self) -> DiagnosticCode { | ||
168 | DiagnosticCode("internal:match-check-bailed-out") | ||
169 | } | ||
170 | fn message(&self) -> String { | ||
171 | format!("Internal: match check bailed out") | ||
172 | } | ||
173 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
174 | InFile { file_id: self.file, value: self.pat_syntax_ptr.clone() } | ||
175 | } | ||
176 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
177 | self | ||
178 | } | ||
179 | } | ||
180 | |||
181 | pub use hir_ty::diagnostics::IncorrectCase; | 158 | pub use hir_ty::diagnostics::IncorrectCase; |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 2e794ff4a..7f689cd41 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -86,8 +86,8 @@ use crate::{ | |||
86 | pub use crate::{ | 86 | pub use crate::{ |
87 | attrs::{HasAttrs, Namespace}, | 87 | attrs::{HasAttrs, Namespace}, |
88 | diagnostics::{ | 88 | diagnostics::{ |
89 | AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, InternalBailedOut, | 89 | AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, MacroError, |
90 | MacroError, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, | 90 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, |
91 | MissingUnsafe, NoSuchField, RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap, | 91 | MissingUnsafe, NoSuchField, RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap, |
92 | UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, | 92 | UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, |
93 | UnresolvedModule, UnresolvedProcMacro, | 93 | UnresolvedModule, UnresolvedProcMacro, |
@@ -461,7 +461,6 @@ impl Module { | |||
461 | self, | 461 | self, |
462 | db: &dyn HirDatabase, | 462 | db: &dyn HirDatabase, |
463 | sink: &mut DiagnosticSink, | 463 | sink: &mut DiagnosticSink, |
464 | internal_diagnostics: bool, | ||
465 | ) -> Vec<AnyDiagnostic> { | 464 | ) -> Vec<AnyDiagnostic> { |
466 | let _p = profile::span("Module::diagnostics").detail(|| { | 465 | let _p = profile::span("Module::diagnostics").detail(|| { |
467 | format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string())) | 466 | format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string())) |
@@ -619,11 +618,11 @@ impl Module { | |||
619 | } | 618 | } |
620 | for decl in self.declarations(db) { | 619 | for decl in self.declarations(db) { |
621 | match decl { | 620 | match decl { |
622 | ModuleDef::Function(f) => acc.extend(f.diagnostics(db, sink, internal_diagnostics)), | 621 | ModuleDef::Function(f) => acc.extend(f.diagnostics(db, sink)), |
623 | ModuleDef::Module(m) => { | 622 | ModuleDef::Module(m) => { |
624 | // Only add diagnostics from inline modules | 623 | // Only add diagnostics from inline modules |
625 | if def_map[m.id.local_id].origin.is_inline() { | 624 | if def_map[m.id.local_id].origin.is_inline() { |
626 | acc.extend(m.diagnostics(db, sink, internal_diagnostics)) | 625 | acc.extend(m.diagnostics(db, sink)) |
627 | } | 626 | } |
628 | } | 627 | } |
629 | _ => acc.extend(decl.diagnostics(db)), | 628 | _ => acc.extend(decl.diagnostics(db)), |
@@ -633,7 +632,7 @@ impl Module { | |||
633 | for impl_def in self.impl_defs(db) { | 632 | for impl_def in self.impl_defs(db) { |
634 | for item in impl_def.items(db) { | 633 | for item in impl_def.items(db) { |
635 | if let AssocItem::Function(f) = item { | 634 | if let AssocItem::Function(f) = item { |
636 | acc.extend(f.diagnostics(db, sink, internal_diagnostics)); | 635 | acc.extend(f.diagnostics(db, sink)); |
637 | } | 636 | } |
638 | } | 637 | } |
639 | } | 638 | } |
@@ -1040,7 +1039,6 @@ impl Function { | |||
1040 | self, | 1039 | self, |
1041 | db: &dyn HirDatabase, | 1040 | db: &dyn HirDatabase, |
1042 | sink: &mut DiagnosticSink, | 1041 | sink: &mut DiagnosticSink, |
1043 | internal_diagnostics: bool, | ||
1044 | ) -> Vec<AnyDiagnostic> { | 1042 | ) -> Vec<AnyDiagnostic> { |
1045 | let mut acc: Vec<AnyDiagnostic> = Vec::new(); | 1043 | let mut acc: Vec<AnyDiagnostic> = Vec::new(); |
1046 | let krate = self.module(db).id.krate(); | 1044 | let krate = self.module(db).id.krate(); |
@@ -1100,9 +1098,7 @@ impl Function { | |||
1100 | } | 1098 | } |
1101 | } | 1099 | } |
1102 | 1100 | ||
1103 | for diagnostic in | 1101 | for diagnostic in BodyValidationDiagnostic::collect(db, self.id.into()) { |
1104 | BodyValidationDiagnostic::collect(db, self.id.into(), internal_diagnostics) | ||
1105 | { | ||
1106 | match diagnostic { | 1102 | match diagnostic { |
1107 | BodyValidationDiagnostic::RecordMissingFields { | 1103 | BodyValidationDiagnostic::RecordMissingFields { |
1108 | record, | 1104 | record, |
@@ -1223,18 +1219,6 @@ impl Function { | |||
1223 | Err(SyntheticSyntax) => (), | 1219 | Err(SyntheticSyntax) => (), |
1224 | } | 1220 | } |
1225 | } | 1221 | } |
1226 | BodyValidationDiagnostic::InternalBailedOut { pat } => { | ||
1227 | match source_map.pat_syntax(pat) { | ||
1228 | Ok(source_ptr) => { | ||
1229 | let pat_syntax_ptr = source_ptr.value.either(Into::into, Into::into); | ||
1230 | sink.push(InternalBailedOut { | ||
1231 | file: source_ptr.file_id, | ||
1232 | pat_syntax_ptr, | ||
1233 | }); | ||
1234 | } | ||
1235 | Err(SyntheticSyntax) => (), | ||
1236 | } | ||
1237 | } | ||
1238 | } | 1222 | } |
1239 | } | 1223 | } |
1240 | 1224 | ||
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 2a211fd8e..b809b96a0 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -50,21 +50,13 @@ pub enum BodyValidationDiagnostic { | |||
50 | MissingMatchArms { | 50 | MissingMatchArms { |
51 | match_expr: ExprId, | 51 | match_expr: ExprId, |
52 | }, | 52 | }, |
53 | InternalBailedOut { | ||
54 | pat: PatId, | ||
55 | }, | ||
56 | } | 53 | } |
57 | 54 | ||
58 | impl BodyValidationDiagnostic { | 55 | impl BodyValidationDiagnostic { |
59 | pub fn collect( | 56 | pub fn collect(db: &dyn HirDatabase, owner: DefWithBodyId) -> Vec<BodyValidationDiagnostic> { |
60 | db: &dyn HirDatabase, | ||
61 | owner: DefWithBodyId, | ||
62 | internal_diagnostics: bool, | ||
63 | ) -> Vec<BodyValidationDiagnostic> { | ||
64 | let _p = profile::span("BodyValidationDiagnostic::collect"); | 57 | let _p = profile::span("BodyValidationDiagnostic::collect"); |
65 | let infer = db.infer(owner); | 58 | let infer = db.infer(owner); |
66 | let mut validator = ExprValidator::new(owner, infer.clone()); | 59 | let mut validator = ExprValidator::new(owner, infer.clone()); |
67 | validator.internal_diagnostics = internal_diagnostics; | ||
68 | validator.validate_body(db); | 60 | validator.validate_body(db); |
69 | validator.diagnostics | 61 | validator.diagnostics |
70 | } | 62 | } |
@@ -74,12 +66,11 @@ struct ExprValidator { | |||
74 | owner: DefWithBodyId, | 66 | owner: DefWithBodyId, |
75 | infer: Arc<InferenceResult>, | 67 | infer: Arc<InferenceResult>, |
76 | pub(super) diagnostics: Vec<BodyValidationDiagnostic>, | 68 | pub(super) diagnostics: Vec<BodyValidationDiagnostic>, |
77 | internal_diagnostics: bool, | ||
78 | } | 69 | } |
79 | 70 | ||
80 | impl ExprValidator { | 71 | impl ExprValidator { |
81 | fn new(owner: DefWithBodyId, infer: Arc<InferenceResult>) -> ExprValidator { | 72 | fn new(owner: DefWithBodyId, infer: Arc<InferenceResult>) -> ExprValidator { |
82 | ExprValidator { owner, infer, diagnostics: Vec::new(), internal_diagnostics: false } | 73 | ExprValidator { owner, infer, diagnostics: Vec::new() } |
83 | } | 74 | } |
84 | 75 | ||
85 | fn validate_body(&mut self, db: &dyn HirDatabase) { | 76 | fn validate_body(&mut self, db: &dyn HirDatabase) { |
@@ -308,9 +299,7 @@ impl ExprValidator { | |||
308 | // fit the match expression, we skip this diagnostic. Skipping the entire | 299 | // fit the match expression, we skip this diagnostic. Skipping the entire |
309 | // diagnostic rather than just not including this match arm is preferred | 300 | // diagnostic rather than just not including this match arm is preferred |
310 | // to avoid the chance of false positives. | 301 | // to avoid the chance of false positives. |
311 | if self.internal_diagnostics { | 302 | cov_mark::hit!(validate_match_bailed_out); |
312 | self.diagnostics.push(BodyValidationDiagnostic::InternalBailedOut { pat: arm.pat }) | ||
313 | } | ||
314 | return; | 303 | return; |
315 | } | 304 | } |
316 | 305 | ||
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 01b68232e..fe6236e44 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -181,10 +181,9 @@ pub(crate) fn diagnostics( | |||
181 | }); | 181 | }); |
182 | 182 | ||
183 | let mut diags = Vec::new(); | 183 | let mut diags = Vec::new(); |
184 | let internal_diagnostics = cfg!(test); | ||
185 | let module = sema.to_module_def(file_id); | 184 | let module = sema.to_module_def(file_id); |
186 | if let Some(m) = module { | 185 | if let Some(m) = module { |
187 | diags = m.diagnostics(db, &mut sink, internal_diagnostics) | 186 | diags = m.diagnostics(db, &mut sink) |
188 | } | 187 | } |
189 | 188 | ||
190 | drop(sink); | 189 | drop(sink); |
diff --git a/crates/ide/src/diagnostics/missing_match_arms.rs b/crates/ide/src/diagnostics/missing_match_arms.rs index 6b977fa59..b636489b3 100644 --- a/crates/ide/src/diagnostics/missing_match_arms.rs +++ b/crates/ide/src/diagnostics/missing_match_arms.rs | |||
@@ -20,9 +20,14 @@ pub(super) fn missing_match_arms( | |||
20 | pub(super) mod tests { | 20 | pub(super) mod tests { |
21 | use crate::diagnostics::tests::check_diagnostics; | 21 | use crate::diagnostics::tests::check_diagnostics; |
22 | 22 | ||
23 | fn check_diagnostics_no_bails(ra_fixture: &str) { | ||
24 | cov_mark::check_count!(validate_match_bailed_out, 0); | ||
25 | crate::diagnostics::tests::check_diagnostics(ra_fixture) | ||
26 | } | ||
27 | |||
23 | #[test] | 28 | #[test] |
24 | fn empty_tuple() { | 29 | fn empty_tuple() { |
25 | check_diagnostics( | 30 | check_diagnostics_no_bails( |
26 | r#" | 31 | r#" |
27 | fn main() { | 32 | fn main() { |
28 | match () { } | 33 | match () { } |
@@ -40,7 +45,7 @@ fn main() { | |||
40 | 45 | ||
41 | #[test] | 46 | #[test] |
42 | fn tuple_of_two_empty_tuple() { | 47 | fn tuple_of_two_empty_tuple() { |
43 | check_diagnostics( | 48 | check_diagnostics_no_bails( |
44 | r#" | 49 | r#" |
45 | fn main() { | 50 | fn main() { |
46 | match ((), ()) { } | 51 | match ((), ()) { } |
@@ -54,7 +59,7 @@ fn main() { | |||
54 | 59 | ||
55 | #[test] | 60 | #[test] |
56 | fn boolean() { | 61 | fn boolean() { |
57 | check_diagnostics( | 62 | check_diagnostics_no_bails( |
58 | r#" | 63 | r#" |
59 | fn test_main() { | 64 | fn test_main() { |
60 | match false { } | 65 | match false { } |
@@ -107,7 +112,7 @@ fn test_main() { | |||
107 | 112 | ||
108 | #[test] | 113 | #[test] |
109 | fn tuple_of_tuple_and_bools() { | 114 | fn tuple_of_tuple_and_bools() { |
110 | check_diagnostics( | 115 | check_diagnostics_no_bails( |
111 | r#" | 116 | r#" |
112 | fn main() { | 117 | fn main() { |
113 | match (false, ((), false)) {} | 118 | match (false, ((), false)) {} |
@@ -135,7 +140,7 @@ fn main() { | |||
135 | 140 | ||
136 | #[test] | 141 | #[test] |
137 | fn enums() { | 142 | fn enums() { |
138 | check_diagnostics( | 143 | check_diagnostics_no_bails( |
139 | r#" | 144 | r#" |
140 | enum Either { A, B, } | 145 | enum Either { A, B, } |
141 | 146 | ||
@@ -163,7 +168,7 @@ fn main() { | |||
163 | 168 | ||
164 | #[test] | 169 | #[test] |
165 | fn enum_containing_bool() { | 170 | fn enum_containing_bool() { |
166 | check_diagnostics( | 171 | check_diagnostics_no_bails( |
167 | r#" | 172 | r#" |
168 | enum Either { A(bool), B } | 173 | enum Either { A(bool), B } |
169 | 174 | ||
@@ -196,7 +201,7 @@ fn main() { | |||
196 | 201 | ||
197 | #[test] | 202 | #[test] |
198 | fn enum_different_sizes() { | 203 | fn enum_different_sizes() { |
199 | check_diagnostics( | 204 | check_diagnostics_no_bails( |
200 | r#" | 205 | r#" |
201 | enum Either { A(bool), B(bool, bool) } | 206 | enum Either { A(bool), B(bool, bool) } |
202 | 207 | ||
@@ -224,7 +229,7 @@ fn main() { | |||
224 | 229 | ||
225 | #[test] | 230 | #[test] |
226 | fn tuple_of_enum_no_diagnostic() { | 231 | fn tuple_of_enum_no_diagnostic() { |
227 | check_diagnostics( | 232 | check_diagnostics_no_bails( |
228 | r#" | 233 | r#" |
229 | enum Either { A(bool), B(bool, bool) } | 234 | enum Either { A(bool), B(bool, bool) } |
230 | enum Either2 { C, D } | 235 | enum Either2 { C, D } |
@@ -243,7 +248,7 @@ fn main() { | |||
243 | 248 | ||
244 | #[test] | 249 | #[test] |
245 | fn or_pattern_no_diagnostic() { | 250 | fn or_pattern_no_diagnostic() { |
246 | check_diagnostics( | 251 | check_diagnostics_no_bails( |
247 | r#" | 252 | r#" |
248 | enum Either {A, B} | 253 | enum Either {A, B} |
249 | 254 | ||
@@ -257,6 +262,7 @@ fn main() { | |||
257 | 262 | ||
258 | #[test] | 263 | #[test] |
259 | fn mismatched_types() { | 264 | fn mismatched_types() { |
265 | cov_mark::check_count!(validate_match_bailed_out, 4); | ||
260 | // Match statements with arms that don't match the | 266 | // Match statements with arms that don't match the |
261 | // expression pattern do not fire this diagnostic. | 267 | // expression pattern do not fire this diagnostic. |
262 | check_diagnostics( | 268 | check_diagnostics( |
@@ -267,18 +273,14 @@ enum Either2 { C, D } | |||
267 | fn main() { | 273 | fn main() { |
268 | match Either::A { | 274 | match Either::A { |
269 | Either2::C => (), | 275 | Either2::C => (), |
270 | // ^^^^^^^^^^ Internal: match check bailed out | ||
271 | Either2::D => (), | 276 | Either2::D => (), |
272 | } | 277 | } |
273 | match (true, false) { | 278 | match (true, false) { |
274 | (true, false, true) => (), | 279 | (true, false, true) => (), |
275 | // ^^^^^^^^^^^^^^^^^^^ Internal: match check bailed out | ||
276 | (true) => (), | 280 | (true) => (), |
277 | } | 281 | } |
278 | match (true, false) { (true,) => {} } | 282 | match (true, false) { (true,) => {} } |
279 | // ^^^^^^^ Internal: match check bailed out | ||
280 | match (0) { () => () } | 283 | match (0) { () => () } |
281 | // ^^ Internal: match check bailed out | ||
282 | match Unresolved::Bar { Unresolved::Baz => () } | 284 | match Unresolved::Bar { Unresolved::Baz => () } |
283 | } | 285 | } |
284 | "#, | 286 | "#, |
@@ -287,13 +289,12 @@ fn main() { | |||
287 | 289 | ||
288 | #[test] | 290 | #[test] |
289 | fn mismatched_types_in_or_patterns() { | 291 | fn mismatched_types_in_or_patterns() { |
292 | cov_mark::check_count!(validate_match_bailed_out, 2); | ||
290 | check_diagnostics( | 293 | check_diagnostics( |
291 | r#" | 294 | r#" |
292 | fn main() { | 295 | fn main() { |
293 | match false { true | () => {} } | 296 | match false { true | () => {} } |
294 | // ^^^^^^^^^ Internal: match check bailed out | ||
295 | match (false,) { (true | (),) => {} } | 297 | match (false,) { (true | (),) => {} } |
296 | // ^^^^^^^^^^^^ Internal: match check bailed out | ||
297 | } | 298 | } |
298 | "#, | 299 | "#, |
299 | ); | 300 | ); |
@@ -303,7 +304,7 @@ fn main() { | |||
303 | fn malformed_match_arm_tuple_enum_missing_pattern() { | 304 | fn malformed_match_arm_tuple_enum_missing_pattern() { |
304 | // We are testing to be sure we don't panic here when the match | 305 | // We are testing to be sure we don't panic here when the match |
305 | // arm `Either::B` is missing its pattern. | 306 | // arm `Either::B` is missing its pattern. |
306 | check_diagnostics( | 307 | check_diagnostics_no_bails( |
307 | r#" | 308 | r#" |
308 | enum Either { A, B(u32) } | 309 | enum Either { A, B(u32) } |
309 | 310 | ||
@@ -319,17 +320,16 @@ fn main() { | |||
319 | 320 | ||
320 | #[test] | 321 | #[test] |
321 | fn malformed_match_arm_extra_fields() { | 322 | fn malformed_match_arm_extra_fields() { |
323 | cov_mark::check_count!(validate_match_bailed_out, 2); | ||
322 | check_diagnostics( | 324 | check_diagnostics( |
323 | r#" | 325 | r#" |
324 | enum A { B(isize, isize), C } | 326 | enum A { B(isize, isize), C } |
325 | fn main() { | 327 | fn main() { |
326 | match A::B(1, 2) { | 328 | match A::B(1, 2) { |
327 | A::B(_, _, _) => (), | 329 | A::B(_, _, _) => (), |
328 | // ^^^^^^^^^^^^^ Internal: match check bailed out | ||
329 | } | 330 | } |
330 | match A::B(1, 2) { | 331 | match A::B(1, 2) { |
331 | A::C(_) => (), | 332 | A::C(_) => (), |
332 | // ^^^^^^^ Internal: match check bailed out | ||
333 | } | 333 | } |
334 | } | 334 | } |
335 | "#, | 335 | "#, |
@@ -338,6 +338,7 @@ fn main() { | |||
338 | 338 | ||
339 | #[test] | 339 | #[test] |
340 | fn expr_diverges() { | 340 | fn expr_diverges() { |
341 | cov_mark::check_count!(validate_match_bailed_out, 2); | ||
341 | check_diagnostics( | 342 | check_diagnostics( |
342 | r#" | 343 | r#" |
343 | enum Either { A, B } | 344 | enum Either { A, B } |
@@ -345,12 +346,10 @@ enum Either { A, B } | |||
345 | fn main() { | 346 | fn main() { |
346 | match loop {} { | 347 | match loop {} { |
347 | Either::A => (), | 348 | Either::A => (), |
348 | // ^^^^^^^^^ Internal: match check bailed out | ||
349 | Either::B => (), | 349 | Either::B => (), |
350 | } | 350 | } |
351 | match loop {} { | 351 | match loop {} { |
352 | Either::A => (), | 352 | Either::A => (), |
353 | // ^^^^^^^^^ Internal: match check bailed out | ||
354 | } | 353 | } |
355 | match loop { break Foo::A } { | 354 | match loop { break Foo::A } { |
356 | //^^^^^^^^^^^^^^^^^^^^^ missing match arm | 355 | //^^^^^^^^^^^^^^^^^^^^^ missing match arm |
@@ -367,7 +366,7 @@ fn main() { | |||
367 | 366 | ||
368 | #[test] | 367 | #[test] |
369 | fn expr_partially_diverges() { | 368 | fn expr_partially_diverges() { |
370 | check_diagnostics( | 369 | check_diagnostics_no_bails( |
371 | r#" | 370 | r#" |
372 | enum Either<T> { A(T), B } | 371 | enum Either<T> { A(T), B } |
373 | 372 | ||
@@ -384,7 +383,7 @@ fn main() -> u32 { | |||
384 | 383 | ||
385 | #[test] | 384 | #[test] |
386 | fn enum_record() { | 385 | fn enum_record() { |
387 | check_diagnostics( | 386 | check_diagnostics_no_bails( |
388 | r#" | 387 | r#" |
389 | enum Either { A { foo: bool }, B } | 388 | enum Either { A { foo: bool }, B } |
390 | 389 | ||
@@ -422,7 +421,7 @@ fn main() { | |||
422 | 421 | ||
423 | #[test] | 422 | #[test] |
424 | fn enum_record_fields_out_of_order() { | 423 | fn enum_record_fields_out_of_order() { |
425 | check_diagnostics( | 424 | check_diagnostics_no_bails( |
426 | r#" | 425 | r#" |
427 | enum Either { | 426 | enum Either { |
428 | A { foo: bool, bar: () }, | 427 | A { foo: bool, bar: () }, |
@@ -449,7 +448,7 @@ fn main() { | |||
449 | 448 | ||
450 | #[test] | 449 | #[test] |
451 | fn enum_record_ellipsis() { | 450 | fn enum_record_ellipsis() { |
452 | check_diagnostics( | 451 | check_diagnostics_no_bails( |
453 | r#" | 452 | r#" |
454 | enum Either { | 453 | enum Either { |
455 | A { foo: bool, bar: bool }, | 454 | A { foo: bool, bar: bool }, |
@@ -485,7 +484,7 @@ fn main() { | |||
485 | 484 | ||
486 | #[test] | 485 | #[test] |
487 | fn enum_tuple_partial_ellipsis() { | 486 | fn enum_tuple_partial_ellipsis() { |
488 | check_diagnostics( | 487 | check_diagnostics_no_bails( |
489 | r#" | 488 | r#" |
490 | enum Either { | 489 | enum Either { |
491 | A(bool, bool, bool, bool), | 490 | A(bool, bool, bool, bool), |
@@ -529,7 +528,7 @@ fn main() { | |||
529 | 528 | ||
530 | #[test] | 529 | #[test] |
531 | fn never() { | 530 | fn never() { |
532 | check_diagnostics( | 531 | check_diagnostics_no_bails( |
533 | r#" | 532 | r#" |
534 | enum Never {} | 533 | enum Never {} |
535 | 534 | ||
@@ -549,6 +548,8 @@ fn bang(never: !) { | |||
549 | 548 | ||
550 | #[test] | 549 | #[test] |
551 | fn unknown_type() { | 550 | fn unknown_type() { |
551 | cov_mark::check_count!(validate_match_bailed_out, 1); | ||
552 | |||
552 | check_diagnostics( | 553 | check_diagnostics( |
553 | r#" | 554 | r#" |
554 | enum Option<T> { Some(T), None } | 555 | enum Option<T> { Some(T), None } |
@@ -558,7 +559,6 @@ fn main() { | |||
558 | match Option::<Never>::None { | 559 | match Option::<Never>::None { |
559 | None => (), | 560 | None => (), |
560 | Some(never) => match never {}, | 561 | Some(never) => match never {}, |
561 | // ^^^^^^^^^^^ Internal: match check bailed out | ||
562 | } | 562 | } |
563 | match Option::<Never>::None { | 563 | match Option::<Never>::None { |
564 | //^^^^^^^^^^^^^^^^^^^^^ missing match arm | 564 | //^^^^^^^^^^^^^^^^^^^^^ missing match arm |
@@ -571,7 +571,7 @@ fn main() { | |||
571 | 571 | ||
572 | #[test] | 572 | #[test] |
573 | fn tuple_of_bools_with_ellipsis_at_end_missing_arm() { | 573 | fn tuple_of_bools_with_ellipsis_at_end_missing_arm() { |
574 | check_diagnostics( | 574 | check_diagnostics_no_bails( |
575 | r#" | 575 | r#" |
576 | fn main() { | 576 | fn main() { |
577 | match (false, true, false) { | 577 | match (false, true, false) { |
@@ -584,7 +584,7 @@ fn main() { | |||
584 | 584 | ||
585 | #[test] | 585 | #[test] |
586 | fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() { | 586 | fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() { |
587 | check_diagnostics( | 587 | check_diagnostics_no_bails( |
588 | r#" | 588 | r#" |
589 | fn main() { | 589 | fn main() { |
590 | match (false, true, false) { | 590 | match (false, true, false) { |
@@ -597,7 +597,7 @@ fn main() { | |||
597 | 597 | ||
598 | #[test] | 598 | #[test] |
599 | fn tuple_of_bools_with_ellipsis_in_middle_missing_arm() { | 599 | fn tuple_of_bools_with_ellipsis_in_middle_missing_arm() { |
600 | check_diagnostics( | 600 | check_diagnostics_no_bails( |
601 | r#" | 601 | r#" |
602 | fn main() { | 602 | fn main() { |
603 | match (false, true, false) { | 603 | match (false, true, false) { |
@@ -610,7 +610,7 @@ fn main() { | |||
610 | 610 | ||
611 | #[test] | 611 | #[test] |
612 | fn record_struct() { | 612 | fn record_struct() { |
613 | check_diagnostics( | 613 | check_diagnostics_no_bails( |
614 | r#"struct Foo { a: bool } | 614 | r#"struct Foo { a: bool } |
615 | fn main(f: Foo) { | 615 | fn main(f: Foo) { |
616 | match f {} | 616 | match f {} |
@@ -635,7 +635,7 @@ fn main(f: Foo) { | |||
635 | 635 | ||
636 | #[test] | 636 | #[test] |
637 | fn tuple_struct() { | 637 | fn tuple_struct() { |
638 | check_diagnostics( | 638 | check_diagnostics_no_bails( |
639 | r#"struct Foo(bool); | 639 | r#"struct Foo(bool); |
640 | fn main(f: Foo) { | 640 | fn main(f: Foo) { |
641 | match f {} | 641 | match f {} |
@@ -653,7 +653,7 @@ fn main(f: Foo) { | |||
653 | 653 | ||
654 | #[test] | 654 | #[test] |
655 | fn unit_struct() { | 655 | fn unit_struct() { |
656 | check_diagnostics( | 656 | check_diagnostics_no_bails( |
657 | r#"struct Foo; | 657 | r#"struct Foo; |
658 | fn main(f: Foo) { | 658 | fn main(f: Foo) { |
659 | match f {} | 659 | match f {} |
@@ -666,7 +666,7 @@ fn main(f: Foo) { | |||
666 | 666 | ||
667 | #[test] | 667 | #[test] |
668 | fn record_struct_ellipsis() { | 668 | fn record_struct_ellipsis() { |
669 | check_diagnostics( | 669 | check_diagnostics_no_bails( |
670 | r#"struct Foo { foo: bool, bar: bool } | 670 | r#"struct Foo { foo: bool, bar: bool } |
671 | fn main(f: Foo) { | 671 | fn main(f: Foo) { |
672 | match f { Foo { foo: true, .. } => () } | 672 | match f { Foo { foo: true, .. } => () } |
@@ -688,7 +688,7 @@ fn main(f: Foo) { | |||
688 | 688 | ||
689 | #[test] | 689 | #[test] |
690 | fn internal_or() { | 690 | fn internal_or() { |
691 | check_diagnostics( | 691 | check_diagnostics_no_bails( |
692 | r#" | 692 | r#" |
693 | fn main() { | 693 | fn main() { |
694 | enum Either { A(bool), B } | 694 | enum Either { A(bool), B } |
@@ -703,6 +703,8 @@ fn main() { | |||
703 | 703 | ||
704 | #[test] | 704 | #[test] |
705 | fn no_panic_at_unimplemented_subpattern_type() { | 705 | fn no_panic_at_unimplemented_subpattern_type() { |
706 | cov_mark::check_count!(validate_match_bailed_out, 1); | ||
707 | |||
706 | check_diagnostics( | 708 | check_diagnostics( |
707 | r#" | 709 | r#" |
708 | struct S { a: char} | 710 | struct S { a: char} |
@@ -710,7 +712,6 @@ fn main(v: S) { | |||
710 | match v { S{ a } => {} } | 712 | match v { S{ a } => {} } |
711 | match v { S{ a: _x } => {} } | 713 | match v { S{ a: _x } => {} } |
712 | match v { S{ a: 'a' } => {} } | 714 | match v { S{ a: 'a' } => {} } |
713 | //^^^^^^^^^^^ Internal: match check bailed out | ||
714 | match v { S{..} => {} } | 715 | match v { S{..} => {} } |
715 | match v { _ => {} } | 716 | match v { _ => {} } |
716 | match v { } | 717 | match v { } |
@@ -722,7 +723,7 @@ fn main(v: S) { | |||
722 | 723 | ||
723 | #[test] | 724 | #[test] |
724 | fn binding() { | 725 | fn binding() { |
725 | check_diagnostics( | 726 | check_diagnostics_no_bails( |
726 | r#" | 727 | r#" |
727 | fn main() { | 728 | fn main() { |
728 | match true { | 729 | match true { |
@@ -738,6 +739,8 @@ fn main() { | |||
738 | 739 | ||
739 | #[test] | 740 | #[test] |
740 | fn binding_ref_has_correct_type() { | 741 | fn binding_ref_has_correct_type() { |
742 | cov_mark::check_count!(validate_match_bailed_out, 1); | ||
743 | |||
741 | // Asserts `PatKind::Binding(ref _x): bool`, not &bool. | 744 | // Asserts `PatKind::Binding(ref _x): bool`, not &bool. |
742 | // If that's not true match checking will panic with "incompatible constructors" | 745 | // If that's not true match checking will panic with "incompatible constructors" |
743 | // FIXME: make facilities to test this directly like `tests::check_infer(..)` | 746 | // FIXME: make facilities to test this directly like `tests::check_infer(..)` |
@@ -749,7 +752,6 @@ fn main() { | |||
749 | // ExprValidator::validate_match(..) checks types of top level patterns incorrecly. | 752 | // ExprValidator::validate_match(..) checks types of top level patterns incorrecly. |
750 | match Foo::A { | 753 | match Foo::A { |
751 | ref _x => {} | 754 | ref _x => {} |
752 | // ^^^^^^ Internal: match check bailed out | ||
753 | Foo::A => {} | 755 | Foo::A => {} |
754 | } | 756 | } |
755 | match (true,) { | 757 | match (true,) { |
@@ -763,7 +765,7 @@ fn main() { | |||
763 | 765 | ||
764 | #[test] | 766 | #[test] |
765 | fn enum_non_exhaustive() { | 767 | fn enum_non_exhaustive() { |
766 | check_diagnostics( | 768 | check_diagnostics_no_bails( |
767 | r#" | 769 | r#" |
768 | //- /lib.rs crate:lib | 770 | //- /lib.rs crate:lib |
769 | #[non_exhaustive] | 771 | #[non_exhaustive] |
@@ -799,7 +801,7 @@ fn main() { | |||
799 | 801 | ||
800 | #[test] | 802 | #[test] |
801 | fn match_guard() { | 803 | fn match_guard() { |
802 | check_diagnostics( | 804 | check_diagnostics_no_bails( |
803 | r#" | 805 | r#" |
804 | fn main() { | 806 | fn main() { |
805 | match true { | 807 | match true { |
@@ -820,7 +822,7 @@ fn main() { | |||
820 | #[test] | 822 | #[test] |
821 | fn pattern_type_is_of_substitution() { | 823 | fn pattern_type_is_of_substitution() { |
822 | cov_mark::check!(match_check_wildcard_expanded_to_substitutions); | 824 | cov_mark::check!(match_check_wildcard_expanded_to_substitutions); |
823 | check_diagnostics( | 825 | check_diagnostics_no_bails( |
824 | r#" | 826 | r#" |
825 | struct Foo<T>(T); | 827 | struct Foo<T>(T); |
826 | struct Bar; | 828 | struct Bar; |
@@ -835,12 +837,13 @@ fn main() { | |||
835 | 837 | ||
836 | #[test] | 838 | #[test] |
837 | fn record_struct_no_such_field() { | 839 | fn record_struct_no_such_field() { |
840 | cov_mark::check_count!(validate_match_bailed_out, 1); | ||
841 | |||
838 | check_diagnostics( | 842 | check_diagnostics( |
839 | r#" | 843 | r#" |
840 | struct Foo { } | 844 | struct Foo { } |
841 | fn main(f: Foo) { | 845 | fn main(f: Foo) { |
842 | match f { Foo { bar } => () } | 846 | match f { Foo { bar } => () } |
843 | // ^^^^^^^^^^^ Internal: match check bailed out | ||
844 | } | 847 | } |
845 | "#, | 848 | "#, |
846 | ); | 849 | ); |
@@ -848,7 +851,7 @@ fn main(f: Foo) { | |||
848 | 851 | ||
849 | #[test] | 852 | #[test] |
850 | fn match_ergonomics_issue_9095() { | 853 | fn match_ergonomics_issue_9095() { |
851 | check_diagnostics( | 854 | check_diagnostics_no_bails( |
852 | r#" | 855 | r#" |
853 | enum Foo<T> { A(T) } | 856 | enum Foo<T> { A(T) } |
854 | fn main() { | 857 | fn main() { |
@@ -875,13 +878,14 @@ fn main() { | |||
875 | 878 | ||
876 | #[test] | 879 | #[test] |
877 | fn integers() { | 880 | fn integers() { |
881 | cov_mark::check_count!(validate_match_bailed_out, 1); | ||
882 | |||
878 | // We don't currently check integer exhaustiveness. | 883 | // We don't currently check integer exhaustiveness. |
879 | check_diagnostics( | 884 | check_diagnostics( |
880 | r#" | 885 | r#" |
881 | fn main() { | 886 | fn main() { |
882 | match 5 { | 887 | match 5 { |
883 | 10 => (), | 888 | 10 => (), |
884 | // ^^ Internal: match check bailed out | ||
885 | 11..20 => (), | 889 | 11..20 => (), |
886 | } | 890 | } |
887 | } | 891 | } |
@@ -891,12 +895,13 @@ fn main() { | |||
891 | 895 | ||
892 | #[test] | 896 | #[test] |
893 | fn reference_patterns_at_top_level() { | 897 | fn reference_patterns_at_top_level() { |
898 | cov_mark::check_count!(validate_match_bailed_out, 1); | ||
899 | |||
894 | check_diagnostics( | 900 | check_diagnostics( |
895 | r#" | 901 | r#" |
896 | fn main() { | 902 | fn main() { |
897 | match &false { | 903 | match &false { |
898 | &true => {} | 904 | &true => {} |
899 | // ^^^^^ Internal: match check bailed out | ||
900 | } | 905 | } |
901 | } | 906 | } |
902 | "#, | 907 | "#, |
@@ -905,16 +910,16 @@ fn main() { | |||
905 | 910 | ||
906 | #[test] | 911 | #[test] |
907 | fn reference_patterns_in_fields() { | 912 | fn reference_patterns_in_fields() { |
913 | cov_mark::check_count!(validate_match_bailed_out, 2); | ||
914 | |||
908 | check_diagnostics( | 915 | check_diagnostics( |
909 | r#" | 916 | r#" |
910 | fn main() { | 917 | fn main() { |
911 | match (&false,) { | 918 | match (&false,) { |
912 | (true,) => {} | 919 | (true,) => {} |
913 | // ^^^^^^^ Internal: match check bailed out | ||
914 | } | 920 | } |
915 | match (&false,) { | 921 | match (&false,) { |
916 | (&true,) => {} | 922 | (&true,) => {} |
917 | // ^^^^^^^^ Internal: match check bailed out | ||
918 | } | 923 | } |
919 | } | 924 | } |
920 | "#, | 925 | "#, |