Skip to content

Commit 2faff7f

Browse files
committed
change: 函数泛型返回值会将 def 转为 ref
1 parent b337baa commit 2faff7f

3 files changed

Lines changed: 56 additions & 1 deletion

File tree

crates/emmylua_code_analysis/src/semantic/generic/instantiate_type_generic.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,10 @@ pub fn instantiate_doc_function(
141141
}
142142
}
143143

144-
let inst_ret_type = instantiate_type_generic(db, &tpl_ret, substitutor);
144+
// 将 substitutor 中存储的类型的 def 转为 ref
145+
let mut modified_substitutor = substitutor.clone();
146+
modified_substitutor.convert_def_to_ref();
147+
let inst_ret_type = instantiate_type_generic(db, &tpl_ret, &modified_substitutor);
145148
LuaType::DocFunction(
146149
LuaFunctionType::new(is_async, colon_define, new_params, inst_ret_type).into(),
147150
)

crates/emmylua_code_analysis/src/semantic/generic/test.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,31 @@ mod test {
9393
assert_eq!(b, expected_b);
9494
assert_eq!(c, expected_c);
9595
}
96+
97+
#[test]
98+
fn test_return() {
99+
let mut ws = crate::VirtualWorkspace::new();
100+
ws.def(
101+
r#"
102+
---@class ab
103+
---@field a number
104+
local A
105+
106+
---@generic T
107+
---@param a T
108+
---@return T
109+
local function name(a)
110+
return a
111+
end
112+
113+
local a = name(A)
114+
a.b = 1
115+
R = A.b
116+
"#,
117+
);
118+
119+
let a = ws.expr_ty("R");
120+
let expected = ws.ty("any");
121+
assert_eq!(a, expected);
122+
}
96123
}

crates/emmylua_code_analysis/src/semantic/generic/type_substitutor.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,31 @@ impl TypeSubstitutor {
111111
pub fn get_self_type(&self) -> Option<&LuaType> {
112112
self.self_type.as_ref()
113113
}
114+
115+
pub fn convert_def_to_ref(&mut self) {
116+
for (_, value) in self.tpl_replace_map.iter_mut() {
117+
match value {
118+
SubstitutorValue::Type(ty) => {
119+
*ty = convert_type_def_to_ref(ty);
120+
}
121+
SubstitutorValue::Params(params) => {
122+
for (_, param_ty) in params.iter_mut() {
123+
if let Some(ty) = param_ty {
124+
*ty = convert_type_def_to_ref(ty);
125+
}
126+
}
127+
}
128+
_ => {}
129+
}
130+
}
131+
}
132+
}
133+
134+
fn convert_type_def_to_ref(ty: &LuaType) -> LuaType {
135+
match ty {
136+
LuaType::Def(type_decl_id) => LuaType::Ref(type_decl_id.clone()),
137+
_ => ty.clone(),
138+
}
114139
}
115140

116141
#[derive(Debug, Clone)]

0 commit comments

Comments
 (0)