diff --git a/crates/cairo-lang-semantic/src/expr/inference.rs b/crates/cairo-lang-semantic/src/expr/inference.rs index 1ee0de9fc3b..7319222fb9f 100644 --- a/crates/cairo-lang-semantic/src/expr/inference.rs +++ b/crates/cairo-lang-semantic/src/expr/inference.rs @@ -1230,15 +1230,9 @@ impl SemanticRewriter for Inference<'_> { let impl_id = impl_type_id.impl_id(); let trait_ty = impl_type_id.ty(); return Ok(match impl_id.lookup_intern(self.db) { - ImplLongId::GenericParameter(_) | ImplLongId::SelfImpl(_) => { - impl_type_id_rewrite_result - } - ImplLongId::ImplImpl(impl_impl) => { - // The grand parent impl must be var free since we are rewriting the parent, - // and the parent is not var. - assert!(impl_impl.impl_id().is_var_free(self.db)); - impl_type_id_rewrite_result - } + ImplLongId::GenericParameter(_) + | ImplLongId::SelfImpl(_) + | ImplLongId::ImplImpl(_) => impl_type_id_rewrite_result, ImplLongId::Concrete(_) => { if let Ok(ty) = self.db.impl_type_concrete_implized(ImplTypeId::new( impl_id, trait_ty, self.db, diff --git a/crates/cairo-lang-semantic/src/items/tests/trait_impl b/crates/cairo-lang-semantic/src/items/tests/trait_impl index c43922036eb..f5b133ceba3 100644 --- a/crates/cairo-lang-semantic/src/items/tests/trait_impl +++ b/crates/cairo-lang-semantic/src/items/tests/trait_impl @@ -1367,3 +1367,64 @@ error: Trait has no implementation in context: core::metaprogramming::TypeEqual: --> lib.cairo:31:11 1_u64.foo(1_u32); ^^^ + +//! > ========================================================================== + +//! > Trait default implementation with recursive types. + +//! > test_runner_name +test_function_diagnostics(expect_diagnostics: true) + +//! > function +fn foo() { + // TODO(orizi): Remove this diagnostic. + mix(1_u64.into_inner(), 1_u32.into_inner()); +} + +//! > function_name +foo + +//! > module_code +trait Outer { + type Inner; + impl Impl: Inner; + fn into_inner(self: T) -> Self::Inner; +} + +trait Inner { + type InnerMost; +} + +fn mix< + T, + U, + impl InnerT: Inner, + impl OuterU: Outer, + +core::metaprogramming::TypeEqual, +>( + lhs: T, rhs: U, +) {} + +impl OuterU32 of Outer { + type Inner = u64; + fn into_inner(self: u32) -> u64 { + self.into() + } +} + +impl OuterU64 of Outer { + type Inner = u64; + fn into_inner(self: u64) -> u64 { + self + } +} + +impl InnerImpl of Inner { + type InnerMost = u128; +} + +//! > expected_diagnostics +error: Impl mismatch: `Outer::Impl` and `test::InnerImpl`. + --> lib.cairo:40:5 + mix(1_u64.into_inner(), 1_u32.into_inner()); + ^^^