diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index 77246379e7b..ba766340161 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -172,6 +172,43 @@ fn foo(s: S) { s.$0 } ); } + #[test] + fn no_unstable_method_on_stable() { + check( + r#" +//- /main.rs crate:main deps:std +fn foo(s: std::S) { s.$0 } +//- /std.rs crate:std +pub struct S; +impl S { + #[unstable] + pub fn bar(&self) {} +} +"#, + expect![""], + ); + } + + #[test] + fn unstable_method_on_nightly() { + check( + r#" +//- toolchain:nightly +//- /main.rs crate:main deps:std +fn foo(s: std::S) { s.$0 } +//- /std.rs crate:std +pub struct S; +impl S { + #[unstable] + pub fn bar(&self) {} +} +"#, + expect![[r#" + me bar() fn(&self) + "#]], + ); + } + #[test] fn test_struct_field_completion_self() { check( diff --git a/crates/ide-completion/src/tests.rs b/crates/ide-completion/src/tests.rs index 05e6aaf09d9..79c1f98f3bd 100644 --- a/crates/ide-completion/src/tests.rs +++ b/crates/ide-completion/src/tests.rs @@ -23,6 +23,7 @@ mod use_tree; mod visibility; +use expect_test::Expect; use hir::PrefixKind; use ide_db::{ base_db::{fixture::ChangeFixture, FileLoader, FilePosition}, @@ -215,6 +216,11 @@ pub(crate) fn check_edit_with_config( assert_eq_text!(&ra_fixture_after, &actual) } +fn check_empty(ra_fixture: &str, expect: Expect) { + let actual = completion_list(ra_fixture); + expect.assert_eq(&actual); +} + pub(crate) fn get_all_items( config: CompletionConfig, code: &str, diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs index c1c6a689eb1..36465be23d8 100644 --- a/crates/ide-completion/src/tests/expression.rs +++ b/crates/ide-completion/src/tests/expression.rs @@ -1,18 +1,13 @@ //! Completion tests for expressions. use expect_test::{expect, Expect}; -use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE}; +use crate::tests::{check_edit, check_empty, completion_list, BASE_ITEMS_FIXTURE}; fn check(ra_fixture: &str, expect: Expect) { let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}")); expect.assert_eq(&actual) } -fn check_empty(ra_fixture: &str, expect: Expect) { - let actual = completion_list(ra_fixture); - expect.assert_eq(&actual); -} - #[test] fn complete_literal_struct_with_a_private_field() { // `FooDesc.bar` is private, the completion should not be triggered. @@ -997,3 +992,105 @@ fn foo() fn() "#]], ); } + +#[test] +fn expr_no_unstable_item_on_stable() { + check_empty( + r#" +//- /main.rs crate:main deps:std +use std::*; +fn main() { + $0 +} +//- /std.rs crate:std +#[unstable] +pub struct UnstableThisShouldNotBeListed; +"#, + expect![[r#" + fn main() fn() + md std + bt u32 + kw const + kw crate:: + kw enum + kw extern + kw false + kw fn + kw for + kw if + kw if let + kw impl + kw let + kw loop + kw match + kw mod + kw return + kw self:: + kw static + kw struct + kw trait + kw true + kw type + kw union + kw unsafe + kw use + kw while + kw while let + sn macro_rules + sn pd + sn ppd + "#]], + ); +} + +#[test] +fn expr_unstable_item_on_nightly() { + check_empty( + r#" +//- toolchain:nightly +//- /main.rs crate:main deps:std +use std::*; +fn main() { + $0 +} +//- /std.rs crate:std +#[unstable] +pub struct UnstableButWeAreOnNightlyAnyway; +"#, + expect![[r#" + fn main() fn() + md std + st UnstableButWeAreOnNightlyAnyway + bt u32 + kw const + kw crate:: + kw enum + kw extern + kw false + kw fn + kw for + kw if + kw if let + kw impl + kw let + kw loop + kw match + kw mod + kw return + kw self:: + kw static + kw struct + kw trait + kw true + kw type + kw union + kw unsafe + kw use + kw while + kw while let + sn macro_rules + sn pd + sn ppd + "#]], + ); +} diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs index 0b485eb776d..d727320b514 100644 --- a/crates/ide-completion/src/tests/flyimport.rs +++ b/crates/ide-completion/src/tests/flyimport.rs @@ -1107,6 +1107,41 @@ fn function() { ); } +#[test] +fn flyimport_pattern_no_unstable_item_on_stable() { + check( + r#" +//- /main.rs crate:main deps:std +fn function() { + let foo$0 +} +//- /std.rs crate:std +#[unstable] +pub struct FooStruct {} +"#, + expect![""], + ); +} + +#[test] +fn flyimport_pattern_unstable_item_on_nightly() { + check( + r#" +//- toolchain:nightly +//- /main.rs crate:main deps:std +fn function() { + let foo$0 +} +//- /std.rs crate:std +#[unstable] +pub struct FooStruct {} +"#, + expect![[r#" + st FooStruct (use std::FooStruct) + "#]], + ); +} + #[test] fn flyimport_item_name() { check( diff --git a/crates/ide-completion/src/tests/item_list.rs b/crates/ide-completion/src/tests/item_list.rs index 9fc731bb11d..2b5b4dd773c 100644 --- a/crates/ide-completion/src/tests/item_list.rs +++ b/crates/ide-completion/src/tests/item_list.rs @@ -1,7 +1,7 @@ //! Completion tests for item list position. use expect_test::{expect, Expect}; -use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE}; +use crate::tests::{check_edit, check_empty, completion_list, BASE_ITEMS_FIXTURE}; fn check(ra_fixture: &str, expect: Expect) { let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}")); @@ -297,6 +297,58 @@ fn fn function1() ); } +#[test] +fn in_trait_impl_no_unstable_item_on_stable() { + check_empty( + r#" +trait Test { + #[unstable] + type Type; + #[unstable] + const CONST: (); + #[unstable] + fn function(); +} + +impl Test for () { + $0 +} +"#, + expect![[r#" + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn in_trait_impl_unstable_item_on_nightly() { + check_empty( + r#" +//- toolchain:nightly +trait Test { + #[unstable] + type Type; + #[unstable] + const CONST: (); + #[unstable] + fn function(); +} + +impl Test for () { + $0 +} +"#, + expect![[r#" + ct const CONST: () = + fn fn function() + ta type Type = + kw crate:: + kw self:: + "#]], + ); +} + #[test] fn after_unit_struct() { check( diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs index c0e485c36fd..8af6cce98f6 100644 --- a/crates/ide-completion/src/tests/pattern.rs +++ b/crates/ide-completion/src/tests/pattern.rs @@ -1,12 +1,7 @@ //! Completion tests for pattern position. use expect_test::{expect, Expect}; -use crate::tests::{check_edit, completion_list, BASE_ITEMS_FIXTURE}; - -fn check_empty(ra_fixture: &str, expect: Expect) { - let actual = completion_list(ra_fixture); - expect.assert_eq(&actual) -} +use crate::tests::{check_edit, check_empty, completion_list, BASE_ITEMS_FIXTURE}; fn check(ra_fixture: &str, expect: Expect) { let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}\n{ra_fixture}")); @@ -742,3 +737,56 @@ fn f(x: EnumAlias) { "#]], ); } + +#[test] +fn pat_no_unstable_item_on_stable() { + check_empty( + r#" +//- /main.rs crate:main deps:std +use std::*; +fn foo() { + let a$0 +} +//- /std.rs crate:std +#[unstable] +pub struct S; +#[unstable] +pub enum Enum { + Variant +} +"#, + expect![[r#" + md std + kw mut + kw ref + "#]], + ); +} + +#[test] +fn pat_unstable_item_on_nightly() { + check_empty( + r#" +//- toolchain:nightly +//- /main.rs crate:main deps:std +use std::*; +fn foo() { + let a$0 +} +//- /std.rs crate:std +#[unstable] +pub struct S; +#[unstable] +pub enum Enum { + Variant +} +"#, + expect![[r#" + en Enum + md std + st S + kw mut + kw ref + "#]], + ); +} diff --git a/crates/ide-completion/src/tests/predicate.rs b/crates/ide-completion/src/tests/predicate.rs index 2656a4d545e..789ad66345b 100644 --- a/crates/ide-completion/src/tests/predicate.rs +++ b/crates/ide-completion/src/tests/predicate.rs @@ -1,7 +1,7 @@ //! Completion tests for predicates and bounds. use expect_test::{expect, Expect}; -use crate::tests::{completion_list, BASE_ITEMS_FIXTURE}; +use crate::tests::{check_empty, completion_list, BASE_ITEMS_FIXTURE}; fn check(ra_fixture: &str, expect: Expect) { let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}\n{ra_fixture}")); @@ -129,3 +129,43 @@ fn method(self) where $0 {} "#]], ); } + +#[test] +fn pred_no_unstable_item_on_stable() { + check_empty( + r#" +//- /main.rs crate:main deps:std +use std::*; +struct Foo where T: $0 {} +//- /std.rs crate:std +#[unstable] +pub trait Trait {} +"#, + expect![[r#" + md std + kw crate:: + kw self:: + "#]], + ); +} + +#[test] +fn pred_unstable_item_on_nightly() { + check_empty( + r#" +//- toolchain:nightly +//- /main.rs crate:main deps:std +use std::*; +struct Foo where T: $0 {} +//- /std.rs crate:std +#[unstable] +pub trait Trait {} +"#, + expect![[r#" + md std + tt Trait + kw crate:: + kw self:: + "#]], + ); +} diff --git a/crates/ide-completion/src/tests/type_pos.rs b/crates/ide-completion/src/tests/type_pos.rs index c3f4fb4d181..8cb1ff4a125 100644 --- a/crates/ide-completion/src/tests/type_pos.rs +++ b/crates/ide-completion/src/tests/type_pos.rs @@ -1,7 +1,7 @@ //! Completion tests for type position. use expect_test::{expect, Expect}; -use crate::tests::{completion_list, BASE_ITEMS_FIXTURE}; +use crate::tests::{check_empty, completion_list, BASE_ITEMS_FIXTURE}; fn check(ra_fixture: &str, expect: Expect) { let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}\n{ra_fixture}")); @@ -669,3 +669,53 @@ fn f(t: impl MyTrait {} } +"#, + expect![""], + ); +} + +#[test] +fn use_tree_unstable_items_on_nightly() { + check( + r#" +//- toolchain:nightly +//- /lib.rs crate:main deps:std +use std::$0 +//- /std.rs crate:std +#[unstable] +pub mod simd {} +#[unstable] +pub struct S; +#[unstable] +pub fn foo() {} +#[unstable] +#[macro_export] +marco_rules! m { () => {} } +"#, + expect![[r#" + fn foo fn() + md simd + st S + "#]], + ); +}