diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index f845dd62b2..5d862a8960 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -116,7 +116,7 @@ let GetRangeOfError(err:PhasedError) = #endif | ReservedKeyword(_,m) | IndentationProblem(_,m) - | ErrorFromAddingTypeEquation(_,_,_,_,_,_,m) + | ErrorFromAddingTypeEquation(_,_,_,_,_,m) | ErrorFromApplyingDefault(_,_,_,_,_,m) | ErrorsFromAddingSubsumptionConstraint(_,_,_,_,_,_,m) | FunctionExpected(_,_,m) @@ -202,7 +202,7 @@ let GetRangeOfError(err:PhasedError) = | ConstraintSolverTupleDiffLengths(_,_,_,m,_) | ConstraintSolverInfiniteTypes(_,_,_,_,m,_) | ConstraintSolverMissingConstraint(_,_,_,m,_) - | ConstraintSolverTypesNotInEqualityRelation(_,_,_,m,_) + | ConstraintSolverTypesNotInEqualityRelation(_,_,_,m,_,_) | ConstraintSolverError(_,m,_) | ConstraintSolverTypesNotInSubsumptionRelation(_,_,_,m,_) | ConstraintSolverRelatedInformation(_,m,_) @@ -408,9 +408,9 @@ let SplitRelatedErrors(err:PhasedError) = | ConstraintSolverRelatedInformation(fopt,m2,e) -> let e,related = SplitRelatedException e ConstraintSolverRelatedInformation(fopt,m2,e.Exception)|>ToPhased, related - | ErrorFromAddingTypeEquation(g,denv,t1,t2,e,specializedMessageF,m) -> + | ErrorFromAddingTypeEquation(g,denv,t1,t2,e,m) -> let e,related = SplitRelatedException e - ErrorFromAddingTypeEquation(g,denv,t1,t2,e.Exception,specializedMessageF,m)|>ToPhased, related + ErrorFromAddingTypeEquation(g,denv,t1,t2,e.Exception,m)|>ToPhased, related | ErrorFromApplyingDefault(g,denv,tp,defaultType,e,m) -> let e,related = SplitRelatedException e ErrorFromApplyingDefault(g,denv,tp,defaultType,e.Exception,m)|>ToPhased, related @@ -601,8 +601,8 @@ let OutputPhasedErrorR (os:System.Text.StringBuilder) (err:PhasedError) = let rec OutputExceptionR (os:System.Text.StringBuilder) = function | ConstraintSolverTupleDiffLengths(_,tl1,tl2,m,m2) -> os.Append(ConstraintSolverTupleDiffLengthsE().Format tl1.Length tl2.Length) |> ignore - (if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore) + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore | ConstraintSolverInfiniteTypes(contextInfo,denv,t1,t2,m,m2) -> // REVIEW: consider if we need to show _cxs (the type parameter constraints) let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 @@ -615,30 +615,39 @@ let OutputPhasedErrorR (os:System.Text.StringBuilder) (err:PhasedError) = os.Append(" " + FSComp.SR.yieldUsedInsteadOfYieldBang()) |> ignore | _ -> () - (if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore ) + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore | ConstraintSolverMissingConstraint(denv,tpr,tpc,m,m2) -> os.Append(ConstraintSolverMissingConstraintE().Format (NicePrint.stringOfTyparConstraint denv (tpr,tpc))) |> ignore - (if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore ) - | ConstraintSolverTypesNotInEqualityRelation(denv,(TType_measure _ as t1),(TType_measure _ as t2),m,m2) -> + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore + | ConstraintSolverTypesNotInEqualityRelation(denv,(TType_measure _ as t1),(TType_measure _ as t2),m,m2,contextInfo) -> // REVIEW: consider if we need to show _cxs (the type parameter constraints) let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - os.Append(ConstraintSolverTypesNotInEqualityRelation1E().Format t1 t2 ) |> ignore - (if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore) - | ConstraintSolverTypesNotInEqualityRelation(denv,t1,t2,m,m2) -> - // REVIEW: consider if we need to show _cxs (the type parameter constrants) + + match contextInfo with + | ContextInfo.OmittedElseBranch range when range = m -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore + | ContextInfo.ElseBranchResult range when range = m -> os.Append(FSComp.SR.elseBranchHasWrongType(t1,t2)) |> ignore + | _ -> os.Append(ConstraintSolverTypesNotInEqualityRelation1E().Format t1 t2 ) |> ignore + + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore + | ConstraintSolverTypesNotInEqualityRelation(denv,t1,t2,m,m2,contextInfo) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - os.Append(ConstraintSolverTypesNotInEqualityRelation2E().Format t1 t2) |> ignore - (if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore) + + match contextInfo with + | ContextInfo.OmittedElseBranch range when range = m -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore + | ContextInfo.ElseBranchResult range when range = m -> os.Append(FSComp.SR.elseBranchHasWrongType(t1,t2)) |> ignore + | _ -> os.Append(ConstraintSolverTypesNotInEqualityRelation2E().Format t1 t2) |> ignore + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore | ConstraintSolverTypesNotInSubsumptionRelation(denv,t1,t2,m,m2) -> // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, cxs= NicePrint.minimalStringsOfTwoTypes denv t1 t2 + let t1, t2, cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 os.Append(ConstraintSolverTypesNotInSubsumptionRelationE().Format t2 t1 cxs) |> ignore - (if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m2)) |> ignore) + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m2)) |> ignore | ConstraintSolverError(msg,m,m2) -> os.Append(ConstraintSolverErrorE().Format msg) |> ignore if m.StartLine <> m2.StartLine then @@ -648,13 +657,13 @@ let OutputPhasedErrorR (os:System.Text.StringBuilder) (err:PhasedError) = | ConstraintSolverError _ -> OutputExceptionR os e | _ -> () fopt |> Option.iter (Printf.bprintf os " %s") - | ErrorFromAddingTypeEquation(g,denv,t1,t2,ConstraintSolverTypesNotInEqualityRelation(_, t1', t2',_ ,_ ),contextInfo,_) + | ErrorFromAddingTypeEquation(g,denv,t1,t2,ConstraintSolverTypesNotInEqualityRelation(_, t1', t2',m ,_ , contextInfo),_) when typeEquiv g t1 t1' && typeEquiv g t2 t2' -> let t1,t2,tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 match contextInfo with - | ContextInfo.OmittedElseBranch -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore - | ContextInfo.ElseBranch -> os.Append(FSComp.SR.elseBranchHasWrongType(t1,t2)) |> ignore + | ContextInfo.OmittedElseBranch range when range = m -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore + | ContextInfo.ElseBranchResult range when range = m -> os.Append(FSComp.SR.elseBranchHasWrongType(t1,t2)) |> ignore | ContextInfo.TupleInRecordFields -> os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore os.Append(System.Environment.NewLine + FSComp.SR.commaInsteadOfSemicolonInRecord()) |> ignore @@ -662,13 +671,15 @@ let OutputPhasedErrorR (os:System.Text.StringBuilder) (err:PhasedError) = os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore os.Append(System.Environment.NewLine + FSComp.SR.derefInsteadOfNot()) |> ignore | _ -> os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore - | ErrorFromAddingTypeEquation(_,_,_,_,((ConstraintSolverTypesNotInSubsumptionRelation _ | ConstraintSolverError _) as e), _, _) -> + | ErrorFromAddingTypeEquation(_,_,_,_,((ConstraintSolverTypesNotInEqualityRelation (_,_,_,_,_,contextInfo) ) as e), _) when contextInfo <> ContextInfo.NoContext -> OutputExceptionR os e - | ErrorFromAddingTypeEquation(g,denv,t1,t2,e,_,_) -> - if not (typeEquiv g t1 t2) then ( + | ErrorFromAddingTypeEquation(_,_,_,_,((ConstraintSolverTypesNotInSubsumptionRelation _ | ConstraintSolverError _ ) as e), _) -> + OutputExceptionR os e + | ErrorFromAddingTypeEquation(g,denv,t1,t2,e,_) -> + if not (typeEquiv g t1 t2) then let t1,t2,tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 if t1<>t2 + tpcs then os.Append(ErrorFromAddingTypeEquation2E().Format t1 t2 tpcs) |> ignore - ) + OutputExceptionR os e | ErrorFromApplyingDefault(_,denv,_,defaultType,e,_) -> let defaultType = NicePrint.minimalStringOfType denv defaultType diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 94c31e5ec1..c6f3fa7dc7 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -121,9 +121,9 @@ type ContextInfo = /// No context was given. | NoContext /// The type equation comes from an omitted else branch. -| OmittedElseBranch -/// The type equation comes from checking an else branch. -| ElseBranch +| OmittedElseBranch of range +/// The type equation comes from checking an the result of an else branch. +| ElseBranchResult of range /// The type equation comes from the verification of record fields. | RecordFields /// The type equation comes from the verification of a tuple in record fields. @@ -139,14 +139,14 @@ type ContextInfo = exception ConstraintSolverTupleDiffLengths of DisplayEnv * TType list * TType list * range * range exception ConstraintSolverInfiniteTypes of ContextInfo * DisplayEnv * TType * TType * range * range -exception ConstraintSolverTypesNotInEqualityRelation of DisplayEnv * TType * TType * range * range +exception ConstraintSolverTypesNotInEqualityRelation of DisplayEnv * TType * TType * range * range * ContextInfo exception ConstraintSolverTypesNotInSubsumptionRelation of DisplayEnv * TType * TType * range * range exception ConstraintSolverMissingConstraint of DisplayEnv * Tast.Typar * Tast.TyparConstraint * range * range exception ConstraintSolverError of string * range * range exception ConstraintSolverRelatedInformation of string option * range * exn exception ErrorFromApplyingDefault of TcGlobals * DisplayEnv * Tast.Typar * TType * exn * range -exception ErrorFromAddingTypeEquation of TcGlobals * DisplayEnv * TType * TType * exn * ContextInfo * range +exception ErrorFromAddingTypeEquation of TcGlobals * DisplayEnv * TType * TType * exn * range exception ErrorsFromAddingSubsumptionConstraint of TcGlobals * DisplayEnv * TType * TType * exn * ContextInfo * range exception ErrorFromAddingConstraint of DisplayEnv * exn * range exception PossibleOverload of DisplayEnv * string * exn * range @@ -794,7 +794,7 @@ and private SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 // Back out of expansions of type abbreviations to give improved error messages. // Note: any "normalization" of equations on type variables must respect the trace parameter TryD (fun () -> SolveTypEqualsTyp csenv ndeep m2 trace cxsln ty1 ty2) - (function LocallyAbortOperationThatLosesAbbrevs -> ErrorD(ConstraintSolverTypesNotInEqualityRelation(csenv.DisplayEnv,ty1,ty2,csenv.m,m2)) + (function LocallyAbortOperationThatLosesAbbrevs -> ErrorD(ConstraintSolverTypesNotInEqualityRelation(csenv.DisplayEnv,ty1,ty2,csenv.m,m2,csenv.eContextInfo)) | err -> ErrorD err) and SolveTypEqualsTypEqns csenv ndeep m2 trace cxsln origl1 origl2 = @@ -1948,11 +1948,11 @@ and private SolveTypSubsumesTypWithReport (csenv:ConstraintSolverEnv) ndeep m tr | _ -> ErrorD (ErrorsFromAddingSubsumptionConstraint(csenv.g,csenv.DisplayEnv,ty1,ty2,res,ContextInfo.NoContext,m)) | _ -> ErrorD (ErrorsFromAddingSubsumptionConstraint(csenv.g,csenv.DisplayEnv,ty1,ty2,res,csenv.eContextInfo,m))) -and private SolveTypEqualsTypWithReport contextInfo (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = +and private SolveTypEqualsTypWithReport (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = TryD (fun () -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m trace cxsln ty1 ty2) (function | LocallyAbortOperationThatFailsToResolveOverload -> CompleteD - | res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g,csenv.DisplayEnv,ty1,ty2,res,contextInfo,m))) + | res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g,csenv.DisplayEnv,ty1,ty2,res,m))) and ArgsMustSubsumeOrConvert (csenv:ConstraintSolverEnv) @@ -1975,10 +1975,10 @@ and ArgsMustSubsumeOrConvert CompleteD) and MustUnify csenv ndeep trace cxsln ty1 ty2 = - SolveTypEqualsTypWithReport ContextInfo.NoContext csenv ndeep csenv.m trace cxsln ty1 ty2 + SolveTypEqualsTypWithReport csenv ndeep csenv.m trace cxsln ty1 ty2 and MustUnifyInsideUndo csenv ndeep trace cxsln ty1 ty2 = - SolveTypEqualsTypWithReport ContextInfo.NoContext csenv ndeep csenv.m (WithTrace trace) cxsln ty1 ty2 + SolveTypEqualsTypWithReport csenv ndeep csenv.m (WithTrace trace) cxsln ty1 ty2 and ArgsMustSubsumeOrConvertInsideUndo (csenv:ConstraintSolverEnv) ndeep trace cxsln isConstraint calledArg (CallerArg(callerArgTy,m,_,_) as callerArg) = let calledArgTy = AdjustCalledArgType csenv.InfoReader isConstraint calledArg callerArg @@ -2465,7 +2465,7 @@ let EliminateConstraintsForGeneralizedTypars csenv (trace:OptionalTrace) (genera //------------------------------------------------------------------------- let AddCxTypeEqualsType contextInfo denv css m ty1 ty2 = - SolveTypEqualsTypWithReport contextInfo (MakeConstraintSolverEnv contextInfo css m denv) 0 m NoTrace None ty1 ty2 + SolveTypEqualsTypWithReport (MakeConstraintSolverEnv contextInfo css m denv) 0 m NoTrace None ty1 ty2 |> RaiseOperationResult let UndoIfFailed f = diff --git a/src/fsharp/ConstraintSolver.fsi b/src/fsharp/ConstraintSolver.fsi index 0b4fafaba4..d49e4c1734 100644 --- a/src/fsharp/ConstraintSolver.fsi +++ b/src/fsharp/ConstraintSolver.fsi @@ -53,9 +53,9 @@ type ContextInfo = /// No context was given. | NoContext /// The type equation comes from an omitted else branch. -| OmittedElseBranch -/// The type equation comes from checking an else branch. -| ElseBranch +| OmittedElseBranch of range +/// The type equation comes from checking an the result of an else branch. +| ElseBranchResult of range /// The type equation comes from the verification of record fields. | RecordFields /// The type equation comes from the verification of a tuple in record fields. @@ -71,13 +71,13 @@ type ContextInfo = exception ConstraintSolverTupleDiffLengths of DisplayEnv * TType list * TType list * range * range exception ConstraintSolverInfiniteTypes of ContextInfo * DisplayEnv * TType * TType * range * range -exception ConstraintSolverTypesNotInEqualityRelation of DisplayEnv * TType * TType * range * range +exception ConstraintSolverTypesNotInEqualityRelation of DisplayEnv * TType * TType * range * range * ContextInfo exception ConstraintSolverTypesNotInSubsumptionRelation of DisplayEnv * TType * TType * range * range exception ConstraintSolverMissingConstraint of DisplayEnv * Typar * TyparConstraint * range * range exception ConstraintSolverError of string * range * range exception ConstraintSolverRelatedInformation of string option * range * exn exception ErrorFromApplyingDefault of TcGlobals * DisplayEnv * Typar * TType * exn * range -exception ErrorFromAddingTypeEquation of TcGlobals * DisplayEnv * TType * TType * exn * ContextInfo * range +exception ErrorFromAddingTypeEquation of TcGlobals * DisplayEnv * TType * TType * exn * range exception ErrorsFromAddingSubsumptionConstraint of TcGlobals * DisplayEnv * TType * TType * exn * ContextInfo * range exception ErrorFromAddingConstraint of DisplayEnv * exn * range exception UnresolvedConversionOperator of DisplayEnv * TType * TType * range diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index d02c44e78b..f254498b14 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -3317,7 +3317,7 @@ let mkSeqCollect cenv env m enumElemTy genTy lam enumExpr = let mkSeqUsing cenv (env: TcEnv) m resourceTy genTy resourceExpr lam = AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace cenv.g.system_IDisposable_typ resourceTy let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) mkCallSeqUsing cenv.g m resourceTy genResultTy resourceExpr lam let mkSeqDelay cenv env m genTy lam = @@ -5418,8 +5418,6 @@ and TcStmt cenv env tpenv synExpr = else mkCompGenSequential m expr (mkUnit cenv.g m),tpenv - - /// During checking of expressions of the form (x(y)).z(w1,w2) /// keep a stack of things on the right. This lets us recognize /// method applications and other item-based syntax. @@ -5487,7 +5485,6 @@ and TcExprUndelayedNoType cenv env tpenv expr : Expr * TType * _ = expr',exprty,tpenv and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = - match expr with | SynExpr.Paren (expr2,_,_,mWholeExprIncludingParentheses) -> // We invoke CallExprHasTypeSink for every construct which is atomic in the syntax, i.e. where a '.' immediately following the @@ -5688,7 +5685,6 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = | SynExpr.ArrayOrListOfSeqExpr (isArray,comp,m) -> CallExprHasTypeSink cenv.tcSink (m,env.NameEnv,overallTy, env.DisplayEnv,env.eAccessRights) - match comp with | SynExpr.CompExpr(_,_,(SimpleSemicolonSequence true elems as body),_) -> match body with @@ -5784,7 +5780,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = let e1',tpenv = TcExprThatCantBeCtorBody cenv cenv.g.bool_ty env tpenv e1 let e2',tpenv = if not isRecovery && Option.isNone e3opt then - let env = { env with eContextInfo = ContextInfo.OmittedElseBranch } + let env = { env with eContextInfo = ContextInfo.OmittedElseBranch e2.Range} UnifyTypes cenv env m cenv.g.unit_ty overallTy TcExprThatCanBeCtorBody cenv overallTy env tpenv e2 else @@ -5793,8 +5789,8 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = match e3opt with | None -> mkUnit cenv.g mIfToThen,SuppressSequencePointAtTarget, tpenv // the fake 'unit' value gets exactly the same range as spIfToThen - | Some e3 -> - let env = { env with eContextInfo = ContextInfo.ElseBranch } + | Some e3 -> + let env = { env with eContextInfo = ContextInfo.ElseBranchResult e3.Range } let e3',tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv e3 e3',SequencePointAtTarget,tpenv primMkCond spIfToThen SequencePointAtTarget sp2 m overallTy e1' e2' e3', tpenv diff --git a/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs b/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs index 428ce37019..51be95c940 100644 --- a/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs +++ b/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs @@ -1,6 +1,6 @@ // #Regression #Diagnostics #Async // Regression tests for FSHARP1.0:4394 -//All branches of an 'if' expression must return the same type. This expression was expected to have type 'unit' but here has type 'int' +//This expression was expected to have type async { if true then return () else diff --git a/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInAppl.fs b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInAppl.fs new file mode 100644 index 0000000000..79152abb78 --- /dev/null +++ b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInAppl.fs @@ -0,0 +1,11 @@ +// #Warnings +//This expression was expected to have + +let test = 100 +let f x : string = x +let y = + if test > 10 then "test" + else + f 123 + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInAppl2.fs b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInAppl2.fs new file mode 100644 index 0000000000..5478d8b09d --- /dev/null +++ b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInAppl2.fs @@ -0,0 +1,12 @@ +// #Warnings +//This expression was expected to have + +let test = 100 +let f x = printfn "%s" x +let y = + if test > 10 then "test" + else + f 123 + "test" + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInForLoop.fs b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInForLoop.fs new file mode 100644 index 0000000000..bfd5a18dd1 --- /dev/null +++ b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateInForLoop.fs @@ -0,0 +1,14 @@ +// #Warnings +//This expression was expected to have + +let test = 100 +let list = [1..10] +let y = + if test > 10 then "test" + else + for (x:string) in list do + printfn "%s" x + + "test" + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateToLinesBeforeLastLine.fs b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateToLinesBeforeLastLine.fs new file mode 100644 index 0000000000..9facc603ff --- /dev/null +++ b/tests/fsharpqa/Source/Warnings/ElseBranchContextDoesntPropagateToLinesBeforeLastLine.fs @@ -0,0 +1,13 @@ +// #Warnings +//This expression was expected to have type + +let test = 100 +let list = [1..10] +let y = + if test > 10 then "test" + else + printfn "%s" 1 + + "test" + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/ElseBranchHasWrongType2.fs b/tests/fsharpqa/Source/Warnings/ElseBranchHasWrongType2.fs new file mode 100644 index 0000000000..5b975f0562 --- /dev/null +++ b/tests/fsharpqa/Source/Warnings/ElseBranchHasWrongType2.fs @@ -0,0 +1,10 @@ +// #Warnings +//All branches of an 'if' expression must return the same type. This expression was expected to have type 'string' but here has type 'int'. + +let test = 100 +let f x = test +let y = + if test > 10 then "test" + else f 10 + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/WarnIfMissingElseBranch2.fs b/tests/fsharpqa/Source/Warnings/WarnIfMissingElseBranch2.fs new file mode 100644 index 0000000000..a8b98922a0 --- /dev/null +++ b/tests/fsharpqa/Source/Warnings/WarnIfMissingElseBranch2.fs @@ -0,0 +1,10 @@ +// #Warnings +//This expression was expected to have type + +let x = 10 +let y = + if x > 10 then + if x <> "test" then printfn "test" + () + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/env.lst b/tests/fsharpqa/Source/Warnings/env.lst index b26c21de72..5fb27f22b5 100644 --- a/tests/fsharpqa/Source/Warnings/env.lst +++ b/tests/fsharpqa/Source/Warnings/env.lst @@ -1,5 +1,6 @@ SOURCE=WrongNumericLiteral.fs # WrongNumericLiteral.fs SOURCE=WarnIfMissingElseBranch.fs # WarnIfMissingElseBranch.fs + SOURCE=WarnIfMissingElseBranch2.fs # WarnIfMissingElseBranch2.fs SOURCE=ReturnInsteadOfReturnBang.fs # ReturnInsteadOfReturnBang.fs SOURCE=YieldInsteadOfYieldBang.fs # YieldInsteadOfYieldBang.fs SOURCE=TupleInAbstractMethod.fs # TupleInAbstractMethod.fs @@ -15,6 +16,11 @@ SOURCE=AccessOfTypeAbbreviation6.fs # AccessOfTypeAbbreviation6.fs SOURCE=SuggestTypesInModule.fs # SuggestTypesInModule.fs SOURCE=ElseBranchHasWrongType.fs # ElseBranchHasWrongType.fs + SOURCE=ElseBranchHasWrongType2.fs # ElseBranchHasWrongType2.fs + SOURCE=ElseBranchContextDoesntPropagateInAppl.fs # ElseBranchContextDoesntPropagateInAppl.fs + SOURCE=ElseBranchContextDoesntPropagateInAppl2.fs # ElseBranchContextDoesntPropagateInAppl2.fs + SOURCE=ElseBranchContextDoesntPropagateInForLoop.fs # ElseBranchContextDoesntPropagateInForLoop.fs + SOURCE=ElseBranchContextDoesntPropagateToLinesBeforeLastLine.fs # ElseBranchContextDoesntPropagateToLinesBeforeLastLine.fs SOURCE=MatchingMethodWithSameNameIsNotAbstract.fs # MatchingMethodWithSameNameIsNotAbstract.fs SOURCE=NoMatchingAbstractMethodWithSameName.fs # NoMatchingAbstractMethodWithSameName.fs SOURCE=MissingExpressionAfterLet.fs # MissingExpressionAfterLet.fs