From 7daf672381873ff104ce281464d8bf74e3475f9f Mon Sep 17 00:00:00 2001 From: ncave <777696+ncave@users.noreply.github.com> Date: Tue, 31 Jan 2023 14:20:17 -0800 Subject: [PATCH] Don't lose attributes of method parameters (#12) Temporary fix, remove when upstream dotnet#13786 is fixed. --- src/Compiler/Checking/CheckComputationExpressions.fs | 2 +- src/Compiler/Checking/CheckExpressions.fs | 7 ++++--- src/Compiler/Checking/MethodCalls.fs | 2 +- src/Compiler/Checking/NicePrint.fs | 4 ++-- src/Compiler/Checking/PostInferenceChecks.fs | 4 ++-- src/Compiler/Checking/infos.fs | 12 ++++++------ src/Compiler/Checking/infos.fsi | 6 +++--- src/Compiler/Service/FSharpCheckerResults.fs | 2 +- src/Compiler/Service/ServiceDeclarationLists.fs | 2 +- src/Compiler/Symbols/Symbols.fs | 6 ++---- 10 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs index f9887d625f30..90ef6e35c92f 100644 --- a/src/Compiler/Checking/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/CheckComputationExpressions.fs @@ -441,7 +441,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 diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 496081df39d0..d4f8ac482d2c 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -4093,7 +4093,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 @@ -9415,6 +9415,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 = @@ -9468,7 +9469,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 @@ -9713,7 +9714,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 diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs index 0c72bc72600f..eeec6f40ae8d 100644 --- a/src/Compiler/Checking/MethodCalls.fs +++ b/src/Compiler/Checking/MethodCalls.fs @@ -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 diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index a97d919e64b3..53ec1c5f5116 100755 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1574,7 +1574,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 @@ -1617,7 +1617,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 diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs index 67128182ace1..79720a00406a 100644 --- a/src/Compiler/Checking/PostInferenceChecks.fs +++ b/src/Compiler/Checking/PostInferenceChecks.fs @@ -2341,13 +2341,13 @@ let CheckEntityDefn cenv env (tycon: Entity) = if numCurriedArgSets > 1 && (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) - |> List.existsSquared (fun (ParamData(isParamArrayArg, _isInArg, isOutArg, optArgInfo, callerInfo, _, reflArgInfo, ty)) -> + |> 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)) -> + |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfo, _, _, ty), _) -> ignore isInArg match (optArgInfo, callerInfo) with | _, NoCallerInfo -> () diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs index af33e162200e..109ed93c1f3e 100644 --- a/src/Compiler/Checking/infos.fs +++ b/src/Compiler/Checking/infos.fs @@ -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 @@ -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 @@ -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. @@ -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. /// diff --git a/src/Compiler/Checking/infos.fsi b/src/Compiler/Checking/infos.fsi index 5f6aab66a91d..992e6b58a7d9 100644 --- a/src/Compiler/Checking/infos.fsi +++ b/src/Compiler/Checking/infos.fsi @@ -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. [] @@ -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 diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index b5dab2dd05d1..70ff652481af 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -590,7 +590,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) diff --git a/src/Compiler/Service/ServiceDeclarationLists.fs b/src/Compiler/Service/ServiceDeclarationLists.fs index 104ae1da0ff7..be9ad7d70942 100644 --- a/src/Compiler/Service/ServiceDeclarationLists.fs +++ b/src/Compiler/Service/ServiceDeclarationLists.fs @@ -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 diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index 9c7a86a61f6e..dc2772708b17 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -2096,10 +2096,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