diff --git a/src/hir_lower.bux b/src/hir_lower.bux index 231d2ab..9f84e2b 100644 --- a/src/hir_lower.bux +++ b/src/hir_lower.bux @@ -1788,6 +1788,15 @@ module HirLower { // Unary if kind == ekUnary { + // `&NamedFunc` — the ident already lowers to the fat-pointer value + // (BuxFn_* struct init via __adapt_); taking its address would yield + // a pointer-to-struct where the struct value is expected. + if expr.intValue == tkAmp && expr.child1 != null as *Expr && expr.child1.kind == ekIdent { + let ampSym: Symbol = Scope_Lookup(ctx.scope, expr.child1.strValue); + if ampSym.kind == skFunc { + return Lcx_LowerExpr(ctx, expr.child1); + } + } // Overflow checking: in @[Checked] mode, lower negation on signed integers to checked call if ctx.checkedFunc && !ctx.releaseFunc && expr.intValue == tkMinus { var isSignedInt: bool = false; diff --git a/src/sema.bux b/src/sema.bux index 8383e9b..2fbbba6 100644 --- a/src/sema.bux +++ b/src/sema.bux @@ -232,6 +232,9 @@ module Sema { } return true; } + // Func-typed values: `&Func` reports tyPointer as its kind while its + // refType is tekFunc — accept when both sides are func-typed. + if toTe.kind == tekFunc && fromTe != null as *TypeExpr && fromTe.kind == tekFunc { return true; } if fromKind == toKind { return true; } if Sema_IsStrictNumeric(fromKind) && Sema_IsStrictNumeric(toKind) { return true; } if Sema_IsBool(fromKind) && Sema_IsBool(toKind) { return true; }