@@ -17,17 +17,18 @@ use hir_def::{
1717 item_scope:: ItemScope ,
1818 keys,
1919 nameres:: CrateDefMap ,
20- AssocItemId , DefWithBodyId , LocalModuleId , Lookup , ModuleDefId , ModuleId ,
20+ AssocItemId , DefWithBodyId , LocalModuleId , Lookup , ModuleDefId ,
2121} ;
2222use hir_expand:: { db:: AstDatabase , InFile } ;
2323use insta:: assert_snapshot;
24- use ra_db:: { fixture:: WithFixture , salsa:: Database , FilePosition , SourceDatabase } ;
24+ use ra_db:: { fixture:: WithFixture , salsa:: Database , FileRange , SourceDatabase } ;
2525use ra_syntax:: {
2626 algo,
2727 ast:: { self , AstNode } ,
2828 SyntaxNode ,
2929} ;
3030use stdx:: format_to;
31+ use test_utils:: extract_annotations;
3132
3233use crate :: {
3334 db:: HirDatabase , display:: HirDisplay , infer:: TypeMismatch , test_db:: TestDB , InferenceResult , Ty ,
@@ -37,21 +38,38 @@ use crate::{
3738// against snapshots of the expected results using insta. Use cargo-insta to
3839// update the snapshots.
3940
40- fn type_at_pos ( db : & TestDB , pos : FilePosition ) -> String {
41- type_at_pos_displayed ( db , pos , |ty , _| ty . display ( db ) . to_string ( ) )
41+ fn check_types ( ra_fixture : & str ) {
42+ check_types_impl ( ra_fixture , false )
4243}
4344
44- fn displayed_source_at_pos ( db : & TestDB , pos : FilePosition ) -> String {
45- type_at_pos_displayed ( db , pos , |ty , module_id| ty . display_source_code ( db , module_id ) . unwrap ( ) )
45+ fn check_types_source_code ( ra_fixture : & str ) {
46+ check_types_impl ( ra_fixture , true )
4647}
4748
48- fn type_at_pos_displayed (
49- db : & TestDB ,
50- pos : FilePosition ,
51- display_fn : impl FnOnce ( & Ty , ModuleId ) -> String ,
52- ) -> String {
49+ fn check_types_impl ( ra_fixture : & str , display_source : bool ) {
50+ let db = TestDB :: with_files ( ra_fixture) ;
51+ let mut checked_one = false ;
52+ for file_id in db. all_files ( ) {
53+ let text = db. parse ( file_id) . syntax_node ( ) . to_string ( ) ;
54+ let annotations = extract_annotations ( & text) ;
55+ for ( range, expected) in annotations {
56+ let ty = type_at_range ( & db, FileRange { file_id, range } ) ;
57+ let actual = if display_source {
58+ let module = db. module_for_file ( file_id) ;
59+ ty. display_source_code ( & db, module) . unwrap ( )
60+ } else {
61+ ty. display ( & db) . to_string ( )
62+ } ;
63+ assert_eq ! ( expected, actual) ;
64+ checked_one = true ;
65+ }
66+ }
67+ assert ! ( checked_one, "no `//^` annotations found" ) ;
68+ }
69+
70+ fn type_at_range ( db : & TestDB , pos : FileRange ) -> Ty {
5371 let file = db. parse ( pos. file_id ) . ok ( ) . unwrap ( ) ;
54- let expr = algo:: find_node_at_offset :: < ast:: Expr > ( file. syntax ( ) , pos. offset ) . unwrap ( ) ;
72+ let expr = algo:: find_node_at_range :: < ast:: Expr > ( file. syntax ( ) , pos. range ) . unwrap ( ) ;
5573 let fn_def = expr. syntax ( ) . ancestors ( ) . find_map ( ast:: FnDef :: cast) . unwrap ( ) ;
5674 let module = db. module_for_file ( pos. file_id ) ;
5775 let func = * module. child_by_source ( db) [ keys:: FUNCTION ]
@@ -61,17 +79,11 @@ fn type_at_pos_displayed(
6179 let ( _body, source_map) = db. body_with_source_map ( func. into ( ) ) ;
6280 if let Some ( expr_id) = source_map. node_expr ( InFile :: new ( pos. file_id . into ( ) , & expr) ) {
6381 let infer = db. infer ( func. into ( ) ) ;
64- let ty = & infer[ expr_id] ;
65- return display_fn ( ty, module) ;
82+ return infer[ expr_id] . clone ( ) ;
6683 }
6784 panic ! ( "Can't find expression" )
6885}
6986
70- fn type_at ( ra_fixture : & str ) -> String {
71- let ( db, file_pos) = TestDB :: with_position ( ra_fixture) ;
72- type_at_pos ( & db, file_pos)
73- }
74-
7587fn infer ( ra_fixture : & str ) -> String {
7688 infer_with_mismatches ( ra_fixture, false )
7789}
0 commit comments