diff --git a/src/core/IronPython/Compiler/Ast/FunctionDefinition.cs b/src/core/IronPython/Compiler/Ast/FunctionDefinition.cs index 97489e908..b06cb04eb 100644 --- a/src/core/IronPython/Compiler/Ast/FunctionDefinition.cs +++ b/src/core/IronPython/Compiler/Ast/FunctionDefinition.cs @@ -680,11 +680,12 @@ private LightLambdaExpression CreateFunctionLambda() { InitializeParameters(init, needsWrapperMethod, parameters); List statements = new List(); - // add beginning sequence point - var start = GlobalParent.IndexToLocation(StartIndex); - statements.Add(GlobalParent.AddDebugInfo( - AstUtils.Empty(), - new SourceSpan(new SourceLocation(0, start.Line, start.Column), new SourceLocation(0, start.Line, int.MaxValue)))); + + // Add beginning sequence point. For async functions this body is deferred into the nested Async/AsyncEnumerable lambda, + // and the outer factory (which runs first, and is the only one traced today) re-emits its own entry point at StartIndex; + // anchor this one at HeaderIndex (end of the signature) so the two occupy distinct source locations should the deferred + // body ever become traceable. For single-line signatures both still land on the same line (differing only in column). + statements.Add(MakeFunctionEntrySequencePoint(IsAsync ? HeaderIndex : StartIndex)); // For generators/coroutines, we need to do a check before the first statement for Generator.Throw() / Generator.Close(). @@ -758,6 +759,7 @@ private LightLambdaExpression CreateFunctionLambda() { // rather than whatever context happened to be current at construction. body = MSAst.Expression.Block( [cts, excBox], + MakeFunctionEntrySequencePoint(StartIndex), MSAst.Expression.Assign(cts, MSAst.Expression.New(typeof(CancellationTokenSource))), MSAst.Expression.Assign(excBox, MSAst.Expression.New(typeof(StrongBox))), Ast.Call( @@ -805,6 +807,13 @@ private LightLambdaExpression CreateFunctionLambda() { internal FunctionCode FunctionCode => GetOrMakeFunctionCode(); + private MSAst.Expression MakeFunctionEntrySequencePoint(int index) { + var loc = GlobalParent.IndexToLocation(index); + return GlobalParent.AddDebugInfo( + AstUtils.Empty(), + new SourceSpan(new SourceLocation(0, loc.Line, loc.Column), new SourceLocation(0, loc.Line, int.MaxValue))); + } + private static MSAst.Expression/*!*/ AddDefaultReturn(MSAst.Expression/*!*/ body, Type returnType) { if (body.Type == typeof(void) && returnType != typeof(void)) { body = Ast.Block(body, Ast.Default(returnType));