Skip to content

✨ Implement tuple mode#1369

Merged
harehare merged 1 commit intomainfrom
feat/add-tuple
Mar 1, 2026
Merged

✨ Implement tuple mode#1369
harehare merged 1 commit intomainfrom
feat/add-tuple

Conversation

@harehare
Copy link
Copy Markdown
Owner

@harehare harehare commented Mar 1, 2026

No description provided.

Copilot AI review requested due to automatic review settings March 1, 2026 14:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements "tuple mode" for the mq-check type checker. When the --tuple flag is enabled, heterogeneous array literals (e.g., [1, "hello"]) are inferred as Tuple(number, string) instead of a generic Array('a). This enables precise per-element type tracking so that v[0] resolves to number and v[1] resolves to string, while homogeneous arrays remain unaffected. The PR also renames the crate from mq-typechecker to mq-check and adds a large suite of new integration tests and builtin type-registration tests.

Changes:

  • Added Type::Tuple(Vec<Type>) variant to the type system with full support across unification, substitution, display, and overload scoring.
  • Added the --tuple CLI flag and TypeCheckerOptions::tuple field, plus deferred tuple-index access resolution in lib.rs.
  • Added two new test files (integration_test.rs, error_location_test.rs) and a new builtin.rs with comprehensive type signatures and tests; renamed crate from mq-typechecker to mq-check in Cargo.toml.

Reviewed changes

Copilot reviewed 9 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
crates/mq-check/src/types.rs Adds Type::Tuple variant; implements display, unification, match scoring, substitution, free-var collection
crates/mq-check/src/unify.rs Tuple-to-tuple and tuple-to-array unification cases; occurs check and substitution for Tuple
crates/mq-check/src/constraint.rs Generates Tuple type for heterogeneous arrays in tuple mode; defers tuple index access resolution
crates/mq-check/src/lib.rs Adds TypeCheckerOptions::tuple; drives resolve_deferred_tuple_accesses post-unification
crates/mq-check/src/infer.rs Adds DeferredTupleAccess struct and context fields/methods
crates/mq-check/src/narrowing.rs New file: flow-sensitive type narrowing from predicates and structural selectors
crates/mq-check/src/builtin.rs New file: all builtin function type signatures, organized by category
crates/mq-check/src/main.rs Adds --tuple CLI flag; refactors check_file to use CheckOptions struct
crates/mq-check/README.md Documents tuple mode, all CLI options
crates/mq-check/Cargo.toml New manifest for mq-check
Cargo.toml Replaces mq-typechecker with mq-check in workspace members
crates/mq-check/tests/type_errors_test.rs Adds helper + tests for tuple mode
crates/mq-check/tests/integration_test.rs Large new integration test file covering the type checker
crates/mq-check/tests/error_location_test.rs New tests for error location and message readability
Comments suppressed due to low confidence (1)

crates/mq-check/src/types.rs:348

  • There is a potential integer division by zero panic on this line. When both elems1 and elems2 are empty tuples (Type::Tuple(vec![])), the guard elems1.len() == elems2.len() passes (0 == 0), total is 0, and then total / elems1.len() as u32 evaluates to 0 / 0, which panics in Rust in both debug and release builds.

The fix is to guard against the empty-tuple case, for example by returning Some(20) early when elems1.is_empty(), or by using elems1.len().max(1) in the divisor.

@harehare harehare merged commit fe2fc86 into main Mar 1, 2026
12 checks passed
@harehare harehare deleted the feat/add-tuple branch March 1, 2026 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants