diff options
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests.rs | 31 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_scope.rs | 62 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_project_model/src/sysroot.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_error.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation.rs | 23 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt | 99 |
12 files changed, 251 insertions, 10 deletions
diff --git a/.travis.yml b/.travis.yml index 7d66f72d8..af71a9cce 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -14,7 +14,6 @@ matrix: | |||
14 | script: | 14 | script: |
15 | - rustup component add rustfmt | 15 | - rustup component add rustfmt |
16 | - rustup component add rust-src | 16 | - rustup component add rust-src |
17 | - sed -i "s/debug = 1/debug = false/g" Cargo.toml | ||
18 | - cargo test --no-run # let's measure compile time separately | 17 | - cargo test --no-run # let's measure compile time separately |
19 | - cargo test | 18 | - cargo test |
20 | env: | 19 | env: |
diff --git a/Cargo.toml b/Cargo.toml index 97c02b40f..5c57020f7 100644 --- a/Cargo.toml +++ b/Cargo.toml | |||
@@ -2,7 +2,9 @@ | |||
2 | members = [ "crates/*", "xtask/" ] | 2 | members = [ "crates/*", "xtask/" ] |
3 | 3 | ||
4 | [profile.dev] | 4 | [profile.dev] |
5 | debug = 1 # only line info | 5 | # disabling debug info speeds up builds a bunch, |
6 | # and we don't rely on it for debugging that much. | ||
7 | debug = 0 | ||
6 | 8 | ||
7 | [profile.release] | 9 | [profile.release] |
8 | incremental = true | 10 | incremental = true |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 131f6c797..9dc8d139b 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -76,7 +76,11 @@ pub use crate::{ | |||
76 | resolve::ScopeDef, | 76 | resolve::ScopeDef, |
77 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 77 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
78 | ty::{ | 78 | ty::{ |
79 | display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | 79 | display::HirDisplay, |
80 | primitive::{ | ||
81 | FloatBitness, FloatTy, IntBitness, IntTy, Signedness, UncertainFloatTy, UncertainIntTy, | ||
82 | }, | ||
83 | ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk, | ||
80 | }, | 84 | }, |
81 | }; | 85 | }; |
82 | 86 | ||
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 7e6083961..6db9937a4 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -36,11 +36,12 @@ pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> | |||
36 | ); | 36 | ); |
37 | 37 | ||
38 | // look for the prelude | 38 | // look for the prelude |
39 | if def_map.prelude.is_none() { | 39 | // If the dependency defines a prelude, we overwrite an already defined |
40 | let map = db.crate_def_map(dep.crate_id); | 40 | // prelude. This is necessary to import the "std" prelude if a crate |
41 | if map.prelude.is_some() { | 41 | // depends on both "core" and "std". |
42 | def_map.prelude = map.prelude; | 42 | let dep_def_map = db.crate_def_map(dep.crate_id); |
43 | } | 43 | if dep_def_map.prelude.is_some() { |
44 | def_map.prelude = dep_def_map.prelude; | ||
44 | } | 45 | } |
45 | } | 46 | } |
46 | 47 | ||
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 52bd0aa91..256f7d4be 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs | |||
@@ -464,6 +464,37 @@ fn values_dont_shadow_extern_crates() { | |||
464 | } | 464 | } |
465 | 465 | ||
466 | #[test] | 466 | #[test] |
467 | fn std_prelude_takes_precedence_above_core_prelude() { | ||
468 | let map = def_map( | ||
469 | r#" | ||
470 | //- /main.rs crate:main deps:core,std | ||
471 | use {Foo, Bar}; | ||
472 | |||
473 | //- /std.rs crate:std deps:core | ||
474 | #[prelude_import] | ||
475 | pub use self::prelude::*; | ||
476 | mod prelude { | ||
477 | pub struct Foo; | ||
478 | pub use core::prelude::Bar; | ||
479 | } | ||
480 | |||
481 | //- /core.rs crate:core | ||
482 | #[prelude_import] | ||
483 | pub use self::prelude::*; | ||
484 | mod prelude { | ||
485 | pub struct Bar; | ||
486 | } | ||
487 | "#, | ||
488 | ); | ||
489 | |||
490 | assert_snapshot!(map, @r###" | ||
491 | ⋮crate | ||
492 | ⋮Bar: t v | ||
493 | ⋮Foo: t v | ||
494 | "###); | ||
495 | } | ||
496 | |||
497 | #[test] | ||
467 | fn cfg_not_test() { | 498 | fn cfg_not_test() { |
468 | let map = def_map( | 499 | let map = def_map( |
469 | r#" | 500 | r#" |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 4e56de3f5..3e205efd1 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -598,6 +598,68 @@ mod tests { | |||
598 | } | 598 | } |
599 | 599 | ||
600 | #[test] | 600 | #[test] |
601 | fn completes_std_prelude_if_core_is_defined() { | ||
602 | assert_debug_snapshot!( | ||
603 | do_reference_completion( | ||
604 | " | ||
605 | //- /main.rs | ||
606 | fn foo() { let x: <|> } | ||
607 | |||
608 | //- /core/lib.rs | ||
609 | #[prelude_import] | ||
610 | use prelude::*; | ||
611 | |||
612 | mod prelude { | ||
613 | struct Option; | ||
614 | } | ||
615 | |||
616 | //- /std/lib.rs | ||
617 | #[prelude_import] | ||
618 | use prelude::*; | ||
619 | |||
620 | mod prelude { | ||
621 | struct String; | ||
622 | } | ||
623 | " | ||
624 | ), | ||
625 | @r###" | ||
626 | [ | ||
627 | CompletionItem { | ||
628 | label: "String", | ||
629 | source_range: [18; 18), | ||
630 | delete: [18; 18), | ||
631 | insert: "String", | ||
632 | kind: Struct, | ||
633 | }, | ||
634 | CompletionItem { | ||
635 | label: "core", | ||
636 | source_range: [18; 18), | ||
637 | delete: [18; 18), | ||
638 | insert: "core", | ||
639 | kind: Module, | ||
640 | }, | ||
641 | CompletionItem { | ||
642 | label: "foo()", | ||
643 | source_range: [18; 18), | ||
644 | delete: [18; 18), | ||
645 | insert: "foo()$0", | ||
646 | kind: Function, | ||
647 | lookup: "foo", | ||
648 | detail: "fn foo()", | ||
649 | }, | ||
650 | CompletionItem { | ||
651 | label: "std", | ||
652 | source_range: [18; 18), | ||
653 | delete: [18; 18), | ||
654 | insert: "std", | ||
655 | kind: Module, | ||
656 | }, | ||
657 | ] | ||
658 | "### | ||
659 | ); | ||
660 | } | ||
661 | |||
662 | #[test] | ||
601 | fn completes_macros_as_value() { | 663 | fn completes_macros_as_value() { |
602 | assert_debug_snapshot!( | 664 | assert_debug_snapshot!( |
603 | do_reference_completion( | 665 | do_reference_completion( |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 8b8663a78..0e14f1b70 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -199,6 +199,7 @@ impl ProjectWorkspace { | |||
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied()); | ||
202 | let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); | 203 | let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); |
203 | 204 | ||
204 | let mut pkg_to_lib_crate = FxHashMap::default(); | 205 | let mut pkg_to_lib_crate = FxHashMap::default(); |
@@ -226,7 +227,7 @@ impl ProjectWorkspace { | |||
226 | } | 227 | } |
227 | } | 228 | } |
228 | 229 | ||
229 | // Set deps to the std and to the lib target of the current package | 230 | // Set deps to the core, std and to the lib target of the current package |
230 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 231 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { |
231 | if let Some(to) = lib_tgt { | 232 | if let Some(to) = lib_tgt { |
232 | if to != from { | 233 | if to != from { |
@@ -240,6 +241,13 @@ impl ProjectWorkspace { | |||
240 | } | 241 | } |
241 | } | 242 | } |
242 | } | 243 | } |
244 | // core is added as a dependency before std in order to | ||
245 | // mimic rustcs dependency order | ||
246 | if let Some(core) = libcore { | ||
247 | if let Err(_) = crate_graph.add_dep(from, "core".into(), core) { | ||
248 | log::error!("cyclic dependency on core for {}", pkg.name(&cargo)) | ||
249 | } | ||
250 | } | ||
243 | if let Some(std) = libstd { | 251 | if let Some(std) = libstd { |
244 | if let Err(_) = crate_graph.add_dep(from, "std".into(), std) { | 252 | if let Err(_) = crate_graph.add_dep(from, "std".into(), std) { |
245 | log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) | 253 | log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) |
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index 35d6df5cb..3d827809e 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -27,6 +27,10 @@ struct SysrootCrateData { | |||
27 | } | 27 | } |
28 | 28 | ||
29 | impl Sysroot { | 29 | impl Sysroot { |
30 | pub fn core(&self) -> Option<SysrootCrate> { | ||
31 | self.by_name("core") | ||
32 | } | ||
33 | |||
30 | pub fn std(&self) -> Option<SysrootCrate> { | 34 | pub fn std(&self) -> Option<SysrootCrate> { |
31 | self.by_name("std") | 35 | self.by_name("std") |
32 | } | 36 | } |
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index d6eca2ad7..1f60a7aab 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs | |||
@@ -82,6 +82,7 @@ pub enum SyntaxErrorKind { | |||
82 | InvalidBlockAttr, | 82 | InvalidBlockAttr, |
83 | InvalidMatchInnerAttr, | 83 | InvalidMatchInnerAttr, |
84 | InvalidTupleIndexFormat, | 84 | InvalidTupleIndexFormat, |
85 | VisibilityNotAllowed, | ||
85 | } | 86 | } |
86 | 87 | ||
87 | impl fmt::Display for SyntaxErrorKind { | 88 | impl fmt::Display for SyntaxErrorKind { |
@@ -99,6 +100,9 @@ impl fmt::Display for SyntaxErrorKind { | |||
99 | } | 100 | } |
100 | ParseError(msg) => write!(f, "{}", msg.0), | 101 | ParseError(msg) => write!(f, "{}", msg.0), |
101 | EscapeError(err) => write!(f, "{}", err), | 102 | EscapeError(err) => write!(f, "{}", err), |
103 | VisibilityNotAllowed => { | ||
104 | write!(f, "unnecessary visibility qualifier") | ||
105 | } | ||
102 | } | 106 | } |
103 | } | 107 | } |
104 | } | 108 | } |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index ab4f15908..2d596763e 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -6,7 +6,7 @@ use rustc_lexer::unescape; | |||
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | ast, match_ast, AstNode, SyntaxError, SyntaxErrorKind, | 8 | ast, match_ast, AstNode, SyntaxError, SyntaxErrorKind, |
9 | SyntaxKind::{BYTE, BYTE_STRING, CHAR, INT_NUMBER, STRING}, | 9 | SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF}, |
10 | SyntaxNode, SyntaxToken, TextUnit, T, | 10 | SyntaxNode, SyntaxToken, TextUnit, T, |
11 | }; | 11 | }; |
12 | 12 | ||
@@ -102,6 +102,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | |||
102 | ast::BlockExpr(it) => { block::validate_block_expr(it, &mut errors) }, | 102 | ast::BlockExpr(it) => { block::validate_block_expr(it, &mut errors) }, |
103 | ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, | 103 | ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, |
104 | ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, | 104 | ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, |
105 | ast::Visibility(it) => { validate_visibility(it, &mut errors) }, | ||
105 | _ => (), | 106 | _ => (), |
106 | } | 107 | } |
107 | } | 108 | } |
@@ -206,3 +207,23 @@ fn validate_numeric_name(name_ref: Option<ast::NameRef>, errors: &mut Vec<Syntax | |||
206 | name_ref?.syntax().first_child_or_token()?.into_token().filter(|it| it.kind() == INT_NUMBER) | 207 | name_ref?.syntax().first_child_or_token()?.into_token().filter(|it| it.kind() == INT_NUMBER) |
207 | } | 208 | } |
208 | } | 209 | } |
210 | |||
211 | fn validate_visibility(vis: ast::Visibility, errors: &mut Vec<SyntaxError>) { | ||
212 | let parent = match vis.syntax().parent() { | ||
213 | Some(it) => it, | ||
214 | None => return, | ||
215 | }; | ||
216 | match parent.kind() { | ||
217 | FN_DEF | CONST_DEF | TYPE_ALIAS_DEF => (), | ||
218 | _ => return, | ||
219 | } | ||
220 | let impl_block = match parent.parent().and_then(|it| it.parent()).and_then(ast::ImplBlock::cast) | ||
221 | { | ||
222 | Some(it) => it, | ||
223 | None => return, | ||
224 | }; | ||
225 | if impl_block.target_trait().is_some() { | ||
226 | errors | ||
227 | .push(SyntaxError::new(SyntaxErrorKind::VisibilityNotAllowed, vis.syntax.text_range())) | ||
228 | } | ||
229 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rs b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rs new file mode 100644 index 000000000..a43e7ef10 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | impl T for () { | ||
2 | fn foo() {} | ||
3 | pub fn bar() {} | ||
4 | pub(crate) type Baz = (); | ||
5 | pub(crate) const C: i32 = 92; | ||
6 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt new file mode 100644 index 000000000..749c8cddb --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt | |||
@@ -0,0 +1,99 @@ | |||
1 | SOURCE_FILE@[0; 118) | ||
2 | IMPL_BLOCK@[0; 117) | ||
3 | IMPL_KW@[0; 4) "impl" | ||
4 | WHITESPACE@[4; 5) " " | ||
5 | PATH_TYPE@[5; 6) | ||
6 | PATH@[5; 6) | ||
7 | PATH_SEGMENT@[5; 6) | ||
8 | NAME_REF@[5; 6) | ||
9 | IDENT@[5; 6) "T" | ||
10 | WHITESPACE@[6; 7) " " | ||
11 | FOR_KW@[7; 10) "for" | ||
12 | WHITESPACE@[10; 11) " " | ||
13 | TUPLE_TYPE@[11; 13) | ||
14 | L_PAREN@[11; 12) "(" | ||
15 | R_PAREN@[12; 13) ")" | ||
16 | WHITESPACE@[13; 14) " " | ||
17 | ITEM_LIST@[14; 117) | ||
18 | L_CURLY@[14; 15) "{" | ||
19 | WHITESPACE@[15; 20) "\n " | ||
20 | FN_DEF@[20; 31) | ||
21 | FN_KW@[20; 22) "fn" | ||
22 | WHITESPACE@[22; 23) " " | ||
23 | NAME@[23; 26) | ||
24 | IDENT@[23; 26) "foo" | ||
25 | PARAM_LIST@[26; 28) | ||
26 | L_PAREN@[26; 27) "(" | ||
27 | R_PAREN@[27; 28) ")" | ||
28 | WHITESPACE@[28; 29) " " | ||
29 | BLOCK_EXPR@[29; 31) | ||
30 | BLOCK@[29; 31) | ||
31 | L_CURLY@[29; 30) "{" | ||
32 | R_CURLY@[30; 31) "}" | ||
33 | WHITESPACE@[31; 36) "\n " | ||
34 | FN_DEF@[36; 51) | ||
35 | VISIBILITY@[36; 39) | ||
36 | PUB_KW@[36; 39) "pub" | ||
37 | WHITESPACE@[39; 40) " " | ||
38 | FN_KW@[40; 42) "fn" | ||
39 | WHITESPACE@[42; 43) " " | ||
40 | NAME@[43; 46) | ||
41 | IDENT@[43; 46) "bar" | ||
42 | PARAM_LIST@[46; 48) | ||
43 | L_PAREN@[46; 47) "(" | ||
44 | R_PAREN@[47; 48) ")" | ||
45 | WHITESPACE@[48; 49) " " | ||
46 | BLOCK_EXPR@[49; 51) | ||
47 | BLOCK@[49; 51) | ||
48 | L_CURLY@[49; 50) "{" | ||
49 | R_CURLY@[50; 51) "}" | ||
50 | WHITESPACE@[51; 56) "\n " | ||
51 | TYPE_ALIAS_DEF@[56; 81) | ||
52 | VISIBILITY@[56; 66) | ||
53 | PUB_KW@[56; 59) "pub" | ||
54 | L_PAREN@[59; 60) "(" | ||
55 | CRATE_KW@[60; 65) "crate" | ||
56 | R_PAREN@[65; 66) ")" | ||
57 | WHITESPACE@[66; 67) " " | ||
58 | TYPE_KW@[67; 71) "type" | ||
59 | WHITESPACE@[71; 72) " " | ||
60 | NAME@[72; 75) | ||
61 | IDENT@[72; 75) "Baz" | ||
62 | WHITESPACE@[75; 76) " " | ||
63 | EQ@[76; 77) "=" | ||
64 | WHITESPACE@[77; 78) " " | ||
65 | TUPLE_TYPE@[78; 80) | ||
66 | L_PAREN@[78; 79) "(" | ||
67 | R_PAREN@[79; 80) ")" | ||
68 | SEMI@[80; 81) ";" | ||
69 | WHITESPACE@[81; 86) "\n " | ||
70 | CONST_DEF@[86; 115) | ||
71 | VISIBILITY@[86; 96) | ||
72 | PUB_KW@[86; 89) "pub" | ||
73 | L_PAREN@[89; 90) "(" | ||
74 | CRATE_KW@[90; 95) "crate" | ||
75 | R_PAREN@[95; 96) ")" | ||
76 | WHITESPACE@[96; 97) " " | ||
77 | CONST_KW@[97; 102) "const" | ||
78 | WHITESPACE@[102; 103) " " | ||
79 | NAME@[103; 104) | ||
80 | IDENT@[103; 104) "C" | ||
81 | COLON@[104; 105) ":" | ||
82 | WHITESPACE@[105; 106) " " | ||
83 | PATH_TYPE@[106; 109) | ||
84 | PATH@[106; 109) | ||
85 | PATH_SEGMENT@[106; 109) | ||
86 | NAME_REF@[106; 109) | ||
87 | IDENT@[106; 109) "i32" | ||
88 | WHITESPACE@[109; 110) " " | ||
89 | EQ@[110; 111) "=" | ||
90 | WHITESPACE@[111; 112) " " | ||
91 | LITERAL@[112; 114) | ||
92 | INT_NUMBER@[112; 114) "92" | ||
93 | SEMI@[114; 115) ";" | ||
94 | WHITESPACE@[115; 116) "\n" | ||
95 | R_CURLY@[116; 117) "}" | ||
96 | WHITESPACE@[117; 118) "\n" | ||
97 | error [36; 39): unnecessary visibility qualifier | ||
98 | error [56; 66): unnecessary visibility qualifier | ||
99 | error [86; 96): unnecessary visibility qualifier | ||