Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 40 additions & 29 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ let GetRangeOfError(err:PhasedError) =
#endif
| ReservedKeyword(_,m)
| IndentationProblem(_,m)
| ErrorFromAddingTypeEquation(_,_,_,_,_,_,m)
| ErrorFromAddingTypeEquation(_,_,_,_,_,m)
| ErrorFromApplyingDefault(_,_,_,_,_,m)
| ErrorsFromAddingSubsumptionConstraint(_,_,_,_,_,_,m)
| FunctionExpected(_,_,m)
Expand Down Expand Up @@ -202,7 +202,7 @@ let GetRangeOfError(err:PhasedError) =
| ConstraintSolverTupleDiffLengths(_,_,_,m,_)
| ConstraintSolverInfiniteTypes(_,_,_,_,m,_)
| ConstraintSolverMissingConstraint(_,_,_,m,_)
| ConstraintSolverTypesNotInEqualityRelation(_,_,_,m,_)
| ConstraintSolverTypesNotInEqualityRelation(_,_,_,m,_,_)
| ConstraintSolverError(_,m,_)
| ConstraintSolverTypesNotInSubsumptionRelation(_,_,_,m,_)
| ConstraintSolverRelatedInformation(_,m,_)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -648,27 +657,29 @@ 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
| _ when t2 = "bool" && t1.EndsWith " ref" ->
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
Expand Down
22 changes: 11 additions & 11 deletions src/fsharp/ConstraintSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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 =
Expand Down
10 changes: 5 additions & 5 deletions src/fsharp/ConstraintSolver.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
12 changes: 4 additions & 8 deletions src/fsharp/TypeChecker.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// #Regression #Diagnostics #Async
// Regression tests for FSHARP1.0:4394
//<Expects status="error" span="(7,18-7,19)" id="FS0001">All branches of an 'if' expression must return the same type. This expression was expected to have type 'unit' but here has type 'int'</Expects>
//<Expects status="error" span="(7,18-7,19)" id="FS0001">This expression was expected to have type</Expects>
async { if true then
return ()
else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// #Warnings
//<Expects status="Error" id="FS0001">This expression was expected to have</Expects>

let test = 100
let f x : string = x
let y =
if test > 10 then "test"
else
f 123

exit 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// #Warnings
//<Expects status="Error" id="FS0001">This expression was expected to have</Expects>

let test = 100
let f x = printfn "%s" x
let y =
if test > 10 then "test"
else
f 123
"test"

exit 0
Loading