Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr_store/tests.rs')
| -rw-r--r-- | crates/hir-def/src/expr_store/tests.rs | 505 |
1 files changed, 2 insertions, 503 deletions
diff --git a/crates/hir-def/src/expr_store/tests.rs b/crates/hir-def/src/expr_store/tests.rs index 16bf46d3e3..f09ee6f0b9 100644 --- a/crates/hir-def/src/expr_store/tests.rs +++ b/crates/hir-def/src/expr_store/tests.rs @@ -1,503 +1,2 @@ -mod block; - -use crate::{hir::MatchArm, test_db::TestDB, ModuleDefId}; -use expect_test::{expect, Expect}; -use la_arena::RawIdx; -use test_fixture::WithFixture; - -use super::*; - -fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) { - let db = TestDB::with_files(ra_fixture); - - let krate = db.fetch_test_crate(); - let def_map = db.crate_def_map(krate); - let mut fn_def = None; - 'outer: for (_, module) in def_map.modules() { - for decl in module.scope.declarations() { - if let ModuleDefId::FunctionId(it) = decl { - fn_def = Some(it); - break 'outer; - } - } - } - let fn_def = fn_def.unwrap().into(); - - let body = db.body(fn_def); - (db, body, fn_def) -} - -fn def_map_at(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String { - let (db, position) = TestDB::with_position(ra_fixture); - - let module = db.module_at_position(position); - module.def_map(&db).dump(&db) -} - -fn check_block_scopes_at(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { - let (db, position) = TestDB::with_position(ra_fixture); - - let module = db.module_at_position(position); - let actual = module.def_map(&db).dump_block_scopes(&db); - expect.assert_eq(&actual); -} - -fn check_at(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { - let actual = def_map_at(ra_fixture); - expect.assert_eq(&actual); -} - -#[test] -fn your_stack_belongs_to_me() { - cov_mark::check!(your_stack_belongs_to_me); - lower( - r#" -#![recursion_limit = "32"] -macro_rules! n_nuple { - ($e:tt) => (); - ($($rest:tt)*) => {{ - (n_nuple!($($rest)*)None,) - }}; -} -fn main() { n_nuple!(1,2,3); } -"#, - ); -} - -#[test] -fn your_stack_belongs_to_me2() { - cov_mark::check!(overflow_but_not_me); - lower( - r#" -#![recursion_limit = "32"] -macro_rules! foo { - () => {{ foo!(); foo!(); }} -} -fn main() { foo!(); } -"#, - ); -} - -#[test] -fn recursion_limit() { - lower( - r#" -#![recursion_limit = "2"] -macro_rules! n_nuple { - ($e:tt) => (); - ($first:tt $($rest:tt)*) => {{ - n_nuple!($($rest)*) - }}; -} -fn main() { n_nuple!(1,2,3); } -"#, - ); -} - -#[test] -fn issue_3642_bad_macro_stackover() { - lower( - r#" -#[macro_export] -macro_rules! match_ast { - (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; - - (match ($node:expr) { - $( ast::$ast:ident($it:ident) => $res:expr, )* - _ => $catch_all:expr $(,)? - }) => {{ - $( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )* - { $catch_all } - }}; -} - -fn main() { - let anchor = match_ast! { - match parent { - as => {}, - _ => return None - } - }; -}"#, - ); -} - -#[test] -fn macro_resolve() { - // Regression test for a path resolution bug introduced with inner item handling. - lower( - r#" -macro_rules! vec { - () => { () }; - ($elem:expr; $n:expr) => { () }; - ($($x:expr),+ $(,)?) => { () }; -} -mod m { - fn outer() { - let _ = vec![FileSet::default(); self.len()]; - } -} -"#, - ); -} - -#[test] -fn desugar_for_loop() { - let (db, body, def) = lower( - r#" -//- minicore: iterator -fn main() { - for ident in 0..10 { - foo(); - bar() - } -} -"#, - ); - - expect![[r#" - fn main() -> () { - match builtin#lang(into_iter)( - (0) ..(10) , - ) { - mut <ra@gennew>11 => loop { - match builtin#lang(next)( - &mut <ra@gennew>11, - ) { - builtin#lang(None) => break, - builtin#lang(Some)(ident) => { - foo(); - bar() - }, - } - }, - } - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) -} - -#[test] -fn desugar_builtin_format_args() { - let (db, body, def) = lower( - r#" -//- minicore: fmt -fn main() { - let are = "are"; - let count = 10; - builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!"); -} -"#, - ); - - expect![[r#" - fn main() -> () { - let are = "are"; - let count = 10; - builtin#lang(Arguments::new_v1_formatted)( - &[ - "\u{1b}hello ", " ", " friends, we ", " ", "", - ], - &[ - builtin#lang(Argument::new_display)( - &count, - ), builtin#lang(Argument::new_display)( - &"fancy", - ), builtin#lang(Argument::new_debug)( - &are, - ), builtin#lang(Argument::new_display)( - &"!", - ), - ], - &[ - builtin#lang(Placeholder::new)( - 0usize, - ' ', - builtin#lang(Alignment::Unknown), - 8u32, - builtin#lang(Count::Implied), - builtin#lang(Count::Is)( - 2usize, - ), - ), builtin#lang(Placeholder::new)( - 1usize, - ' ', - builtin#lang(Alignment::Unknown), - 0u32, - builtin#lang(Count::Implied), - builtin#lang(Count::Implied), - ), builtin#lang(Placeholder::new)( - 2usize, - ' ', - builtin#lang(Alignment::Unknown), - 0u32, - builtin#lang(Count::Implied), - builtin#lang(Count::Implied), - ), builtin#lang(Placeholder::new)( - 1usize, - ' ', - builtin#lang(Alignment::Unknown), - 0u32, - builtin#lang(Count::Implied), - builtin#lang(Count::Implied), - ), builtin#lang(Placeholder::new)( - 3usize, - ' ', - builtin#lang(Alignment::Unknown), - 0u32, - builtin#lang(Count::Implied), - builtin#lang(Count::Implied), - ), - ], - unsafe { - builtin#lang(UnsafeArg::new)() - }, - ); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) -} - -#[test] -fn test_macro_hygiene() { - let (db, body, def) = lower( - r##" -//- minicore: fmt, from -//- /main.rs -mod error; - -use crate::error::error; - -fn main() { - // _ = forces body expansion instead of block def map expansion - _ = error!("Failed to resolve path `{}`", node.text()); -} -//- /error.rs -macro_rules! _error { - ($fmt:expr, $($arg:tt)+) => {$crate::error::intermediate!(format_args!($fmt, $($arg)+))} -} -pub(crate) use _error as error; -macro_rules! _intermediate { - ($arg:expr) => {$crate::error::SsrError::new($arg)} -} -pub(crate) use _intermediate as intermediate; - -pub struct SsrError(pub(crate) core::fmt::Arguments); - -impl SsrError { - pub(crate) fn new(message: impl Into<core::fmt::Arguments>) -> SsrError { - SsrError(message.into()) - } -} -"##, - ); - - assert_eq!(db.body_with_source_map(def).1.diagnostics(), &[]); - expect![[r#" - fn main() -> () { - _ = $crate::error::SsrError::new( - builtin#lang(Arguments::new_v1_formatted)( - &[ - "Failed to resolve path `", "`", - ], - &[ - builtin#lang(Argument::new_display)( - &node.text(), - ), - ], - &[ - builtin#lang(Placeholder::new)( - 0usize, - ' ', - builtin#lang(Alignment::Unknown), - 0u32, - builtin#lang(Count::Implied), - builtin#lang(Count::Implied), - ), - ], - unsafe { - builtin#lang(UnsafeArg::new)() - }, - ), - ); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) -} - -#[test] -fn regression_10300() { - let (db, body, def) = lower( - r#" -//- minicore: concat, panic -mod private { - pub use core::concat; -} - -macro_rules! m { - () => { - panic!(concat!($crate::private::concat!("cc"))); - }; -} - -fn f(a: i32, b: u32) -> String { - m!(); -} -"#, - ); - - let (_, source_map) = db.body_with_source_map(def); - assert_eq!(source_map.diagnostics(), &[]); - - for (_, def_map) in body.blocks(&db) { - assert_eq!(def_map.diagnostics(), &[]); - } - - expect![[r#" - fn f(a: i32, b: u32) -> String { - { - $crate::panicking::panic_fmt( - builtin#lang(Arguments::new_v1_formatted)( - &[ - "cc", - ], - &[], - &[], - unsafe { - builtin#lang(UnsafeArg::new)() - }, - ), - ); - }; - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) -} - -#[test] -fn destructuring_assignment_tuple_macro() { - // This is a funny one. `let m!()() = Bar()` is an error in rustc, because `m!()()` isn't a valid pattern, - // but in destructuring assignment it is valid, because `m!()()` is a valid expression, and destructuring - // assignments start their lives as expressions. So we have to do the same. - - let (db, body, def) = lower( - r#" -struct Bar(); - -macro_rules! m { - () => { Bar }; -} - -fn foo() { - m!()() = Bar(); -} -"#, - ); - - let (_, source_map) = db.body_with_source_map(def); - assert_eq!(source_map.diagnostics(), &[]); - - for (_, def_map) in body.blocks(&db) { - assert_eq!(def_map.diagnostics(), &[]); - } - - expect![[r#" - fn foo() -> () { - Bar() = Bar(); - }"#]] - .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) -} - -#[test] -fn shadowing_record_variant() { - let (_, body, _) = lower( - r#" -enum A { - B { field: i32 }, -} -fn f() { - use A::*; - match () { - B => {} - }; -} - "#, - ); - assert_eq!(body.bindings.len(), 1, "should have a binding for `B`"); - assert_eq!( - body.bindings[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(), - "B", - "should have a binding for `B`", - ); -} - -#[test] -fn regression_pretty_print_bind_pat() { - let (db, body, owner) = lower( - r#" -fn foo() { - let v @ u = 123; -} -"#, - ); - let printed = body.pretty_print(&db, owner, Edition::CURRENT); - assert_eq!( - printed, - r#"fn foo() -> () { - let v @ u = 123; -}"# - ); -} - -#[test] -fn skip_skips_body() { - let (db, body, owner) = lower( - r#" -#[rust_analyzer::skip] -async fn foo(a: (), b: i32) -> u32 { - 0 + 1 + b() -} -"#, - ); - let printed = body.pretty_print(&db, owner, Edition::CURRENT); - expect!["fn foo(�: (), �: i32) -> impl ::core::future::Future::<Output = u32> �"] - .assert_eq(&printed); -} - -#[test] -fn range_bounds_are_hir_exprs() { - let (_, body, _) = lower( - r#" -pub const L: i32 = 6; -mod x { - pub const R: i32 = 100; -} -const fn f(x: i32) -> i32 { - match x { - -1..=5 => x * 10, - L..=x::R => x * 100, - _ => x, - } -}"#, - ); - - let mtch_arms = body - .exprs - .iter() - .find_map(|(_, expr)| { - if let Expr::Match { arms, .. } = expr { - return Some(arms); - } - - None - }) - .unwrap(); - - let MatchArm { pat, .. } = mtch_arms[1]; - match body.pats[pat] { - Pat::Range { start, end } => { - let hir_start = &body.exprs[start.unwrap()]; - let hir_end = &body.exprs[end.unwrap()]; - - assert!(matches!(hir_start, Expr::Path { .. })); - assert!(matches!(hir_end, Expr::Path { .. })); - } - _ => {} - } -} +mod body; +mod signatures; |