Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/path/tests.rs')
-rw-r--r--crates/hir-def/src/path/tests.rs126
1 files changed, 126 insertions, 0 deletions
diff --git a/crates/hir-def/src/path/tests.rs b/crates/hir-def/src/path/tests.rs
new file mode 100644
index 0000000000..67a27bf85e
--- /dev/null
+++ b/crates/hir-def/src/path/tests.rs
@@ -0,0 +1,126 @@
+use expect_test::{expect, Expect};
+use span::Edition;
+use syntax::ast::{self, make};
+use test_fixture::WithFixture;
+
+use crate::{
+ lower::LowerCtx,
+ path::{
+ lower::{hir_segment_to_ast_segment, SEGMENT_LOWERING_MAP},
+ Path,
+ },
+ pretty,
+ test_db::TestDB,
+ type_ref::{TypesMap, TypesSourceMap},
+};
+
+fn lower_path(path: ast::Path) -> (TestDB, TypesMap, Option<Path>) {
+ let (db, file_id) = TestDB::with_single_file("");
+ let mut types_map = TypesMap::default();
+ let mut types_source_map = TypesSourceMap::default();
+ let mut ctx = LowerCtx::new(&db, file_id.into(), &mut types_map, &mut types_source_map);
+ let lowered_path = ctx.lower_path(path);
+ (db, types_map, lowered_path)
+}
+
+#[track_caller]
+fn check_hir_to_ast(path: &str, ignore_segments: &[&str]) {
+ let path = make::path_from_text(path);
+ SEGMENT_LOWERING_MAP.with_borrow_mut(|map| map.clear());
+ let _ = lower_path(path.clone()).2.expect("failed to lower path");
+ SEGMENT_LOWERING_MAP.with_borrow(|map| {
+ for (segment, segment_idx) in map {
+ if ignore_segments.contains(&&*segment.to_string()) {
+ continue;
+ }
+
+ let restored_segment = hir_segment_to_ast_segment(&path, *segment_idx as u32)
+ .unwrap_or_else(|| {
+ panic!(
+ "failed to map back segment `{segment}` \
+ numbered {segment_idx} in HIR from path `{path}`"
+ )
+ });
+ assert_eq!(
+ segment, &restored_segment,
+ "mapping back `{segment}` numbered {segment_idx} in HIR \
+ from path `{path}` produced incorrect segment `{restored_segment}`"
+ );
+ }
+ });
+}
+
+#[test]
+fn hir_to_ast_trait_ref() {
+ check_hir_to_ast("<A as B::C::D>::E::F", &["A"]);
+}
+
+#[test]
+fn hir_to_ast_plain_path() {
+ check_hir_to_ast("A::B::C::D::E::F", &[]);
+}
+
+#[test]
+fn hir_to_ast_crate_path() {
+ check_hir_to_ast("crate::A::B::C", &[]);
+ check_hir_to_ast("crate::super::super::A::B::C", &[]);
+}
+
+#[test]
+fn hir_to_ast_self_path() {
+ check_hir_to_ast("self::A::B::C", &[]);
+ check_hir_to_ast("self::super::super::A::B::C", &[]);
+}
+
+#[test]
+fn hir_to_ast_super_path() {
+ check_hir_to_ast("super::A::B::C", &[]);
+ check_hir_to_ast("super::super::super::A::B::C", &[]);
+}
+
+#[test]
+fn hir_to_ast_type_anchor_path() {
+ check_hir_to_ast("<A::B>::C::D", &["A", "B"]);
+}
+
+#[test]
+fn hir_to_ast_path_super_in_middle() {
+ check_hir_to_ast("A::super::B::super::super::C::D", &[]);
+}
+
+#[track_caller]
+fn check_fail_lowering(path: &str) {
+ let (_, _, lowered_path) = lower_path(make::path_from_text(path));
+ assert!(lowered_path.is_none(), "path `{path}` should fail lowering");
+}
+
+#[test]
+fn keywords_in_middle_fail_lowering1() {
+ check_fail_lowering("self::A::self::B::super::C::crate::D");
+}
+
+#[test]
+fn keywords_in_middle_fail_lowering2() {
+ check_fail_lowering("A::super::self::C::D");
+}
+
+#[test]
+fn keywords_in_middle_fail_lowering3() {
+ check_fail_lowering("A::crate::B::C::D");
+}
+
+#[track_caller]
+fn check_path_lowering(path: &str, expected: Expect) {
+ let (db, types_map, lowered_path) = lower_path(make::path_from_text(path));
+ let lowered_path = lowered_path.expect("failed to lower path");
+ let mut buf = String::new();
+ pretty::print_path(&db, &lowered_path, &types_map, &mut buf, Edition::CURRENT)
+ .expect("failed to pretty-print path");
+ expected.assert_eq(&buf);
+}
+
+#[test]
+fn fn_like_path_with_coloncolon() {
+ check_path_lowering("Fn::(A, B) -> C", expect![[r#"Fn::<(A, B), Output = C>"#]]);
+ check_path_lowering("Fn::(A, B)", expect![[r#"Fn::<(A, B), Output = ()>"#]]);
+}