Skip to content

Don't lose attributes of method parameters #13800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Compiler/Checking/CheckComputationExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
argInfos
|> List.map (fun (_nm, __maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, methInfo) ->
match methInfo.GetParamAttribs(cenv.amap, mWhole) with
| [curriedArgInfo] -> Some curriedArgInfo // one for the actual argument group
| [curriedArgInfo] -> Some (List.map fst curriedArgInfo) // one for the actual argument group
| _ -> None)
|> Some
| _ -> None
Expand Down
7 changes: 4 additions & 3 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4095,7 +4095,7 @@ and TcPseudoMemberSpec cenv newOk env synTypes tpenv synMemberSig m =
let logicalCompiledName = ComputeLogicalName id memberFlags
for argInfos in curriedArgInfos do
for argInfo in argInfos do
let info = CrackParamAttribsInfo g argInfo
let info, _ = CrackParamAttribsInfo g argInfo
let (ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo)) = info
if isParamArrayArg || isInArg || isOutArg || optArgInfo.IsOptional || callerInfo <> CallerInfo.NoCallerInfo || reflArgInfo <> ReflectedArgInfo.None then
if g.langVersion.SupportsFeature(LanguageFeature.InterfacesWithAbstractStaticMembers) then
Expand Down Expand Up @@ -9417,6 +9417,7 @@ and GenerateMatchingSimpleArgumentTypes (cenv: cenv) (calledMeth: MethInfo) mIte
let g = cenv.g
let curriedMethodArgAttribs = calledMeth.GetParamAttribs(cenv.amap, mItem)
curriedMethodArgAttribs
|> List.map (List.map fst)
|> List.map (List.filter isSimpleFormalArg >> NewInferenceTypes g)

and UnifyMatchingSimpleArgumentTypes (cenv: cenv) (env: TcEnv) exprTy (calledMeth: MethInfo) mMethExpr mItem =
Expand Down Expand Up @@ -9470,7 +9471,7 @@ and TcMethodApplication_SplitSynArguments
let singleMethodCurriedArgs =
match candidates with
| [calledMeth] when List.forall isNil namedCurriedCallerArgs ->
let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem)
let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem) |> List.map (List.map fst)
match curriedCalledArgs with
| [arg :: _] when isSimpleFormalArg arg -> Some(curriedCalledArgs)
| _ -> None
Expand Down Expand Up @@ -9715,7 +9716,7 @@ and TcAdhocChecksOnLibraryMethods (cenv: cenv) (env: TcEnv) isInstance (finalCal
if HasHeadType g g.tcref_System_Collections_Generic_Dictionary finalCalledMethInfo.ApparentEnclosingType &&
finalCalledMethInfo.IsConstructor &&
not (finalCalledMethInfo.GetParamDatas(cenv.amap, mItem, finalCalledMeth.CalledTyArgs)
|> List.existsSquared (fun (ParamData(_, _, _, _, _, _, _, ty)) ->
|> List.existsSquared (fun (ParamData(_, _, _, _, _, _, _, ty), _) ->
HasHeadType g g.tcref_System_Collections_Generic_IEqualityComparer ty)) then

match argsOfAppTy g finalCalledMethInfo.ApparentEnclosingType with
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/MethodCalls.fs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ type CalledMethArgSet<'T> =
let MakeCalledArgs amap m (minfo: MethInfo) minst =
// Mark up the arguments with their position, so we can sort them back into order later
let paramDatas = minfo.GetParamDatas(amap, m, minst)
paramDatas |> List.mapiSquared (fun i j (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoFlags, nmOpt, reflArgInfo, calledArgTy)) ->
paramDatas |> List.mapiSquared (fun i j (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoFlags, nmOpt, reflArgInfo, calledArgTy), _) ->
{ Position=(i,j)
IsParamArray=isParamArrayArg
OptArgInfo=optArgInfo
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/NicePrint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,7 @@ module InfoMemberPrinting =
let layout = layoutXmlDocOfMethInfo denv infoReader minfo layout

let paramsL =
let paramDatas = minfo.GetParamDatas(amap, m, minst)
let paramDatas = minfo.GetParamDatas(amap, m, minst) |> List.map (List.map fst)
if List.forall isNil paramDatas then
WordL.structUnit
else
Expand Down Expand Up @@ -1609,7 +1609,7 @@ module InfoMemberPrinting =
PrintTypes.layoutTyparDecls denv idL true minfo.FormalMethodTypars ^^
SepL.leftParen

let paramDatas = minfo.GetParamDatas (amap, m, minst)
let paramDatas = minfo.GetParamDatas (amap, m, minst) |> List.map (List.map fst)
let layout = layout ^^ sepListL RightL.comma ((List.concat >> List.map (layoutParamData denv)) paramDatas)
layout ^^ RightL.rightParen ^^ WordL.colon ^^ PrintTypes.layoutType denv retTy

Expand Down
12 changes: 6 additions & 6 deletions src/Compiler/Checking/PostInferenceChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2339,15 +2339,15 @@ let CheckEntityDefn cenv env (tycon: Entity) =
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
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
minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
|> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, _, _, ty)) ->
minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst)
|> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, _, _, ty), _) ->
ignore isInArg
match (optArgInfo, callerInfo) with
| _, NoCallerInfo -> ()
Expand Down
12 changes: 6 additions & 6 deletions src/Compiler/Checking/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ let CrackParamAttribsInfo g (ty: TType, argInfo: ArgReprInfo) =
| ValueSome optTy when typeEquiv g g.int32_ty optTy -> CallerFilePath
| _ -> CallerLineNumber

ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo)
ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo), argInfo.Attribs

