From 0ddf1732811cf97455acad82351afae199853d9c Mon Sep 17 00:00:00 2001 From: saem Date: Wed, 28 Aug 2024 16:06:18 -0700 Subject: [PATCH] fix(sem): errors in lambdas no longer crash Summary --------- Errors in lambdas requiring inference (`proc(e: auto) echo e`), no longer crash the compiler. Instead errors within the lambda body are reported and lambda inference fails as it should. Details ------- `semInferredLambda` failed to wrap its output when there were errors. This would reach `transf` and result in a compiler crash by hitting an `unreachable` assertion. Now errors in the body are reported immediately (to provide context for inference failure) and AST output from the inference attempt is correctly wrapped such that inference appropriately fails. --- compiler/sem/semstmts.nim | 49 +++++++++++-------- ...to_inference_failure_due_to_body_error.nim | 11 +++++ 2 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 tests/lang_callable/generics/tauto_inference_failure_due_to_body_error.nim diff --git a/compiler/sem/semstmts.nim b/compiler/sem/semstmts.nim index 5acc11c8df9..00ad6c8901a 100644 --- a/compiler/sem/semstmts.nim +++ b/compiler/sem/semstmts.nim @@ -2182,45 +2182,52 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode = proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode {.nosinks.} = ## used for resolving 'auto' in lambdas based on their callsite addInNimDebugUtils(c.config, "semInferredLambda", n, result) - var n = n let original = n[namePos].sym let s = original #copySym(original, false) #incl(s.flags, sfFromGeneric) #s.owner = original - n = instantiateTypesInBody(c, pt, n, original) - result = n + result = instantiateTypesInBody(c, pt, n, original) s.ast = result - n[namePos].sym = s - n[genericParamsPos] = c.graph.emptyNode + result[namePos].sym = s + result[genericParamsPos] = c.graph.emptyNode # for LL we need to avoid wrong aliasing - n[paramsPos] = newNodeI(nkFormalParams, n[paramsPos].info, n.typ.n.len) - for i, p in n.typ.n.pairs: - n[paramsPos][i] = + result[paramsPos] = newNodeI(nkFormalParams, result[paramsPos].info, + result.typ.n.len) + for i, p in result.typ.n.pairs: + result[paramsPos][i] = case i of 0: # return type - newNodeIT(nkType, n.info, n.typ[0]) + newNodeIT(nkType, n.info, result.typ[0]) else: # copy instantiated parameters - n.typ.n[i] - s.typ = n.typ - let params = n.typ.n - for i in 1..