From 523ccd92f83197a46b79a10dc46a1bfa979d7b3b Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sat, 24 Aug 2024 16:19:47 +0100 Subject: [PATCH 01/27] Use `SynPat` range for let binding errors --- .../Checking/Expressions/CheckExpressions.fs | 489 +++++++++--------- 1 file changed, 243 insertions(+), 246 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 8d6e26140e1..93a0c50a439 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -10810,286 +10810,283 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind = - let g = cenv.g - let envinner = AddDeclaredTypars NoCheckForDuplicateTypars (enclosingDeclaredTypars@declaredTypars) env + let (NormalizedBinding(vis, kind, isInline, isMutable, attrs, xmlDoc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), _, debugPoint)) = bind + let (SynValData(memberFlags = memberFlagsOpt)) = valSynData + let mBinding = pat.Range - match bind with - | NormalizedBinding(vis, kind, isInline, isMutable, attrs, xmlDoc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), mBinding, debugPoint) -> - let (SynValData(memberFlags = memberFlagsOpt)) = valSynData - - let isClassLetBinding = - match declKind, kind with - | ClassLetBinding _, SynBindingKind.Normal -> true - | _ -> false + let isClassLetBinding = + match declKind, kind with + | ClassLetBinding _, SynBindingKind.Normal -> true + | _ -> false - let callerName = - match declKind, kind, pat with - | ExpressionBinding, _, _ -> envinner.eCallerMemberName - | _, _, (SynPat.Named(SynIdent(name,_), _, _, _) | SynPat.As(_, SynPat.Named(SynIdent(name,_), _, _, _), _)) -> - match memberFlagsOpt with - | Some memberFlags -> - match memberFlags.MemberKind with - | SynMemberKind.PropertyGet | SynMemberKind.PropertySet | SynMemberKind.PropertyGetSet -> Some(name.idText.Substring 4) - | SynMemberKind.ClassConstructor -> Some(".ctor") - | SynMemberKind.Constructor -> Some(".ctor") - | _ -> Some(name.idText) + let callerName = + match declKind, kind, pat with + | ExpressionBinding, _, _ -> envinner.eCallerMemberName + | _, _, (SynPat.Named(SynIdent(name,_), _, _, _) | SynPat.As(_, SynPat.Named(SynIdent(name,_), _, _, _), _)) -> + match memberFlagsOpt with + | Some memberFlags -> + match memberFlags.MemberKind with + | SynMemberKind.PropertyGet | SynMemberKind.PropertySet | SynMemberKind.PropertyGetSet -> Some(name.idText.Substring 4) + | SynMemberKind.ClassConstructor -> Some(".ctor") + | SynMemberKind.Constructor -> Some(".ctor") | _ -> Some(name.idText) - | ClassLetBinding false, SynBindingKind.Do, _ -> Some(".ctor") - | ClassLetBinding true, SynBindingKind.Do, _ -> Some(".cctor") - | ModuleOrMemberBinding, SynBindingKind.StandaloneExpression, _ -> Some(".cctor") - | _, _, _ -> envinner.eCallerMemberName - - let envinner = { envinner with eCallerMemberName = callerName } - let attrTgt = declKind.AllowedAttribTargets memberFlagsOpt - - let isFixed, rhsExpr, overallPatTy, overallExprTy = - match rhsExpr with - | SynExpr.Fixed (e, _) -> true, e, NewInferenceType g, overallTy - // { new Foo() } is parsed as a SynExpr.ComputationExpr.(See pars.fsy `objExpr` rule). - // If a SynExpr.ComputationExpr body consists of a single SynExpr.New, and it's not the argument of a computation expression builder type. - // Then we should treat it as a SynExpr.ObjExpr and make it consistent with the other object expressions. e.g. - // { new Foo } -> SynExpr.ObjExpr - // { new Foo() } -> SynExpr.ObjExpr - // { New Foo with ... } -> SynExpr.ObjExpr - | SynExpr.ComputationExpr(false, SynExpr.New(_, targetType, expr, m), _) -> - false, SynExpr.ObjExpr(targetType, Some(expr, None), None, [], [], [], m, rhsExpr.Range), overallTy, overallTy - | e -> false, e, overallTy, overallTy - - // Check the attributes of the binding, parameters or return value - let TcAttrs tgt isRet attrs = - // For all but attributes positioned at the return value, disallow implicitly - // targeting the return value. - let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue - let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs - if attrTgt = enum 0 && not (isNil attrs) then - errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), mBinding)) - attrs - - // Rotate [] from binding to return value - // Also patch the syntactic representation - let retAttribs, valAttribs, valSynData = - let attribs = TcAttrs attrTgt false attrs - let rotRetSynAttrs, rotRetAttribs, valAttribs = - // Do not rotate if some attrs fail to typecheck... - if attribs.Length <> attrs.Length then [], [], attribs - else attribs - |> List.zip attrs - |> List.partition(function | _, Attrib(_, _, _, _, _, Some ts, _) -> ts &&& AttributeTargets.ReturnValue <> enum 0 | _ -> false) - |> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v) - let retAttribs = - match rtyOpt with - | Some (SynBindingReturnInfo(attributes = Attributes retAttrs)) -> - rotRetAttribs @ TcAttrs AttributeTargets.ReturnValue true retAttrs - | None -> rotRetAttribs - let valSynData = - match rotRetSynAttrs with - | [] -> valSynData - | {Range=mHead} :: _ -> - let (SynValData(valMf, SynValInfo(args, SynArgInfo(attrs, opt, retId)), valId)) = valSynData - SynValData(valMf, SynValInfo(args, SynArgInfo({Attributes=rotRetSynAttrs; Range=mHead} :: attrs, opt, retId)), valId) - retAttribs, valAttribs, valSynData - - let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute valAttribs - let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable g valAttribs mBinding - - let argAttribs = - spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter false)) - - // Assert the return type of an active pattern. A [] attribute may be used on a partial active pattern. - let isStructRetTy = HasFSharpAttribute g g.attrib_StructAttribute retAttribs - - let argAndRetAttribs = ArgAndRetAttribs(argAttribs, retAttribs) - - // See RFC FS-1087, the 'Zero' method of a builder may have 'DefaultValueAttribute' indicating it should - // always be used for empty branches of if/then/else and others - let isZeroMethod = - match declKind, pat with - | ModuleOrMemberBinding, SynPat.Named(SynIdent(id,_), _, _, _) when id.idText = "Zero" -> - match memberFlagsOpt with - | Some memberFlags -> - match memberFlags.MemberKind with - | SynMemberKind.Member -> true - | _ -> false - | _ -> false - | _ -> false - - if HasFSharpAttribute g g.attrib_DefaultValueAttribute valAttribs && not isZeroMethod then - errorR(Error(FSComp.SR.tcDefaultValueAttributeRequiresVal(), mBinding)) - - let isThreadStatic = isThreadOrContextStatic g valAttribs - if isThreadStatic then errorR(DeprecatedThreadStaticBindingWarning mBinding) - - if isVolatile then - match declKind with - | ClassLetBinding _ -> () - | _ -> errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), mBinding)) - - if (not isMutable || isThreadStatic) then - errorR(Error(FSComp.SR.tcVolatileFieldsMustBeMutable(), mBinding)) + | _ -> Some(name.idText) + | ClassLetBinding false, SynBindingKind.Do, _ -> Some(".ctor") + | ClassLetBinding true, SynBindingKind.Do, _ -> Some(".cctor") + | ModuleOrMemberBinding, SynBindingKind.StandaloneExpression, _ -> Some(".cctor") + | _, _, _ -> envinner.eCallerMemberName - if isFixed && (declKind <> ExpressionBinding || isInline || isMutable) then - errorR(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) - - if (not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false)) && - HasFSharpAttributeOpt g g.attrib_DllImportAttribute valAttribs then - errorR(Error(FSComp.SR.tcDllImportNotAllowed(), mBinding)) + let envinner = { envinner with eCallerMemberName = callerName } + let attrTgt = declKind.AllowedAttribTargets memberFlagsOpt - if Option.isNone memberFlagsOpt && HasFSharpAttribute g g.attrib_ConditionalAttribute valAttribs then - errorR(Error(FSComp.SR.tcConditionalAttributeRequiresMembers(), mBinding)) + let isFixed, rhsExpr, overallPatTy, overallExprTy = + match rhsExpr with + | SynExpr.Fixed (e, _) -> true, e, NewInferenceType g, overallTy + // { new Foo() } is parsed as a SynExpr.ComputationExpr.(See pars.fsy `objExpr` rule). + // If a SynExpr.ComputationExpr body consists of a single SynExpr.New, and it's not the argument of a computation expression builder type. + // Then we should treat it as a SynExpr.ObjExpr and make it consistent with the other object expressions. e.g. + // { new Foo } -> SynExpr.ObjExpr + // { new Foo() } -> SynExpr.ObjExpr + // { New Foo with ... } -> SynExpr.ObjExpr + | SynExpr.ComputationExpr(false, SynExpr.New(_, targetType, expr, m), _) -> + false, SynExpr.ObjExpr(targetType, Some(expr, None), None, [], [], [], m, rhsExpr.Range), overallTy, overallTy + | e -> false, e, overallTy, overallTy + + // Check the attributes of the binding, parameters or return value + let TcAttrs tgt isRet attrs = + // For all but attributes positioned at the return value, disallow implicitly + // targeting the return value. + let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue + let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs + if attrTgt = enum 0 && not (isNil attrs) then + errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), mBinding)) + attrs + + // Rotate [] from binding to return value + // Also patch the syntactic representation + let retAttribs, valAttribs, valSynData = + let attribs = TcAttrs attrTgt false attrs + let rotRetSynAttrs, rotRetAttribs, valAttribs = + // Do not rotate if some attrs fail to typecheck... + if attribs.Length <> attrs.Length then [], [], attribs + else attribs + |> List.zip attrs + |> List.partition(function | _, Attrib(_, _, _, _, _, Some ts, _) -> ts &&& AttributeTargets.ReturnValue <> enum 0 | _ -> false) + |> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v) + let retAttribs = + match rtyOpt with + | Some (SynBindingReturnInfo(attributes = Attributes retAttrs)) -> + rotRetAttribs @ TcAttrs AttributeTargets.ReturnValue true retAttrs + | None -> rotRetAttribs + let valSynData = + match rotRetSynAttrs with + | [] -> valSynData + | {Range=mHead} :: _ -> + let (SynValData(valMf, SynValInfo(args, SynArgInfo(attrs, opt, retId)), valId)) = valSynData + SynValData(valMf, SynValInfo(args, SynArgInfo({Attributes=rotRetSynAttrs; Range=mHead} :: attrs, opt, retId)), valId) + retAttribs, valAttribs, valSynData + + let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute valAttribs + let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable g valAttribs mBinding + + let argAttribs = + spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter false)) + + // Assert the return type of an active pattern. A [] attribute may be used on a partial active pattern. + let isStructRetTy = HasFSharpAttribute g g.attrib_StructAttribute retAttribs + + let argAndRetAttribs = ArgAndRetAttribs(argAttribs, retAttribs) + + // See RFC FS-1087, the 'Zero' method of a builder may have 'DefaultValueAttribute' indicating it should + // always be used for empty branches of if/then/else and others + let isZeroMethod = + match declKind, pat with + | ModuleOrMemberBinding, SynPat.Named(SynIdent(id,_), _, _, _) when id.idText = "Zero" -> + match memberFlagsOpt with + | Some memberFlags -> + match memberFlags.MemberKind with + | SynMemberKind.Member -> true + | _ -> false + | _ -> false + | _ -> false - if HasFSharpAttribute g g.attrib_EntryPointAttribute valAttribs then - if Option.isSome memberFlagsOpt then - errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(), mBinding)) - else - let entryPointTy = mkFunTy g (mkArrayType g g.string_ty) g.int_ty - UnifyTypes cenv env mBinding overallPatTy entryPointTy + if HasFSharpAttribute g g.attrib_DefaultValueAttribute valAttribs && not isZeroMethod then + errorR(Error(FSComp.SR.tcDefaultValueAttributeRequiresVal(), mBinding)) - if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(), mBinding)) + let isThreadStatic = isThreadOrContextStatic g valAttribs + if isThreadStatic then errorR(DeprecatedThreadStaticBindingWarning mBinding) - if isMutable && not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(), mBinding)) + if isVolatile then + match declKind with + | ClassLetBinding _ -> () + | _ -> errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), mBinding)) - let explicitTyparInfo = if isMutable then dontInferTypars else explicitTyparInfo + if (not isMutable || isThreadStatic) then + errorR(Error(FSComp.SR.tcVolatileFieldsMustBeMutable(), mBinding)) - if isMutable && not (isNil spatsL) then errorR(Error(FSComp.SR.tcMutableValuesSyntax(), mBinding)) + if isFixed && (declKind <> ExpressionBinding || isInline || isMutable) then + errorR(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) - let isInline = - if isInline && isNil spatsL && isNil declaredTypars then - errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(), mBinding)) - false - else - isInline + if (not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false)) && + HasFSharpAttributeOpt g g.attrib_DllImportAttribute valAttribs then + errorR(Error(FSComp.SR.tcDllImportNotAllowed(), mBinding)) - let isCompGen = false + if Option.isNone memberFlagsOpt && HasFSharpAttribute g g.attrib_ConditionalAttribute valAttribs then + errorR(Error(FSComp.SR.tcConditionalAttributeRequiresMembers(), mBinding)) - // Use the syntactic arity if we're defining a function - let (SynValData(valInfo = valSynInfo)) = valSynData - let prelimValReprInfo = TranslateSynValInfo cenv mBinding (TcAttributes cenv env) valSynInfo + if HasFSharpAttribute g g.attrib_EntryPointAttribute valAttribs then + if Option.isSome memberFlagsOpt then + errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(), mBinding)) + else + let entryPointTy = mkFunTy g (mkArrayType g g.string_ty) g.int_ty + UnifyTypes cenv env mBinding overallPatTy entryPointTy - // Check the pattern of the l.h.s. of the binding - let tcPatPhase2, (TcPatLinearEnv (tpenv, nameToPrelimValSchemeMap, _)) = - cenv.TcPat AllIdsOK cenv envinner (Some prelimValReprInfo) (TcPatValFlags (inlineFlag, explicitTyparInfo, argAndRetAttribs, isMutable, vis, isCompGen)) (TcPatLinearEnv (tpenv, NameMap.empty, Set.empty)) overallPatTy pat + if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(), mBinding)) - // Add active pattern result names to the environment - let apinfoOpt = - match NameMap.range nameToPrelimValSchemeMap with - | [PrelimVal1(id, _, ty, _, _, _, _, _, _, _, _) ] -> - match ActivePatternInfoOfValName id.idText id.idRange with - | Some apinfo -> Some (apinfo, ty, id.idRange) - | None -> None - | _ -> None + if isMutable && not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(), mBinding)) - // Add active pattern result names to the environment - let envinner = - match apinfoOpt with - | Some (apinfo, apOverallTy, m) -> - if Option.isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then - error(Error(FSComp.SR.tcInvalidActivePatternName(), mBinding)) + let explicitTyparInfo = if isMutable then dontInferTypars else explicitTyparInfo - apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> - let item = Item.ActivePatternResult(apinfo, apOverallTy, i, tagRange) - CallNameResolutionSink cenv.tcSink (tagRange, env.NameEnv, item, emptyTyparInst, ItemOccurrence.Binding, env.AccessRights)) + if isMutable && not (isNil spatsL) then errorR(Error(FSComp.SR.tcMutableValuesSyntax(), mBinding)) - { envinner with eNameResEnv = AddActivePatternResultTagsToNameEnv apinfo envinner.eNameResEnv apOverallTy m } - | None -> - envinner + let isInline = + if isInline && isNil spatsL && isNil declaredTypars then + errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(), mBinding)) + false + else + isInline - // If binding a ctor then set the ugly counter that permits us to write ctor expressions on the r.h.s. - let isCtor = (match memberFlagsOpt with Some memberFlags -> memberFlags.MemberKind = SynMemberKind.Constructor | _ -> false) + let isCompGen = false - // Now check the right of the binding. - // - // At each module binding, dive into the expression to check for syntax errors and suppress them if they show. - // Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas - let rhsExprChecked, tpenv = - let atTopNonLambdaDefn = - declKind.IsModuleOrMemberOrExtensionBinding && - (match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) && - synExprContainsError rhsExpr - - conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () -> - - // Save the arginfos away to match them up in the lambda - let (PrelimValReprInfo(argInfos, _)) = prelimValReprInfo - - // The right-hand-side is control flow (has an implicit debug point) in any situation where we - // haven't extended the debug point to include the 'let', that is, there is a debug point noted - // at the binding. - // - // This includes - // let _ = expr - // let () = expr - // which are transformed to sequential expressions in TcLetBinding - // - let rhsIsControlFlow = - match pat with - | SynPat.Wild _ - | SynPat.Const (SynConst.Unit, _) - | SynPat.Paren (SynPat.Const (SynConst.Unit, _), _) -> true - | _ -> - match debugPoint with - | DebugPointAtBinding.Yes _ -> false - | _ -> true + // Use the syntactic arity if we're defining a function + let (SynValData(valInfo = valSynInfo)) = valSynData + let prelimValReprInfo = TranslateSynValInfo cenv mBinding (TcAttributes cenv env) valSynInfo - let envinner = { envinner with eLambdaArgInfos = argInfos; eIsControlFlow = rhsIsControlFlow } + // Check the pattern of the l.h.s. of the binding + let tcPatPhase2, (TcPatLinearEnv (tpenv, nameToPrelimValSchemeMap, _)) = + cenv.TcPat AllIdsOK cenv envinner (Some prelimValReprInfo) (TcPatValFlags (inlineFlag, explicitTyparInfo, argAndRetAttribs, isMutable, vis, isCompGen)) (TcPatLinearEnv (tpenv, NameMap.empty, Set.empty)) overallPatTy pat - if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv (MustEqual overallExprTy) envinner tpenv rhsExpr - else TcExprThatCantBeCtorBody cenv (MustConvertTo (false, overallExprTy)) envinner tpenv rhsExpr) + // Add active pattern result names to the environment + let apinfoOpt = + match NameMap.range nameToPrelimValSchemeMap with + | [PrelimVal1(id, _, ty, _, _, _, _, _, _, _, _) ] -> + match ActivePatternInfoOfValName id.idText id.idRange with + | Some apinfo -> Some (apinfo, ty, id.idRange) + | None -> None + | _ -> None - if kind = SynBindingKind.StandaloneExpression && not cenv.isScript then - UnifyUnitType cenv env mBinding overallPatTy rhsExprChecked |> ignore + // Add active pattern result names to the environment + let envinner = + match apinfoOpt with + | Some (apinfo, apOverallTy, m) -> + if Option.isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then + error(Error(FSComp.SR.tcInvalidActivePatternName(), mBinding)) - // Fix up the r.h.s. expression for 'fixed' - let rhsExprChecked = - if isFixed then TcAndBuildFixedExpr cenv env (overallPatTy, rhsExprChecked, overallExprTy, mBinding) - else rhsExprChecked + apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> + let item = Item.ActivePatternResult(apinfo, apOverallTy, i, tagRange) + CallNameResolutionSink cenv.tcSink (tagRange, env.NameEnv, item, emptyTyparInst, ItemOccurrence.Binding, env.AccessRights)) - match apinfoOpt with - | Some (apinfo, apOverallTy, _) -> - let activePatResTys = NewInferenceTypes g apinfo.ActiveTags - let _, apReturnTy = stripFunTy g apOverallTy - let apRetTy = - if apinfo.IsTotal then - if isStructRetTy then errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) - ActivePatternReturnKind.RefTypeWrapper - else - if isStructRetTy || isValueOptionTy cenv.g apReturnTy then ActivePatternReturnKind.StructTypeWrapper - elif isBoolTy cenv.g apReturnTy then ActivePatternReturnKind.Boolean - else ActivePatternReturnKind.RefTypeWrapper + { envinner with eNameResEnv = AddActivePatternResultTagsToNameEnv apinfo envinner.eNameResEnv apOverallTy m } + | None -> + envinner - match apRetTy with - | ActivePatternReturnKind.Boolean -> - checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding - | ActivePatternReturnKind.StructTypeWrapper when not isStructRetTy -> - checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding - | ActivePatternReturnKind.StructTypeWrapper -> - checkLanguageFeatureError g.langVersion LanguageFeature.StructActivePattern mBinding - | ActivePatternReturnKind.RefTypeWrapper -> () + // If binding a ctor then set the ugly counter that permits us to write ctor expressions on the r.h.s. + let isCtor = (match memberFlagsOpt with Some memberFlags -> memberFlags.MemberKind = SynMemberKind.Constructor | _ -> false) - UnifyTypes cenv env mBinding (apinfo.ResultType g rhsExpr.Range activePatResTys apRetTy) apReturnTy + // Now check the right of the binding. + // + // At each module binding, dive into the expression to check for syntax errors and suppress them if they show. + // Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas + let rhsExprChecked, tpenv = + let atTopNonLambdaDefn = + declKind.IsModuleOrMemberOrExtensionBinding && + (match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) && + synExprContainsError rhsExpr + + conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () -> + + // Save the arginfos away to match them up in the lambda + let (PrelimValReprInfo(argInfos, _)) = prelimValReprInfo + + // The right-hand-side is control flow (has an implicit debug point) in any situation where we + // haven't extended the debug point to include the 'let', that is, there is a debug point noted + // at the binding. + // + // This includes + // let _ = expr + // let () = expr + // which are transformed to sequential expressions in TcLetBinding + // + let rhsIsControlFlow = + match pat with + | SynPat.Wild _ + | SynPat.Const (SynConst.Unit, _) + | SynPat.Paren (SynPat.Const (SynConst.Unit, _), _) -> true + | _ -> + match debugPoint with + | DebugPointAtBinding.Yes _ -> false + | _ -> true + + let envinner = { envinner with eLambdaArgInfos = argInfos; eIsControlFlow = rhsIsControlFlow } + + if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv (MustEqual overallExprTy) envinner tpenv rhsExpr + else TcExprThatCantBeCtorBody cenv (MustConvertTo (false, overallExprTy)) envinner tpenv rhsExpr) + + if kind = SynBindingKind.StandaloneExpression && not cenv.isScript then + UnifyUnitType cenv env mBinding overallPatTy rhsExprChecked |> ignore + + // Fix up the r.h.s. expression for 'fixed' + let rhsExprChecked = + if isFixed then TcAndBuildFixedExpr cenv env (overallPatTy, rhsExprChecked, overallExprTy, mBinding) + else rhsExprChecked + + match apinfoOpt with + | Some (apinfo, apOverallTy, _) -> + let activePatResTys = NewInferenceTypes g apinfo.ActiveTags + let _, apReturnTy = stripFunTy g apOverallTy + let apRetTy = + if apinfo.IsTotal then + if isStructRetTy then errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) + ActivePatternReturnKind.RefTypeWrapper + else + if isStructRetTy || isValueOptionTy cenv.g apReturnTy then ActivePatternReturnKind.StructTypeWrapper + elif isBoolTy cenv.g apReturnTy then ActivePatternReturnKind.Boolean + else ActivePatternReturnKind.RefTypeWrapper - | None -> - if isStructRetTy then - errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) + match apRetTy with + | ActivePatternReturnKind.Boolean -> + checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding + | ActivePatternReturnKind.StructTypeWrapper when not isStructRetTy -> + checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding + | ActivePatternReturnKind.StructTypeWrapper -> + checkLanguageFeatureError g.langVersion LanguageFeature.StructActivePattern mBinding + | ActivePatternReturnKind.RefTypeWrapper -> () - // Check other attributes - let hasLiteralAttr, literalValue = TcLiteral cenv overallExprTy env tpenv (valAttribs, rhsExpr) + UnifyTypes cenv env mBinding (apinfo.ResultType g rhsExpr.Range activePatResTys apRetTy) apReturnTy - if hasLiteralAttr then - if isThreadStatic then - errorR(Error(FSComp.SR.tcIllegalAttributesForLiteral(), mBinding)) - if isMutable then - errorR(Error(FSComp.SR.tcLiteralCannotBeMutable(), mBinding)) - if isInline then - errorR(Error(FSComp.SR.tcLiteralCannotBeInline(), mBinding)) - if not (isNil declaredTypars) then - errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding)) + | None -> + if isStructRetTy then + errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) - if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty then - TcAttributeTargetsOnLetBindings { cenv with tcSink = TcResultsSink.NoSink } env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty) isClassLetBinding + // Check other attributes + let hasLiteralAttr, literalValue = TcLiteral cenv overallExprTy env tpenv (valAttribs, rhsExpr) - CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv + if hasLiteralAttr then + if isThreadStatic then + errorR(Error(FSComp.SR.tcIllegalAttributesForLiteral(), mBinding)) + if isMutable then + errorR(Error(FSComp.SR.tcLiteralCannotBeMutable(), mBinding)) + if isInline then + errorR(Error(FSComp.SR.tcLiteralCannotBeInline(), mBinding)) + if not (isNil declaredTypars) then + errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding)) + + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty then + TcAttributeTargetsOnLetBindings { cenv with tcSink = TcResultsSink.NoSink } env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty) isClassLetBinding + + CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv // Note: // - Let bound values can only have attributes that uses AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue From 619b4f630375b8abbf55e8bdfa2d143d996fef55 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sat, 24 Aug 2024 17:33:06 +0100 Subject: [PATCH 02/27] update error range for tcAttributesAreNotPermittedOnLetBindings --- src/Compiler/Checking/Expressions/CheckExpressions.fs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 93a0c50a439..4dc4ee52993 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -10860,8 +10860,10 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt // targeting the return value. let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs + let attrs: Attrib list = attrs if attrTgt = enum 0 && not (isNil attrs) then - errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), mBinding)) + for attr in attrs do + errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), attr.Range)) attrs // Rotate [] from binding to return value From 912ab6d582eb85a9373fc413717148e79a04106c Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sat, 24 Aug 2024 20:19:39 +0100 Subject: [PATCH 03/27] Include typars --- .../Checking/Expressions/CheckExpressions.fs | 13 ++++++++++--- .../CustomAttributes/Basic/Basic.fs | 7 +++++-- .../Basic/E_AttributeApplication06.fs | 4 +++- .../TypeFunctions/E_NoTypeFuncsInTypes.fs | 1 + .../LetBindings/TypeFunctions/TypeFunctions.fs | 3 ++- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 4dc4ee52993..a3d5194069f 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -2274,7 +2274,7 @@ module GeneralizationHelpers = // to C<_> occurs then generate C for a fresh type inference variable ?ty. //------------------------------------------------------------------------- - let CheckDeclaredTyparsPermitted (memFlagsOpt: SynMemberFlags option, declaredTypars, m) = + let CheckDeclaredTyparsPermitted (memFlagsOpt: SynMemberFlags option, declaredTypars: Typars, m) = match memFlagsOpt with | None -> () | Some memberFlags -> @@ -2284,7 +2284,13 @@ module GeneralizationHelpers = | SynMemberKind.PropertySet | SynMemberKind.PropertyGetSet -> if not (isNil declaredTypars) then - errorR(Error(FSComp.SR.tcPropertyRequiresExplicitTypeParameters(), m)) + let declaredTyparsRange = + declaredTypars + |> List.map(fun typar -> typar.Range) + + let m = declaredTyparsRange |> List.fold (fun r a -> unionRanges r a) range.Zero + + errorR(Error(FSComp.SR.tcPropertyRequiresExplicitTypeParameters(), m)) | SynMemberKind.Constructor -> if not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcConstructorCannotHaveTypeParameters(), m)) @@ -12706,8 +12712,9 @@ let TcAndPublishValSpec (cenv: cenv, env, containerInfo: ContainerInfo, declKind let (SynValSig (attributes=Attributes synAttrs; explicitTypeParams=explicitTypeParams; isInline=isInline; isMutable=mutableFlag; xmlDoc=xmlDoc; accessibility=vis; synExpr=literalExprOpt; range=m)) = synValSig let (ValTyparDecls (synTypars, _, synCanInferTypars)) = explicitTypeParams + let declaredTypars = TcTyparDecls cenv env synTypars - GeneralizationHelpers.CheckDeclaredTyparsPermitted(memFlagsOpt, synTypars, m) + GeneralizationHelpers.CheckDeclaredTyparsPermitted(memFlagsOpt, declaredTypars, m) let canInferTypars = GeneralizationHelpers.ComputeCanInferExtraGeneralizableTypars (containerInfo.ParentRef, synCanInferTypars, memFlagsOpt) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs index 52dde397f29..2e40461c0fd 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/Basic.fs @@ -92,8 +92,11 @@ module CustomAttributes_Basic = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 824, Line 8, Col 5, Line 8, Col 20, "Attributes are not permitted on 'let' bindings in expressions") - (Warning 20, Line 8, Col 1, Line 8, Col 41, "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + (Error 824, Line 8, Col 13, Line 8, Col 14, "Attributes are not permitted on 'let' bindings in expressions") + (Warning 20, Line 8, Col 28, Line 8, Col 41, "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + (Error 824, Line 10, Col 14, Line 10, Col 15, "Attributes are not permitted on 'let' bindings in expressions") + (Error 824, Line 10, Col 26, Line 10, Col 27, "Attributes are not permitted on 'let' bindings in expressions") + (Warning 20, Line 8, Col 1, Line 10, Col 60, "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") ] // SOURCE=E_AttributeApplication07.fs # E_AttributeApplication07.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_AttributeApplication06.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_AttributeApplication06.fs index 5727ec89087..745e5e8b3fa 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_AttributeApplication06.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/Basic/E_AttributeApplication06.fs @@ -5,5 +5,7 @@ [] type A() = inherit System.Attribute() -let foo ( [] x ) = 1 in foo 2 + foo 3 +let foo ( [] x ) = 1 in foo 2 + foo 3 + +let foo2 ( [] x ) ( [] y ) = 1 in foo2 2 3 + foo2 4 5 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/E_NoTypeFuncsInTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/E_NoTypeFuncsInTypes.fs index 43057b3833a..bb08f0663a9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/E_NoTypeFuncsInTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/E_NoTypeFuncsInTypes.fs @@ -4,3 +4,4 @@ type Foo() = member this.TypeFunc<'a> = typeof<'a>.Name + member this.TypeFunc2<'a, 'b> = typeof<'a>.Name diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/TypeFunctions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/TypeFunctions.fs index 66e2276a0be..582db53d54c 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/TypeFunctions.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/TypeFunctions/TypeFunctions.fs @@ -55,7 +55,8 @@ module LetBindings_TypeFunctions = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 671, Line 6, Col 12, Line 6, Col 29, "A property cannot have explicit type parameters. Consider using a method instead.") + (Error 671, Line 6, Col 26, Line 6, Col 28, "A property cannot have explicit type parameters. Consider using a method instead."); + (Error 671, Line 7, Col 27, Line 7, Col 33, "A property cannot have explicit type parameters. Consider using a method instead.") ] //This type requires a definition From 4e4f496319f031b3352af21748c83afa47bd499d Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sun, 25 Aug 2024 18:39:42 +0100 Subject: [PATCH 04/27] AP better error message --- src/Compiler/Checking/Expressions/CheckExpressions.fs | 2 +- src/Compiler/FSComp.txt | 2 +- src/Compiler/SyntaxTree/PrettyNaming.fs | 7 +++++++ src/Compiler/SyntaxTree/PrettyNaming.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.de.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.es.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.it.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- .../MethodsAndProperties/MethodsAndProperties.fs | 7 +++++-- 18 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index a3d5194069f..f71c1047ada 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -10990,7 +10990,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt match apinfoOpt with | Some (apinfo, apOverallTy, m) -> if Option.isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then - error(Error(FSComp.SR.tcInvalidActivePatternName(), mBinding)) + errorR(Error(FSComp.SR.tcInvalidActivePatternName(apinfo.LogicalName), m)) apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> let item = Item.ActivePatternResult(apinfo, apOverallTy, i, tagRange) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 4776f65c28e..7cc526b603b 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -679,7 +679,7 @@ tcUnnamedArgumentsDoNotFormPrefix,"The unnamed arguments do not form a prefix of 824,tcAttributesAreNotPermittedOnLetBindings,"Attributes are not permitted on 'let' bindings in expressions" 825,tcDefaultValueAttributeRequiresVal,"The 'DefaultValue' attribute may only be used on 'val' declarations" 826,tcConditionalAttributeRequiresMembers,"The 'ConditionalAttribute' attribute may only be used on members" -827,tcInvalidActivePatternName,"This is not a valid name for an active pattern" +827,tcInvalidActivePatternName,"'%s' is not a valid method name. Active patterns may only be defined as let-bound module or class functions." 828,tcEntryPointAttributeRequiresFunctionInModule,"The 'EntryPointAttribute' attribute may only be used on function definitions in modules" 829,tcMutableValuesCannotBeInline,"Mutable values cannot be marked 'inline'" 830,tcMutableValuesMayNotHaveGenericParameters,"Mutable values cannot have generic parameters" diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index 5194a859977..4d379fb7b54 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -963,6 +963,13 @@ type ActivePatternInfo = member x.ActiveTagsWithRanges = let (APInfo(_, tags, _)) = x in tags + member x.LogicalName = + let (APInfo(_, tags, _)) = x + tags + |> List.map fst + |> String.concat "|" + |> fun s -> "(|" + s + "|)" + member x.Range = let (APInfo(_, _, m)) = x in m let ActivePatternInfoOfValName nm (m: range) = diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fsi b/src/Compiler/SyntaxTree/PrettyNaming.fsi index 6e2db976eb2..9843656e46f 100644 --- a/src/Compiler/SyntaxTree/PrettyNaming.fsi +++ b/src/Compiler/SyntaxTree/PrettyNaming.fsi @@ -228,6 +228,7 @@ type internal ActivePatternInfo = member ActiveTags: string list member ActiveTagsWithRanges: (string * range) list + member LogicalName: string member IsTotal: bool member Range: range diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index f48c78209bf..c18471a2c1e 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Toto není platný název aktivního vzoru. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 7420a6afdc4..e504a7c458d 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Dies ist kein gültiger Name für ein aktives Muster. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 845bd6a8ca8..a7dac2c523a 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Este no es un nombre válido para un patrón activo. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 85ce7e5e43c..29fdbb88335 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Nom non valide pour un modèle actif + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 887bd6e57cd..6bdc5a31f99 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Questo non è un nome valido per un criterio attivo + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 1d5a0740a1e..12d9f5f063a 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - アクティブ パターンの有効な名前ではありません + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index e8eebabddf5..5dbec5ef358 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - 활성 패턴에 대한 올바른 이름이 아닙니다. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index ca1b6a407b3..9bdd39d3e2d 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - To nie jest prawidłowa nazwa aktywnego wzorca + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index f927f204fae..e65b25d2eb0 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Este não é um nome válido para um padrão ativo + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 5c3701a06de..211888c720a 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Недопустимое имя для активного шаблона + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 9b13279b1eb..a3ba01ee368 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - Etkin desen için bu geçerli bir ad değil + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index c583e45c53d..91eeb80944e 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - 对于活动模式来说,这不是有效的名称 + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 17fc8934c3c..0a7ccf8f3b0 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -4943,8 +4943,8 @@ - This is not a valid name for an active pattern - 這不是現用模式的有效名稱 + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs index e295ca5ad5f..8128b8ea392 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs @@ -70,7 +70,7 @@ module MemberDefinitions_MethodsAndProperties = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 827, Line 10, Col 19, Line 10, Col 37, "This is not a valid name for an active pattern") + (Error 827, Line 10, Col 20, Line 10, Col 29, "'(|Foo|Bar|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions.") (Error 39, Line 21, Col 10, Line 21, Col 13, "The type 'FaaBor' does not define the field, constructor or member 'Foo'.") ] @@ -81,7 +81,10 @@ module MemberDefinitions_MethodsAndProperties = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 827, Line 6, Col 12, Line 6, Col 27, "This is not a valid name for an active pattern") + (Error 827, Line 6, Col 15, Line 6, Col 24, "'(|Foo|Bar|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3868, Line 16, Col 11, Line 16, Col 14, "This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Foo e1 pat'."); + (Error 3868, Line 17, Col 11, Line 17, Col 14, "This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Bar e1 pat'."); + (Warning 25, Line 15, Col 15, Line 15, Col 16, "Incomplete pattern matches on this expression.") ] // SOURCE=E_DuplicateProperty01.fs SCFLAGS="--test:ErrorRanges" # E_DuplicateProperty01.fs From db78b2ea8b615d726280d44e574d06a30995800f Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sun, 25 Aug 2024 18:55:00 +0100 Subject: [PATCH 05/27] fantomas --- src/Compiler/SyntaxTree/PrettyNaming.fs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index 4d379fb7b54..56ce16a0a1f 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -965,10 +965,7 @@ type ActivePatternInfo = member x.LogicalName = let (APInfo(_, tags, _)) = x - tags - |> List.map fst - |> String.concat "|" - |> fun s -> "(|" + s + "|)" + tags |> List.map fst |> String.concat "|" |> (fun s -> "(|" + s + "|)") member x.Range = let (APInfo(_, _, m)) = x in m From 730e9804183b7af210046ffca39fb6cff5a56c27 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sun, 25 Aug 2024 20:21:59 +0100 Subject: [PATCH 06/27] Fix tests --- src/Compiler/SyntaxTree/PrettyNaming.fs | 13 +++- .../EntryPoint/EntryPoint.fs | 2 +- .../PatternMatching/Named/Named.fs | 73 +++++++++++++------ .../Types/StructTypes/StructActivePatterns.fs | 4 +- .../ErrorMessages/InvalidLiteralTests.fs | 2 +- 5 files changed, 66 insertions(+), 28 deletions(-) diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index 56ce16a0a1f..b27efe1f8bb 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -963,9 +963,18 @@ type ActivePatternInfo = member x.ActiveTagsWithRanges = let (APInfo(_, tags, _)) = x in tags + // FIXME member x.LogicalName = - let (APInfo(_, tags, _)) = x - tags |> List.map fst |> String.concat "|" |> (fun s -> "(|" + s + "|)") + let (APInfo(isTotal, tags, _)) = x + tags + |> List.map fst + |> String.concat "|" + |> (fun s -> + if isTotal then + "(|" + s + "|)" + else + "(|" + s + "|_|)" + ) member x.Range = let (APInfo(_, _, m)) = x in m diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/EntryPoint/EntryPoint.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/EntryPoint/EntryPoint.fs index 509fe8c9adb..ce51bcf6c14 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/EntryPoint/EntryPoint.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/EntryPoint/EntryPoint.fs @@ -51,7 +51,7 @@ module EntryPoint = |> compile |> shouldFail |> withDiagnostics [ - (Error 433, Line 18, Col 5, Line 19, Col 19, "A function labeled with the 'EntryPointAttribute' attribute must be the last declaration in the last file in the compilation sequence.") + (Error 433, Line 19, Col 9, Line 19, Col 14, "A function labeled with the 'EntryPointAttribute' attribute must be the last declaration in the last file in the compilation sequence.") ] // SOURCE="E_twofiles_002b.fs E_twofiles_002a.fs" SCFLAGS="--test:ErrorRanges" # E_twofiles_002b/a diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs index 58f5a809e27..c3ed95f5887 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs @@ -223,7 +223,7 @@ module Named = |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 1, Line 5, Col 9, Line 5, Col 30, "This expression was expected to have type + |> withSingleDiagnostic (Error 1, Line 5, Col 10, Line 5, Col 19, "This expression was expected to have type 'Choice<'a,'b>' but here has type 'string' ") @@ -236,7 +236,14 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 827, Line 4, Col 9, Line 4, Col 34, "This is not a valid name for an active pattern") + |> withDiagnostics [ + (Error 827, Line 4, Col 10, Line 4, Col 23, "'(|Foo2|Bar2|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 1, Line 4, Col 10, Line 4, Col 23, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + ] + // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) [] @@ -246,8 +253,14 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 827, Line 4, Col 10, Line 4, Col 43, "This is not a valid name for an active pattern") - + |> withDiagnostics [ + (Error 827, Line 4, Col 11, Line 4, Col 32, "'(|Foo2b|Bar2b|Baz2b|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 1, Line 4, Col 11, Line 4, Col 32, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + ] + // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) [] let ``Named - E_Error_LetRec04_fs - --test:ErrorRanges`` compilation = @@ -256,7 +269,7 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 1, Line 4, Col 9, Line 4, Col 29, "This expression was expected to have type + |> withSingleDiagnostic (Error 1, Line 4, Col 10, Line 4, Col 18, "This expression was expected to have type ''a option' but here has type 'string' ") @@ -269,7 +282,7 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 1, Line 4, Col 5, Line 4, Col 18, "This expression was expected to have type + |> withSingleDiagnostic (Error 1, Line 4, Col 6, Line 4, Col 15, "This expression was expected to have type 'Choice<'a,'b>' but here has type 'string' ") @@ -282,7 +295,13 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 827, Line 4, Col 5, Line 4, Col 22, "This is not a valid name for an active pattern") + |> withDiagnostics [ + (Error 827, Line 4, Col 6, Line 4, Col 19, "'(|Foo2|Bar2|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 1, Line 4, Col 6, Line 4, Col 19, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + ] // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) [] @@ -292,7 +311,13 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 827, Line 4, Col 5, Line 4, Col 30, "This is not a valid name for an active pattern") + |> withDiagnostics [ + (Error 827, Line 4, Col 6, Line 4, Col 27, "'(|Foo2b|Bar2b|Baz2b|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 1, Line 4, Col 6, Line 4, Col 27, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + ] // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) [] @@ -302,7 +327,7 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 1, Line 4, Col 5, Line 4, Col 17, "This expression was expected to have type + |> withSingleDiagnostic (Error 1, Line 4, Col 6, Line 4, Col 14, "This expression was expected to have type ''a option' but here has type 'string' ") @@ -315,7 +340,7 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 1, Line 4, Col 5, Line 4, Col 26, "This expression was expected to have type + |> withSingleDiagnostic (Error 1, Line 4, Col 6, Line 4, Col 15, "This expression was expected to have type 'Choice<'a,'b>' but here has type 'string' ") @@ -328,7 +353,13 @@ but here has type |> withOptions ["--test:ErrorRanges"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 827, Line 4, Col 5, Line 4, Col 31, "This is not a valid name for an active pattern") + |> withDiagnostics [ + (Error 827, Line 4, Col 6, Line 4, Col 19, "'(|Foo2|Bar2|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 1, Line 4, Col 6, Line 4, Col 19, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + ] // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) [] @@ -339,7 +370,11 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 4, Col 5, Line 4, Col 38, "This is not a valid name for an active pattern") + (Error 827, Line 4, Col 6, Line 4, Col 27, "'(|Foo2b|Bar2b|Baz2b|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 1, Line 4, Col 6, Line 4, Col 27, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") ] // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) @@ -351,7 +386,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 1, Line 4, Col 5, Line 4, Col 25, "This expression was expected to have type + (Error 1, Line 4, Col 6, Line 4, Col 14, "This expression was expected to have type ''a option' but here has type 'string' ") @@ -377,15 +412,9 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 8, Col 5, Line 8, Col 64, "This is not a valid name for an active pattern") - (Error 39, Line 20, Col 7, Line 20, Col 15, "The pattern discriminator 'Sentence' is not defined.") - (Error 72, Line 20, Col 25, Line 20, Col 37, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.") - (Error 39, Line 21, Col 7, Line 21, Col 11, "The pattern discriminator 'Word' is not defined.") - (Error 72, Line 21, Col 20, Line 21, Col 31, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.") - (Warning 49, Line 22, Col 7, Line 22, Col 17, "Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.") - (Error 39, Line 23, Col 7, Line 23, Col 18, "The pattern discriminator 'Punctuation' is not defined.") - (Warning 26, Line 23, Col 7, Line 23, Col 20, "This rule will never be matched") - (Warning 26, Line 24, Col 7, Line 24, Col 8, "This rule will never be matched") + (Error 827, Line 8, Col 6, Line 8, Col 46, "'(|Sentence|Word|Punctuation|WhiteSpace|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3868, Line 22, Col 7, Line 22, Col 17, "This active pattern expects exactly one pattern argument, e.g., 'WhiteSpace pat'."); + (Error 1107, Line 20, Col 7, Line 20, Col 21, "Partial active patterns may only generate one result") ] // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructActivePatterns.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructActivePatterns.fs index 156d3007ddd..58da91ef0dc 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructActivePatterns.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructActivePatterns.fs @@ -33,7 +33,7 @@ let rec (|IsOne|_|) someNumber = |> withOptions ["--warnaserror+"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 1,Line 2, Col 1 , Line 3, Col 31, """This expression was expected to have type + |> withSingleDiagnostic (Error 1,Line 3, Col 10 , Line 3, Col 19, """This expression was expected to have type ''a voption' but here has type 'int option' """) @@ -50,7 +50,7 @@ let rec (|IsOne|_|) someNumber = |> withOptions ["--warnaserror+"] |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 3350, Line 2, Col 9, Line 2, Col 31, "Feature 'Boolean-returning and return-type-directed partial active patterns' is not available in F# 8.0. Please use language version 9.0 or greater.") + |> withSingleDiagnostic (Error 3350, Line 2, Col 10, Line 2, Col 19, "Feature 'Boolean-returning and return-type-directed partial active patterns' is not available in F# 8.0. Please use language version 9.0 or greater.") [] let ``Rec struct active pattern is possible`` () = diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs index 61381dfbebd..024269afe27 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs @@ -15,4 +15,4 @@ let [] (A x) = 1 """ |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 3396, Line 3, Col 5, Line 3, Col 22, "A [] declaration cannot use an active pattern for its identifier") + |> withSingleDiagnostic (Error 3396, Line 3, Col 17, Line 3, Col 22, "A [] declaration cannot use an active pattern for its identifier") From 4b7967e6c29dcd527d1060f1ff67e5dcdac55325 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sun, 25 Aug 2024 20:25:54 +0100 Subject: [PATCH 07/27] fantomas --- src/Compiler/SyntaxTree/PrettyNaming.fs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index b27efe1f8bb..cf5158d634e 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -966,15 +966,11 @@ type ActivePatternInfo = // FIXME member x.LogicalName = let (APInfo(isTotal, tags, _)) = x + tags - |> List.map fst - |> String.concat "|" - |> (fun s -> - if isTotal then - "(|" + s + "|)" - else - "(|" + s + "|_|)" - ) + |> List.map fst + |> String.concat "|" + |> (fun s -> if isTotal then "(|" + s + "|)" else "(|" + s + "|_|)") member x.Range = let (APInfo(_, _, m)) = x in m From 49c59fb2ac01330c3b029d197b5ce62bfe91f808 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 00:11:01 +0100 Subject: [PATCH 08/27] update tests --- .../MethodImplAttribute/MethodImplAttribute.fs | 2 +- ...ngAndReturnTypeDirectedPartialActivePatternTests.fs | 4 ++-- .../Compiler/Language/StructActivePatternTests.fs | 10 +++++----- tests/fsharp/typecheck/sigs/neg20.bsl | 2 +- tests/fsharp/typecheck/sigs/neg32.bsl | 10 +++++----- tests/fsharp/typecheck/sigs/neg37.bsl | 4 ++-- tests/fsharp/typecheck/sigs/neg47.bsl | 6 +++--- tests/fsharp/typecheck/sigs/neg62.bsl | 2 +- tests/fsharp/typecheck/sigs/neg85.bsl | 2 +- tests/fsharp/typecheck/sigs/neg92.bsl | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/MethodImplAttribute/MethodImplAttribute.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/MethodImplAttribute/MethodImplAttribute.fs index a13fee6baaf..bc83b54da00 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/MethodImplAttribute/MethodImplAttribute.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/MethodImplAttribute/MethodImplAttribute.fs @@ -39,7 +39,7 @@ module MethodImplAttribute = compilation |> withLangVersion80 |> typecheck - |> withSingleDiagnostic (Warning 3151, Line 2, Col 1, Line 3, Col 38, "This member, function or value declaration may not be declared 'inline'") + |> withSingleDiagnostic (Warning 3151, Line 3, Col 12, Line 3, Col 19, "This member, function or value declaration may not be declared 'inline'") [] let ``NoInlining_fs with inline keyword => should not warn in F# 7 or older`` compilation = diff --git a/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs index b2d7e262549..6562e347bbd 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs @@ -67,8 +67,8 @@ let (|OddVOption|_|) x = if x % 2 = 1 then ValueSome() else ValueNone |> typecheck |> shouldFail |> withDiagnostics [ - (Error 3350, Line 1, Col 5, Line 1, Col 20, "Feature 'Boolean-returning and return-type-directed partial active patterns' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 2, Col 5, Line 2, Col 23, "Feature 'Boolean-returning and return-type-directed partial active patterns' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 1, Col 6, Line 1, Col 17, "Feature 'Boolean-returning and return-type-directed partial active patterns' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 2, Col 6, Line 2, Col 20, "Feature 'Boolean-returning and return-type-directed partial active patterns' is not available in F# 8.0. Please use language version 9.0 or greater.") ] [] diff --git a/tests/fsharp/Compiler/Language/StructActivePatternTests.fs b/tests/fsharp/Compiler/Language/StructActivePatternTests.fs index e2382b2f441..0496bd5415a 100644 --- a/tests/fsharp/Compiler/Language/StructActivePatternTests.fs +++ b/tests/fsharp/Compiler/Language/StructActivePatternTests.fs @@ -167,7 +167,7 @@ match ret_attrs, binding_attrs with [] let (|Foo|_|) x = ValueNone """ - [|(FSharpDiagnosticSeverity.Error, 3350, (2, 1, 3, 16), + [|(FSharpDiagnosticSeverity.Error, 3350, (3, 6, 3, 13), "Feature 'struct representation for active patterns' is not available in F# 5.0. Please use language version 6.0 or greater.")|] [] @@ -179,7 +179,7 @@ let (|Foo|_|) x = ValueNone """ [|(FSharpDiagnosticSeverity.Error, 842, (2, 3, 2, 9), "This attribute is not valid for use on this language element"); - (FSharpDiagnosticSeverity.Error, 3350, (2, 1, 3, 16), + (FSharpDiagnosticSeverity.Error, 3350, (3, 6, 3, 13), "Feature 'Boolean-returning and return-type-directed partial active patterns' is not available in F# 8.0. Please use language version 9.0 or greater.")|] [] @@ -195,10 +195,10 @@ let f x = x [] let (|A|B|) x = A """ - [|(FSharpDiagnosticSeverity.Error, 3385, (2, 1, 3, 6), + [|(FSharpDiagnosticSeverity.Error, 3385, (3, 5, 3, 6), "The use of '[]' on values, functions and methods is only allowed on partial active pattern definitions") - (FSharpDiagnosticSeverity.Error, 3385, (5, 1, 6, 8), + (FSharpDiagnosticSeverity.Error, 3385, (6, 5, 6, 6), "The use of '[]' on values, functions and methods is only allowed on partial active pattern definitions") - (FSharpDiagnosticSeverity.Error, 3385, (8, 1, 9, 14), + (FSharpDiagnosticSeverity.Error, 3385, (9, 6, 9, 11), "The use of '[]' on values, functions and methods is only allowed on partial active pattern definitions")|] diff --git a/tests/fsharp/typecheck/sigs/neg20.bsl b/tests/fsharp/typecheck/sigs/neg20.bsl index 8f6822eb135..ea20ab65acf 100644 --- a/tests/fsharp/typecheck/sigs/neg20.bsl +++ b/tests/fsharp/typecheck/sigs/neg20.bsl @@ -217,7 +217,7 @@ neg20.fs(195,5,195,10): typecheck error FS0842: This attribute is not valid for neg20.fs(198,5,198,11): typecheck error FS0842: This attribute is not valid for use on this language element -neg20.fs(201,3,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations +neg20.fs(202,7,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations neg20.fs(204,5,204,14): typecheck error FS0842: This attribute is not valid for use on this language element diff --git a/tests/fsharp/typecheck/sigs/neg32.bsl b/tests/fsharp/typecheck/sigs/neg32.bsl index 50625a4882d..87fbc723312 100644 --- a/tests/fsharp/typecheck/sigs/neg32.bsl +++ b/tests/fsharp/typecheck/sigs/neg32.bsl @@ -5,7 +5,7 @@ neg32.fs(24,15,24,16): typecheck error FS0043: The member or object constructor neg32.fs(43,17,43,19): typecheck error FS0039: The type parameter 'T is not defined. -neg32.fs(44,4,44,23): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. +neg32.fs(44,15,44,17): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. neg32.fs(44,21,44,23): typecheck error FS0039: The type parameter 'U is not defined. @@ -19,7 +19,7 @@ neg32.fs(46,24,46,26): typecheck error FS0039: The type parameter 'U is not defi neg32.fs(50,17,50,19): typecheck error FS0039: The type parameter 'T is not defined. -neg32.fs(51,4,51,23): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. +neg32.fs(51,15,51,17): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. neg32.fs(51,21,51,23): typecheck error FS0039: The type parameter 'U is not defined. @@ -37,11 +37,11 @@ neg32.fs(55,18,55,20): typecheck error FS0039: The type parameter 'T is not defi neg32.fs(56,18,56,20): typecheck error FS0039: The type parameter 'T is not defined. -neg32.fs(57,4,57,38): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. +neg32.fs(57,16,57,18): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. -neg32.fs(58,4,58,33): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. +neg32.fs(58,16,58,18): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. -neg32.fs(59,4,59,33): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. +neg32.fs(59,16,59,18): typecheck error FS0671: A property cannot have explicit type parameters. Consider using a method instead. neg32.fs(62,10,62,12): typecheck error FS0039: The type parameter 'T is not defined. diff --git a/tests/fsharp/typecheck/sigs/neg37.bsl b/tests/fsharp/typecheck/sigs/neg37.bsl index 3e8742849b7..71065f796f6 100644 --- a/tests/fsharp/typecheck/sigs/neg37.bsl +++ b/tests/fsharp/typecheck/sigs/neg37.bsl @@ -1,9 +1,9 @@ -neg37.fs(7,19,7,29): typecheck error FS0670: This code is not sufficiently generic. The type variable 'T could not be generalized because it would escape its scope. +neg37.fs(7,19,7,22): typecheck error FS0670: This code is not sufficiently generic. The type variable 'T could not be generalized because it would escape its scope. neg37.fs(19,33,19,40): typecheck error FS1125: The instantiation of the generic type 'CCC' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'CCC<_>'. -neg37.fs(19,19,19,29): typecheck error FS0670: This code is not sufficiently generic. The type variable 'T could not be generalized because it would escape its scope. +neg37.fs(19,19,19,22): typecheck error FS0670: This code is not sufficiently generic. The type variable 'T could not be generalized because it would escape its scope. neg37.fs(24,10,24,37): typecheck error FS0331: The implicit instantiation of a generic construct at or near this point could not be resolved because it could resolve to multiple unrelated types, e.g. 'IComparable <'T>' and 'IEvent <'T>'. Consider using type annotations to resolve the ambiguity diff --git a/tests/fsharp/typecheck/sigs/neg47.bsl b/tests/fsharp/typecheck/sigs/neg47.bsl index 7653ed8d5b1..98d4f5a2b5e 100644 --- a/tests/fsharp/typecheck/sigs/neg47.bsl +++ b/tests/fsharp/typecheck/sigs/neg47.bsl @@ -1,8 +1,8 @@ neg47.fs(18,9,18,26): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module -neg47.fs(23,5,24,33): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module +neg47.fs(24,14,24,31): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module -neg47.fs(28,9,29,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module +neg47.fs(29,18,29,24): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module -neg47.fs(32,5,33,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module +neg47.fs(33,14,33,25): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module diff --git a/tests/fsharp/typecheck/sigs/neg62.bsl b/tests/fsharp/typecheck/sigs/neg62.bsl index b378b650c97..0632741def0 100644 --- a/tests/fsharp/typecheck/sigs/neg62.bsl +++ b/tests/fsharp/typecheck/sigs/neg62.bsl @@ -19,7 +19,7 @@ neg62.fs(50,5,50,34): typecheck error FS0901: Structs cannot contain value defin neg62.fs(54,31,54,34): typecheck error FS3135: To indicate that this property can be set, use 'member val PropertyName = expr with get,set'. -neg62.fs(69,22,69,40): typecheck error FS0670: This code is not sufficiently generic. The type variable 'S could not be generalized because it would escape its scope. +neg62.fs(69,24,69,30): typecheck error FS0670: This code is not sufficiently generic. The type variable 'S could not be generalized because it would escape its scope. neg62.fs(75,5,75,28): typecheck error FS3151: This member, function or value declaration may not be declared 'inline' diff --git a/tests/fsharp/typecheck/sigs/neg85.bsl b/tests/fsharp/typecheck/sigs/neg85.bsl index f1f4f663e48..a0b1671b72b 100644 --- a/tests/fsharp/typecheck/sigs/neg85.bsl +++ b/tests/fsharp/typecheck/sigs/neg85.bsl @@ -1,2 +1,2 @@ -neg85.fsx(7,9,7,56): typecheck error FS3162: A type variable has been constrained by multiple different class types. A type variable may only have one class constraint. +neg85.fsx(7,9,7,38): typecheck error FS3162: A type variable has been constrained by multiple different class types. A type variable may only have one class constraint. diff --git a/tests/fsharp/typecheck/sigs/neg92.bsl b/tests/fsharp/typecheck/sigs/neg92.bsl index 3ad79cb7c45..997be061e03 100644 --- a/tests/fsharp/typecheck/sigs/neg92.bsl +++ b/tests/fsharp/typecheck/sigs/neg92.bsl @@ -1,4 +1,4 @@ neg92.fs(10,19,10,20): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type ''U'. -neg92.fs(9,9,9,30): typecheck error FS0670: This code is not sufficiently generic. The type variable 'U could not be generalized because it would escape its scope. +neg92.fs(9,9,9,17): typecheck error FS0670: This code is not sufficiently generic. The type variable 'U could not be generalized because it would escape its scope. From 2ac08a72e568778bb53dfee3ac55022812287ba4 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 12:11:25 +0100 Subject: [PATCH 09/27] Add a new compiler error for multi-case partial active patterns are not supported --- src/Compiler/FSComp.txt | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 +++++ 14 files changed, 66 insertions(+) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 7cc526b603b..5fc27c7b2ce 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1782,3 +1782,4 @@ featureEmptyBodiedComputationExpressions,"Support for computation expressions wi featureAllowAccessModifiersToAutoPropertiesGettersAndSetters,"Allow access modifiers to auto properties getters and setters" 3871,tcAccessModifiersNotAllowedInSRTPConstraint,"Access modifiers cannot be applied to an SRTP constraint." featureAllowObjectExpressionWithoutOverrides,"Allow object expressions without overrides" +3872,tcPartialActivePattern,"Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern." \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index c18471a2c1e..282acb4047a 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1522,6 +1522,11 @@ Syntaxe (expr1)[expr2] je teď pro indexování vyhrazená a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction (expr1) [expr2]. + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index e504a7c458d..0a3484405c2 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1522,6 +1522,11 @@ Die Syntax "(expr1)[expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction (expr1) [expr2]". + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index a7dac2c523a..d86822e8b04 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1522,6 +1522,11 @@ La sintaxis "(expr1)[expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción (expr1) [expr2]". + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 29fdbb88335..7e8118954d7 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1522,6 +1522,11 @@ La syntaxe « (expr1)[expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction (expr1) [expr2] ». + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 6bdc5a31f99..c73b79551b9 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1522,6 +1522,11 @@ La sintassi '(expr1)[expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction (expr1) [expr2]'. + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 12d9f5f063a..24996877bd2 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1522,6 +1522,11 @@ 構文 '(expr1)[expr2]' はインデックス作成に予約されているので、引数として使うとあいまいです。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合には、'someFunction (expr1) [expr2]' のように間にスペースを追加します。 + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 5dbec5ef358..12204b14d55 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1522,6 +1522,11 @@ 구문 '(expr1)[expr2]'는 이제 인덱싱을 위해 예약되었으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction (expr1) [expr2]'). + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 9bdd39d3e2d..46e49da5f15 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1522,6 +1522,11 @@ Składnia wyrażenia „(expr1)[expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction (expr1) [expr2]”. + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index e65b25d2eb0..27315912bbd 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1522,6 +1522,11 @@ A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'. + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 211888c720a..d944cbbb923 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1522,6 +1522,11 @@ Синтаксис "(expr1)[expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction (expr1) [expr2]". + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index a3ba01ee368..f9d6f22d603 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1522,6 +1522,11 @@ Söz dizimi “(expr1)[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction (expr1) [expr2]”. + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 91eeb80944e..ce190fa9246 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1522,6 +1522,11 @@ 语法“(expr1)[expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction (expr1) [expr2]”。 + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 0a7ccf8f3b0..3290aababbe 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1522,6 +1522,11 @@ 語法 '(expr1)[expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction (expr1) [expr2]'。 + + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + + Value known to be without null passed to a function meant for nullables: {0} Value known to be without null passed to a function meant for nullables: {0} From 82254f48cdf40c0dc39458c8aeafca5e0ba03fc6 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 12:11:57 +0100 Subject: [PATCH 10/27] use tcPartialActivePattern and add more tests --- .../Checking/Expressions/CheckExpressions.fs | 6 ++++- .../E_ActivePatternMember03.fs | 24 +++++++++++++++++++ .../MethodsAndProperties.fs | 13 ++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember03.fs diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index f71c1047ada..8b20727afaa 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -10989,7 +10989,11 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt let envinner = match apinfoOpt with | Some (apinfo, apOverallTy, m) -> - if Option.isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then + let isMultiCasePartialAP = memberFlagsOpt.IsNone && not apinfo.IsTotal && apinfo.ActiveTags.Length > 1 + if isMultiCasePartialAP then + errorR(Error(FSComp.SR.tcPartialActivePattern(), m)) + + if Option.isSome memberFlagsOpt && not spatsL.IsEmpty then errorR(Error(FSComp.SR.tcInvalidActivePatternName(apinfo.LogicalName), m)) apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember03.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember03.fs new file mode 100644 index 00000000000..2a61a9bf3ef --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember03.fs @@ -0,0 +1,24 @@ +module APUsageInModule +let (|A|) = 6 +let (|A|B|) x = if x = "Foo" then A else B + +let (|A|B|_|) = None + +type APUsageInClass() = + + let (|A|) = 7 + + let (|A|B|) x = + if x = "Foo" then A + else B + + let (|A|B|_|) = None + + let (|A|B|) x = + if x = "Foo" then A + else B + + static member (|A|) = 7 + static member (|A|B|) = ValueNone + static member (|C|) = 5 + static member (|A|B|) x = A \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs index 8128b8ea392..b9e799ddb0f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs @@ -86,6 +86,19 @@ module MemberDefinitions_MethodsAndProperties = (Error 3868, Line 17, Col 11, Line 17, Col 14, "This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Bar e1 pat'."); (Warning 25, Line 15, Col 15, Line 15, Col 16, "Incomplete pattern matches on this expression.") ] + + + // SOURCE=E_ActivePatternMember03.fs SCFLAGS="--test:ErrorRanges" # E_ActivePatternMember03.fs + [] + let ``E_ActivePatternMember03_fs`` compilation = + compilation + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 3872, Line 5, Col 6, Line 5, Col 13, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") + (Error 3872, Line 15, Col 10, Line 15, Col 17, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") + (Error 827, Line 24, Col 20, Line 24, Col 25, "'(|A|B|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions.") + ] // SOURCE=E_DuplicateProperty01.fs SCFLAGS="--test:ErrorRanges" # E_DuplicateProperty01.fs [] From 14b9b61ba24cd52e17a7be3cc54bc7180e622b5a Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 14:16:30 +0100 Subject: [PATCH 11/27] update tests --- .../Conformance/PatternMatching/Named/Named.fs | 14 +++++++------- .../E_TwoDifferentTypeVariablesGen00.bsl | 18 +++++++++--------- .../E_TwoDifferentTypeVariablesGen00rec.bsl | 18 +++++++++--------- tests/fsharp/typecheck/sigs/neg16.bsl | 18 +++++++++--------- tests/fsharp/typecheck/sigs/neg45.bsl | 10 +++++++--- .../fsharp/typecheck/sigs/version50/neg20.bsl | 2 +- 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs index c3ed95f5887..a2d8254c754 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs @@ -237,7 +237,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 4, Col 10, Line 4, Col 23, "'(|Foo2|Bar2|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3872, Line 4, Col 10, Line 4, Col 23, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 1, Line 4, Col 10, Line 4, Col 23, "This expression was expected to have type 'Choice<'a,'b> option' but here has type @@ -254,7 +254,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 4, Col 11, Line 4, Col 32, "'(|Foo2b|Bar2b|Baz2b|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3872, Line 4, Col 11, Line 4, Col 32, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 1, Line 4, Col 11, Line 4, Col 32, "This expression was expected to have type 'Choice<'a,'b,'c> option' but here has type @@ -296,7 +296,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 4, Col 6, Line 4, Col 19, "'(|Foo2|Bar2|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3872, Line 4, Col 6, Line 4, Col 19, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 1, Line 4, Col 6, Line 4, Col 19, "This expression was expected to have type 'Choice<'a,'b> option' but here has type @@ -312,7 +312,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 4, Col 6, Line 4, Col 27, "'(|Foo2b|Bar2b|Baz2b|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3872, Line 4, Col 6, Line 4, Col 27, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 1, Line 4, Col 6, Line 4, Col 27, "This expression was expected to have type 'Choice<'a,'b,'c> option' but here has type @@ -354,7 +354,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 4, Col 6, Line 4, Col 19, "'(|Foo2|Bar2|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3872, Line 4, Col 6, Line 4, Col 19, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 1, Line 4, Col 6, Line 4, Col 19, "This expression was expected to have type 'Choice<'a,'b> option' but here has type @@ -370,7 +370,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 4, Col 6, Line 4, Col 27, "'(|Foo2b|Bar2b|Baz2b|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3872, Line 4, Col 6, Line 4, Col 27, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 1, Line 4, Col 6, Line 4, Col 27, "This expression was expected to have type 'Choice<'a,'b,'c> option' but here has type @@ -412,7 +412,7 @@ but here has type |> typecheck |> shouldFail |> withDiagnostics [ - (Error 827, Line 8, Col 6, Line 8, Col 46, "'(|Sentence|Word|Punctuation|WhiteSpace|_|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 3872, Line 8, Col 6, Line 8, Col 46, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 3868, Line 22, Col 7, Line 22, Col 17, "This active pattern expects exactly one pattern argument, e.g., 'WhiteSpace pat'."); (Error 1107, Line 20, Col 7, Line 20, Col 21, "Partial active patterns may only generate one result") ] diff --git a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.bsl b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.bsl index b8d0b1ba38c..9d9d4a60369 100644 --- a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.bsl +++ b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.bsl @@ -1,13 +1,13 @@ E_TwoDifferentTypeVariablesGen00.fsx(61,52,61,53): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. -E_TwoDifferentTypeVariablesGen00.fsx(61,18,61,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. +E_TwoDifferentTypeVariablesGen00.fsx(61,18,61,21): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. -E_TwoDifferentTypeVariablesGen00.fsx(61,18,61,42): typecheck error FS0043: The type ''b' does not match the type ''b0' +E_TwoDifferentTypeVariablesGen00.fsx(61,18,61,21): typecheck error FS0043: The type ''b' does not match the type ''b0' E_TwoDifferentTypeVariablesGen00.fsx(62,52,62,53): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type 'int'. -E_TwoDifferentTypeVariablesGen00.fsx(62,18,62,42): typecheck error FS0043: The type ''b' does not match the type 'int' +E_TwoDifferentTypeVariablesGen00.fsx(62,18,62,21): typecheck error FS0043: The type ''b' does not match the type 'int' E_TwoDifferentTypeVariablesGen00.fsx(63,45,63,55): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. @@ -19,15 +19,15 @@ Candidates: E_TwoDifferentTypeVariablesGen00.fsx(64,56,64,57): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. -E_TwoDifferentTypeVariablesGen00.fsx(64,18,64,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. +E_TwoDifferentTypeVariablesGen00.fsx(64,18,64,21): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. -E_TwoDifferentTypeVariablesGen00.fsx(64,18,64,42): typecheck error FS0043: The type ''b' does not match the type ''b0' +E_TwoDifferentTypeVariablesGen00.fsx(64,18,64,21): typecheck error FS0043: The type ''b' does not match the type ''b0' E_TwoDifferentTypeVariablesGen00.fsx(65,54,65,55): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. E_TwoDifferentTypeVariablesGen00.fsx(65,56,65,57): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'. -E_TwoDifferentTypeVariablesGen00.fsx(65,18,65,42): typecheck error FS0043: The type ''a' does not match the type 'int' +E_TwoDifferentTypeVariablesGen00.fsx(65,18,65,21): typecheck error FS0043: The type ''a' does not match the type 'int' E_TwoDifferentTypeVariablesGen00.fsx(66,45,66,59): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. @@ -39,9 +39,9 @@ Candidates: E_TwoDifferentTypeVariablesGen00.fsx(67,55,67,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. -E_TwoDifferentTypeVariablesGen00.fsx(67,18,67,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. +E_TwoDifferentTypeVariablesGen00.fsx(67,18,67,21): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. -E_TwoDifferentTypeVariablesGen00.fsx(67,18,67,42): typecheck error FS0043: The type ''b' does not match the type ''b0' +E_TwoDifferentTypeVariablesGen00.fsx(67,18,67,21): typecheck error FS0043: The type ''b' does not match the type ''b0' E_TwoDifferentTypeVariablesGen00.fsx(68,45,68,58): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. @@ -53,4 +53,4 @@ Candidates: E_TwoDifferentTypeVariablesGen00.fsx(69,55,69,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type 'int'. -E_TwoDifferentTypeVariablesGen00.fsx(69,18,69,42): typecheck error FS0043: The type ''b' does not match the type 'int' +E_TwoDifferentTypeVariablesGen00.fsx(69,18,69,21): typecheck error FS0043: The type ''b' does not match the type 'int' diff --git a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl index f24aa582b86..99d338ef47a 100644 --- a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl +++ b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl @@ -1,13 +1,13 @@ E_TwoDifferentTypeVariablesGen00rec.fsx(61,52,61,53): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. -E_TwoDifferentTypeVariablesGen00rec.fsx(61,18,61,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. +E_TwoDifferentTypeVariablesGen00rec.fsx(61,18,61,21): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. -E_TwoDifferentTypeVariablesGen00rec.fsx(61,18,61,42): typecheck error FS0043: The type ''b' does not match the type ''b0' +E_TwoDifferentTypeVariablesGen00rec.fsx(61,18,61,21): typecheck error FS0043: The type ''b' does not match the type ''b0' E_TwoDifferentTypeVariablesGen00rec.fsx(62,52,62,53): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type 'int'. -E_TwoDifferentTypeVariablesGen00rec.fsx(62,18,62,42): typecheck error FS0043: The type ''b' does not match the type 'int' +E_TwoDifferentTypeVariablesGen00rec.fsx(62,18,62,21): typecheck error FS0043: The type ''b' does not match the type 'int' E_TwoDifferentTypeVariablesGen00rec.fsx(63,45,63,55): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. @@ -19,15 +19,15 @@ Candidates: E_TwoDifferentTypeVariablesGen00rec.fsx(64,56,64,57): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. -E_TwoDifferentTypeVariablesGen00rec.fsx(64,18,64,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. +E_TwoDifferentTypeVariablesGen00rec.fsx(64,18,64,21): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. -E_TwoDifferentTypeVariablesGen00rec.fsx(64,18,64,42): typecheck error FS0043: The type ''b' does not match the type ''b0' +E_TwoDifferentTypeVariablesGen00rec.fsx(64,18,64,21): typecheck error FS0043: The type ''b' does not match the type ''b0' E_TwoDifferentTypeVariablesGen00rec.fsx(65,54,65,55): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. E_TwoDifferentTypeVariablesGen00rec.fsx(65,56,65,57): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'. -E_TwoDifferentTypeVariablesGen00rec.fsx(65,18,65,42): typecheck error FS0043: The type ''a' does not match the type 'int' +E_TwoDifferentTypeVariablesGen00rec.fsx(65,18,65,21): typecheck error FS0043: The type ''a' does not match the type 'int' E_TwoDifferentTypeVariablesGen00rec.fsx(66,45,66,59): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. @@ -39,9 +39,9 @@ Candidates: E_TwoDifferentTypeVariablesGen00rec.fsx(67,55,67,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. -E_TwoDifferentTypeVariablesGen00rec.fsx(67,18,67,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. +E_TwoDifferentTypeVariablesGen00rec.fsx(67,18,67,21): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. -E_TwoDifferentTypeVariablesGen00rec.fsx(67,18,67,42): typecheck error FS0043: The type ''b' does not match the type ''b0' +E_TwoDifferentTypeVariablesGen00rec.fsx(67,18,67,21): typecheck error FS0043: The type ''b' does not match the type ''b0' E_TwoDifferentTypeVariablesGen00rec.fsx(68,45,68,58): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. @@ -53,4 +53,4 @@ Candidates: E_TwoDifferentTypeVariablesGen00rec.fsx(69,55,69,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type 'int'. -E_TwoDifferentTypeVariablesGen00rec.fsx(69,18,69,42): typecheck error FS0043: The type ''b' does not match the type 'int' +E_TwoDifferentTypeVariablesGen00rec.fsx(69,18,69,21): typecheck error FS0043: The type ''b' does not match the type 'int' diff --git a/tests/fsharp/typecheck/sigs/neg16.bsl b/tests/fsharp/typecheck/sigs/neg16.bsl index 1440ccc78d3..d3bf47f9d8e 100644 --- a/tests/fsharp/typecheck/sigs/neg16.bsl +++ b/tests/fsharp/typecheck/sigs/neg16.bsl @@ -71,26 +71,26 @@ neg16.fs(90,8,90,18): typecheck error FS0039: The pattern discriminator 'FooB++' neg16.fs(90,7,90,22): typecheck error FS0025: Incomplete pattern matches on this expression. -neg16.fs(96,3,97,16): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes +neg16.fs(97,15,97,16): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes neg16.fs(99,5,99,18): typecheck error FS0842: This attribute is not valid for use on this language element -neg16.fs(99,3,100,14): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes +neg16.fs(100,11,100,12): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes -neg16.fs(99,3,100,14): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(100,11,100,12): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(102,3,103,9): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes +neg16.fs(103,7,103,9): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes -neg16.fs(102,3,103,9): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(103,7,103,9): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static neg16.fs(119,17,119,18): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes -neg16.fs(106,5,107,19): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(107,16,107,19): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(109,5,110,20): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(110,16,110,17): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(112,5,113,11): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(113,9,113,11): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(115,5,116,13): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(116,9,116,10): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static neg16.fs(130,10,130,11): typecheck error FS0935: Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal diff --git a/tests/fsharp/typecheck/sigs/neg45.bsl b/tests/fsharp/typecheck/sigs/neg45.bsl index 4fe0cd14a72..589e2e80d08 100644 --- a/tests/fsharp/typecheck/sigs/neg45.bsl +++ b/tests/fsharp/typecheck/sigs/neg45.bsl @@ -11,11 +11,15 @@ neg45.fs(34,25,34,26): typecheck error FS0465: Type inference problem too compli neg45.fs(34,27,34,28): typecheck error FS0465: Type inference problem too complicated (maximum iteration depth reached). Consider adding further type annotations. -neg45.fs(41,23,41,41): typecheck error FS0827: This is not a valid name for an active pattern +neg45.fs(41,24,41,33): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. -neg45.fs(52,14,52,17): typecheck error FS0039: The type 'FooBir' does not define the field, constructor or member 'Foo'. +neg45.fs(56,19,56,28): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. -neg45.fs(56,16,56,31): typecheck error FS0827: This is not a valid name for an active pattern +neg45.fs(64,19,64,20): typecheck error FS0025: Incomplete pattern matches on this expression. + +neg45.fs(65,15,65,18): typecheck error FS3868: This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Foo e1 pat'. + +neg45.fs(66,15,66,18): typecheck error FS3868: This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Bir e1 pat'. neg45.fs(72,26,72,31): typecheck error FS0001: A type parameter is missing a constraint 'when 'T :> System.IComparable' diff --git a/tests/fsharp/typecheck/sigs/version50/neg20.bsl b/tests/fsharp/typecheck/sigs/version50/neg20.bsl index fde27808b4e..169c18e8573 100644 --- a/tests/fsharp/typecheck/sigs/version50/neg20.bsl +++ b/tests/fsharp/typecheck/sigs/version50/neg20.bsl @@ -265,7 +265,7 @@ neg20.fs(195,5,195,10): typecheck error FS0842: This attribute is not valid for neg20.fs(198,5,198,11): typecheck error FS0842: This attribute is not valid for use on this language element -neg20.fs(201,3,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations +neg20.fs(202,7,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations neg20.fs(204,5,204,14): typecheck error FS0842: This attribute is not valid for use on this language element From 3e6eb431d7149b5c7ca9b736e9c457c7bd2b3021 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 17:46:13 +0100 Subject: [PATCH 12/27] Update src/Compiler/FSComp.txt Co-authored-by: Brian Rourke Boll --- src/Compiler/FSComp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 5fc27c7b2ce..7dc65da9155 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -679,7 +679,7 @@ tcUnnamedArgumentsDoNotFormPrefix,"The unnamed arguments do not form a prefix of 824,tcAttributesAreNotPermittedOnLetBindings,"Attributes are not permitted on 'let' bindings in expressions" 825,tcDefaultValueAttributeRequiresVal,"The 'DefaultValue' attribute may only be used on 'val' declarations" 826,tcConditionalAttributeRequiresMembers,"The 'ConditionalAttribute' attribute may only be used on members" -827,tcInvalidActivePatternName,"'%s' is not a valid method name. Active patterns may only be defined as let-bound module or class functions." +827,tcInvalidActivePatternName,"'%s' is not a valid method name. Use a let-binding instead." 828,tcEntryPointAttributeRequiresFunctionInModule,"The 'EntryPointAttribute' attribute may only be used on function definitions in modules" 829,tcMutableValuesCannotBeInline,"Mutable values cannot be marked 'inline'" 830,tcMutableValuesMayNotHaveGenericParameters,"Mutable values cannot have generic parameters" From e65f1c4928195fab9beea07304db973ee0b96943 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 17:51:48 +0100 Subject: [PATCH 13/27] Update FSComp.txt --- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.de.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.es.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.it.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 282acb4047a..7c2284e467b 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 0a3484405c2..5739bac40b2 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index d86822e8b04..308f169a61b 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 7e8118954d7..c7a209573ff 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index c73b79551b9..447a64380c5 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 24996877bd2..c937f16f934 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 12204b14d55..c314df414f6 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 46e49da5f15..2b69fa4579e 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 27315912bbd..cc33532d35d 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index d944cbbb923..b93b979f71c 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index f9d6f22d603..8bfb7b0e191 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index ce190fa9246..bd9d5d55b84 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 3290aababbe..d863abb13fe 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. - '{0}' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. + '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a let-binding instead. From 5ed584e14a5cfe8b745d6bcb34bba1b797bfa3ac Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 20:34:55 +0100 Subject: [PATCH 14/27] Update src/Compiler/FSComp.txt Co-authored-by: Brian Rourke Boll --- src/Compiler/FSComp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 7dc65da9155..8205fc213fe 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -679,7 +679,7 @@ tcUnnamedArgumentsDoNotFormPrefix,"The unnamed arguments do not form a prefix of 824,tcAttributesAreNotPermittedOnLetBindings,"Attributes are not permitted on 'let' bindings in expressions" 825,tcDefaultValueAttributeRequiresVal,"The 'DefaultValue' attribute may only be used on 'val' declarations" 826,tcConditionalAttributeRequiresMembers,"The 'ConditionalAttribute' attribute may only be used on members" -827,tcInvalidActivePatternName,"'%s' is not a valid method name. Use a let-binding instead." +827,tcInvalidActivePatternName,"'%s' is not a valid method name. Use a 'let' binding instead." 828,tcEntryPointAttributeRequiresFunctionInModule,"The 'EntryPointAttribute' attribute may only be used on function definitions in modules" 829,tcMutableValuesCannotBeInline,"Mutable values cannot be marked 'inline'" 830,tcMutableValuesMayNotHaveGenericParameters,"Mutable values cannot have generic parameters" From 5518da5ff260f82f9eb95dd71982ce0083bf2809 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 20:58:31 +0100 Subject: [PATCH 15/27] more tests --- .../MethodsAndProperties/MethodsAndProperties.fs | 6 +++--- tests/fsharp/typecheck/sigs/neg45.bsl | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs index b9e799ddb0f..6f5331abcbb 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/MethodsAndProperties/MethodsAndProperties.fs @@ -70,7 +70,7 @@ module MemberDefinitions_MethodsAndProperties = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 827, Line 10, Col 20, Line 10, Col 29, "'(|Foo|Bar|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions.") + (Error 827, Line 10, Col 20, Line 10, Col 29, "'(|Foo|Bar|)' is not a valid method name. Use a 'let' binding instead.") (Error 39, Line 21, Col 10, Line 21, Col 13, "The type 'FaaBor' does not define the field, constructor or member 'Foo'.") ] @@ -81,7 +81,7 @@ module MemberDefinitions_MethodsAndProperties = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 827, Line 6, Col 15, Line 6, Col 24, "'(|Foo|Bar|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions."); + (Error 827, Line 6, Col 15, Line 6, Col 24, "'(|Foo|Bar|)' is not a valid method name. Use a 'let' binding instead.") (Error 3868, Line 16, Col 11, Line 16, Col 14, "This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Foo e1 pat'."); (Error 3868, Line 17, Col 11, Line 17, Col 14, "This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Bar e1 pat'."); (Warning 25, Line 15, Col 15, Line 15, Col 16, "Incomplete pattern matches on this expression.") @@ -97,7 +97,7 @@ module MemberDefinitions_MethodsAndProperties = |> withDiagnostics [ (Error 3872, Line 5, Col 6, Line 5, Col 13, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") (Error 3872, Line 15, Col 10, Line 15, Col 17, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern.") - (Error 827, Line 24, Col 20, Line 24, Col 25, "'(|A|B|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions.") + (Error 827, Line 24, Col 20, Line 24, Col 25, "'(|A|B|)' is not a valid method name. Use a 'let' binding instead.") ] // SOURCE=E_DuplicateProperty01.fs SCFLAGS="--test:ErrorRanges" # E_DuplicateProperty01.fs diff --git a/tests/fsharp/typecheck/sigs/neg45.bsl b/tests/fsharp/typecheck/sigs/neg45.bsl index 589e2e80d08..b279a0a3e87 100644 --- a/tests/fsharp/typecheck/sigs/neg45.bsl +++ b/tests/fsharp/typecheck/sigs/neg45.bsl @@ -11,9 +11,9 @@ neg45.fs(34,25,34,26): typecheck error FS0465: Type inference problem too compli neg45.fs(34,27,34,28): typecheck error FS0465: Type inference problem too complicated (maximum iteration depth reached). Consider adding further type annotations. -neg45.fs(41,24,41,33): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. +neg45.fs(41,24,41,33): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Use a 'let' binding instead. -neg45.fs(56,19,56,28): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Active patterns may only be defined as let-bound module or class functions. +neg45.fs(56,19,56,28): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Use a 'let' binding instead. neg45.fs(64,19,64,20): typecheck error FS0025: Incomplete pattern matches on this expression. From 9d887b653a36a96aa4693d8b69fdd51ff8a23495 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 21:00:36 +0100 Subject: [PATCH 16/27] release notes --- docs/release-notes/.FSharp.Compiler.Service/9.0.100.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md index d3e795bf8b7..df4a524f8ba 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md @@ -35,4 +35,6 @@ * Applied nullable reference types to FSharp.Compiler.Service itself ([PR #15310](https://github.com/dotnet/fsharp/pull/15310)) * Ensure that isinteractive multi-emit backing fields are not public. ([Issue #17439](https://github.com/dotnet/fsharp/issues/17438)), ([PR #17439](https://github.com/dotnet/fsharp/pull/17439)) * Better error reporting for unions with duplicated fields. ([PR #17521](https://github.com/dotnet/fsharp/pull/17521)) +* Better error reporting for let bindings. ([PR #17601](https://github.com/dotnet/fsharp/pull/17601)) + ### Breaking Changes From a041fb7f8a39ddb438ef7d1895ee27e8a8ac465d Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 21:32:15 +0100 Subject: [PATCH 17/27] Update xlf --- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.de.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.es.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.it.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 7c2284e467b..b4a446b5d47 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 5739bac40b2..001b866c876 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 308f169a61b..65421f1b7b9 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index c7a209573ff..cf69af26882 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 447a64380c5..f18db74a743 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index c937f16f934..e8b22b7c45e 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index c314df414f6..33db7e8f252 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 2b69fa4579e..3956f600aee 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index cc33532d35d..feeaeef252a 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index b93b979f71c..172bdfeff59 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 8bfb7b0e191..360ad4a0f0b 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index bd9d5d55b84..62586de21a8 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index d863abb13fe..5c3e23604f5 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -4948,8 +4948,8 @@ - '{0}' is not a valid method name. Use a let-binding instead. - '{0}' is not a valid method name. Use a let-binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. + '{0}' is not a valid method name. Use a 'let' binding instead. From 714770f4c6f46dde2909c741c2d6c7aa2779645b Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 26 Aug 2024 22:34:17 +0100 Subject: [PATCH 18/27] reduce diff --- .../Checking/Expressions/CheckExpressions.fs | 498 +++++++++--------- 1 file changed, 251 insertions(+), 247 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 34c5df4ab52..9c698b95b65 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -10816,284 +10816,288 @@ and TcAndBuildFixedExpr (cenv: cenv) env (overallPatTy, fixedExpr, overallExprTy /// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind = + let g = cenv.g - let envinner = AddDeclaredTypars NoCheckForDuplicateTypars (enclosingDeclaredTypars@declaredTypars) env - let (NormalizedBinding(vis, kind, isInline, isMutable, attrs, xmlDoc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), _, debugPoint)) = bind - let (SynValData(memberFlags = memberFlagsOpt)) = valSynData - let mBinding = pat.Range - let isClassLetBinding = - match declKind, kind with - | ClassLetBinding _, SynBindingKind.Normal -> true - | _ -> false + let envinner = AddDeclaredTypars NoCheckForDuplicateTypars (enclosingDeclaredTypars@declaredTypars) env - let callerName = - match declKind, kind, pat with - | ExpressionBinding, _, _ -> envinner.eCallerMemberName - | _, _, (SynPat.Named(SynIdent(name,_), _, _, _) | SynPat.As(_, SynPat.Named(SynIdent(name,_), _, _, _), _)) -> - match memberFlagsOpt with - | Some memberFlags -> - match memberFlags.MemberKind with - | SynMemberKind.PropertyGet | SynMemberKind.PropertySet | SynMemberKind.PropertyGetSet -> Some(name.idText.Substring 4) - | SynMemberKind.ClassConstructor -> Some(".ctor") - | SynMemberKind.Constructor -> Some(".ctor") - | _ -> Some(name.idText) - | _ -> Some(name.idText) - | ClassLetBinding false, SynBindingKind.Do, _ -> Some(".ctor") - | ClassLetBinding true, SynBindingKind.Do, _ -> Some(".cctor") - | ModuleOrMemberBinding, SynBindingKind.StandaloneExpression, _ -> Some(".cctor") - | _, _, _ -> envinner.eCallerMemberName + match bind with + | NormalizedBinding(vis, kind, isInline, isMutable, attrs, xmlDoc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), _, debugPoint) -> + let (SynValData(memberFlags = memberFlagsOpt)) = valSynData + let mBinding = pat.Range - let envinner = { envinner with eCallerMemberName = callerName } - let attrTgt = declKind.AllowedAttribTargets memberFlagsOpt + let isClassLetBinding = + match declKind, kind with + | ClassLetBinding _, SynBindingKind.Normal -> true + | _ -> false - let isFixed, rhsExpr, overallPatTy, overallExprTy = - match rhsExpr with - | SynExpr.Fixed (e, _) -> true, e, NewInferenceType g, overallTy - // { new Foo() } is parsed as a SynExpr.ComputationExpr.(See pars.fsy `objExpr` rule). - // If a SynExpr.ComputationExpr body consists of a single SynExpr.New, and it's not the argument of a computation expression builder type. - // Then we should treat it as a SynExpr.ObjExpr and make it consistent with the other object expressions. e.g. - // { new Foo } -> SynExpr.ObjExpr - // { new Foo() } -> SynExpr.ObjExpr - // { New Foo with ... } -> SynExpr.ObjExpr - | SynExpr.ComputationExpr(false, SynExpr.New(_, targetType, expr, m), _) -> - false, SynExpr.ObjExpr(targetType, Some(expr, None), None, [], [], [], m, rhsExpr.Range), overallTy, overallTy - | e -> false, e, overallTy, overallTy - - // Check the attributes of the binding, parameters or return value - let TcAttrs tgt isRet attrs = - // For all but attributes positioned at the return value, disallow implicitly - // targeting the return value. - let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue - let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs - let attrs: Attrib list = attrs - if attrTgt = enum 0 && not (isNil attrs) then - for attr in attrs do - errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), attr.Range)) - attrs - - // Rotate [] from binding to return value - // Also patch the syntactic representation - let retAttribs, valAttribs, valSynData = - let attribs = TcAttrs attrTgt false attrs - let rotRetSynAttrs, rotRetAttribs, valAttribs = - // Do not rotate if some attrs fail to typecheck... - if attribs.Length <> attrs.Length then [], [], attribs - else attribs - |> List.zip attrs - |> List.partition(function | _, Attrib(_, _, _, _, _, Some ts, _) -> ts &&& AttributeTargets.ReturnValue <> enum 0 | _ -> false) - |> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v) - let retAttribs = - match rtyOpt with - | Some (SynBindingReturnInfo(attributes = Attributes retAttrs)) -> - rotRetAttribs @ TcAttrs AttributeTargets.ReturnValue true retAttrs - | None -> rotRetAttribs - let valSynData = - match rotRetSynAttrs with - | [] -> valSynData - | {Range=mHead} :: _ -> - let (SynValData(valMf, SynValInfo(args, SynArgInfo(attrs, opt, retId)), valId)) = valSynData - SynValData(valMf, SynValInfo(args, SynArgInfo({Attributes=rotRetSynAttrs; Range=mHead} :: attrs, opt, retId)), valId) - retAttribs, valAttribs, valSynData - - let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute valAttribs - let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable g valAttribs mBinding - - let argAttribs = - spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter false)) - - // Assert the return type of an active pattern. A [] attribute may be used on a partial active pattern. - let isStructRetTy = HasFSharpAttribute g g.attrib_StructAttribute retAttribs - - let argAndRetAttribs = ArgAndRetAttribs(argAttribs, retAttribs) - - // See RFC FS-1087, the 'Zero' method of a builder may have 'DefaultValueAttribute' indicating it should - // always be used for empty branches of if/then/else and others - let isZeroMethod = - match declKind, pat with - | ModuleOrMemberBinding, SynPat.Named(SynIdent(id,_), _, _, _) when id.idText = "Zero" -> - match memberFlagsOpt with - | Some memberFlags -> - match memberFlags.MemberKind with - | SynMemberKind.Member -> true + let callerName = + match declKind, kind, pat with + | ExpressionBinding, _, _ -> envinner.eCallerMemberName + | _, _, (SynPat.Named(SynIdent(name,_), _, _, _) | SynPat.As(_, SynPat.Named(SynIdent(name,_), _, _, _), _)) -> + match memberFlagsOpt with + | Some memberFlags -> + match memberFlags.MemberKind with + | SynMemberKind.PropertyGet | SynMemberKind.PropertySet | SynMemberKind.PropertyGetSet -> Some(name.idText.Substring 4) + | SynMemberKind.ClassConstructor -> Some(".ctor") + | SynMemberKind.Constructor -> Some(".ctor") + | _ -> Some(name.idText) + | _ -> Some(name.idText) + | ClassLetBinding false, SynBindingKind.Do, _ -> Some(".ctor") + | ClassLetBinding true, SynBindingKind.Do, _ -> Some(".cctor") + | ModuleOrMemberBinding, SynBindingKind.StandaloneExpression, _ -> Some(".cctor") + | _, _, _ -> envinner.eCallerMemberName + + let envinner = { envinner with eCallerMemberName = callerName } + let attrTgt = declKind.AllowedAttribTargets memberFlagsOpt + + let isFixed, rhsExpr, overallPatTy, overallExprTy = + match rhsExpr with + | SynExpr.Fixed (e, _) -> true, e, NewInferenceType g, overallTy + // { new Foo() } is parsed as a SynExpr.ComputationExpr.(See pars.fsy `objExpr` rule). + // If a SynExpr.ComputationExpr body consists of a single SynExpr.New, and it's not the argument of a computation expression builder type. + // Then we should treat it as a SynExpr.ObjExpr and make it consistent with the other object expressions. e.g. + // { new Foo } -> SynExpr.ObjExpr + // { new Foo() } -> SynExpr.ObjExpr + // { New Foo with ... } -> SynExpr.ObjExpr + | SynExpr.ComputationExpr(false, SynExpr.New(_, targetType, expr, m), _) -> + false, SynExpr.ObjExpr(targetType, Some(expr, None), None, [], [], [], m, rhsExpr.Range), overallTy, overallTy + | e -> false, e, overallTy, overallTy + + // Check the attributes of the binding, parameters or return value + let TcAttrs tgt isRet attrs = + // For all but attributes positioned at the return value, disallow implicitly + // targeting the return value. + let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue + let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs + let attrs: Attrib list = attrs + if attrTgt = enum 0 && not (isNil attrs) then + for attr in attrs do + errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), attr.Range)) + attrs + + // Rotate [] from binding to return value + // Also patch the syntactic representation + let retAttribs, valAttribs, valSynData = + let attribs = TcAttrs attrTgt false attrs + let rotRetSynAttrs, rotRetAttribs, valAttribs = + // Do not rotate if some attrs fail to typecheck... + if attribs.Length <> attrs.Length then [], [], attribs + else attribs + |> List.zip attrs + |> List.partition(function | _, Attrib(_, _, _, _, _, Some ts, _) -> ts &&& AttributeTargets.ReturnValue <> enum 0 | _ -> false) + |> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v) + let retAttribs = + match rtyOpt with + | Some (SynBindingReturnInfo(attributes = Attributes retAttrs)) -> + rotRetAttribs @ TcAttrs AttributeTargets.ReturnValue true retAttrs + | None -> rotRetAttribs + let valSynData = + match rotRetSynAttrs with + | [] -> valSynData + | {Range=mHead} :: _ -> + let (SynValData(valMf, SynValInfo(args, SynArgInfo(attrs, opt, retId)), valId)) = valSynData + SynValData(valMf, SynValInfo(args, SynArgInfo({Attributes=rotRetSynAttrs; Range=mHead} :: attrs, opt, retId)), valId) + retAttribs, valAttribs, valSynData + + let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute valAttribs + let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable g valAttribs mBinding + + let argAttribs = + spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter false)) + + // Assert the return type of an active pattern. A [] attribute may be used on a partial active pattern. + let isStructRetTy = HasFSharpAttribute g g.attrib_StructAttribute retAttribs + + let argAndRetAttribs = ArgAndRetAttribs(argAttribs, retAttribs) + + // See RFC FS-1087, the 'Zero' method of a builder may have 'DefaultValueAttribute' indicating it should + // always be used for empty branches of if/then/else and others + let isZeroMethod = + match declKind, pat with + | ModuleOrMemberBinding, SynPat.Named(SynIdent(id,_), _, _, _) when id.idText = "Zero" -> + match memberFlagsOpt with + | Some memberFlags -> + match memberFlags.MemberKind with + | SynMemberKind.Member -> true + | _ -> false | _ -> false | _ -> false - | _ -> false - if HasFSharpAttribute g g.attrib_DefaultValueAttribute valAttribs && not isZeroMethod then - errorR(Error(FSComp.SR.tcDefaultValueAttributeRequiresVal(), mBinding)) + if HasFSharpAttribute g g.attrib_DefaultValueAttribute valAttribs && not isZeroMethod then + errorR(Error(FSComp.SR.tcDefaultValueAttributeRequiresVal(), mBinding)) - let isThreadStatic = isThreadOrContextStatic g valAttribs - if isThreadStatic then errorR(DeprecatedThreadStaticBindingWarning mBinding) + let isThreadStatic = isThreadOrContextStatic g valAttribs + if isThreadStatic then errorR(DeprecatedThreadStaticBindingWarning mBinding) - if isVolatile then - match declKind with - | ClassLetBinding _ -> () - | _ -> errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), mBinding)) + if isVolatile then + match declKind with + | ClassLetBinding _ -> () + | _ -> errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), mBinding)) - if (not isMutable || isThreadStatic) then - errorR(Error(FSComp.SR.tcVolatileFieldsMustBeMutable(), mBinding)) + if (not isMutable || isThreadStatic) then + errorR(Error(FSComp.SR.tcVolatileFieldsMustBeMutable(), mBinding)) - if isFixed && (declKind <> ExpressionBinding || isInline || isMutable) then - errorR(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + if isFixed && (declKind <> ExpressionBinding || isInline || isMutable) then + errorR(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) - if (not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false)) && - HasFSharpAttributeOpt g g.attrib_DllImportAttribute valAttribs then - errorR(Error(FSComp.SR.tcDllImportNotAllowed(), mBinding)) + if (not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false)) && + HasFSharpAttributeOpt g g.attrib_DllImportAttribute valAttribs then + errorR(Error(FSComp.SR.tcDllImportNotAllowed(), mBinding)) - if Option.isNone memberFlagsOpt && HasFSharpAttribute g g.attrib_ConditionalAttribute valAttribs then - errorR(Error(FSComp.SR.tcConditionalAttributeRequiresMembers(), mBinding)) + if Option.isNone memberFlagsOpt && HasFSharpAttribute g g.attrib_ConditionalAttribute valAttribs then + errorR(Error(FSComp.SR.tcConditionalAttributeRequiresMembers(), mBinding)) - if HasFSharpAttribute g g.attrib_EntryPointAttribute valAttribs then - if Option.isSome memberFlagsOpt then - errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(), mBinding)) - else - let entryPointTy = mkFunTy g (mkArrayType g g.string_ty) g.int_ty - UnifyTypes cenv env mBinding overallPatTy entryPointTy + if HasFSharpAttribute g g.attrib_EntryPointAttribute valAttribs then + if Option.isSome memberFlagsOpt then + errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(), mBinding)) + else + let entryPointTy = mkFunTy g (mkArrayType g g.string_ty) g.int_ty + UnifyTypes cenv env mBinding overallPatTy entryPointTy - if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(), mBinding)) + if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(), mBinding)) - if isMutable && not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(), mBinding)) + if isMutable && not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(), mBinding)) - let explicitTyparInfo = if isMutable then dontInferTypars else explicitTyparInfo + let explicitTyparInfo = if isMutable then dontInferTypars else explicitTyparInfo - if isMutable && not (isNil spatsL) then errorR(Error(FSComp.SR.tcMutableValuesSyntax(), mBinding)) + if isMutable && not (isNil spatsL) then errorR(Error(FSComp.SR.tcMutableValuesSyntax(), mBinding)) - let isInline = - if isInline && isNil spatsL && isNil declaredTypars then - errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(), mBinding)) - false - else - isInline + let isInline = + if isInline && isNil spatsL && isNil declaredTypars then + errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(), mBinding)) + false + else + isInline - let isCompGen = false + let isCompGen = false - // Use the syntactic arity if we're defining a function - let (SynValData(valInfo = valSynInfo)) = valSynData - let prelimValReprInfo = TranslateSynValInfo cenv mBinding (TcAttributes cenv env) valSynInfo + // Use the syntactic arity if we're defining a function + let (SynValData(valInfo = valSynInfo)) = valSynData + let prelimValReprInfo = TranslateSynValInfo cenv mBinding (TcAttributes cenv env) valSynInfo - // Check the pattern of the l.h.s. of the binding - let tcPatPhase2, (TcPatLinearEnv (tpenv, nameToPrelimValSchemeMap, _)) = - cenv.TcPat AllIdsOK cenv envinner (Some prelimValReprInfo) (TcPatValFlags (inlineFlag, explicitTyparInfo, argAndRetAttribs, isMutable, vis, isCompGen)) (TcPatLinearEnv (tpenv, NameMap.empty, Set.empty)) overallPatTy pat + // Check the pattern of the l.h.s. of the binding + let tcPatPhase2, (TcPatLinearEnv (tpenv, nameToPrelimValSchemeMap, _)) = + cenv.TcPat AllIdsOK cenv envinner (Some prelimValReprInfo) (TcPatValFlags (inlineFlag, explicitTyparInfo, argAndRetAttribs, isMutable, vis, isCompGen)) (TcPatLinearEnv (tpenv, NameMap.empty, Set.empty)) overallPatTy pat - // Add active pattern result names to the environment - let apinfoOpt = - match NameMap.range nameToPrelimValSchemeMap with - | [PrelimVal1(id, _, ty, _, _, _, _, _, _, _, _) ] -> - match ActivePatternInfoOfValName id.idText id.idRange with - | Some apinfo -> Some (apinfo, ty, id.idRange) - | None -> None - | _ -> None + // Add active pattern result names to the environment + let apinfoOpt = + match NameMap.range nameToPrelimValSchemeMap with + | [PrelimVal1(id, _, ty, _, _, _, _, _, _, _, _) ] -> + match ActivePatternInfoOfValName id.idText id.idRange with + | Some apinfo -> Some (apinfo, ty, id.idRange) + | None -> None + | _ -> None - // Add active pattern result names to the environment - let envinner = - match apinfoOpt with - | Some (apinfo, apOverallTy, m) -> - let isMultiCasePartialAP = memberFlagsOpt.IsNone && not apinfo.IsTotal && apinfo.ActiveTags.Length > 1 - if isMultiCasePartialAP then - errorR(Error(FSComp.SR.tcPartialActivePattern(), m)) - - if Option.isSome memberFlagsOpt && not spatsL.IsEmpty then - errorR(Error(FSComp.SR.tcInvalidActivePatternName(apinfo.LogicalName), m)) - - apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> - let item = Item.ActivePatternResult(apinfo, apOverallTy, i, tagRange) - CallNameResolutionSink cenv.tcSink (tagRange, env.NameEnv, item, emptyTyparInst, ItemOccurrence.Binding, env.AccessRights)) - - { envinner with eNameResEnv = AddActivePatternResultTagsToNameEnv apinfo envinner.eNameResEnv apOverallTy m } - | None -> - envinner + // Add active pattern result names to the environment + let envinner = + match apinfoOpt with + | Some (apinfo, apOverallTy, m) -> + let isMultiCasePartialAP = memberFlagsOpt.IsNone && not apinfo.IsTotal && apinfo.ActiveTags.Length > 1 + if isMultiCasePartialAP then + errorR(Error(FSComp.SR.tcPartialActivePattern(), m)) + + if Option.isSome memberFlagsOpt && not spatsL.IsEmpty then + errorR(Error(FSComp.SR.tcInvalidActivePatternName(apinfo.LogicalName), m)) + + apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> + let item = Item.ActivePatternResult(apinfo, apOverallTy, i, tagRange) + CallNameResolutionSink cenv.tcSink (tagRange, env.NameEnv, item, emptyTyparInst, ItemOccurrence.Binding, env.AccessRights)) + + { envinner with eNameResEnv = AddActivePatternResultTagsToNameEnv apinfo envinner.eNameResEnv apOverallTy m } + | None -> + envinner - // If binding a ctor then set the ugly counter that permits us to write ctor expressions on the r.h.s. - let isCtor = (match memberFlagsOpt with Some memberFlags -> memberFlags.MemberKind = SynMemberKind.Constructor | _ -> false) + // If binding a ctor then set the ugly counter that permits us to write ctor expressions on the r.h.s. + let isCtor = (match memberFlagsOpt with Some memberFlags -> memberFlags.MemberKind = SynMemberKind.Constructor | _ -> false) - // Now check the right of the binding. - // - // At each module binding, dive into the expression to check for syntax errors and suppress them if they show. - // Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas - let rhsExprChecked, tpenv = - let atTopNonLambdaDefn = - declKind.IsModuleOrMemberOrExtensionBinding && - (match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) && - synExprContainsError rhsExpr - - conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () -> - - // Save the arginfos away to match them up in the lambda - let (PrelimValReprInfo(argInfos, _)) = prelimValReprInfo - - // The right-hand-side is control flow (has an implicit debug point) in any situation where we - // haven't extended the debug point to include the 'let', that is, there is a debug point noted - // at the binding. - // - // This includes - // let _ = expr - // let () = expr - // which are transformed to sequential expressions in TcLetBinding - // - let rhsIsControlFlow = - match pat with - | SynPat.Wild _ - | SynPat.Const (SynConst.Unit, _) - | SynPat.Paren (SynPat.Const (SynConst.Unit, _), _) -> true - | _ -> - match debugPoint with - | DebugPointAtBinding.Yes _ -> false - | _ -> true - - let envinner = { envinner with eLambdaArgInfos = argInfos; eIsControlFlow = rhsIsControlFlow } - - if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv (MustEqual overallExprTy) envinner tpenv rhsExpr - else TcExprThatCantBeCtorBody cenv (MustConvertTo (false, overallExprTy)) envinner tpenv rhsExpr) - - if kind = SynBindingKind.StandaloneExpression && not cenv.isScript then - UnifyUnitType cenv env mBinding overallPatTy rhsExprChecked |> ignore - - // Fix up the r.h.s. expression for 'fixed' - let rhsExprChecked = - if isFixed then TcAndBuildFixedExpr cenv env (overallPatTy, rhsExprChecked, overallExprTy, mBinding) - else rhsExprChecked - - match apinfoOpt with - | Some (apinfo, apOverallTy, _) -> - let activePatResTys = NewInferenceTypes g apinfo.ActiveTags - let _, apReturnTy = stripFunTy g apOverallTy - let apRetTy = - if apinfo.IsTotal then - if isStructRetTy then errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) - ActivePatternReturnKind.RefTypeWrapper - else - if isStructRetTy || isValueOptionTy cenv.g apReturnTy then ActivePatternReturnKind.StructTypeWrapper - elif isBoolTy cenv.g apReturnTy then ActivePatternReturnKind.Boolean - else ActivePatternReturnKind.RefTypeWrapper + // Now check the right of the binding. + // + // At each module binding, dive into the expression to check for syntax errors and suppress them if they show. + // Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas + let rhsExprChecked, tpenv = + let atTopNonLambdaDefn = + declKind.IsModuleOrMemberOrExtensionBinding && + (match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) && + synExprContainsError rhsExpr + + conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () -> + + // Save the arginfos away to match them up in the lambda + let (PrelimValReprInfo(argInfos, _)) = prelimValReprInfo + + // The right-hand-side is control flow (has an implicit debug point) in any situation where we + // haven't extended the debug point to include the 'let', that is, there is a debug point noted + // at the binding. + // + // This includes + // let _ = expr + // let () = expr + // which are transformed to sequential expressions in TcLetBinding + // + let rhsIsControlFlow = + match pat with + | SynPat.Wild _ + | SynPat.Const (SynConst.Unit, _) + | SynPat.Paren (SynPat.Const (SynConst.Unit, _), _) -> true + | _ -> + match debugPoint with + | DebugPointAtBinding.Yes _ -> false + | _ -> true - match apRetTy with - | ActivePatternReturnKind.Boolean -> - checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding - | ActivePatternReturnKind.StructTypeWrapper when not isStructRetTy -> - checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding - | ActivePatternReturnKind.StructTypeWrapper -> - checkLanguageFeatureError g.langVersion LanguageFeature.StructActivePattern mBinding - | ActivePatternReturnKind.RefTypeWrapper -> () + let envinner = { envinner with eLambdaArgInfos = argInfos; eIsControlFlow = rhsIsControlFlow } - UnifyTypes cenv env mBinding (apinfo.ResultType g rhsExpr.Range activePatResTys apRetTy) apReturnTy + if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv (MustEqual overallExprTy) envinner tpenv rhsExpr + else TcExprThatCantBeCtorBody cenv (MustConvertTo (false, overallExprTy)) envinner tpenv rhsExpr) - | None -> - if isStructRetTy then - errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) + if kind = SynBindingKind.StandaloneExpression && not cenv.isScript then + UnifyUnitType cenv env mBinding overallPatTy rhsExprChecked |> ignore - // Check other attributes - let hasLiteralAttr, literalValue = TcLiteral cenv overallExprTy env tpenv (valAttribs, rhsExpr) + // Fix up the r.h.s. expression for 'fixed' + let rhsExprChecked = + if isFixed then TcAndBuildFixedExpr cenv env (overallPatTy, rhsExprChecked, overallExprTy, mBinding) + else rhsExprChecked - if hasLiteralAttr then - if isThreadStatic then - errorR(Error(FSComp.SR.tcIllegalAttributesForLiteral(), mBinding)) - if isMutable then - errorR(Error(FSComp.SR.tcLiteralCannotBeMutable(), mBinding)) - if isInline then - errorR(Error(FSComp.SR.tcLiteralCannotBeInline(), mBinding)) - if not (isNil declaredTypars) then - errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding)) + match apinfoOpt with + | Some (apinfo, apOverallTy, _) -> + let activePatResTys = NewInferenceTypes g apinfo.ActiveTags + let _, apReturnTy = stripFunTy g apOverallTy + let apRetTy = + if apinfo.IsTotal then + if isStructRetTy then errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) + ActivePatternReturnKind.RefTypeWrapper + else + if isStructRetTy || isValueOptionTy cenv.g apReturnTy then ActivePatternReturnKind.StructTypeWrapper + elif isBoolTy cenv.g apReturnTy then ActivePatternReturnKind.Boolean + else ActivePatternReturnKind.RefTypeWrapper + + match apRetTy with + | ActivePatternReturnKind.Boolean -> + checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding + | ActivePatternReturnKind.StructTypeWrapper when not isStructRetTy -> + checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern mBinding + | ActivePatternReturnKind.StructTypeWrapper -> + checkLanguageFeatureError g.langVersion LanguageFeature.StructActivePattern mBinding + | ActivePatternReturnKind.RefTypeWrapper -> () + + UnifyTypes cenv env mBinding (apinfo.ResultType g rhsExpr.Range activePatResTys apRetTy) apReturnTy + + | None -> + if isStructRetTy then + errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) + + // Check other attributes + let hasLiteralAttr, literalValue = TcLiteral cenv overallExprTy env tpenv (valAttribs, rhsExpr) + + if hasLiteralAttr then + if isThreadStatic then + errorR(Error(FSComp.SR.tcIllegalAttributesForLiteral(), mBinding)) + if isMutable then + errorR(Error(FSComp.SR.tcLiteralCannotBeMutable(), mBinding)) + if isInline then + errorR(Error(FSComp.SR.tcLiteralCannotBeInline(), mBinding)) + if not (isNil declaredTypars) then + errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding)) let supportEnforceAttributeTargets = (g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) && memberFlagsOpt.IsNone && not attrs.IsEmpty) @@ -11102,7 +11106,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt if supportEnforceAttributeTargets then TcAttributeTargetsOnLetBindings { cenv with tcSink = TcResultsSink.NoSink } env attrs overallPatTy overallExprTy (not declaredTypars.IsEmpty) isClassLetBinding - CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv + CheckedBindingInfo(inlineFlag, valAttribs, xmlDoc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, debugPoint, isCompGen, literalValue, isFixed), tpenv // Note: // - Let bound values can only have attributes that uses AttributeTargets.Field ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue From 1a7819bd36df74e478342e42d11a8a1c01960d54 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 27 Aug 2024 09:16:46 +0100 Subject: [PATCH 19/27] update tests --- .../AttributeUsage/AttributeUsage.fs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index bbce93b8480..d309d1dd4ff 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -800,16 +800,16 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 823, Line 3, Col 3, Line 4, Col 16, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 823, Line 6, Col 3, Line 7, Col 14, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 879, Line 6, Col 3, Line 7, Col 14, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 823, Line 9, Col 3, Line 10, Col 9, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 879, Line 9, Col 3, Line 10, Col 9, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 823, Line 4, Col 15, Line 4, Col 16, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") + (Error 823, Line 7, Col 11, Line 7, Col 12, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") + (Error 879, Line 7, Col 11, Line 7, Col 12, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 823, Line 10, Col 7, Line 10, Col 9, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") + (Error 879, Line 10, Col 7, Line 10, Col 9, "Volatile fields must be marked 'mutable' and cannot be thread-static") (Error 823, Line 26, Col 17, Line 26, Col 18, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 879, Line 13, Col 5, Line 14, Col 19, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 879, Line 16, Col 5, Line 17, Col 20, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 879, Line 19, Col 5, Line 20, Col 11, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 879, Line 22, Col 5, Line 23, Col 13, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 14, Col 16, Line 14, Col 19, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 17, Col 16, Line 17, Col 17, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 20, Col 9, Line 20, Col 11, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 23, Col 9, Line 23, Col 10, "Volatile fields must be marked 'mutable' and cannot be thread-static") ] // SOURCE=E_VolatileField.fs # E_VolatileField.fs @@ -820,16 +820,16 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) = |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 823, Line 3, Col 3, Line 4, Col 16, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 823, Line 6, Col 3, Line 7, Col 14, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 879, Line 6, Col 3, Line 7, Col 14, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 823, Line 9, Col 3, Line 10, Col 9, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 879, Line 9, Col 3, Line 10, Col 9, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 823, Line 4, Col 15, Line 4, Col 16, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") + (Error 823, Line 7, Col 11, Line 7, Col 12, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") + (Error 879, Line 7, Col 11, Line 7, Col 12, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 823, Line 10, Col 7, Line 10, Col 9, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") + (Error 879, Line 10, Col 7, Line 10, Col 9, "Volatile fields must be marked 'mutable' and cannot be thread-static") (Error 823, Line 26, Col 17, Line 26, Col 18, "The 'VolatileField' attribute may only be used on 'let' bindings in classes") - (Error 879, Line 13, Col 5, Line 14, Col 19, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 879, Line 16, Col 5, Line 17, Col 20, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 879, Line 19, Col 5, Line 20, Col 11, "Volatile fields must be marked 'mutable' and cannot be thread-static") - (Error 879, Line 22, Col 5, Line 23, Col 13, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 14, Col 16, Line 14, Col 19, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 17, Col 16, Line 17, Col 17, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 20, Col 9, Line 20, Col 11, "Volatile fields must be marked 'mutable' and cannot be thread-static") + (Error 879, Line 23, Col 9, Line 23, Col 10, "Volatile fields must be marked 'mutable' and cannot be thread-static") ] // SOURCE= VolatileField01.fs # VolatileField01.fs From d6a5137820e9842378517296c9f7009f42e48d1f Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 27 Aug 2024 10:26:02 +0100 Subject: [PATCH 20/27] baselines --- tests/fsharp/typecheck/sigs/neg16.bsl | 57 ++++++++++++++----- tests/fsharp/typecheck/sigs/neg45.bsl | 2 + .../System.ThreadStatic/W_Deprecated01.fs | 2 +- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg16.bsl b/tests/fsharp/typecheck/sigs/neg16.bsl index d2e55e78ad4..db6a8c2160e 100644 --- a/tests/fsharp/typecheck/sigs/neg16.bsl +++ b/tests/fsharp/typecheck/sigs/neg16.bsl @@ -17,44 +17,73 @@ neg16.fs(49,7,49,23): typecheck error FS0842: This attribute is not valid for us neg16.fs(52,7,52,23): typecheck error FS0842: This attribute is not valid for use on this language element -neg16.fs(59,7,59,20): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b>' +neg16.fs(59,8,59,17): typecheck error FS0001: This expression was expected to have type + 'Choice<'a,'b>' but here has type 'string' -neg16.fs(60,7,60,24): typecheck error FS0827: This is not a valid name for an active pattern +neg16.fs(60,8,60,21): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + +neg16.fs(60,8,60,21): typecheck error FS0001: This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' -neg16.fs(61,7,61,32): typecheck error FS0827: This is not a valid name for an active pattern +neg16.fs(61,8,61,29): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. -neg16.fs(62,7,62,19): typecheck error FS0001: This expression was expected to have type - ''a option' +neg16.fs(61,8,61,29): typecheck error FS0001: This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' + +neg16.fs(62,8,62,16): typecheck error FS0001: This expression was expected to have type + ''a option' but here has type 'string' -neg16.fs(67,7,67,28): typecheck error FS0001: This expression was expected to have type +neg16.fs(67,8,67,17): typecheck error FS0001: This expression was expected to have type 'Choice<'a,'b>' but here has type 'string' -neg16.fs(68,7,68,33): typecheck error FS0827: This is not a valid name for an active pattern +neg16.fs(68,8,68,21): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + +neg16.fs(68,8,68,21): typecheck error FS0001: This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' + +neg16.fs(69,8,69,29): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. -neg16.fs(69,7,69,40): typecheck error FS0827: This is not a valid name for an active pattern +neg16.fs(69,8,69,29): typecheck error FS0001: This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' -neg16.fs(70,7,70,27): typecheck error FS0001: This expression was expected to have type +neg16.fs(70,8,70,16): typecheck error FS0001: This expression was expected to have type ''a option' but here has type 'string' -neg16.fs(75,11,75,32): typecheck error FS0001: This expression was expected to have type +neg16.fs(75,12,75,21): typecheck error FS0001: This expression was expected to have type 'Choice<'a,'b>' but here has type 'string' -neg16.fs(76,11,76,36): typecheck error FS0827: This is not a valid name for an active pattern +neg16.fs(76,12,76,25): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. -neg16.fs(77,12,77,45): typecheck error FS0827: This is not a valid name for an active pattern +neg16.fs(76,12,76,25): typecheck error FS0001: This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' + +neg16.fs(77,13,77,34): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. + +neg16.fs(77,13,77,34): typecheck error FS0001: This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type -neg16.fs(78,11,78,31): typecheck error FS0001: This expression was expected to have type +neg16.fs(78,12,78,20): typecheck error FS0001: This expression was expected to have type ''a option' but here has type 'string' diff --git a/tests/fsharp/typecheck/sigs/neg45.bsl b/tests/fsharp/typecheck/sigs/neg45.bsl index b279a0a3e87..43ab44d13fc 100644 --- a/tests/fsharp/typecheck/sigs/neg45.bsl +++ b/tests/fsharp/typecheck/sigs/neg45.bsl @@ -13,6 +13,8 @@ neg45.fs(34,27,34,28): typecheck error FS0465: Type inference problem too compli neg45.fs(41,24,41,33): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Use a 'let' binding instead. +neg45.fs(52,14,52,17): typecheck error FS0039: The type 'FooBir' does not define the field, constructor or member 'Foo'. + neg45.fs(56,19,56,28): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Use a 'let' binding instead. neg45.fs(64,19,64,20): typecheck error FS0025: Incomplete pattern matches on this expression. diff --git a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs index 60f29755a2a..fab0d7f9e46 100644 --- a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs +++ b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #Attributes // Regression test for FSHARP1.0:4226 // We want to make sure the warning emits the correct suggestion (val and mutable were swapped) -//Thread static and context static 'let' bindings are deprecated\. Instead use a declaration of the form 'static val mutable : ' in a class\. Add the 'DefaultValue' attribute to this declaration to indicate that the value is initialized to the default value on each new thread\.$ +//Thread static and context static 'let' bindings are deprecated\. Instead use a declaration of the form 'static val mutable : ' in a class\. Add the 'DefaultValue' attribute to this declaration to indicate that the value is initialized to the default value on each new thread\.$ module M module Foo = [] From fda8c6f6cbbb210b5d807a42c006be96076320f4 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 28 Aug 2024 09:24:16 +0100 Subject: [PATCH 21/27] move `neg16.bsl` content to different tests --- src/Compiler/SyntaxTree/PrettyNaming.fs | 1 - .../AttributeUsage/AttributeUsage.fs | 4 +- .../AttributeUsage/E_AllowNullLiteral.fs | 9 +++ .../Named/E_ActivePatterns03.fs | 36 ++++++++++ .../PatternMatching/Named/Named.fs | 70 +++++++++++++++++++ .../Miscellaneous/MigratedTypeCheckTests.fs | 2 +- 6 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index cf5158d634e..8ea10266de8 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -963,7 +963,6 @@ type ActivePatternInfo = member x.ActiveTagsWithRanges = let (APInfo(_, tags, _)) = x in tags - // FIXME member x.LogicalName = let (APInfo(isTotal, tags, _)) = x diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 52ce98bb50e..adfe0e3cfcb 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -756,6 +756,7 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) = (Error 934, Line 39, Col 10, Line 39, Col 13, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") (Error 842, Line 41, Col 7, Line 41, Col 23, "This attribute is not valid for use on this language element") (Error 842, Line 44, Col 7, Line 44, Col 23, "This attribute is not valid for use on this language element") + (Error 935, Line 54, Col 10, Line 54, Col 11, "Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal") ] // SOURCE=E_AllowNullLiteral.fs # E_AllowNullLiteral.fs @@ -772,8 +773,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) = (Error 934, Line 33, Col 10, Line 33, Col 11, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") (Error 934, Line 36, Col 10, Line 36, Col 11, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") (Error 934, Line 39, Col 10, Line 39, Col 13, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") - (Error 842, Line 41, Col 7, Line 41, Col 23, "This attribute is not valid for use on this language element"); + (Error 842, Line 41, Col 7, Line 41, Col 23, "This attribute is not valid for use on this language element") (Error 842, Line 44, Col 7, Line 44, Col 23, "This attribute is not valid for use on this language element") + (Error 935, Line 54, Col 10, Line 54, Col 11, "Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal") ] // SOURCE= AllowNullLiteral01.fs # AllowNullLiteral01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs index 243abb38667..0f376db3122 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs @@ -45,4 +45,13 @@ module AllowNullLiteralTest = begin let f x = 1 end + +module AllowNullLiteralWithArgumentTest = begin + + type A() = class end + + [] // expect an error here + type B() = inherit A() + +end \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs new file mode 100644 index 00000000000..6bbebdb858e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs @@ -0,0 +1,36 @@ +module ActivePatternSanityCHeckTests1 = begin + + let (|Foo|Bar|) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo2|Bar2|_|) x = "BAD DOG!" // expect: invalid name for an active pattern + let (|Foo2b|Bar2b|Baz2b|_|) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo3|_|) x = "BAD DOG!" // expect: type string doesn't match type 'option' + +end +module ActivePatternSanityCHeckTests2 = begin + + let (|Foo|Bar|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo2|Bar2|_|) (a:int) x = "BAD DOG!" // expect: invalid name for an active pattern + let (|Foo2b|Bar2b|Baz2b|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo3|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'option' +end + +module ActivePatternSanityCHeckTests3 = begin + + let rec (|Foo|Bar|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let rec (|Foo2|Bar2|_|) (a:int) x = "BAD DOG!" // expect: invalid name for an active pattern + let rec (|Foo2b|Bar2b|Baz2b|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let rec (|Foo3|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'option' + +end + +module ActivePatternIllegalPatterns = begin + + let (|``FooA++``|) (x:int) = x + let (``FooA++``(x)) = 10 + + let (|OneA|``TwoA+``|) (x:int) = if x = 0 then OneA else ``TwoA+`` + + let (|``FooB++``|_|) (x:int) = if x = 0 then Some(x) else None + let (``FooB++``(x)) = 10 + +end \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs index a2d8254c754..1a542bf6cca 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs @@ -200,6 +200,76 @@ module Named = (Error 3210, Line 6, Col 15, Line 6, Col 24, "A is an active pattern and cannot be treated as a discriminated union case with named fields.") (Warning 20, Line 6, Col 1, Line 6, Col 38, "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") ] + + [] + let ``Named - E_ActivePatterns03_fs - --test:ErrorRanges`` compilation = + compilation + |> asFs + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 3, Col 8, Line 3, Col 17, "This expression was expected to have type + 'Choice<'a,'b>' +but here has type + 'string' ") + (Error 3872, Line 4, Col 8, Line 4, Col 21, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 4, Col 8, Line 4, Col 21, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + (Error 3872, Line 5, Col 8, Line 5, Col 29, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 5, Col 8, Line 5, Col 29, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + (Error 1, Line 6, Col 8, Line 6, Col 16, "This expression was expected to have type + ''a option' +but here has type + 'string' ") + (Error 1, Line 11, Col 8, Line 11, Col 17, "This expression was expected to have type + 'Choice<'a,'b>' +but here has type + 'string' ") + (Error 3872, Line 12, Col 8, Line 12, Col 21, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 12, Col 8, Line 12, Col 21, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + (Error 3872, Line 13, Col 8, Line 13, Col 29, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 13, Col 8, Line 13, Col 29, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + (Error 1, Line 14, Col 8, Line 14, Col 16, "This expression was expected to have type + ''a option' +but here has type + 'string' ") + (Error 1, Line 19, Col 12, Line 19, Col 21, "This expression was expected to have type + 'Choice<'a,'b>' +but here has type + 'string' ") + (Error 3872, Line 20, Col 12, Line 20, Col 25, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 20, Col 12, Line 20, Col 25, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + (Error 3872, Line 21, Col 13, Line 21, Col 34, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 21, Col 13, Line 21, Col 34, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + (Error 1, Line 22, Col 12, Line 22, Col 20, "This expression was expected to have type + ''a option' +but here has type + 'string' ") + (Error 39, Line 29, Col 8, Line 29, Col 18, "The pattern discriminator 'FooA++' is not defined.") + (Warning 25, Line 29, Col 7, Line 29, Col 22, "Incomplete pattern matches on this expression.") + (Error 39, Line 31, Col 50, Line 31, Col 54, "The value or constructor 'OneA' is not defined.") + (Error 39, Line 31, Col 60, Line 31, Col 69, "The value or constructor 'TwoA+' is not defined.") + (Error 39, Line 34, Col 8, Line 34, Col 18, "The pattern discriminator 'FooB++' is not defined.") + (Warning 25, Line 34, Col 7, Line 34, Col 22, "Incomplete pattern matches on this expression.") + ] // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) [] diff --git a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs index b52d62858fa..a088380e499 100644 --- a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs @@ -63,7 +63,7 @@ let ``type check neg14`` () = singleNegTest ( "typecheck/sigs") "neg14" [] let ``type check neg15`` () = singleNegTest ( "typecheck/sigs") "neg15" -[] +[] let ``type check neg16`` () = singleNegTest ( "typecheck/sigs") "neg16" [] From 8d947633c2b34d3800ff31d6d25ef3370ed22ed5 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 28 Aug 2024 09:24:16 +0100 Subject: [PATCH 22/27] move `neg16.bsl` content to different tests --- src/Compiler/SyntaxTree/PrettyNaming.fs | 1 - .../AttributeUsage/AttributeUsage.fs | 4 +- .../AttributeUsage/E_AllowNullLiteral.fs | 9 +++ .../Named/E_ActivePatterns03.fs | 36 ++++++++++ .../PatternMatching/Named/Named.fs | 70 +++++++++++++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index cf5158d634e..8ea10266de8 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -963,7 +963,6 @@ type ActivePatternInfo = member x.ActiveTagsWithRanges = let (APInfo(_, tags, _)) = x in tags - // FIXME member x.LogicalName = let (APInfo(isTotal, tags, _)) = x diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 52ce98bb50e..adfe0e3cfcb 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -756,6 +756,7 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) = (Error 934, Line 39, Col 10, Line 39, Col 13, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") (Error 842, Line 41, Col 7, Line 41, Col 23, "This attribute is not valid for use on this language element") (Error 842, Line 44, Col 7, Line 44, Col 23, "This attribute is not valid for use on this language element") + (Error 935, Line 54, Col 10, Line 54, Col 11, "Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal") ] // SOURCE=E_AllowNullLiteral.fs # E_AllowNullLiteral.fs @@ -772,8 +773,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) = (Error 934, Line 33, Col 10, Line 33, Col 11, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") (Error 934, Line 36, Col 10, Line 36, Col 11, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") (Error 934, Line 39, Col 10, Line 39, Col 13, "Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute") - (Error 842, Line 41, Col 7, Line 41, Col 23, "This attribute is not valid for use on this language element"); + (Error 842, Line 41, Col 7, Line 41, Col 23, "This attribute is not valid for use on this language element") (Error 842, Line 44, Col 7, Line 44, Col 23, "This attribute is not valid for use on this language element") + (Error 935, Line 54, Col 10, Line 54, Col 11, "Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal") ] // SOURCE= AllowNullLiteral01.fs # AllowNullLiteral01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs index 243abb38667..0f376db3122 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AllowNullLiteral.fs @@ -45,4 +45,13 @@ module AllowNullLiteralTest = begin let f x = 1 end + +module AllowNullLiteralWithArgumentTest = begin + + type A() = class end + + [] // expect an error here + type B() = inherit A() + +end \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs new file mode 100644 index 00000000000..6bbebdb858e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/E_ActivePatterns03.fs @@ -0,0 +1,36 @@ +module ActivePatternSanityCHeckTests1 = begin + + let (|Foo|Bar|) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo2|Bar2|_|) x = "BAD DOG!" // expect: invalid name for an active pattern + let (|Foo2b|Bar2b|Baz2b|_|) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo3|_|) x = "BAD DOG!" // expect: type string doesn't match type 'option' + +end +module ActivePatternSanityCHeckTests2 = begin + + let (|Foo|Bar|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo2|Bar2|_|) (a:int) x = "BAD DOG!" // expect: invalid name for an active pattern + let (|Foo2b|Bar2b|Baz2b|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let (|Foo3|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'option' +end + +module ActivePatternSanityCHeckTests3 = begin + + let rec (|Foo|Bar|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let rec (|Foo2|Bar2|_|) (a:int) x = "BAD DOG!" // expect: invalid name for an active pattern + let rec (|Foo2b|Bar2b|Baz2b|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' + let rec (|Foo3|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'option' + +end + +module ActivePatternIllegalPatterns = begin + + let (|``FooA++``|) (x:int) = x + let (``FooA++``(x)) = 10 + + let (|OneA|``TwoA+``|) (x:int) = if x = 0 then OneA else ``TwoA+`` + + let (|``FooB++``|_|) (x:int) = if x = 0 then Some(x) else None + let (``FooB++``(x)) = 10 + +end \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs index a2d8254c754..1a542bf6cca 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Named/Named.fs @@ -200,6 +200,76 @@ module Named = (Error 3210, Line 6, Col 15, Line 6, Col 24, "A is an active pattern and cannot be treated as a discriminated union case with named fields.") (Warning 20, Line 6, Col 1, Line 6, Col 38, "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") ] + + [] + let ``Named - E_ActivePatterns03_fs - --test:ErrorRanges`` compilation = + compilation + |> asFs + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 3, Col 8, Line 3, Col 17, "This expression was expected to have type + 'Choice<'a,'b>' +but here has type + 'string' ") + (Error 3872, Line 4, Col 8, Line 4, Col 21, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 4, Col 8, Line 4, Col 21, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + (Error 3872, Line 5, Col 8, Line 5, Col 29, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 5, Col 8, Line 5, Col 29, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + (Error 1, Line 6, Col 8, Line 6, Col 16, "This expression was expected to have type + ''a option' +but here has type + 'string' ") + (Error 1, Line 11, Col 8, Line 11, Col 17, "This expression was expected to have type + 'Choice<'a,'b>' +but here has type + 'string' ") + (Error 3872, Line 12, Col 8, Line 12, Col 21, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 12, Col 8, Line 12, Col 21, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + (Error 3872, Line 13, Col 8, Line 13, Col 29, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 13, Col 8, Line 13, Col 29, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + (Error 1, Line 14, Col 8, Line 14, Col 16, "This expression was expected to have type + ''a option' +but here has type + 'string' ") + (Error 1, Line 19, Col 12, Line 19, Col 21, "This expression was expected to have type + 'Choice<'a,'b>' +but here has type + 'string' ") + (Error 3872, Line 20, Col 12, Line 20, Col 25, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 20, Col 12, Line 20, Col 25, "This expression was expected to have type + 'Choice<'a,'b> option' +but here has type + 'string' ") + (Error 3872, Line 21, Col 13, Line 21, Col 34, "Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."); + (Error 1, Line 21, Col 13, Line 21, Col 34, "This expression was expected to have type + 'Choice<'a,'b,'c> option' +but here has type + 'string' ") + (Error 1, Line 22, Col 12, Line 22, Col 20, "This expression was expected to have type + ''a option' +but here has type + 'string' ") + (Error 39, Line 29, Col 8, Line 29, Col 18, "The pattern discriminator 'FooA++' is not defined.") + (Warning 25, Line 29, Col 7, Line 29, Col 22, "Incomplete pattern matches on this expression.") + (Error 39, Line 31, Col 50, Line 31, Col 54, "The value or constructor 'OneA' is not defined.") + (Error 39, Line 31, Col 60, Line 31, Col 69, "The value or constructor 'TwoA+' is not defined.") + (Error 39, Line 34, Col 8, Line 34, Col 18, "The pattern discriminator 'FooB++' is not defined.") + (Warning 25, Line 34, Col 7, Line 34, Col 22, "Incomplete pattern matches on this expression.") + ] // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Named) [] From 0e86a9392bba751fbfa5203e1717f254f5c92d69 Mon Sep 17 00:00:00 2001 From: psfinaki Date: Fri, 30 Aug 2024 14:45:08 +0200 Subject: [PATCH 23/27] Update bsl --- tests/fsharp/core/quotesDebugInfo/test.fsx | 4 ++-- tests/fsharp/typecheck/sigs/neg10.bsl | 2 +- tests/fsharp/typecheck/sigs/neg45.bsl | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/fsharp/core/quotesDebugInfo/test.fsx b/tests/fsharp/core/quotesDebugInfo/test.fsx index f7e2f868106..63b68a71777 100644 --- a/tests/fsharp/core/quotesDebugInfo/test.fsx +++ b/tests/fsharp/core/quotesDebugInfo/test.fsx @@ -348,7 +348,7 @@ do foo (Some 5) @> let baseLine = """ -[DebugRange(344:16 - 344:21)] <{ +[DebugRange(344:16 - 344:19)] <{ let foo : FSharpFunc`2 = [DebugRange(345:16 - 347:29)] <{ (fun x : FSharpOption`1 -> @@ -452,7 +452,7 @@ do f Unchecked.defaultof<_> @> let baseLine = """ -[DebugRange(451:16 - 451:25)] <{ +[DebugRange(451:16 - 451:17)] <{ let f : FSharpFunc`2 = [DebugRange(451:28 - 451:31)] <{ (fun x : A -> diff --git a/tests/fsharp/typecheck/sigs/neg10.bsl b/tests/fsharp/typecheck/sigs/neg10.bsl index dea47f9439d..60e9056de56 100644 --- a/tests/fsharp/typecheck/sigs/neg10.bsl +++ b/tests/fsharp/typecheck/sigs/neg10.bsl @@ -116,7 +116,7 @@ is not compatible with type neg10.fs(245,50,245,51): typecheck error FS0193: A type parameter is missing a constraint 'when 'b :> C' -neg10.fs(245,17,245,40): typecheck error FS0043: A type parameter is missing a constraint 'when 'b :> C' +neg10.fs(245,17,245,20): typecheck error FS0043: A type parameter is missing a constraint 'when 'b :> C' neg10.fs(251,49,251,61): typecheck error FS0001: The type '('a -> 'a)' does not support the 'equality' constraint because it is a function type diff --git a/tests/fsharp/typecheck/sigs/neg45.bsl b/tests/fsharp/typecheck/sigs/neg45.bsl index 43ab44d13fc..3ec59a417f6 100644 --- a/tests/fsharp/typecheck/sigs/neg45.bsl +++ b/tests/fsharp/typecheck/sigs/neg45.bsl @@ -17,12 +17,12 @@ neg45.fs(52,14,52,17): typecheck error FS0039: The type 'FooBir' does not define neg45.fs(56,19,56,28): typecheck error FS0827: '(|Foo|Bir|)' is not a valid method name. Use a 'let' binding instead. -neg45.fs(64,19,64,20): typecheck error FS0025: Incomplete pattern matches on this expression. - neg45.fs(65,15,65,18): typecheck error FS3868: This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Foo e1 pat'. neg45.fs(66,15,66,18): typecheck error FS3868: This active pattern expects 1 expression argument(s) and a pattern argument, e.g., 'Bir e1 pat'. +neg45.fs(64,19,64,20): typecheck error FS0025: Incomplete pattern matches on this expression. + neg45.fs(72,26,72,31): typecheck error FS0001: A type parameter is missing a constraint 'when 'T :> System.IComparable' neg45.fs(72,10,72,19): typecheck error FS0035: This construct is deprecated: This type abbreviation has one or more declared type parameters that do not appear in the type being abbreviated. Type abbreviations must use all declared type parameters in the type being abbreviated. Consider removing one or more type parameters, or use a concrete type definition that wraps an underlying type, such as 'type C<'a> = C of ...'. From a79ce39b9ae1af0c1b2f4e4788b9b59cb8d8fb3e Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 30 Aug 2024 16:47:59 +0100 Subject: [PATCH 24/27] Update last failing tests. --- vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs b/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs index 5f658cb5155..7475f891a07 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs @@ -535,7 +535,7 @@ module Test = static let fu$$nc x = () """ - let expectedSignature = "val func: x: 'a -> unit" + let expectedSignature = "val private func: x: 'a -> unit" let tooltip = GetQuickInfoTextFromCode code From b2a8f0b9d9f973b27b83de2d184c22c13b3a70ca Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 30 Aug 2024 17:25:03 +0100 Subject: [PATCH 25/27] Update last failing tests. --- vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs b/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs index 7475f891a07..5f658cb5155 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/QuickInfoTests.fs @@ -535,7 +535,7 @@ module Test = static let fu$$nc x = () """ - let expectedSignature = "val private func: x: 'a -> unit" + let expectedSignature = "val func: x: 'a -> unit" let tooltip = GetQuickInfoTextFromCode code From 3cb5d6fa96fe133971c6ef9cd7dd23a38a917c5d Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 2 Sep 2024 14:06:31 +0100 Subject: [PATCH 26/27] FactForDESKTOP neg16 --- .../Miscellaneous/MigratedTypeCheckTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs index a088380e499..b52d62858fa 100644 --- a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedTypeCheckTests.fs @@ -63,7 +63,7 @@ let ``type check neg14`` () = singleNegTest ( "typecheck/sigs") "neg14" [] let ``type check neg15`` () = singleNegTest ( "typecheck/sigs") "neg15" -[] +[] let ``type check neg16`` () = singleNegTest ( "typecheck/sigs") "neg16" [] From 843b5228f0959aeed2fd613d0b049ea92a312fa2 Mon Sep 17 00:00:00 2001 From: psfinaki Date: Tue, 3 Sep 2024 17:28:57 +0200 Subject: [PATCH 27/27] fix bsl --- tests/fsharp/typecheck/sigs/neg16.bsl | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg16.bsl b/tests/fsharp/typecheck/sigs/neg16.bsl index db6a8c2160e..4c2300470f7 100644 --- a/tests/fsharp/typecheck/sigs/neg16.bsl +++ b/tests/fsharp/typecheck/sigs/neg16.bsl @@ -18,26 +18,26 @@ neg16.fs(49,7,49,23): typecheck error FS0842: This attribute is not valid for us neg16.fs(52,7,52,23): typecheck error FS0842: This attribute is not valid for use on this language element neg16.fs(59,8,59,17): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b>' + 'Choice<'a,'b>' but here has type 'string' neg16.fs(60,8,60,21): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. neg16.fs(60,8,60,21): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b> option' + 'Choice<'a,'b> option' but here has type - 'string' + 'string' neg16.fs(61,8,61,29): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. neg16.fs(61,8,61,29): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b,'c> option' + 'Choice<'a,'b,'c> option' but here has type - 'string' + 'string' neg16.fs(62,8,62,16): typecheck error FS0001: This expression was expected to have type - ''a option' + ''a option' but here has type 'string' @@ -49,16 +49,16 @@ but here has type neg16.fs(68,8,68,21): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. neg16.fs(68,8,68,21): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b> option' + 'Choice<'a,'b> option' but here has type - 'string' + 'string' neg16.fs(69,8,69,29): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. neg16.fs(69,8,69,29): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b,'c> option' + 'Choice<'a,'b,'c> option' but here has type - 'string' + 'string' neg16.fs(70,8,70,16): typecheck error FS0001: This expression was expected to have type ''a option' @@ -73,15 +73,16 @@ but here has type neg16.fs(76,12,76,25): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. neg16.fs(76,12,76,25): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b> option' + 'Choice<'a,'b> option' but here has type - 'string' + 'string' neg16.fs(77,13,77,34): typecheck error FS3872: Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. neg16.fs(77,13,77,34): typecheck error FS0001: This expression was expected to have type - 'Choice<'a,'b,'c> option' + 'Choice<'a,'b,'c> option' but here has type + 'string' neg16.fs(78,12,78,20): typecheck error FS0001: This expression was expected to have type ''a option'