File tree Expand file tree Collapse file tree
crates/cairo-lang-semantic/src Expand file tree Collapse file tree Original file line number Diff line number Diff 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+ ^^^
Original file line number Diff line number Diff 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}
You can’t perform that action at this time.
0 commit comments