#if !NO_TYPEPROVIDERS

Expand Down Expand Up @@ -1195,7 +1195,7 @@ type MethInfo =
if p.Type.TypeRef.FullName = "System.Int32" then CallerFilePath
else CallerLineNumber

ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo) ] ]
ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo), [] ] ]

| FSMeth(g, _, vref, _) ->
GetArgInfosOfMember x.IsCSharpStyleExtensionMember g vref
Expand All @@ -1216,7 +1216,7 @@ type MethInfo =
| None -> ReflectedArgInfo.None
let isOutArg = p.PUntaint((fun p -> p.IsOut && not p.IsIn), m)
let isInArg = p.PUntaint((fun p -> p.IsIn && not p.IsOut), m)
ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, NoCallerInfo, reflArgInfo)] ]
ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, NoCallerInfo, reflArgInfo), [] ] ]
#endif

/// Get the signature of an abstract method slot.
Expand Down Expand Up @@ -1317,13 +1317,13 @@ type MethInfo =
#endif

let paramAttribs = x.GetParamAttribs(amap, m)
(paramAttribs, paramNamesAndTypes) ||> List.map2 (List.map2 (fun info (ParamNameAndType(nmOpt, pty)) ->
(paramAttribs, paramNamesAndTypes) ||> List.map2 (List.map2 (fun (info, attribs) (ParamNameAndType(nmOpt, pty)) ->
let (ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo)) = info
ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, nmOpt, reflArgInfo, pty)))
ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, nmOpt, reflArgInfo, pty), attribs))

/// Get the ParamData objects for the parameters of a MethInfo
member x.HasParamArrayArg(amap, m, minst) =
x.GetParamDatas(amap, m, minst) |> List.existsSquared (fun (ParamData(isParamArrayArg, _, _, _, _, _, _, _)) -> isParamArrayArg)
x.GetParamDatas(amap, m, minst) |> List.existsSquared (fun (ParamData(isParamArrayArg, _, _, _, _, _, _, _), _) -> isParamArrayArg)

/// Select all the type parameters of the declaring type of a method.
///
Expand Down
6 changes: 3 additions & 3 deletions src/Compiler/Checking/infos.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ type ParamAttribs =
callerInfo: CallerInfo *
reflArgInfo: ReflectedArgInfo

val CrackParamAttribsInfo: TcGlobals -> ty: TType * argInfo: ArgReprInfo -> ParamAttribs
val CrackParamAttribsInfo: TcGlobals -> ty: TType * argInfo: ArgReprInfo -> ParamAttribs * Attribs

/// Describes an F# use of an IL type, including the type instantiation associated with the type at a particular usage point.
[<NoComparison; NoEquality>]
Expand Down Expand Up @@ -512,10 +512,10 @@ type MethInfo =
member GetCustomAttrs: unit -> ILAttributes

/// Get the parameter attributes of a method info, which get combined with the parameter names and types
member GetParamAttribs: amap: ImportMap * m: range -> ParamAttribs list list
member GetParamAttribs: amap: ImportMap * m: range -> (ParamAttribs * Attribs) list list

/// Get the ParamData objects for the parameters of a MethInfo
member GetParamDatas: amap: ImportMap * m: range * minst: TType list -> ParamData list list
member GetParamDatas: amap: ImportMap * m: range * minst: TType list -> (ParamData * Attribs) list list

/// Get the parameter names of a MethInfo
member GetParamNames: unit -> string option list list
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ type internal TypeCheckInfo
match meth.GetParamDatas(amap, m, meth.FormalMethodInst) with
| x :: _ ->
x
|> List.choose (fun (ParamData (_isParamArray, _isInArg, _isOutArg, _optArgInfo, _callerInfo, name, _, ty)) ->
|> List.choose (fun (ParamData (_isParamArray, _isInArg, _isOutArg, _optArgInfo, _callerInfo, name, _, ty), _) ->
match name with
| Some id -> Some(Item.OtherName(Some id, ty, None, Some(ArgumentContainer.Method meth), id.idRange))
| None -> None)
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/ServiceDeclarationLists.fs
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ module internal DescriptionListsImpl =

| Item.CtorGroup(_, minfo :: _)
| Item.MethodGroup(_, minfo :: _, _) ->
let paramDatas = minfo.GetParamDatas(amap, m, minfo.FormalMethodInst) |> List.head
let paramDatas = minfo.GetParamDatas(amap, m, minfo.FormalMethodInst) |> List.head |> List.map fst
let retTy = minfo.GetFSharpReturnType(amap, m, minfo.FormalMethodInst)
let _prettyTyparInst, prettyParams, prettyRetTyL, _prettyConstraintsL = PrettyParamsOfParamDatas g denv item.TyparInstantiation paramDatas retTy
// FUTURE: prettyTyparInst is the pretty version of the known instantiations of type parameters in the output. It could be returned
Expand Down
6 changes: 2 additions & 4 deletions src/Compiler/Symbols/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2092,10 +2092,8 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
| M m | C m ->
[ for argTys in m.GetParamDatas(cenv.amap, range0, m.FormalMethodInst) do
yield
[ for ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty) in argTys do
// INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for
// either .NET or F# parameters
let argInfo: ArgReprInfo = { Name=nmOpt; Attribs=[]; OtherRange=None }
[ for ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty), attribs in argTys do
let argInfo: ArgReprInfo = { Name=nmOpt; Attribs=attribs; OtherRange=None }
let m =
match nmOpt with
| Some v -> v.idRange
Expand Down