aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--Cargo.toml4
-rw-r--r--crates/ra_hir/src/lib.rs6
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs11
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs31
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs62
-rw-r--r--crates/ra_project_model/src/lib.rs10
-rw-r--r--crates/ra_project_model/src/sysroot.rs4
-rw-r--r--crates/ra_syntax/src/syntax_error.rs4
-rw-r--r--crates/ra_syntax/src/validation.rs23
-rw-r--r--crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.rs6
-rw-r--r--crates/ra_syntax/test_data/parser/err/0037_visibility_in_traits.txt99
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 @@
2members = [ "crates/*", "xtask/" ] 2members = [ "crates/*", "xtask/" ]
3 3
4[profile.dev] 4[profile.dev]
5debug = 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.
7debug = 0
6 8
7[profile.release] 9[profile.release]
8incremental = true 10incremental = 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]
467fn 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]
467fn cfg_not_test() { 498fn 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
29impl Sysroot { 29impl 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
87impl fmt::Display for SyntaxErrorKind { 88impl 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
7use crate::{ 7use 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
211fn 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 @@
1impl 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 @@
1SOURCE_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"
97error [36; 39): unnecessary visibility qualifier
98error [56; 66): unnecessary visibility qualifier
99error [86; 96): unnecessary visibility qualifier