From 8f2936bafdfa022bddbe9b588a05c4f1592c3bd0 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Fri, 15 Nov 2024 00:59:55 +0900 Subject: [PATCH] fix: intersection type bug --- crates/erg_compiler/context/compare.rs | 2 +- crates/erg_compiler/context/generalize.rs | 14 -------------- crates/erg_compiler/context/hint.rs | 9 +++++++++ .../erg_compiler/context/initialize/const_func.rs | 7 +++++-- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/crates/erg_compiler/context/compare.rs b/crates/erg_compiler/context/compare.rs index a6b0ce947..1a73a3e51 100644 --- a/crates/erg_compiler/context/compare.rs +++ b/crates/erg_compiler/context/compare.rs @@ -877,7 +877,7 @@ impl Context { } if l.len() == r.len() { let mut r = r.clone(); - for _ in 1..l.len() { + for _ in 0..r.len() { if l.iter().zip(&r).all(|(l, r)| self.supertype_of(l, r)) { return true; } diff --git a/crates/erg_compiler/context/generalize.rs b/crates/erg_compiler/context/generalize.rs index 76284ced4..f764d28e8 100644 --- a/crates/erg_compiler/context/generalize.rs +++ b/crates/erg_compiler/context/generalize.rs @@ -1401,27 +1401,13 @@ impl Context { /// This is needed because the trait implementation spec can contain projection types. /// e.g. `Tuple(Ts) <: Container(Ts.union())` fn poly_class_trait_impl_exists(&self, class: &Type, trait_: &Type) -> bool { - let class_hash = get_hash(&class); - let trait_hash = get_hash(&trait_); for imp in self.get_trait_impls(trait_).into_iter() { let _sub_subs = Substituter::substitute_typarams(self, &imp.sub_type, class).ok(); let _sup_subs = Substituter::substitute_typarams(self, &imp.sup_trait, trait_).ok(); if self.supertype_of(&imp.sub_type, class) && self.supertype_of(&imp.sup_trait, trait_) { - if class_hash != get_hash(&class) { - class.undo(); - } - if trait_hash != get_hash(&trait_) { - trait_.undo(); - } return true; } - if class_hash != get_hash(&class) { - class.undo(); - } - if trait_hash != get_hash(&trait_) { - trait_.undo(); - } } false } diff --git a/crates/erg_compiler/context/hint.rs b/crates/erg_compiler/context/hint.rs index a45a7b098..c429ead44 100644 --- a/crates/erg_compiler/context/hint.rs +++ b/crates/erg_compiler/context/hint.rs @@ -44,6 +44,9 @@ impl Context { expected: &Type, found: &Type, ) -> Option { + if self.cfg.fast_error_report { + return None; + } if &callee_t.qual_name()[..] == "List" && attr == Some("__getitem__") && nth == 1 { let len = &callee_t.typarams().get(1).cloned()?; let (_, _, pred) = found.clone().deconstruct_refinement().ok()?; @@ -73,6 +76,9 @@ impl Context { expected: &Type, found: &Type, ) -> Option { + if self.cfg.fast_error_report { + return None; + } let expected = if let Some(fv) = expected.as_free() { if fv.is_linked() { fv.crack().clone() @@ -284,6 +290,9 @@ impl Context { } pub(crate) fn get_no_candidate_hint(&self, proj: &Type) -> Option { + if self.cfg.fast_error_report { + return None; + } match proj { Type::Proj { lhs, rhs: _ } => { if let Some(fv) = lhs.as_free() { diff --git a/crates/erg_compiler/context/initialize/const_func.rs b/crates/erg_compiler/context/initialize/const_func.rs index 60881fd79..30d66589d 100644 --- a/crates/erg_compiler/context/initialize/const_func.rs +++ b/crates/erg_compiler/context/initialize/const_func.rs @@ -243,9 +243,12 @@ pub(crate) fn sub_vdict_get<'d>( if key == k { return Some(v); } - match (ctx.convert_value_into_type(key.clone()), ctx.convert_value_into_type(k.clone())) { + match ( + ctx.convert_value_into_type(key.clone()), + ctx.convert_value_into_type(k.clone()), + ) { (Ok(idx), Ok(kt)) - if ctx.subtype_of(&idx.lower_bounded(), &kt.lower_bounded()) /*|| dict.len() == 1*/ => + if dict.len() == 1 || ctx.subtype_of(&idx.lower_bounded(), &kt.lower_bounded()) => { matches.push((idx, kt, v)); }