|
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 |
|
) |
These checks don't be performed on F#-style extension methods.
fsharp/src/Compiler/Checking/PostInferenceChecks.fs
Lines 2407 to 2477 in a9d3ead
Repro steps
Put this code into fsi:
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