Skip to content

Commit 3855e3f

Browse files
authored
fix: handle mismatched generic param kinds in substitution rewriter instead of panicking (#9815)
1 parent 7360a15 commit 3855e3f

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

crates/cairo-lang-semantic/src/expr/test_data/generics

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,3 +712,35 @@ error[E2041]: Unexpected argument type. Expected: "test::MyStruct::<2>", found:
712712
--> lib.cairo:11:10
713713
bar2(s);
714714
^
715+
716+
//! > ==========================================================================
717+
718+
//! > Impl function with mismatched generic param kind (impl vs type).
719+
720+
//! > test_runner_name
721+
test_function_diagnostics(expect_diagnostics: true)
722+
723+
//! > function_code
724+
fn foo() {}
725+
726+
//! > function_name
727+
foo
728+
729+
//! > module_code
730+
trait Foo {
731+
fn bar<T>(self: T);
732+
}
733+
impl FooImpl of Foo {
734+
fn bar<+Drop<felt252>>(self: felt252) {}
735+
}
736+
737+
//! > expected_diagnostics
738+
error[E2036]: Parameter name of impl function FooImpl::bar is incompatible with Foo::bar parameter `T`.
739+
--> lib.cairo:5:12
740+
fn bar<+Drop<felt252>>(self: felt252) {}
741+
^^^^^^^^^^^^^^
742+
743+
error[E2038]: Generic parameter kind of impl function `FooImpl::bar` is incompatible with `Foo::bar`. Expected: `Type`, actual: `Impl`.
744+
--> lib.cairo:5:12
745+
fn bar<+Drop<felt252>>(self: felt252) {}
746+
^^^^^^^^^^^^^^

crates/cairo-lang-semantic/src/substitution.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use cairo_lang_defs::ids::{
66
ImplFunctionId, ImplImplDefId, LanguageElementId, LocalVarId, MemberId, ParamId, StructId,
77
TraitConstantId, TraitFunctionId, TraitId, TraitImplId, TraitTypeId, VariantId,
88
};
9-
use cairo_lang_diagnostics::{DiagnosticAdded, Maybe};
9+
use cairo_lang_diagnostics::{DiagnosticAdded, Maybe, skip_diagnostic};
1010
use cairo_lang_utils::deque::Deque;
1111
use cairo_lang_utils::extract_matches;
1212
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
@@ -514,7 +514,11 @@ impl<'db> SemanticRewriter<TypeLongId<'db>, DiagnosticAdded> for SubstitutionRew
514514
match value {
515515
TypeLongId::GenericParameter(generic_param) => {
516516
if let Some(generic_arg) = self.substitution.get(generic_param) {
517-
let type_id = *extract_matches!(generic_arg, GenericArgumentId::Type);
517+
let GenericArgumentId::Type(type_id) = generic_arg else {
518+
// The generic arg kind doesn't match the type parameter; a diagnostic
519+
// (WrongGenericParamKindForImplFunction) was already reported.
520+
return Err(skip_diagnostic());
521+
};
518522
// return self.rewrite(type_id.long(self.db));
519523
*value = type_id.long(self.db).clone();
520524
return Ok(RewriteResult::Modified);

0 commit comments

Comments
 (0)