iter 23.1.4: E2E fixture — bare LT match via implicit prelude import
This commit is contained in:
@@ -1639,6 +1639,16 @@ impl<'a> Emitter<'a> {
|
||||
/// under a swapped `module_name` (see `emit_specialised_fn`)
|
||||
/// resolve its bare ctor references against the *owner* module's
|
||||
/// ctor table, not the consumer's.
|
||||
///
|
||||
/// Iter 23.1: bare-type lookup now falls back to imported modules
|
||||
/// when the ctor is not local — mirroring `lookup_ctor_in_pattern`.
|
||||
/// The typechecker (Iter 23.1 Task 3) already accepts a bare
|
||||
/// `Term::Ctor { type_name, ctor }` whose `type_name` is owned by
|
||||
/// an imported module (the implicit `prelude` import is the
|
||||
/// motivating case: an `Ordering` ctor `LT` written without an
|
||||
/// explicit `imports: ["prelude"]`). Codegen must honour the same
|
||||
/// resolution path so the lockstep `Pattern::Ctor ↔ Term::Ctor ↔
|
||||
/// codegen` is preserved.
|
||||
pub(crate) fn lookup_ctor_by_type(
|
||||
&self,
|
||||
type_name: &str,
|
||||
@@ -1669,24 +1679,41 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
Ok(cref)
|
||||
} else {
|
||||
let cref = self
|
||||
// Local-first: current module's ctor table wins on conflict.
|
||||
if let Some(cref) = self
|
||||
.module_ctor_index
|
||||
.get(self.module_name)
|
||||
.and_then(|m| m.get(ctor_name))
|
||||
.cloned()
|
||||
.ok_or_else(|| {
|
||||
CodegenError::Internal(format!(
|
||||
"unknown ctor `{ctor_name}` in module `{}`",
|
||||
self.module_name
|
||||
))
|
||||
})?;
|
||||
if cref.type_name != type_name {
|
||||
return Err(CodegenError::Internal(format!(
|
||||
"ctor `{ctor_name}` belongs to `{}`, not `{type_name}`",
|
||||
cref.type_name
|
||||
)));
|
||||
{
|
||||
if cref.type_name != type_name {
|
||||
return Err(CodegenError::Internal(format!(
|
||||
"ctor `{ctor_name}` belongs to `{}`, not `{type_name}`",
|
||||
cref.type_name
|
||||
)));
|
||||
}
|
||||
return Ok(cref);
|
||||
}
|
||||
Ok(cref)
|
||||
// Iter 23.1: fallback — scan other modules for a bare ctor
|
||||
// whose declared `type_name` matches. The typechecker has
|
||||
// already pinned uniqueness (an ambiguous bare type name
|
||||
// is rejected with `CheckError::AmbiguousType`), so the
|
||||
// first hit whose owning type matches the requested
|
||||
// `type_name` is unique. Mirrors `lookup_ctor_in_pattern`.
|
||||
for (mname, ctors) in self.module_ctor_index.iter() {
|
||||
if mname == self.module_name {
|
||||
continue;
|
||||
}
|
||||
if let Some(cref) = ctors.get(ctor_name).cloned() {
|
||||
if cref.type_name == type_name {
|
||||
return Ok(cref);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(CodegenError::Internal(format!(
|
||||
"unknown ctor `{ctor_name}` in module `{}`",
|
||||
self.module_name
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user