File tree Expand file tree Collapse file tree 3 files changed +76
-6
lines changed
crates/emmylua_code_analysis/src Expand file tree Collapse file tree 3 files changed +76
-6
lines changed Original file line number Diff line number Diff line change 11#[ cfg( test) ]
22mod test {
3-
43 use crate :: { DiagnosticCode , LuaType , VirtualWorkspace } ;
54
65 #[ test]
@@ -1174,8 +1173,25 @@ end
11741173 end
11751174 "# ,
11761175 ) ;
1177- let a = ws. expr_ty ( "A" ) ;
1178- assert_eq ! ( ws. humanize_type( a) , "T" ) ;
1176+
1177+ // Note: we can't use `ws.ty_expr("A")` to get a true type of `A`
1178+ // because `infer_global_type` will not allow generic variables
1179+ // from `bindGC` to escape into global space.
1180+ let db = & ws. analysis . compilation . db ;
1181+ let decl_id = db
1182+ . get_global_index ( )
1183+ . get_global_decl_ids ( "A" )
1184+ . unwrap ( )
1185+ . first ( )
1186+ . unwrap ( )
1187+ . clone ( ) ;
1188+ let typ = db
1189+ . get_type_index ( )
1190+ . get_type_cache ( & decl_id. into ( ) )
1191+ . unwrap ( )
1192+ . as_type ( ) ;
1193+
1194+ assert_eq ! ( ws. humanize_type( typ. clone( ) ) , "T" ) ;
11791195 }
11801196
11811197 #[ test]
Original file line number Diff line number Diff line change @@ -120,4 +120,42 @@ mod test {
120120 let expected = ws. ty ( "string" ) ;
121121 assert_eq ! ( a_ty, expected) ;
122122 }
123+
124+ #[ test]
125+ fn test_local_generics_in_global_scope ( ) {
126+ let mut ws = VirtualWorkspace :: new ( ) ;
127+ ws. def (
128+ r#"
129+ --- @generic T
130+ --- @param x T
131+ function foo(x)
132+ a = x
133+ end
134+ "# ,
135+ ) ;
136+ let a_ty = ws. expr_ty ( "a" ) ;
137+ assert_eq ! ( a_ty, ws. ty( "unknown" ) ) ;
138+ }
139+
140+ // Currently fails:
141+ /*
142+ #[test]
143+ fn test_local_generics_in_global_scope_member() {
144+ let mut ws = VirtualWorkspace::new();
145+ ws.def(
146+ r#"
147+ t = {}
148+
149+ --- @generic T
150+ --- @param x T
151+ function foo(x)
152+ t.a = x
153+ end
154+ local b = t.a
155+ "#,
156+ );
157+ let a_ty = ws.expr_ty("t.a");
158+ assert_eq!(a_ty, LuaType::Unknown);
159+ }
160+ */
123161}
Original file line number Diff line number Diff line change @@ -344,9 +344,17 @@ pub fn infer_global_type(db: &DbIndex, name: &str) -> InferResult {
344344 . ok_or ( InferFailReason :: None ) ?;
345345 if decl_ids. len ( ) == 1 {
346346 let id = decl_ids[ 0 ] ;
347- return match db. get_type_index ( ) . get_type_cache ( & id. into ( ) ) {
348- Some ( type_cache) => Ok ( type_cache. as_type ( ) . clone ( ) ) ,
349- None => Err ( InferFailReason :: UnResolveDeclType ( id) ) ,
347+ let typ = match db. get_type_index ( ) . get_type_cache ( & id. into ( ) ) {
348+ Some ( type_cache) => type_cache. as_type ( ) . clone ( ) ,
349+ None => return Err ( InferFailReason :: UnResolveDeclType ( id) ) ,
350+ } ;
351+ return if typ. contain_tpl ( ) {
352+ // This decl is located in a generic function,
353+ // and is type contains references to generic variables
354+ // of this function.
355+ Ok ( LuaType :: Unknown )
356+ } else {
357+ Ok ( typ)
350358 } ;
351359 }
352360
@@ -365,6 +373,14 @@ pub fn infer_global_type(db: &DbIndex, name: &str) -> InferResult {
365373 match decl_type_cache {
366374 Some ( type_cache) => {
367375 let typ = type_cache. as_type ( ) ;
376+
377+ if typ. contain_tpl ( ) {
378+ // This decl is located in a generic function,
379+ // and is type contains references to generic variables
380+ // of this function.
381+ continue ;
382+ }
383+
368384 if typ. is_def ( ) || typ. is_ref ( ) || typ. is_function ( ) {
369385 return Ok ( typ. clone ( ) ) ;
370386 }
You can’t perform that action at this time.
0 commit comments