@@ -2164,11 +2164,13 @@ module GeneralizationHelpers =
21642164
21652165 // Some situations, e.g. implicit class constructions that represent functions as fields,
21662166 // do not allow generalisation over constrained typars. (since they can not be represented as fields)
2167+ //
2168+ // Don't generalize IsCompatFlex type parameters to avoid changing inferred types.
21672169 let generalizedTypars, ungeneralizableTypars3 =
21682170 generalizedTypars
21692171 |> List.partition (fun tp ->
2170- genConstrainedTyparFlag = CanGeneralizeConstrainedTypars ||
2171- tp.Constraints.IsEmpty )
2172+ ( genConstrainedTyparFlag = CanGeneralizeConstrainedTypars ||tp.Constraints.IsEmpty) &&
2173+ not tp.IsCompatFlex )
21722174
21732175 if isNil ungeneralizableTypars1 && isNil ungeneralizableTypars2 && isNil ungeneralizableTypars3 then
21742176 generalizedTypars, freeInEnv
@@ -2930,7 +2932,7 @@ let TcRuntimeTypeTest isCast isOperator cenv denv m tgty srcTy =
29302932 if TypeDefinitelySubsumesTypeNoCoercion 0 cenv.g cenv.amap m tgty srcTy then
29312933 warning(TypeTestUnnecessary(m))
29322934
2933- if isTyparTy cenv.g srcTy then
2935+ if isTyparTy cenv.g srcTy&& not (destTyparTy cenv.g srcTy).IsCompatFlex then
29342936 error(IndeterminateRuntimeCoercion(denv, srcTy, tgty, m))
29352937
29362938 if isSealedTy cenv.g srcTy then
@@ -2956,20 +2958,18 @@ let TcRuntimeTypeTest isCast isOperator cenv denv m tgty srcTy =
29562958/// Checks, warnings and constraint assertions for upcasts
29572959let TcStaticUpcast cenv denv m tgty srcTy =
29582960 if isTyparTy cenv.g tgty then
2959- error(IndeterminateStaticCoercion(denv, srcTy, tgty, m))
2961+ if not (destTyparTy cenv.g tgty).IsCompatFlex then
2962+ error(IndeterminateStaticCoercion(denv, srcTy, tgty, m))
2963+ //else warning(UpcastUnnecessary(m))
29602964
2961- if isSealedTy cenv.g tgty then
2965+ if isSealedTy cenv.g tgty&& not (isTyparTy cenv.g tgty) then
29622966 warning(CoercionTargetSealed(denv, tgty, m))
29632967
29642968 if typeEquiv cenv.g srcTy tgty then
29652969 warning(UpcastUnnecessary(m))
29662970
29672971 AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace tgty srcTy
29682972
2969-
2970-
2971-
2972-
29732973let BuildPossiblyConditionalMethodCall cenv env isMutable m isProp minfo valUseFlags minst objArgs args =
29742974
29752975 let conditionalCallDefineOpt = TryFindMethInfoStringAttribute cenv.g m cenv.g.attrib_ConditionalAttribute minfo
@@ -5460,9 +5460,11 @@ and TcExprOfUnknownType cenv env tpenv expr =
54605460 let expr', tpenv = TcExpr cenv exprty env tpenv expr
54615461 expr', exprty, tpenv
54625462
5463- and TcExprFlex cenv flex ty (env: TcEnv) tpenv (e: SynExpr) =
5463+ and TcExprFlex cenv flexcompat ty (env: TcEnv) tpenv (e: SynExpr) =
54645464 if flex then
54655465 let argty = NewInferenceType ()
5466+ if compat then
5467+ (destTyparTy cenv.g argty).SetIsCompatFlex(true)
54665468 AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css e.Range NoTrace ty argty
54675469 let e', tpenv = TcExpr cenv argty env tpenv e
54685470 let e' = mkCoerceIfNeeded cenv.g ty argty e'
@@ -5592,7 +5594,7 @@ and TcExprThen cenv overallTy env tpenv synExpr delayed =
55925594and TcExprs cenv env m tpenv flexes argtys args =
55935595 if List.length args <> List.length argtys then error(Error(FSComp.SR.tcExpressionCountMisMatch((List.length argtys), (List.length args)), m))
55945596 (tpenv, List.zip3 flexes argtys args) ||> List.mapFold (fun tpenv (flex, ty, e) ->
5595- TcExprFlex cenv flex ty env tpenv e)
5597+ TcExprFlex cenv flexfalse ty env tpenv e)
55965598
55975599and CheckSuperInit cenv objTy m =
55985600 // Check the type is not abstract
@@ -5757,7 +5759,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
57575759 else
57585760 { env with eContextInfo = ContextInfo.CollectionElement (isArray, m) }
57595761
5760- let args', tpenv = List.mapFold (fun tpenv (x:SynExpr) -> TcExprFlex cenv flex argty (getInitEnv x.Range) tpenv x) tpenv args
5762+ let args', tpenv = List.mapFold (fun tpenv (x:SynExpr) -> TcExprFlex cenv flexfalse argty (getInitEnv x.Range) tpenv x) tpenv args
57615763
57625764 let expr =
57635765 if isArray then Expr.Op(TOp.Array, [argty], args', m)
@@ -5844,19 +5846,37 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
58445846
58455847 TcExprUndelayed cenv overallTy env tpenv replacementExpr
58465848 | _ ->
5849+
58475850 let genCollElemTy = NewInferenceType ()
5851+
58485852 let genCollTy = (if isArray then mkArrayType else mkListTy) cenv.g genCollElemTy
5853+
58495854 UnifyTypes cenv env m overallTy genCollTy
5850- let exprty = NewInferenceType ()
5851- let genEnumTy = mkSeqTy cenv.g genCollElemTy
5852- AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace genEnumTy exprty
5855+
5856+ let exprty = mkSeqTy cenv.g genCollElemTy
5857+
5858+ // Check the comprehension
58535859 let expr, tpenv = TcExpr cenv exprty env tpenv comp
5854- let expr = mkCoerceIfNeeded cenv.g genEnumTy (tyOfExpr cenv.g expr) expr
5855- (if isArray then mkCallSeqToArray else mkCallSeqToList) cenv.g m genCollElemTy
5856- // We add a call to 'seq ... ' to make sure sequence expression compilation gets applied to the contents of the
5857- // comprehension. But don't do this in FSharp.Core.dll since 'seq' may not yet be defined.
5858- ((if cenv.g.compilingFslib then id else mkCallSeq cenv.g m genCollElemTy)
5859- (mkCoerceExpr(expr, genEnumTy, expr.Range, exprty))), tpenv
5860+
5861+ let expr = mkCoerceIfNeeded cenv.g exprty (tyOfExpr cenv.g expr) expr
5862+
5863+ let expr =
5864+ if cenv.g.compilingFslib then
5865+ expr
5866+ else
5867+ // We add a call to 'seq ... ' to make sure sequence expression compilation gets applied to the contents of the
5868+ // comprehension. But don't do this in FSharp.Core.dll since 'seq' may not yet be defined.
5869+ mkCallSeq cenv.g m genCollElemTy expr
5870+
5871+ let expr = mkCoerceExpr(expr, exprty, expr.Range, overallTy)
5872+
5873+ let expr =
5874+ if isArray then
5875+ mkCallSeqToArray cenv.g m genCollElemTy expr
5876+ else
5877+ mkCallSeqToList cenv.g m genCollElemTy expr
5878+
5879+ expr, tpenv
58605880
58615881 | SynExpr.LetOrUse _ ->
58625882 TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false expr (fun x -> x)
@@ -6069,6 +6089,7 @@ and TcIteratedLambdas cenv isFirst (env: TcEnv) overallTy takenNames tpenv e =
60696089 | e ->
60706090 // Dive into the expression to check for syntax errors and suppress them if they show.
60716091 conditionallySuppressErrorReporting (not isFirst && synExprContainsError e) (fun () ->
6092+ //TcExprFlex cenv true true overallTy env tpenv e)
60726093 TcExpr cenv overallTy env tpenv e)
60736094
60746095
@@ -6279,7 +6300,7 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m =
62796300 let fldsList, tpenv =
62806301 let env = { env with eContextInfo = ContextInfo.RecordFields }
62816302 (tpenv, fldsList) ||> List.mapFold (fun tpenv (fname, fexpr, fty, flex) ->
6282- let fieldExpr, tpenv = TcExprFlex cenv flex fty env tpenv fexpr
6303+ let fieldExpr, tpenv = TcExprFlex cenv flexfalse fty env tpenv fexpr
62836304 (fname, fieldExpr), tpenv)
62846305
62856306 // Add rebindings for unbound field when an "old value" is available
@@ -8068,6 +8089,12 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv
80688089/// Also "ienumerable extraction" is performed on arguments to "for".
80698090and TcSequenceExpression cenv env tpenv comp overallTy m =
80708091
8092+ let genEnumElemTy = NewInferenceType ()
8093+ UnifyTypes cenv env m overallTy (mkSeqTy cenv.g genEnumElemTy)
8094+
8095+ // Allow subsumption at 'yield' if the element type is nominal prior to the analysis of the body of the sequence expression
8096+ let flex = not (isTyparTy cenv.g genEnumElemTy)
8097+
80718098 let mkDelayedExpr (coreExpr:Expr) =
80728099 let m = coreExpr.Range
80738100 let overallTy = tyOfExpr cenv.g coreExpr
@@ -8217,7 +8244,7 @@ and TcSequenceExpression cenv env tpenv comp overallTy m =
82178244 if not isYield then errorR(Error(FSComp.SR.tcSeqResultsUseYield(), m))
82188245 UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy)
82198246
8220- let resultExpr, tpenv =TcExpr cenv genResultTy env tpenv yieldExpr
8247+ let resultExpr, tpenv =TcExprFlex cenv flex true genResultTy env tpenv yieldExpr
82218248 Some(mkCallSeqSingleton cenv.g m genResultTy resultExpr, tpenv )
82228249
82238250 | _ -> None
@@ -8233,9 +8260,6 @@ and TcSequenceExpression cenv env tpenv comp overallTy m =
82338260 let expr, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv comp
82348261 Expr.Sequential(expr, mkSeqEmpty cenv env m genOuterTy, NormalSeq, SuppressSequencePointOnStmtOfSequential, m), tpenv
82358262
8236- let genEnumElemTy = NewInferenceType ()
8237- UnifyTypes cenv env m overallTy (mkSeqTy cenv.g genEnumElemTy)
8238-
82398263 let coreExpr, tpenv = tcSequenceExprBody env overallTy tpenv comp
82408264 let delayedExpr = mkDelayedExpr coreExpr
82418265 delayedExpr, tpenv
@@ -8823,7 +8847,7 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
88238847 if not vref.IsMutable then error (ValNotMutable(env.DisplayEnv, vref, mStmt))
88248848 vty
88258849 // Always allow subsumption on assignment to fields
8826- let e2', tpenv = TcExprFlex cenv true vty2 env tpenv e2
8850+ let e2', tpenv = TcExprFlex cenv truefalse vty2 env tpenv e2
88278851 let vexp =
88288852 if isByrefTy cenv.g vty then
88298853 mkAddrSet mStmt vref e2'
@@ -8889,7 +8913,7 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
88898913 | DelayedSet(e2, mStmt) :: _delayed' ->
88908914 UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
88918915 // Always allow subsumption on assignment to fields
8892- let e2', tpenv = TcExprFlex cenv true exprty env tpenv e2
8916+ let e2', tpenv = TcExprFlex cenv truefalse exprty env tpenv e2
88938917 let expr = BuildILStaticFieldSet mStmt finfo e2'
88948918 expr, tpenv
88958919 | _ ->
@@ -8927,7 +8951,7 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
89278951 UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
89288952 let fieldTy = rfinfo.FieldType
89298953 // Always allow subsumption on assignment to fields
8930- let e2', tpenv = TcExprFlex cenv true fieldTy env tpenv e2
8954+ let e2', tpenv = TcExprFlex cenv truefalse fieldTy env tpenv e2
89318955 let expr = mkStaticRecdFieldSet (rfinfo.RecdFieldRef, rfinfo.TypeInst, e2', mStmt)
89328956 expr, tpenv
89338957 | _ ->
@@ -9067,7 +9091,7 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela
90679091 CheckRecdFieldMutation mItem env.DisplayEnv rfinfo
90689092 UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
90699093 // Always allow subsumption on assignment to fields
9070- let e2', tpenv = TcExprFlex cenv true fieldTy env tpenv e2
9094+ let e2', tpenv = TcExprFlex cenv truefalse fieldTy env tpenv e2
90719095 BuildRecdFieldSet cenv.g mStmt objExpr rfinfo e2', tpenv
90729096
90739097 | _ ->
@@ -9086,7 +9110,7 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela
90869110 | DelayedSet(e2, mStmt) :: _delayed' ->
90879111 UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
90889112 // Always allow subsumption on assignment to fields
9089- let e2', tpenv = TcExprFlex cenv true exprty env tpenv e2
9113+ let e2', tpenv = TcExprFlex cenv truefalse exprty env tpenv e2
90909114 let expr = BuildILFieldSet cenv.g mStmt objExpr finfo e2'
90919115 expr, tpenv
90929116 | _ ->