mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 12:24:45 +00:00
Fix assert casting
This commit is contained in:
parent
f94ab31256
commit
aa7ae368dc
2 changed files with 47 additions and 11 deletions
|
@ -1083,7 +1083,7 @@ impl Context {
|
||||||
type_spec: ast::TypeSpec,
|
type_spec: ast::TypeSpec,
|
||||||
call: &mut hir::Call,
|
call: &mut hir::Call,
|
||||||
) -> TyCheckResult<()> {
|
) -> TyCheckResult<()> {
|
||||||
let target_t =
|
let cast_to =
|
||||||
self.instantiate_typespec(&type_spec, None, None, RegistrationMode::Normal)?;
|
self.instantiate_typespec(&type_spec, None, None, RegistrationMode::Normal)?;
|
||||||
let lhs = enum_unwrap!(
|
let lhs = enum_unwrap!(
|
||||||
call.args.get_mut_left_or_key("pred").unwrap(),
|
call.args.get_mut_left_or_key("pred").unwrap(),
|
||||||
|
@ -1092,36 +1092,44 @@ impl Context {
|
||||||
.lhs
|
.lhs
|
||||||
.as_mut();
|
.as_mut();
|
||||||
match (
|
match (
|
||||||
self.supertype_of(lhs.ref_t(), &target_t),
|
self.supertype_of(lhs.ref_t(), &cast_to),
|
||||||
self.subtype_of(lhs.ref_t(), &target_t),
|
self.subtype_of(lhs.ref_t(), &cast_to),
|
||||||
) {
|
) {
|
||||||
// assert 1 in {1}
|
// assert 1 in {1}
|
||||||
(true, true) => {}
|
(true, true) => Ok(()),
|
||||||
// assert x in Int (x: Nat)
|
// assert x in Int (x: Nat)
|
||||||
(false, true) => {} // TODO: warn (needless)
|
(false, true) => Ok(()), // TODO: warn (needless)
|
||||||
// assert x in Nat (x: Int)
|
// assert x in Nat (x: Int)
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
if let hir::Expr::Accessor(ref acc) = lhs {
|
if let hir::Expr::Accessor(ref acc) = lhs {
|
||||||
self.change_var_type(acc, target_t.clone())?;
|
self.change_var_type(acc, cast_to.clone())?;
|
||||||
}
|
}
|
||||||
match lhs.ref_t() {
|
match lhs.ref_t() {
|
||||||
Type::FreeVar(fv) if fv.is_linked() => {
|
Type::FreeVar(fv) if fv.is_linked() => {
|
||||||
let constraint = Constraint::new_subtype_of(target_t, Cyclicity::Not);
|
let constraint = Constraint::new_subtype_of(cast_to, Cyclicity::Not);
|
||||||
fv.replace(FreeKind::new_unbound(self.level, constraint));
|
fv.replace(FreeKind::new_unbound(self.level, constraint));
|
||||||
}
|
}
|
||||||
Type::FreeVar(fv) => {
|
Type::FreeVar(fv) => {
|
||||||
let new_constraint = Constraint::new_subtype_of(target_t, Cyclicity::Not);
|
let new_constraint = Constraint::new_subtype_of(cast_to, Cyclicity::Not);
|
||||||
fv.update_constraint(new_constraint);
|
fv.update_constraint(new_constraint);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*lhs.ref_mut_t() = target_t;
|
*lhs.ref_mut_t() = cast_to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
// assert x in Str (x: Int)
|
// assert x in Str (x: Int)
|
||||||
(false, false) => todo!(),
|
(false, false) => Err(TyCheckErrors::from(TyCheckError::invalid_type_cast_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
lhs.loc(),
|
||||||
|
self.caused_by(),
|
||||||
|
&lhs.to_string(),
|
||||||
|
&cast_to,
|
||||||
|
None,
|
||||||
|
))),
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_var_type(&mut self, acc: &hir::Accessor, t: Type) -> TyCheckResult<()> {
|
fn change_var_type(&mut self, acc: &hir::Accessor, t: Type) -> TyCheckResult<()> {
|
||||||
|
|
|
@ -1568,6 +1568,34 @@ impl LowerError {
|
||||||
caused_by,
|
caused_by,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn invalid_type_cast_error(
|
||||||
|
input: Input,
|
||||||
|
errno: usize,
|
||||||
|
loc: Location,
|
||||||
|
caused_by: AtomicStr,
|
||||||
|
name: &str,
|
||||||
|
cast_to: &Type,
|
||||||
|
hint: Option<AtomicStr>,
|
||||||
|
) -> Self {
|
||||||
|
Self::new(
|
||||||
|
ErrorCore::new(
|
||||||
|
errno,
|
||||||
|
TypeError,
|
||||||
|
loc,
|
||||||
|
switch_lang!(
|
||||||
|
"japanese" => format!("{YELLOW}{name}{RESET}の型を{RED}{cast_to}{RESET}にキャストすることはできません"),
|
||||||
|
"simplified_chinese" => format!("{YELLOW}{name}{RESET}的类型无法转换为{RED}{cast_to}{RESET}"),
|
||||||
|
"traditional_chinese" => format!("{YELLOW}{name}{RESET}的類型無法轉換為{RED}{cast_to}{RESET}"),
|
||||||
|
"english" => format!("the type of {YELLOW}{name}{RESET} cannot be cast to {RED}{cast_to}{RESET}"),
|
||||||
|
),
|
||||||
|
hint,
|
||||||
|
),
|
||||||
|
input,
|
||||||
|
caused_by,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue