diff options
author | Aleksey Kladov <[email protected]> | 2021-06-12 20:05:23 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-06-12 20:05:23 +0100 |
commit | 7731714578d4ae6eb7a54ead2e51ae032e9a700a (patch) | |
tree | f8dc2d68cfc72c1fcb839ec85093fb49f479663d /crates/ide | |
parent | 6940cfed1e24a67e816e69e1093e04c0eb73e070 (diff) |
internal: move diagnostics infra to hir
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index dffb6fdc8..e34341631 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -1338,6 +1338,35 @@ fn main() { | |||
1338 | "#, | 1338 | "#, |
1339 | ); | 1339 | ); |
1340 | } | 1340 | } |
1341 | |||
1342 | #[test] | ||
1343 | fn import_extern_crate_clash_with_inner_item() { | ||
1344 | // This is more of a resolver test, but doesn't really work with the hir_def testsuite. | ||
1345 | |||
1346 | check_diagnostics( | ||
1347 | r#" | ||
1348 | //- /lib.rs crate:lib deps:jwt | ||
1349 | mod permissions; | ||
1350 | |||
1351 | use permissions::jwt; | ||
1352 | |||
1353 | fn f() { | ||
1354 | fn inner() {} | ||
1355 | jwt::Claims {}; // should resolve to the local one with 0 fields, and not get a diagnostic | ||
1356 | } | ||
1357 | |||
1358 | //- /permissions.rs | ||
1359 | pub mod jwt { | ||
1360 | pub struct Claims {} | ||
1361 | } | ||
1362 | |||
1363 | //- /jwt/lib.rs crate:jwt | ||
1364 | pub struct Claims { | ||
1365 | field: u8, | ||
1366 | } | ||
1367 | "#, | ||
1368 | ); | ||
1369 | } | ||
1341 | } | 1370 | } |
1342 | 1371 | ||
1343 | #[cfg(test)] | 1372 | #[cfg(test)] |
@@ -2245,3 +2274,328 @@ fn main() { | |||
2245 | } | 2274 | } |
2246 | } | 2275 | } |
2247 | } | 2276 | } |
2277 | |||
2278 | #[cfg(test)] | ||
2279 | mod decl_check_tests { | ||
2280 | use crate::diagnostics::tests::check_diagnostics; | ||
2281 | |||
2282 | #[test] | ||
2283 | fn incorrect_function_name() { | ||
2284 | check_diagnostics( | ||
2285 | r#" | ||
2286 | fn NonSnakeCaseName() {} | ||
2287 | // ^^^^^^^^^^^^^^^^ Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name` | ||
2288 | "#, | ||
2289 | ); | ||
2290 | } | ||
2291 | |||
2292 | #[test] | ||
2293 | fn incorrect_function_params() { | ||
2294 | check_diagnostics( | ||
2295 | r#" | ||
2296 | fn foo(SomeParam: u8) {} | ||
2297 | // ^^^^^^^^^ Parameter `SomeParam` should have snake_case name, e.g. `some_param` | ||
2298 | |||
2299 | fn foo2(ok_param: &str, CAPS_PARAM: u8) {} | ||
2300 | // ^^^^^^^^^^ Parameter `CAPS_PARAM` should have snake_case name, e.g. `caps_param` | ||
2301 | "#, | ||
2302 | ); | ||
2303 | } | ||
2304 | |||
2305 | #[test] | ||
2306 | fn incorrect_variable_names() { | ||
2307 | check_diagnostics( | ||
2308 | r#" | ||
2309 | fn foo() { | ||
2310 | let SOME_VALUE = 10; | ||
2311 | // ^^^^^^^^^^ Variable `SOME_VALUE` should have snake_case name, e.g. `some_value` | ||
2312 | let AnotherValue = 20; | ||
2313 | // ^^^^^^^^^^^^ Variable `AnotherValue` should have snake_case name, e.g. `another_value` | ||
2314 | } | ||
2315 | "#, | ||
2316 | ); | ||
2317 | } | ||
2318 | |||
2319 | #[test] | ||
2320 | fn incorrect_struct_names() { | ||
2321 | check_diagnostics( | ||
2322 | r#" | ||
2323 | struct non_camel_case_name {} | ||
2324 | // ^^^^^^^^^^^^^^^^^^^ Structure `non_camel_case_name` should have CamelCase name, e.g. `NonCamelCaseName` | ||
2325 | |||
2326 | struct SCREAMING_CASE {} | ||
2327 | // ^^^^^^^^^^^^^^ Structure `SCREAMING_CASE` should have CamelCase name, e.g. `ScreamingCase` | ||
2328 | "#, | ||
2329 | ); | ||
2330 | } | ||
2331 | |||
2332 | #[test] | ||
2333 | fn no_diagnostic_for_camel_cased_acronyms_in_struct_name() { | ||
2334 | check_diagnostics( | ||
2335 | r#" | ||
2336 | struct AABB {} | ||
2337 | "#, | ||
2338 | ); | ||
2339 | } | ||
2340 | |||
2341 | #[test] | ||
2342 | fn incorrect_struct_field() { | ||
2343 | check_diagnostics( | ||
2344 | r#" | ||
2345 | struct SomeStruct { SomeField: u8 } | ||
2346 | // ^^^^^^^^^ Field `SomeField` should have snake_case name, e.g. `some_field` | ||
2347 | "#, | ||
2348 | ); | ||
2349 | } | ||
2350 | |||
2351 | #[test] | ||
2352 | fn incorrect_enum_names() { | ||
2353 | check_diagnostics( | ||
2354 | r#" | ||
2355 | enum some_enum { Val(u8) } | ||
2356 | // ^^^^^^^^^ Enum `some_enum` should have CamelCase name, e.g. `SomeEnum` | ||
2357 | |||
2358 | enum SOME_ENUM {} | ||
2359 | // ^^^^^^^^^ Enum `SOME_ENUM` should have CamelCase name, e.g. `SomeEnum` | ||
2360 | "#, | ||
2361 | ); | ||
2362 | } | ||
2363 | |||
2364 | #[test] | ||
2365 | fn no_diagnostic_for_camel_cased_acronyms_in_enum_name() { | ||
2366 | check_diagnostics( | ||
2367 | r#" | ||
2368 | enum AABB {} | ||
2369 | "#, | ||
2370 | ); | ||
2371 | } | ||
2372 | |||
2373 | #[test] | ||
2374 | fn incorrect_enum_variant_name() { | ||
2375 | check_diagnostics( | ||
2376 | r#" | ||
2377 | enum SomeEnum { SOME_VARIANT(u8) } | ||
2378 | // ^^^^^^^^^^^^ Variant `SOME_VARIANT` should have CamelCase name, e.g. `SomeVariant` | ||
2379 | "#, | ||
2380 | ); | ||
2381 | } | ||
2382 | |||
2383 | #[test] | ||
2384 | fn incorrect_const_name() { | ||
2385 | check_diagnostics( | ||
2386 | r#" | ||
2387 | const some_weird_const: u8 = 10; | ||
2388 | // ^^^^^^^^^^^^^^^^ Constant `some_weird_const` should have UPPER_SNAKE_CASE name, e.g. `SOME_WEIRD_CONST` | ||
2389 | "#, | ||
2390 | ); | ||
2391 | } | ||
2392 | |||
2393 | #[test] | ||
2394 | fn incorrect_static_name() { | ||
2395 | check_diagnostics( | ||
2396 | r#" | ||
2397 | static some_weird_const: u8 = 10; | ||
2398 | // ^^^^^^^^^^^^^^^^ Static variable `some_weird_const` should have UPPER_SNAKE_CASE name, e.g. `SOME_WEIRD_CONST` | ||
2399 | "#, | ||
2400 | ); | ||
2401 | } | ||
2402 | |||
2403 | #[test] | ||
2404 | fn fn_inside_impl_struct() { | ||
2405 | check_diagnostics( | ||
2406 | r#" | ||
2407 | struct someStruct; | ||
2408 | // ^^^^^^^^^^ Structure `someStruct` should have CamelCase name, e.g. `SomeStruct` | ||
2409 | |||
2410 | impl someStruct { | ||
2411 | fn SomeFunc(&self) { | ||
2412 | // ^^^^^^^^ Function `SomeFunc` should have snake_case name, e.g. `some_func` | ||
2413 | let WHY_VAR_IS_CAPS = 10; | ||
2414 | // ^^^^^^^^^^^^^^^ Variable `WHY_VAR_IS_CAPS` should have snake_case name, e.g. `why_var_is_caps` | ||
2415 | } | ||
2416 | } | ||
2417 | "#, | ||
2418 | ); | ||
2419 | } | ||
2420 | |||
2421 | #[test] | ||
2422 | fn no_diagnostic_for_enum_varinats() { | ||
2423 | check_diagnostics( | ||
2424 | r#" | ||
2425 | enum Option { Some, None } | ||
2426 | |||
2427 | fn main() { | ||
2428 | match Option::None { | ||
2429 | None => (), | ||
2430 | Some => (), | ||
2431 | } | ||
2432 | } | ||
2433 | "#, | ||
2434 | ); | ||
2435 | } | ||
2436 | |||
2437 | #[test] | ||
2438 | fn non_let_bind() { | ||
2439 | check_diagnostics( | ||
2440 | r#" | ||
2441 | enum Option { Some, None } | ||
2442 | |||
2443 | fn main() { | ||
2444 | match Option::None { | ||
2445 | SOME_VAR @ None => (), | ||
2446 | // ^^^^^^^^ Variable `SOME_VAR` should have snake_case name, e.g. `some_var` | ||
2447 | Some => (), | ||
2448 | } | ||
2449 | } | ||
2450 | "#, | ||
2451 | ); | ||
2452 | } | ||
2453 | |||
2454 | #[test] | ||
2455 | fn allow_attributes() { | ||
2456 | check_diagnostics( | ||
2457 | r#" | ||
2458 | #[allow(non_snake_case)] | ||
2459 | fn NonSnakeCaseName(SOME_VAR: u8) -> u8{ | ||
2460 | // cov_flags generated output from elsewhere in this file | ||
2461 | extern "C" { | ||
2462 | #[no_mangle] | ||
2463 | static lower_case: u8; | ||
2464 | } | ||
2465 | |||
2466 | let OtherVar = SOME_VAR + 1; | ||
2467 | OtherVar | ||
2468 | } | ||
2469 | |||
2470 | #[allow(nonstandard_style)] | ||
2471 | mod CheckNonstandardStyle { | ||
2472 | fn HiImABadFnName() {} | ||
2473 | } | ||
2474 | |||
2475 | #[allow(bad_style)] | ||
2476 | mod CheckBadStyle { | ||
2477 | fn HiImABadFnName() {} | ||
2478 | } | ||
2479 | |||
2480 | mod F { | ||
2481 | #![allow(non_snake_case)] | ||
2482 | fn CheckItWorksWithModAttr(BAD_NAME_HI: u8) {} | ||
2483 | } | ||
2484 | |||
2485 | #[allow(non_snake_case, non_camel_case_types)] | ||
2486 | pub struct some_type { | ||
2487 | SOME_FIELD: u8, | ||
2488 | SomeField: u16, | ||
2489 | } | ||
2490 | |||
2491 | #[allow(non_upper_case_globals)] | ||
2492 | pub const some_const: u8 = 10; | ||
2493 | |||
2494 | #[allow(non_upper_case_globals)] | ||
2495 | pub static SomeStatic: u8 = 10; | ||
2496 | "#, | ||
2497 | ); | ||
2498 | } | ||
2499 | |||
2500 | #[test] | ||
2501 | fn allow_attributes_crate_attr() { | ||
2502 | check_diagnostics( | ||
2503 | r#" | ||
2504 | #![allow(non_snake_case)] | ||
2505 | |||
2506 | mod F { | ||
2507 | fn CheckItWorksWithCrateAttr(BAD_NAME_HI: u8) {} | ||
2508 | } | ||
2509 | "#, | ||
2510 | ); | ||
2511 | } | ||
2512 | |||
2513 | #[test] | ||
2514 | #[ignore] | ||
2515 | fn bug_trait_inside_fn() { | ||
2516 | // FIXME: | ||
2517 | // This is broken, and in fact, should not even be looked at by this | ||
2518 | // lint in the first place. There's weird stuff going on in the | ||
2519 | // collection phase. | ||
2520 | // It's currently being brought in by: | ||
2521 | // * validate_func on `a` recursing into modules | ||
2522 | // * then it finds the trait and then the function while iterating | ||
2523 | // through modules | ||
2524 | // * then validate_func is called on Dirty | ||
2525 | // * ... which then proceeds to look at some unknown module taking no | ||
2526 | // attrs from either the impl or the fn a, and then finally to the root | ||
2527 | // module | ||
2528 | // | ||
2529 | // It should find the attribute on the trait, but it *doesn't even see | ||
2530 | // the trait* as far as I can tell. | ||
2531 | |||
2532 | check_diagnostics( | ||
2533 | r#" | ||
2534 | trait T { fn a(); } | ||
2535 | struct U {} | ||
2536 | impl T for U { | ||
2537 | fn a() { | ||
2538 | // this comes out of bitflags, mostly | ||
2539 | #[allow(non_snake_case)] | ||
2540 | trait __BitFlags { | ||
2541 | const HiImAlsoBad: u8 = 2; | ||
2542 | #[inline] | ||
2543 | fn Dirty(&self) -> bool { | ||
2544 | false | ||
2545 | } | ||
2546 | } | ||
2547 | |||
2548 | } | ||
2549 | } | ||
2550 | "#, | ||
2551 | ); | ||
2552 | } | ||
2553 | |||
2554 | #[test] | ||
2555 | #[ignore] | ||
2556 | fn bug_traits_arent_checked() { | ||
2557 | // FIXME: Traits and functions in traits aren't currently checked by | ||
2558 | // r-a, even though rustc will complain about them. | ||
2559 | check_diagnostics( | ||
2560 | r#" | ||
2561 | trait BAD_TRAIT { | ||
2562 | // ^^^^^^^^^ Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait` | ||
2563 | fn BAD_FUNCTION(); | ||
2564 | // ^^^^^^^^^^^^ Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function` | ||
2565 | fn BadFunction(); | ||
2566 | // ^^^^^^^^^^^^ Function `BadFunction` should have snake_case name, e.g. `bad_function` | ||
2567 | } | ||
2568 | "#, | ||
2569 | ); | ||
2570 | } | ||
2571 | |||
2572 | #[test] | ||
2573 | fn ignores_extern_items() { | ||
2574 | check_diagnostics( | ||
2575 | r#" | ||
2576 | extern { | ||
2577 | fn NonSnakeCaseName(SOME_VAR: u8) -> u8; | ||
2578 | pub static SomeStatic: u8 = 10; | ||
2579 | } | ||
2580 | "#, | ||
2581 | ); | ||
2582 | } | ||
2583 | |||
2584 | #[test] | ||
2585 | fn infinite_loop_inner_items() { | ||
2586 | check_diagnostics( | ||
2587 | r#" | ||
2588 | fn qualify() { | ||
2589 | mod foo { | ||
2590 | use super::*; | ||
2591 | } | ||
2592 | } | ||
2593 | "#, | ||
2594 | ) | ||
2595 | } | ||
2596 | |||
2597 | #[test] // Issue #8809. | ||
2598 | fn parenthesized_parameter() { | ||
2599 | check_diagnostics(r#"fn f((O): _) {}"#) | ||
2600 | } | ||
2601 | } | ||