Sitelet https://github.com/starkware-libs/cairo/commit/431559058b778e5d19ae18acbea7a0a34bd5a5ee
Skip to content

Commit 4315590

Browse files
authored
bugfix(semantic): don't ICE on a Deref impl with the wrong number of associated types. (#10183)
1 parent 845aa10 commit 4315590

2 files changed

Lines changed: 50 additions & 10 deletions

File tree

  • crates/cairo-lang-semantic/src

‎crates/cairo-lang-semantic/src/expr/test_data/deref‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,47 @@ struct A {
248248
}
249249

250250
//! > expected_diagnostics
251+
252+
//! > ==========================================================================
253+
254+
//! > Deref impl missing its associated type reports the trait-item mismatch instead of an ICE.
255+
256+
//! > test_runner_name
257+
test_function_diagnostics(expect_diagnostics: true)
258+
259+
//! > function_code
260+
fn foo() {
261+
let b = MyBox {};
262+
b.get();
263+
}
264+
265+
//! > function_name
266+
foo
267+
268+
//! > module_code
269+
#[derive(Drop)]
270+
struct Inner {}
271+
272+
#[derive(Drop)]
273+
struct MyBox {}
274+
275+
// `type Target` is missing: resolving a method through the deref chain used to ICE.
276+
impl MyDeref of core::ops::Deref<MyBox> {
277+
fn deref(self: MyBox) -> Inner {
278+
Inner {}
279+
}
280+
}
281+
282+
//! > expected_diagnostics
283+
error[E0004]: Not all trait items are implemented. Missing: 'Target'.
284+
--> lib.cairo:8:6
285+
impl MyDeref of core::ops::Deref<MyBox> {
286+
^^^^^^^
287+
288+
error[E0002]: Method `get` could not be called on type `test::MyBox`.
289+
Candidate `core::array::ArrayTrait::get` inference failed with: Type mismatch: `test::MyBox` and `@core::array::Array::<?0>`.
290+
Candidate `core::array::SpanTrait::get` inference failed with: Type mismatch: `test::MyBox` and `core::array::Span::<?0>`.
291+
Candidate `core::dict::Felt252DictTrait::get` inference failed with: Type mismatch: `test::MyBox` and `core::dict::Felt252Dict::<?0>`.
292+
--> lib.cairo:15:7
293+
b.get();
294+
^^^

‎crates/cairo-lang-semantic/src/items/imp.rs‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,17 +1092,13 @@ fn try_get_deref_func_and_target<'db>(
10921092
}
10931093
.intern(db);
10941094

1095-
let data = impl_definition_data(db, concrete_impl_id.impl_def_id(db)).clone().unwrap();
1096-
let mut types_iter = data.item_type_asts.iter();
1097-
let (impl_item_type_id, _) = types_iter.next().unwrap();
1098-
if types_iter.next().is_some() {
1099-
panic!(
1100-
"get_impl_based_on_single_impl_type called with an impl that has more than one type"
1101-
);
1102-
}
1103-
let ty = db.impl_type_def_resolved_type(*impl_item_type_id).unwrap();
1095+
let data = impl_definition_data(db, concrete_impl_id.impl_def_id(db)).maybe_as_ref()?;
1096+
let Ok((impl_item_type_id, _)) = data.item_type_asts.iter().exactly_one() else {
1097+
return Ok(None);
1098+
};
1099+
let ty = db.impl_type_def_resolved_type(*impl_item_type_id)?;
11041100
let substitution: GenericSubstitution<'db> = concrete_impl_id.substitution(db)?;
1105-
let ty: TypeId<'db> = substitution.substitute(db, ty).unwrap();
1101+
let ty: TypeId<'db> = substitution.substitute(db, ty)?;
11061102

11071103
Ok(Some((function_id, ty)))
11081104
}

0 commit comments

Comments
 (0)