-
Notifications
You must be signed in to change notification settings - Fork 847
Open
Labels
Milestone
Description
These checks don't be performed on F#-style extension methods.
fsharp/src/Compiler/Checking/PostInferenceChecks.fs
Lines 2407 to 2477 in a9d3ead
| for minfo in immediateMeths do | |
| let nm = minfo.LogicalName | |
| let m = (match minfo.ArbitraryValRef with None -> m | Some vref -> vref.DefinitionRange) | |
| let others = getOtherMethods minfo | |
| // abstract/default pairs of duplicate methods are OK | |
| let IsAbstractDefaultPair (x: MethInfo) (y: MethInfo) = | |
| x.IsDispatchSlot && y.IsDefiniteFSharpOverride | |
| let IsAbstractDefaultPair2 (minfo: MethInfo) (minfo2: MethInfo) = | |
| IsAbstractDefaultPair minfo minfo2 || IsAbstractDefaultPair minfo2 minfo | |
| let checkForDup erasureFlag (minfo2: MethInfo) = | |
| not (IsAbstractDefaultPair2 minfo minfo2) | |
| && (minfo.IsInstance = minfo2.IsInstance) | |
| && MethInfosEquivWrtUniqueness erasureFlag m minfo minfo2 | |
| if others |> List.exists (checkForDup EraseAll) then | |
| if others |> List.exists (checkForDup EraseNone) then | |
| errorR(Error(FSComp.SR.chkDuplicateMethod(nm, NicePrint.minimalStringOfType cenv.denv ty), m)) | |
| else | |
| errorR(Error(FSComp.SR.chkDuplicateMethodWithSuffix(nm, NicePrint.minimalStringOfType cenv.denv ty), m)) | |
| let numCurriedArgSets = minfo.NumArgs.Length | |
| if numCurriedArgSets > 1 && others |> List.exists (fun minfo2 -> not (IsAbstractDefaultPair2 minfo minfo2)) then | |
| errorR(Error(FSComp.SR.chkDuplicateMethodCurried(nm, NicePrint.minimalStringOfType cenv.denv ty), m)) | |
| if numCurriedArgSets > 1 && | |
| (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) | |
| |> List.existsSquared (fun (ParamData(isParamArrayArg, _isInArg, isOutArg, optArgInfo, callerInfo, _, reflArgInfo, ty)) -> | |
| isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfo <> NoCallerInfo || isByrefLikeTy g m ty)) then | |
| errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m)) | |
| if numCurriedArgSets = 1 then | |
| let inline tryDestOptionalTy g ty = | |
| if isOptionTy g ty then | |
| destOptionTy g ty |> ValueSome | |
| elif g.langVersion.SupportsFeature LanguageFeature.SupportValueOptionsAsOptionalParameters && isValueOptionTy g ty then | |
| destValueOptionTy g ty |> ValueSome | |
| else | |
| ValueNone | |
| let errorIfNotStringTy m ty callerInfo = | |
| if not (typeEquiv g g.string_ty ty) then | |
| errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "string", NicePrint.minimalStringOfType cenv.denv ty), m)) | |
| let errorIfNotOptional tyToCompare desiredTyName m ty callerInfo = | |
| match tryDestOptionalTy g ty with | |
| | ValueSome t when typeEquiv g tyToCompare t -> () | |
| | ValueSome innerTy -> errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, desiredTyName, NicePrint.minimalStringOfType cenv.denv innerTy), m)) | |
| | ValueNone -> errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, desiredTyName, NicePrint.minimalStringOfType cenv.denv ty), m)) | |
| minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) | |
| |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, nameOpt, _, ty)) -> | |
| ignore isInArg | |
| let m = | |
| match nameOpt with | |
| | Some name -> name.idRange | |
| | None -> m | |
| match (optArgInfo, callerInfo) with | |
| | _, NoCallerInfo -> () | |
| | NotOptional, _ -> errorR(Error(FSComp.SR.tcCallerInfoNotOptional(callerInfo |> string), m)) | |
| | CallerSide _, CallerLineNumber -> | |
| if not (typeEquiv g g.int32_ty ty) then | |
| errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfo |> string, "int", NicePrint.minimalStringOfType cenv.denv ty), m)) | |
| | CalleeSide, CallerLineNumber -> errorIfNotOptional g.int32_ty "int" m ty callerInfo | |
| | CallerSide _, (CallerFilePath | CallerMemberName) -> errorIfNotStringTy m ty callerInfo | |
| | CalleeSide, (CallerFilePath | CallerMemberName) -> errorIfNotOptional g.string_ty "string" m ty callerInfo | |
| ) |
Repro steps
Put this code into fsi:
open System.Runtime.CompilerServices;;
[<Extension>]
type C =
// FS0440: Methods with curried arguments cannot declare 'out', 'ParamArray', 'optional', 'ReflectedDefinition', 'byref', 'CallerLineNumber', 'CallerMemberName', or 'CallerFilePath' arguments
[<Extension>]
static member B(this: obj)(arg: string outref) = ()
// FS1246: 'CallerLineNumber' must be applied to an argument of type 'int', but has been applied to an argument of type 'string'
[<Extension>]
static member C(this: obj, [<CallerLineNumber>] ?line: string) = ()
;;
type System.Object with
// No error
member this.B()(arg: string outref) = ()
// No error
member this.C([<CallerLineNumber>] ?line: string) = ()
;;Expected behavior
Both C#-style and F#-style extension methods give the same error reports.
Actual behavior
Only C#-style extension methods gives the error reports.
Known workarounds
Not using F#-style extension methods.
Related information
- Microsoft (R) F# Interactive version F# 10.0 的 14.0.101.0
- .NET 10.0.101
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
New