diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index ebf9f4db..81de17bb 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -2017,6 +2017,38 @@ impl LowerError { ) } + pub fn union_return_type_warning( + input: Input, + errno: usize, + loc: Location, + caused_by: String, + fn_name: &str, + typ: &Type, + ) -> Self { + let hint = switch_lang!( + "japanese" => format!("`{fn_name}(...): {typ} = ...`など明示的に戻り値型を指定してください"), + "simplified_chinese" => format!("请明确指定函数{fn_name}的返回类型,例如`{fn_name}(...): {typ} = ...`"), + "traditional_chinese" => format!("請明確指定函數{fn_name}的返回類型,例如`{fn_name}(...): {typ} = ...`"), + "english" => format!("please explicitly specify the return type of function {fn_name}, for example `{fn_name}(...): {typ} = ...`"), + ); + LowerError::new( + ErrorCore::new( + vec![SubMessage::ambiguous_new(loc, vec![], Some(hint))], + switch_lang!( + "japanese" => format!("関数{fn_name}の戻り値型が単一ではありません"), + "simplified_chinese" => format!("函数{fn_name}的返回类型不是单一的"), + "traditional_chinese" => format!("函數{fn_name}的返回類型不是單一的"), + "english" => format!("the return type of function {fn_name} is not single"), + ), + errno, + TypeWarning, + loc, + ), + input, + caused_by, + ) + } + pub fn del_error(input: Input, errno: usize, ident: &Identifier, caused_by: String) -> Self { let name = StyledString::new(readable_name(ident.inspect()), Some(WARN), Some(ATTR)); Self::new( diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index ab42b67a..c364af67 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -1170,6 +1170,18 @@ impl ASTLowerer { body.id, found_body_t, )?; + let return_t = t.return_t().unwrap(); + if return_t.union_types().is_some() && sig.return_t_spec.is_none() { + let warn = LowerWarning::union_return_type_warning( + self.input().clone(), + line!() as usize, + sig.loc(), + self.ctx.caused_by(), + sig.ident.inspect(), + &Context::readable_type(return_t), + ); + self.warns.push(warn); + } let mut ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name); ident.vi.t = t; let sig = hir::SubrSignature::new(ident, params); diff --git a/compiler/erg_compiler/ty/mod.rs b/compiler/erg_compiler/ty/mod.rs index 4759c070..aabd272b 100644 --- a/compiler/erg_compiler/ty/mod.rs +++ b/compiler/erg_compiler/ty/mod.rs @@ -2203,7 +2203,7 @@ impl Type { // At least in situations where this function is needed, self cannot be Quantified. Self::Quantified(quant) => { if quant.return_t().unwrap().is_generalized() { - todo!("quantified return type (recursive function type inference)") + log!(err "quantified return type (recursive function type inference)"); } quant.return_t() }