diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-06-13 19:34:32 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-06-13 19:34:32 +0100 |
commit | 76530664e7f01091e0d820eb49bf59db1f06115c (patch) | |
tree | 9700c178acb48fcc029f4120169f00a94d7308f0 /crates/ide/src/diagnostics.rs | |
parent | 2ad78924621420cb323efdeb3d875ca3f47d940f (diff) | |
parent | 3478897f86cc1b3e3f83e9d4e7cedff41721fb04 (diff) |
Merge #9255
9255: internal: remove DiagnosticWithFix infra r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ide/src/diagnostics.rs')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 530 |
1 files changed, 24 insertions, 506 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 814e64ae4..7978c1fc2 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | mod break_outside_of_loop; | 7 | mod break_outside_of_loop; |
8 | mod inactive_code; | 8 | mod inactive_code; |
9 | mod incorrect_case; | ||
9 | mod macro_error; | 10 | mod macro_error; |
10 | mod mismatched_arg_count; | 11 | mod mismatched_arg_count; |
11 | mod missing_fields; | 12 | mod missing_fields; |
@@ -15,20 +16,19 @@ mod no_such_field; | |||
15 | mod remove_this_semicolon; | 16 | mod remove_this_semicolon; |
16 | mod replace_filter_map_next_with_find_map; | 17 | mod replace_filter_map_next_with_find_map; |
17 | mod unimplemented_builtin_macro; | 18 | mod unimplemented_builtin_macro; |
19 | mod unlinked_file; | ||
18 | mod unresolved_extern_crate; | 20 | mod unresolved_extern_crate; |
19 | mod unresolved_import; | 21 | mod unresolved_import; |
20 | mod unresolved_macro_call; | 22 | mod unresolved_macro_call; |
21 | mod unresolved_module; | 23 | mod unresolved_module; |
22 | mod unresolved_proc_macro; | 24 | mod unresolved_proc_macro; |
23 | 25 | ||
24 | mod fixes; | ||
25 | mod field_shorthand; | 26 | mod field_shorthand; |
26 | mod unlinked_file; | ||
27 | 27 | ||
28 | use std::cell::RefCell; | 28 | use std::cell::RefCell; |
29 | 29 | ||
30 | use hir::{ | 30 | use hir::{ |
31 | diagnostics::{AnyDiagnostic, Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder}, | 31 | diagnostics::{AnyDiagnostic, DiagnosticCode, DiagnosticSinkBuilder}, |
32 | Semantics, | 32 | Semantics, |
33 | }; | 33 | }; |
34 | use ide_assists::AssistResolveStrategy; | 34 | use ide_assists::AssistResolveStrategy; |
@@ -37,15 +37,13 @@ use itertools::Itertools; | |||
37 | use rustc_hash::FxHashSet; | 37 | use rustc_hash::FxHashSet; |
38 | use syntax::{ | 38 | use syntax::{ |
39 | ast::{self, AstNode}, | 39 | ast::{self, AstNode}, |
40 | SyntaxNode, SyntaxNodePtr, TextRange, TextSize, | 40 | SyntaxNode, TextRange, |
41 | }; | 41 | }; |
42 | use text_edit::TextEdit; | 42 | use text_edit::TextEdit; |
43 | use unlinked_file::UnlinkedFile; | 43 | use unlinked_file::UnlinkedFile; |
44 | 44 | ||
45 | use crate::{Assist, AssistId, AssistKind, FileId, Label, SourceChange}; | 45 | use crate::{Assist, AssistId, AssistKind, FileId, Label, SourceChange}; |
46 | 46 | ||
47 | use self::fixes::DiagnosticWithFixes; | ||
48 | |||
49 | #[derive(Debug)] | 47 | #[derive(Debug)] |
50 | pub struct Diagnostic { | 48 | pub struct Diagnostic { |
51 | // pub name: Option<String>, | 49 | // pub name: Option<String>, |
@@ -135,7 +133,6 @@ pub struct DiagnosticsConfig { | |||
135 | struct DiagnosticsContext<'a> { | 133 | struct DiagnosticsContext<'a> { |
136 | config: &'a DiagnosticsConfig, | 134 | config: &'a DiagnosticsConfig, |
137 | sema: Semantics<'a, RootDatabase>, | 135 | sema: Semantics<'a, RootDatabase>, |
138 | #[allow(unused)] | ||
139 | resolve: &'a AssistResolveStrategy, | 136 | resolve: &'a AssistResolveStrategy, |
140 | } | 137 | } |
141 | 138 | ||
@@ -165,22 +162,6 @@ pub(crate) fn diagnostics( | |||
165 | } | 162 | } |
166 | let res = RefCell::new(res); | 163 | let res = RefCell::new(res); |
167 | let sink_builder = DiagnosticSinkBuilder::new() | 164 | let sink_builder = DiagnosticSinkBuilder::new() |
168 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { | ||
169 | res.borrow_mut().push(warning_with_fix(d, &sema, resolve)); | ||
170 | }) | ||
171 | .on::<UnlinkedFile, _>(|d| { | ||
172 | // Limit diagnostic to the first few characters in the file. This matches how VS Code | ||
173 | // renders it with the full span, but on other editors, and is less invasive. | ||
174 | let range = sema.diagnostics_display_range(d.display_source()).range; | ||
175 | let range = range.intersect(TextRange::up_to(TextSize::of("..."))).unwrap_or(range); | ||
176 | |||
177 | // Override severity and mark as unused. | ||
178 | res.borrow_mut().push( | ||
179 | Diagnostic::hint(range, d.message()) | ||
180 | .with_fixes(d.fixes(&sema, resolve)) | ||
181 | .with_code(Some(d.code())), | ||
182 | ); | ||
183 | }) | ||
184 | // Only collect experimental diagnostics when they're enabled. | 165 | // Only collect experimental diagnostics when they're enabled. |
185 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) | 166 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) |
186 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); | 167 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); |
@@ -200,11 +181,9 @@ pub(crate) fn diagnostics( | |||
200 | 181 | ||
201 | let mut diags = Vec::new(); | 182 | let mut diags = Vec::new(); |
202 | let internal_diagnostics = cfg!(test); | 183 | let internal_diagnostics = cfg!(test); |
203 | match sema.to_module_def(file_id) { | 184 | let module = sema.to_module_def(file_id); |
204 | Some(m) => diags = m.diagnostics(db, &mut sink, internal_diagnostics), | 185 | if let Some(m) = module { |
205 | None => { | 186 | diags = m.diagnostics(db, &mut sink, internal_diagnostics) |
206 | sink.push(UnlinkedFile { file_id, node: SyntaxNodePtr::new(parse.tree().syntax()) }); | ||
207 | } | ||
208 | } | 187 | } |
209 | 188 | ||
210 | drop(sink); | 189 | drop(sink); |
@@ -212,10 +191,17 @@ pub(crate) fn diagnostics( | |||
212 | let mut res = res.into_inner(); | 191 | let mut res = res.into_inner(); |
213 | 192 | ||
214 | let ctx = DiagnosticsContext { config, sema, resolve }; | 193 | let ctx = DiagnosticsContext { config, sema, resolve }; |
194 | if module.is_none() { | ||
195 | let d = UnlinkedFile { file: file_id }; | ||
196 | let d = unlinked_file::unlinked_file(&ctx, &d); | ||
197 | res.push(d) | ||
198 | } | ||
199 | |||
215 | for diag in diags { | 200 | for diag in diags { |
216 | #[rustfmt::skip] | 201 | #[rustfmt::skip] |
217 | let d = match diag { | 202 | let d = match diag { |
218 | AnyDiagnostic::BreakOutsideOfLoop(d) => break_outside_of_loop::break_outside_of_loop(&ctx, &d), | 203 | AnyDiagnostic::BreakOutsideOfLoop(d) => break_outside_of_loop::break_outside_of_loop(&ctx, &d), |
204 | AnyDiagnostic::IncorrectCase(d) => incorrect_case::incorrect_case(&ctx, &d), | ||
219 | AnyDiagnostic::MacroError(d) => macro_error::macro_error(&ctx, &d), | 205 | AnyDiagnostic::MacroError(d) => macro_error::macro_error(&ctx, &d), |
220 | AnyDiagnostic::MismatchedArgCount(d) => mismatched_arg_count::mismatched_arg_count(&ctx, &d), | 206 | AnyDiagnostic::MismatchedArgCount(d) => mismatched_arg_count::mismatched_arg_count(&ctx, &d), |
221 | AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d), | 207 | AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d), |
@@ -236,30 +222,24 @@ pub(crate) fn diagnostics( | |||
236 | None => continue, | 222 | None => continue, |
237 | } | 223 | } |
238 | }; | 224 | }; |
225 | res.push(d) | ||
226 | } | ||
227 | |||
228 | res.retain(|d| { | ||
239 | if let Some(code) = d.code { | 229 | if let Some(code) = d.code { |
240 | if ctx.config.disabled.contains(code.as_str()) { | 230 | if ctx.config.disabled.contains(code.as_str()) { |
241 | continue; | 231 | return false; |
242 | } | 232 | } |
243 | } | 233 | } |
244 | if ctx.config.disable_experimental && d.experimental { | 234 | if ctx.config.disable_experimental && d.experimental { |
245 | continue; | 235 | return false; |
246 | } | 236 | } |
247 | res.push(d) | 237 | true |
248 | } | 238 | }); |
249 | 239 | ||
250 | res | 240 | res |
251 | } | 241 | } |
252 | 242 | ||
253 | fn warning_with_fix<D: DiagnosticWithFixes>( | ||
254 | d: &D, | ||
255 | sema: &Semantics<RootDatabase>, | ||
256 | resolve: &AssistResolveStrategy, | ||
257 | ) -> Diagnostic { | ||
258 | Diagnostic::hint(sema.diagnostics_display_range(d.display_source()).range, d.message()) | ||
259 | .with_fixes(d.fixes(sema, resolve)) | ||
260 | .with_code(Some(d.code())) | ||
261 | } | ||
262 | |||
263 | fn check_unnecessary_braces_in_use_statement( | 243 | fn check_unnecessary_braces_in_use_statement( |
264 | acc: &mut Vec<Diagnostic>, | 244 | acc: &mut Vec<Diagnostic>, |
265 | file_id: FileId, | 245 | file_id: FileId, |
@@ -390,8 +370,9 @@ mod tests { | |||
390 | file_position.offset | 370 | file_position.offset |
391 | ); | 371 | ); |
392 | } | 372 | } |
373 | |||
393 | /// Checks that there's a diagnostic *without* fix at `$0`. | 374 | /// Checks that there's a diagnostic *without* fix at `$0`. |
394 | fn check_no_fix(ra_fixture: &str) { | 375 | pub(crate) fn check_no_fix(ra_fixture: &str) { |
395 | let (analysis, file_position) = fixture::position(ra_fixture); | 376 | let (analysis, file_position) = fixture::position(ra_fixture); |
396 | let diagnostic = analysis | 377 | let diagnostic = analysis |
397 | .diagnostics( | 378 | .diagnostics( |
@@ -536,142 +517,6 @@ mod a { | |||
536 | } | 517 | } |
537 | 518 | ||
538 | #[test] | 519 | #[test] |
539 | fn unlinked_file_prepend_first_item() { | ||
540 | cov_mark::check!(unlinked_file_prepend_before_first_item); | ||
541 | // Only tests the first one for `pub mod` since the rest are the same | ||
542 | check_fixes( | ||
543 | r#" | ||
544 | //- /main.rs | ||
545 | fn f() {} | ||
546 | //- /foo.rs | ||
547 | $0 | ||
548 | "#, | ||
549 | vec![ | ||
550 | r#" | ||
551 | mod foo; | ||
552 | |||
553 | fn f() {} | ||
554 | "#, | ||
555 | r#" | ||
556 | pub mod foo; | ||
557 | |||
558 | fn f() {} | ||
559 | "#, | ||
560 | ], | ||
561 | ); | ||
562 | } | ||
563 | |||
564 | #[test] | ||
565 | fn unlinked_file_append_mod() { | ||
566 | cov_mark::check!(unlinked_file_append_to_existing_mods); | ||
567 | check_fix( | ||
568 | r#" | ||
569 | //- /main.rs | ||
570 | //! Comment on top | ||
571 | |||
572 | mod preexisting; | ||
573 | |||
574 | mod preexisting2; | ||
575 | |||
576 | struct S; | ||
577 | |||
578 | mod preexisting_bottom;) | ||
579 | //- /foo.rs | ||
580 | $0 | ||
581 | "#, | ||
582 | r#" | ||
583 | //! Comment on top | ||
584 | |||
585 | mod preexisting; | ||
586 | |||
587 | mod preexisting2; | ||
588 | mod foo; | ||
589 | |||
590 | struct S; | ||
591 | |||
592 | mod preexisting_bottom;) | ||
593 | "#, | ||
594 | ); | ||
595 | } | ||
596 | |||
597 | #[test] | ||
598 | fn unlinked_file_insert_in_empty_file() { | ||
599 | cov_mark::check!(unlinked_file_empty_file); | ||
600 | check_fix( | ||
601 | r#" | ||
602 | //- /main.rs | ||
603 | //- /foo.rs | ||
604 | $0 | ||
605 | "#, | ||
606 | r#" | ||
607 | mod foo; | ||
608 | "#, | ||
609 | ); | ||
610 | } | ||
611 | |||
612 | #[test] | ||
613 | fn unlinked_file_old_style_modrs() { | ||
614 | check_fix( | ||
615 | r#" | ||
616 | //- /main.rs | ||
617 | mod submod; | ||
618 | //- /submod/mod.rs | ||
619 | // in mod.rs | ||
620 | //- /submod/foo.rs | ||
621 | $0 | ||
622 | "#, | ||
623 | r#" | ||
624 | // in mod.rs | ||
625 | mod foo; | ||
626 | "#, | ||
627 | ); | ||
628 | } | ||
629 | |||
630 | #[test] | ||
631 | fn unlinked_file_new_style_mod() { | ||
632 | check_fix( | ||
633 | r#" | ||
634 | //- /main.rs | ||
635 | mod submod; | ||
636 | //- /submod.rs | ||
637 | //- /submod/foo.rs | ||
638 | $0 | ||
639 | "#, | ||
640 | r#" | ||
641 | mod foo; | ||
642 | "#, | ||
643 | ); | ||
644 | } | ||
645 | |||
646 | #[test] | ||
647 | fn unlinked_file_with_cfg_off() { | ||
648 | cov_mark::check!(unlinked_file_skip_fix_when_mod_already_exists); | ||
649 | check_no_fix( | ||
650 | r#" | ||
651 | //- /main.rs | ||
652 | #[cfg(never)] | ||
653 | mod foo; | ||
654 | |||
655 | //- /foo.rs | ||
656 | $0 | ||
657 | "#, | ||
658 | ); | ||
659 | } | ||
660 | |||
661 | #[test] | ||
662 | fn unlinked_file_with_cfg_on() { | ||
663 | check_diagnostics( | ||
664 | r#" | ||
665 | //- /main.rs | ||
666 | #[cfg(not(never))] | ||
667 | mod foo; | ||
668 | |||
669 | //- /foo.rs | ||
670 | "#, | ||
671 | ); | ||
672 | } | ||
673 | |||
674 | #[test] | ||
675 | fn import_extern_crate_clash_with_inner_item() { | 520 | fn import_extern_crate_clash_with_inner_item() { |
676 | // This is more of a resolver test, but doesn't really work with the hir_def testsuite. | 521 | // This is more of a resolver test, but doesn't really work with the hir_def testsuite. |
677 | 522 | ||
@@ -1607,330 +1452,3 @@ fn main() { | |||
1607 | } | 1452 | } |
1608 | } | 1453 | } |
1609 | } | 1454 | } |
1610 | |||
1611 | #[cfg(test)] | ||
1612 | mod decl_check_tests { | ||
1613 | use crate::diagnostics::tests::check_diagnostics; | ||
1614 | |||
1615 | #[test] | ||
1616 | fn incorrect_function_name() { | ||
1617 | check_diagnostics( | ||
1618 | r#" | ||
1619 | fn NonSnakeCaseName() {} | ||
1620 | // ^^^^^^^^^^^^^^^^ Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name` | ||
1621 | "#, | ||
1622 | ); | ||
1623 | } | ||
1624 | |||
1625 | #[test] | ||
1626 | fn incorrect_function_params() { | ||
1627 | check_diagnostics( | ||
1628 | r#" | ||
1629 | fn foo(SomeParam: u8) {} | ||
1630 | // ^^^^^^^^^ Parameter `SomeParam` should have snake_case name, e.g. `some_param` | ||
1631 | |||
1632 | fn foo2(ok_param: &str, CAPS_PARAM: u8) {} | ||
1633 | // ^^^^^^^^^^ Parameter `CAPS_PARAM` should have snake_case name, e.g. `caps_param` | ||
1634 | "#, | ||
1635 | ); | ||
1636 | } | ||
1637 | |||
1638 | #[test] | ||
1639 | fn incorrect_variable_names() { | ||
1640 | check_diagnostics( | ||
1641 | r#" | ||
1642 | fn foo() { | ||
1643 | let SOME_VALUE = 10; | ||
1644 | // ^^^^^^^^^^ Variable `SOME_VALUE` should have snake_case name, e.g. `some_value` | ||
1645 | let AnotherValue = 20; | ||
1646 | // ^^^^^^^^^^^^ Variable `AnotherValue` should have snake_case name, e.g. `another_value` | ||
1647 | } | ||
1648 | "#, | ||
1649 | ); | ||
1650 | } | ||
1651 | |||
1652 | #[test] | ||
1653 | fn incorrect_struct_names() { | ||
1654 | check_diagnostics( | ||
1655 | r#" | ||
1656 | struct non_camel_case_name {} | ||
1657 | // ^^^^^^^^^^^^^^^^^^^ Structure `non_camel_case_name` should have CamelCase name, e.g. `NonCamelCaseName` | ||
1658 | |||
1659 | struct SCREAMING_CASE {} | ||
1660 | // ^^^^^^^^^^^^^^ Structure `SCREAMING_CASE` should have CamelCase name, e.g. `ScreamingCase` | ||
1661 | "#, | ||
1662 | ); | ||
1663 | } | ||
1664 | |||
1665 | #[test] | ||
1666 | fn no_diagnostic_for_camel_cased_acronyms_in_struct_name() { | ||
1667 | check_diagnostics( | ||
1668 | r#" | ||
1669 | struct AABB {} | ||
1670 | "#, | ||
1671 | ); | ||
1672 | } | ||
1673 | |||
1674 | #[test] | ||
1675 | fn incorrect_struct_field() { | ||
1676 | check_diagnostics( | ||
1677 | r#" | ||
1678 | struct SomeStruct { SomeField: u8 } | ||
1679 | // ^^^^^^^^^ Field `SomeField` should have snake_case name, e.g. `some_field` | ||
1680 | "#, | ||
1681 | ); | ||
1682 | } | ||
1683 | |||
1684 | #[test] | ||
1685 | fn incorrect_enum_names() { | ||
1686 | check_diagnostics( | ||
1687 | r#" | ||
1688 | enum some_enum { Val(u8) } | ||
1689 | // ^^^^^^^^^ Enum `some_enum` should have CamelCase name, e.g. `SomeEnum` | ||
1690 | |||
1691 | enum SOME_ENUM {} | ||
1692 | // ^^^^^^^^^ Enum `SOME_ENUM` should have CamelCase name, e.g. `SomeEnum` | ||
1693 | "#, | ||
1694 | ); | ||
1695 | } | ||
1696 | |||
1697 | #[test] | ||
1698 | fn no_diagnostic_for_camel_cased_acronyms_in_enum_name() { | ||
1699 | check_diagnostics( | ||
1700 | r#" | ||
1701 | enum AABB {} | ||
1702 | "#, | ||
1703 | ); | ||
1704 | } | ||
1705 | |||
1706 | #[test] | ||
1707 | fn incorrect_enum_variant_name() { | ||
1708 | check_diagnostics( | ||
1709 | r#" | ||
1710 | enum SomeEnum { SOME_VARIANT(u8) } | ||
1711 | // ^^^^^^^^^^^^ Variant `SOME_VARIANT` should have CamelCase name, e.g. `SomeVariant` | ||
1712 | "#, | ||
1713 | ); | ||
1714 | } | ||
1715 | |||
1716 | #[test] | ||
1717 | fn incorrect_const_name() { | ||
1718 | check_diagnostics( | ||
1719 | r#" | ||
1720 | const some_weird_const: u8 = 10; | ||
1721 | // ^^^^^^^^^^^^^^^^ Constant `some_weird_const` should have UPPER_SNAKE_CASE name, e.g. `SOME_WEIRD_CONST` | ||
1722 | "#, | ||
1723 | ); | ||
1724 | } | ||
1725 | |||
1726 | #[test] | ||
1727 | fn incorrect_static_name() { | ||
1728 | check_diagnostics( | ||
1729 | r#" | ||
1730 | static some_weird_const: u8 = 10; | ||
1731 | // ^^^^^^^^^^^^^^^^ Static variable `some_weird_const` should have UPPER_SNAKE_CASE name, e.g. `SOME_WEIRD_CONST` | ||
1732 | "#, | ||
1733 | ); | ||
1734 | } | ||
1735 | |||
1736 | #[test] | ||
1737 | fn fn_inside_impl_struct() { | ||
1738 | check_diagnostics( | ||
1739 | r#" | ||
1740 | struct someStruct; | ||
1741 | // ^^^^^^^^^^ Structure `someStruct` should have CamelCase name, e.g. `SomeStruct` | ||
1742 | |||
1743 | impl someStruct { | ||
1744 | fn SomeFunc(&self) { | ||
1745 | // ^^^^^^^^ Function `SomeFunc` should have snake_case name, e.g. `some_func` | ||
1746 | let WHY_VAR_IS_CAPS = 10; | ||
1747 | // ^^^^^^^^^^^^^^^ Variable `WHY_VAR_IS_CAPS` should have snake_case name, e.g. `why_var_is_caps` | ||
1748 | } | ||
1749 | } | ||
1750 | "#, | ||
1751 | ); | ||
1752 | } | ||
1753 | |||
1754 | #[test] | ||
1755 | fn no_diagnostic_for_enum_varinats() { | ||
1756 | check_diagnostics( | ||
1757 | r#" | ||
1758 | enum Option { Some, None } | ||
1759 | |||
1760 | fn main() { | ||
1761 | match Option::None { | ||
1762 | None => (), | ||
1763 | Some => (), | ||
1764 | } | ||
1765 | } | ||
1766 | "#, | ||
1767 | ); | ||
1768 | } | ||
1769 | |||
1770 | #[test] | ||
1771 | fn non_let_bind() { | ||
1772 | check_diagnostics( | ||
1773 | r#" | ||
1774 | enum Option { Some, None } | ||
1775 | |||
1776 | fn main() { | ||
1777 | match Option::None { | ||
1778 | SOME_VAR @ None => (), | ||
1779 | // ^^^^^^^^ Variable `SOME_VAR` should have snake_case name, e.g. `some_var` | ||
1780 | Some => (), | ||
1781 | } | ||
1782 | } | ||
1783 | "#, | ||
1784 | ); | ||
1785 | } | ||
1786 | |||
1787 | #[test] | ||
1788 | fn allow_attributes() { | ||
1789 | check_diagnostics( | ||
1790 | r#" | ||
1791 | #[allow(non_snake_case)] | ||
1792 | fn NonSnakeCaseName(SOME_VAR: u8) -> u8{ | ||
1793 | // cov_flags generated output from elsewhere in this file | ||
1794 | extern "C" { | ||
1795 | #[no_mangle] | ||
1796 | static lower_case: u8; | ||
1797 | } | ||
1798 | |||
1799 | let OtherVar = SOME_VAR + 1; | ||
1800 | OtherVar | ||
1801 | } | ||
1802 | |||
1803 | #[allow(nonstandard_style)] | ||
1804 | mod CheckNonstandardStyle { | ||
1805 | fn HiImABadFnName() {} | ||
1806 | } | ||
1807 | |||
1808 | #[allow(bad_style)] | ||
1809 | mod CheckBadStyle { | ||
1810 | fn HiImABadFnName() {} | ||
1811 | } | ||
1812 | |||
1813 | mod F { | ||
1814 | #![allow(non_snake_case)] | ||
1815 | fn CheckItWorksWithModAttr(BAD_NAME_HI: u8) {} | ||
1816 | } | ||
1817 | |||
1818 | #[allow(non_snake_case, non_camel_case_types)] | ||
1819 | pub struct some_type { | ||
1820 | SOME_FIELD: u8, | ||
1821 | SomeField: u16, | ||
1822 | } | ||
1823 | |||
1824 | #[allow(non_upper_case_globals)] | ||
1825 | pub const some_const: u8 = 10; | ||
1826 | |||
1827 | #[allow(non_upper_case_globals)] | ||
1828 | pub static SomeStatic: u8 = 10; | ||
1829 | "#, | ||
1830 | ); | ||
1831 | } | ||
1832 | |||
1833 | #[test] | ||
1834 | fn allow_attributes_crate_attr() { | ||
1835 | check_diagnostics( | ||
1836 | r#" | ||
1837 | #![allow(non_snake_case)] | ||
1838 | |||
1839 | mod F { | ||
1840 | fn CheckItWorksWithCrateAttr(BAD_NAME_HI: u8) {} | ||
1841 | } | ||
1842 | "#, | ||
1843 | ); | ||
1844 | } | ||
1845 | |||
1846 | #[test] | ||
1847 | #[ignore] | ||
1848 | fn bug_trait_inside_fn() { | ||
1849 | // FIXME: | ||
1850 | // This is broken, and in fact, should not even be looked at by this | ||
1851 | // lint in the first place. There's weird stuff going on in the | ||
1852 | // collection phase. | ||
1853 | // It's currently being brought in by: | ||
1854 | // * validate_func on `a` recursing into modules | ||
1855 | // * then it finds the trait and then the function while iterating | ||
1856 | // through modules | ||
1857 | // * then validate_func is called on Dirty | ||
1858 | // * ... which then proceeds to look at some unknown module taking no | ||
1859 | // attrs from either the impl or the fn a, and then finally to the root | ||
1860 | // module | ||
1861 | // | ||
1862 | // It should find the attribute on the trait, but it *doesn't even see | ||
1863 | // the trait* as far as I can tell. | ||
1864 | |||
1865 | check_diagnostics( | ||
1866 | r#" | ||
1867 | trait T { fn a(); } | ||
1868 | struct U {} | ||
1869 | impl T for U { | ||
1870 | fn a() { | ||
1871 | // this comes out of bitflags, mostly | ||
1872 | #[allow(non_snake_case)] | ||
1873 | trait __BitFlags { | ||
1874 | const HiImAlsoBad: u8 = 2; | ||
1875 | #[inline] | ||
1876 | fn Dirty(&self) -> bool { | ||
1877 | false | ||
1878 | } | ||
1879 | } | ||
1880 | |||
1881 | } | ||
1882 | } | ||
1883 | "#, | ||
1884 | ); | ||
1885 | } | ||
1886 | |||
1887 | #[test] | ||
1888 | #[ignore] | ||
1889 | fn bug_traits_arent_checked() { | ||
1890 | // FIXME: Traits and functions in traits aren't currently checked by | ||
1891 | // r-a, even though rustc will complain about them. | ||
1892 | check_diagnostics( | ||
1893 | r#" | ||
1894 | trait BAD_TRAIT { | ||
1895 | // ^^^^^^^^^ Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait` | ||
1896 | fn BAD_FUNCTION(); | ||
1897 | // ^^^^^^^^^^^^ Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function` | ||
1898 | fn BadFunction(); | ||
1899 | // ^^^^^^^^^^^^ Function `BadFunction` should have snake_case name, e.g. `bad_function` | ||
1900 | } | ||
1901 | "#, | ||
1902 | ); | ||
1903 | } | ||
1904 | |||
1905 | #[test] | ||
1906 | fn ignores_extern_items() { | ||
1907 | cov_mark::check!(extern_func_incorrect_case_ignored); | ||
1908 | cov_mark::check!(extern_static_incorrect_case_ignored); | ||
1909 | check_diagnostics( | ||
1910 | r#" | ||
1911 | extern { | ||
1912 | fn NonSnakeCaseName(SOME_VAR: u8) -> u8; | ||
1913 | pub static SomeStatic: u8 = 10; | ||
1914 | } | ||
1915 | "#, | ||
1916 | ); | ||
1917 | } | ||
1918 | |||
1919 | #[test] | ||
1920 | fn infinite_loop_inner_items() { | ||
1921 | check_diagnostics( | ||
1922 | r#" | ||
1923 | fn qualify() { | ||
1924 | mod foo { | ||
1925 | use super::*; | ||
1926 | } | ||
1927 | } | ||
1928 | "#, | ||
1929 | ) | ||
1930 | } | ||
1931 | |||
1932 | #[test] // Issue #8809. | ||
1933 | fn parenthesized_parameter() { | ||
1934 | check_diagnostics(r#"fn f((O): _) {}"#) | ||
1935 | } | ||
1936 | } | ||