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 1
1
#[ cfg( test) ]
2
2
mod test {
3
-
4
3
use crate :: { DiagnosticCode , LuaType , VirtualWorkspace } ;
5
4
6
5
#[ test]
@@ -1174,8 +1173,25 @@ end
1174
1173
end
1175
1174
"# ,
1176
1175
) ;
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" ) ;
1179
1195
}
1180
1196
1181
1197
#[ test]
Original file line number Diff line number Diff line change @@ -120,4 +120,42 @@ mod test {
120
120
let expected = ws. ty ( "string" ) ;
121
121
assert_eq ! ( a_ty, expected) ;
122
122
}
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
+ */
123
161
}
Original file line number Diff line number Diff line change @@ -344,9 +344,17 @@ pub fn infer_global_type(db: &DbIndex, name: &str) -> InferResult {
344
344
. ok_or ( InferFailReason :: None ) ?;
345
345
if decl_ids. len ( ) == 1 {
346
346
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)
350
358
} ;
351
359
}
352
360
@@ -365,6 +373,14 @@ pub fn infer_global_type(db: &DbIndex, name: &str) -> InferResult {
365
373
match decl_type_cache {
366
374
Some ( type_cache) => {
367
375
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
+
368
384
if typ. is_def ( ) || typ. is_ref ( ) || typ. is_function ( ) {
369
385
return Ok ( typ. clone ( ) ) ;
370
386
}
You can’t perform that action at this time.
0 commit comments