From 6c2082c4857703a0a3a98ec1b736c0dfe6a926e3 Mon Sep 17 00:00:00 2001 From: Ori Ziv Date: Sun, 26 Jan 2025 15:33:43 +0200 Subject: [PATCH] Delay failure on unknown type for tuple style types. Partially solving issue #7155. --- .../cairo-lang-semantic/src/expr/compute.rs | 45 ++++++++++++++----- tests/bug_samples/issue7155.cairo | 13 ++++++ tests/bug_samples/lib.cairo | 1 + 3 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 tests/bug_samples/issue7155.cairo diff --git a/crates/cairo-lang-semantic/src/expr/compute.rs b/crates/cairo-lang-semantic/src/expr/compute.rs index 68033133eb6..1520b83e03b 100644 --- a/crates/cairo-lang-semantic/src/expr/compute.rs +++ b/crates/cairo-lang-semantic/src/expr/compute.rs @@ -2364,12 +2364,24 @@ fn maybe_compute_tuple_like_pattern_semantic( let (n_snapshots, long_ty) = finalized_snapshot_peeled_ty(ctx, ty, pattern_syntax)?; // Assert that the pattern is of the same type as the expr. match (pattern_syntax, &long_ty) { - (ast::Pattern::Tuple(_), TypeLongId::Tuple(_)) - | (ast::Pattern::FixedSizeArray(_), TypeLongId::FixedSizeArray { .. }) => {} + (ast::Pattern::Tuple(_), TypeLongId::Tuple(_) | TypeLongId::Var(_)) + | ( + ast::Pattern::FixedSizeArray(_), + TypeLongId::FixedSizeArray { .. } | TypeLongId::Var(_), + ) => {} _ => { return Err(ctx.diagnostics.report(pattern_syntax, unexpected_pattern(ty))); } }; + let patterns_syntax = match pattern_syntax { + ast::Pattern::Tuple(pattern_tuple) => { + pattern_tuple.patterns(ctx.db.upcast()).elements(ctx.db.upcast()) + } + ast::Pattern::FixedSizeArray(pattern_fixed_size_array) => { + pattern_fixed_size_array.patterns(ctx.db.upcast()).elements(ctx.db.upcast()) + } + _ => unreachable!(), + }; let inner_tys = match long_ty { TypeLongId::Tuple(inner_tys) => inner_tys, TypeLongId::FixedSizeArray { type_id: inner_ty, size } => { @@ -2381,14 +2393,27 @@ fn maybe_compute_tuple_like_pattern_semantic( .unwrap(); [inner_ty].repeat(size) } - _ => unreachable!(), - }; - let patterns_syntax = match pattern_syntax { - ast::Pattern::Tuple(pattern_tuple) => { - pattern_tuple.patterns(ctx.db.upcast()).elements(ctx.db.upcast()) - } - ast::Pattern::FixedSizeArray(pattern_fixed_size_array) => { - pattern_fixed_size_array.patterns(ctx.db.upcast()).elements(ctx.db.upcast()) + TypeLongId::Var(_) => { + let inference = &mut ctx.resolver.inference(); + let (inner_tys, tuple_like_ty) = if matches!(pattern_syntax, ast::Pattern::Tuple(_)) { + let inner_tys: Vec<_> = patterns_syntax + .iter() + .map(|e| inference.new_type_var(Some(e.stable_ptr().untyped()))) + .collect(); + (inner_tys.clone(), TypeLongId::Tuple(inner_tys)) + } else { + let var = inference.new_type_var(Some(pattern_syntax.stable_ptr().untyped())); + (vec![var; patterns_syntax.len()], TypeLongId::FixedSizeArray { + type_id: var, + size: ConstValue::Int(patterns_syntax.len().into(), get_usize_ty(ctx.db)) + .intern(ctx.db), + }) + }; + match inference.conform_ty(ty, tuple_like_ty.intern(ctx.db)) { + Ok(_) => {} + Err(_) => unreachable!("As the type is a var, conforming should always succeed."), + } + inner_tys } _ => unreachable!(), }; diff --git a/tests/bug_samples/issue7155.cairo b/tests/bug_samples/issue7155.cairo new file mode 100644 index 00000000000..19dd6cf58eb --- /dev/null +++ b/tests/bug_samples/issue7155.cairo @@ -0,0 +1,13 @@ +#[test] +fn test_enumerate_type_resolution() { + // TODO(orizi): Remove "_usize" from the next line. Currently doesn't work without it, due to + // `NumericLiteral` not auto suppling `Destruct` to a type implementing it. + for (k, v) in array![0, 1, 2_usize].into_iter().enumerate() { + assert_eq!(k, v); + }; + + let mut iter = array![0, 1, 2].into_iter().enumerate(); + while let Option::Some((k, v)) = iter.next() { + assert_eq!(k, v); + }; +} diff --git a/tests/bug_samples/lib.cairo b/tests/bug_samples/lib.cairo index 9ecbf9a3e14..2c2d74b0a4e 100644 --- a/tests/bug_samples/lib.cairo +++ b/tests/bug_samples/lib.cairo @@ -59,6 +59,7 @@ mod issue7060; mod issue7071; mod issue7083; mod issue7095; +mod issue7155; mod loop_break_in_match; mod loop_only_change; mod partial_param_local;