@@ -4118,6 +4118,12 @@ type ImplicitlyBoundTyparsAllowed =
41184118 | NewTyparsOK
41194119 | NoNewTypars
41204120
4121+ /// Formats a list of names for display in diagnostics, truncating to at most 5 entries.
4122+ let formatAvailableNames (names: string array) =
4123+ let truncated = names |> Array.truncate 5
4124+ let result = truncated |> String.concat ", "
4125+ if names.Length > 5 then result + ", ..." else result
4126+
41214127//-------------------------------------------------------------------------
41224128// Checking types and type constraints
41234129//-------------------------------------------------------------------------
@@ -5022,7 +5028,12 @@ and CrackStaticConstantArgs (cenv: cenv) env tpenv (staticParameters: Tainted<Pr
50225028 if staticParameters |> Array.exists (fun sp -> n.idText = sp.PUntaint((fun sp -> sp.Name), n.idRange)) then
50235029 error (Error(FSComp.SR.etStaticParameterAlreadyHasValue n.idText, n.idRange))
50245030 else
5025- error (Error(FSComp.SR.etNoStaticParameterWithName n.idText, n.idRange))
5031+ let availableNames =
5032+ staticParameters
5033+ |> Array.map (fun sp -> sp.PUntaint((fun sp -> sp.Name), n.idRange))
5034+ |> formatAvailableNames
5035+
5036+ error (Error(FSComp.SR.etNoStaticParameterWithName (n.idText, availableNames), n.idRange))
50265037 | [_] -> ()
50275038 | _ -> error (Error(FSComp.SR.etMultipleStaticParameterWithName n.idText, n.idRange))
50285039
@@ -6162,6 +6173,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE
61626173 | SynExpr.MatchBang (trivia = { MatchBangKeyword = m })
61636174 | SynExpr.WhileBang (range = m) ->
61646175 error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m))
6176+
61656177 | SynExpr.IndexFromEnd (rightExpr, m) ->
61666178 errorR(Error(FSComp.SR.tcTraitInvocationShouldUseTick(), m))
61676179 let adjustedExpr = ParseHelpers.adjustHatPrefixToTyparLookup m rightExpr
@@ -6294,6 +6306,11 @@ and TcExprTuple (cenv: cenv) overallTy env tpenv (isExplicitStruct, args, m) =
62946306and TcExprArrayOrList (cenv: cenv) overallTy env tpenv (isArray, args, m) =
62956307 let g = cenv.g
62966308
6309+ match isArray, args with
6310+ | false, [ SynExpr.Tuple(false, _, _, _) ] ->
6311+ informationalWarning (Error(FSComp.SR.tcListLiteralWithSingleTupleElement (), m))
6312+ | _ -> ()
6313+
62976314 CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights)
62986315 let argTy = NewInferenceType g
62996316 let actualTy = if isArray then mkArrayType g argTy else mkListTy g argTy
@@ -8295,11 +8312,40 @@ and TcForEachExpr cenv overallTy env tpenv (seqExprOnly, isFromSource, synPat, s
82958312 // Add the pattern match compilation
82968313 let bodyExpr =
82978314 let valsDefinedByMatching = ListSet.remove valEq elemVar vspecs
8298- CompilePatternForMatch
8299- cenv env synEnumExpr.Range pat.Range false IgnoreWithWarning (elemVar, [], None)
8300- [MatchClause(pat, None, TTarget(valsDefinedByMatching, bodyExpr, None), mIn)]
8301- enumElemTy
8302- overallTy.Commit
8315+
8316+ let isConstantPattern =
8317+ match synPat with
8318+ | SynPat.Const _
8319+ | SynPat.Paren(SynPat.Const _, _)
8320+ | SynPat.Typed(SynPat.Const _, _, _)
8321+ | SynPat.Paren(SynPat.Typed(SynPat.Const _, _, _), _) -> true
8322+ | _ -> false
8323+
8324+ let compileMatch () =
8325+ CompilePatternForMatch
8326+ cenv env synEnumExpr.Range pat.Range false IgnoreWithWarning (elemVar, [], None)
8327+ [MatchClause(pat, None, TTarget(valsDefinedByMatching, bodyExpr, None), mIn)]
8328+ enumElemTy
8329+ overallTy.Commit
8330+
8331+ if isConstantPattern then
8332+ use _ =
8333+ UseTransformedDiagnosticsLogger(fun oldLogger ->
8334+ { new DiagnosticsLogger("forLoopConstantHint") with
8335+ member _.DiagnosticSink(diagnostic) =
8336+ match diagnostic.Exception with
8337+ | MatchIncomplete _ ->
8338+ oldLogger.DiagnosticSink(
8339+ { diagnostic with
8340+ Exception = MatchIncompleteForLoopHint(diagnostic.Exception) })
8341+ | _ -> oldLogger.DiagnosticSink(diagnostic)
8342+
8343+ member _.ErrorCount = oldLogger.ErrorCount
8344+ })
8345+
8346+ compileMatch ()
8347+ else
8348+ compileMatch ()
83038349
83048350 // Apply the fixup to bind the elemVar if needed
83058351 let bodyExpr = bodyExprFixup elemVar bodyExpr
@@ -8466,15 +8512,17 @@ and Propagate (cenv: cenv) (overallTy: OverallTy) (env: TcEnv) tpenv (expr: Appl
84668512 else
84678513 if IsIndexerType g cenv.amap expr.Type then
84688514 let old = not (g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot)
8515+ // NotAFunctionButIndexer uses overallTy (expected type) for the indexer suggestion message.
84698516 error (NotAFunctionButIndexer(denv, overallTy.Commit, vName, mExpr, mArg, old))
84708517 else
8471- error (NotAFunction(denv, overallTy.Commit, mExpr, mArg))
8518+ // NotAFunction uses exprTy (actual type) to show "has type X, which does not accept arguments".
8519+ error (NotAFunction(denv, exprTy, mExpr, mArg))
84728520
84738521 // f x (where 'f' is not a function)
84748522 | _ ->
84758523 // 'delayed' is about to be dropped on the floor, first do rudimentary checking to get name resolutions in its body
84768524 RecordNameAndTypeResolutionsDelayed cenv env tpenv delayed
8477- error (NotAFunction(denv, overallTy.Commit , mExpr, mArg))
8525+ error (NotAFunction(denv, exprTy , mExpr, mArg))
84788526
84798527 propagate false delayed expr.Range exprTy
84808528
@@ -8795,7 +8843,7 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg
87958843 TcDelayed cenv overallTy env tpenv mExprAndArg (MakeApplicableExprNoFlex cenv bodyOfCompExpr) (tyOfExpr g bodyOfCompExpr) ExprAtomicFlag.NonAtomic delayed
87968844
87978845 | _ ->
8798- error (NotAFunction(denv, overallTy.Commit , mLeftExpr, mArg))
8846+ error (NotAFunction(denv, exprTy , mLeftExpr, mArg))
87998847
88008848//-------------------------------------------------------------------------
88018849// TcLongIdentThen: Typecheck "A.B.C<D>.E.F ... " constructs
@@ -9358,7 +9406,6 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed =
93589406 | SynExpr.YieldOrReturn _
93599407 | SynExpr.YieldOrReturnFrom _
93609408 | SynExpr.MatchBang _
9361- | LetOrUse(_, true, _)
93629409 | SynExpr.DoBang _
93639410 | SynExpr.WhileBang _
93649411 | SynExpr.TraitCall _
@@ -10773,6 +10820,13 @@ and CheckRecursiveBindingIds binds =
1077310820 if nm <> "" && not (hashOfBinds.Add nm) then
1077410821 error(Duplicate("value", nm, m))
1077510822
10823+ /// Returns true if the expression is an elif chain that ends without a final 'else' branch.
10824+ and elifChainMissingElse expr =
10825+ match expr with
10826+ | SynExpr.IfThenElse(elseExpr = None) -> true
10827+ | SynExpr.IfThenElse(elseExpr = Some elseExpr) -> elifChainMissingElse elseExpr
10828+ | _ -> false
10829+
1077610830/// Process a sequence of sequentials mixed with iterated lets "let ... in let ... in ..." in a tail recursive way
1077710831/// This avoids stack overflow on really large "let" and "letrec" lists
1077810832and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr synExpr cont =
@@ -10819,12 +10873,15 @@ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr synExpr cont =
1081910873 let env = { env with eIsControlFlow = true }
1082010874 let thenExpr, tpenv =
1082110875 let env =
10822- match env.eContextInfo with
10823- | ContextInfo.ElseBranchResult _ -> { env with eContextInfo = ContextInfo.ElseBranchResult synThenExpr.Range }
10824- | _ ->
10825- match synElseExprOpt with
10826- | None -> { env with eContextInfo = ContextInfo.OmittedElseBranch synThenExpr.Range }
10827- | _ -> { env with eContextInfo = ContextInfo.IfExpression synThenExpr.Range }
10876+ match env.eContextInfo, synElseExprOpt with
10877+ // Inside an elif chain with no final else: use full elif range (m) so the error points at the whole elif.
10878+ | ContextInfo.ElseBranchResult _, None -> { env with eContextInfo = ContextInfo.OmittedElseBranch m }
10879+ | ContextInfo.ElseBranchResult _, _ -> { env with eContextInfo = ContextInfo.ElseBranchResult synThenExpr.Range }
10880+ // Top-level if with no else: use then-branch range.
10881+ | _, None -> { env with eContextInfo = ContextInfo.OmittedElseBranch synThenExpr.Range }
10882+ | _, Some elseExpr when elifChainMissingElse elseExpr ->
10883+ { env with eContextInfo = ContextInfo.OmittedElseBranch synThenExpr.Range }
10884+ | _ -> { env with eContextInfo = ContextInfo.IfExpression synThenExpr.Range }
1082810885
1082910886 if not isRecovery && Option.isNone synElseExprOpt then
1083010887 UnifyTypes cenv env m g.unit_ty overallTy.Commit
0 commit comments