Skip to content

fix(mir): resolve user type aliases to their base type for movability - #540

Merged
AkiraTamai merged 2 commits into
developfrom
devin/1788348841-alias-movability
Sep 2, 2026
Merged

fix(mir): resolve user type aliases to their base type for movability#540
AkiraTamai merged 2 commits into
developfrom
devin/1788348841-alias-movability

Conversation

@AkiraTamai

@AkiraTamai AkiraTamai commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #539. mir::movability_from_type only recognizes primitives and a hard-coded list of aliases (Nat, Pos, HumanAge, ...), so any other user alias (type Usd = i64 unit USD;, type Count = Nat;) was treated as Move. Branching on such a parameter and returning it on one path then failed move analysis with conflicting ownership ... alive on one control-flow path but consumed on another.

Fix: MIR lowering and the structured-concurrency ownership check resolve aliases through ModuleEnv before deciding movability.

// mir.rs
pub fn resolve_alias_base(env: &ModuleEnv, name: &str) -> String  // follows `type A = B; type B = i64;`, cycle-safe
pub fn lower_hir_to_mir(hir) -> MirBody { lower_hir_to_mir_with_env(hir, None) }
pub fn lower_hir_to_mir_with_env(hir, module_env: Option<&ModuleEnv>) -> MirBody
// LowerCtx.alias_bases: alias -> base type; alloc_local_with_capability: movability_from_type(alias_bases[ty] ?? ty)

// task_ownership.rs: analyze_task_ownership seeds param types with resolve_alias_base(module_env, ty)

executor.rs passes Some(module_env); LocalDecl::ty still records the alias name (only the movability decision changes). Without an env (unit tests, infer_atom_return_type) behavior is unchanged.

Tests: tests/test_alias_movability.{mm,rs} (branch on Usd/Count params; fails on develop) and task_ownership::tests::copy_alias_consumed_by_siblings_is_allowed.

Link to Devin session: https://app.devin.ai/sessions/2eef5afcd69d4e0ab19ada3b22d5cf7e
Open in Devin Desktop: https://app.devin.ai/desktop/session/2eef5afcd69d4e0ab19ada3b22d5cf7e?variant=devin
Requested by: @AkiraTamai

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@AkiraTamai
AkiraTamai marked this pull request as ready for review September 2, 2026 11:39

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 4 potential issues.

Devin Review

Comment thread mumei-core/src/verification/executor.rs
Comment thread mumei-core/src/mir.rs Outdated
Comment on lines +452 to +461
fn resolve_alias_base(env: &crate::verification::ModuleEnv, name: &str) -> String {
let mut current = name.to_string();
let mut seen = std::collections::HashSet::new();
while let Some(refined) = env.get_type(&current) {
if !seen.insert(current.clone()) || refined._base_type == current {
break;
}
current = refined._base_type.clone();
}
current

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📝 Info: Alias cycles remain conservative

resolve_alias_base stops repeated aliases and returns a non-primitive name. Cyclic or unresolved aliases therefore remain Move instead of becoming Copy.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread mumei-core/src/mir.rs
Comment on lines +271 to +276
let alias_bases = module_env
.map(|env| {
env.types
.keys()
.map(|name| (name.clone(), resolve_alias_base(env, name)))
.collect()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📝 Info: Qualified imports retain alias resolution

Imported types keep qualified and unqualified registrations. A qualified alias can therefore continue through its unqualified base to a primitive.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread mumei-core/src/mir.rs
Comment on lines 466 to +467
pub fn lower_hir_to_mir(hir_atom: &HirAtom) -> MirBody {
let mut ctx = LowerCtx::new();
lower_hir_to_mir_with_env(hir_atom, None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📝 Info: Legacy lowering remains conservative

lower_hir_to_mir still treats unknown aliases as Move. Production move verification uses the environment-aware entry point; remaining callers only prepare liveness and drops.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@AkiraTamai
AkiraTamai merged commit c60ca09 into develop Sep 2, 2026
4 checks passed
@AkiraTamai
AkiraTamai deleted the devin/1788348841-alias-movability branch September 2, 2026 13:06
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.

1 participant