Skip to content

Commit fd03dab

Browse files
dungpaKevinRansom
authored andcommitted
Do not warn unused variables inside extern declarations (dotnet#2032)
* Try to reproduce dotnet#485 * Do not warn unused variables inside extern declarations Fix dotnet#485.
1 parent 97a3858 commit fd03dab

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

src/fsharp/PostInferenceChecks.fs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ type env =
140140
/// Are we in a quotation?
141141
quote : bool
142142
/// Are we under [<ReflectedDefinition>]?
143-
reflect : bool }
143+
reflect : bool
144+
/// Are we in an extern declaration?
145+
external : bool }
144146

145147
let BindTypar env (tp:Typar) =
146148
{ env with
@@ -178,11 +180,12 @@ type cenv =
178180
mutable usesQuotations : bool
179181
mutable entryPointGiven:bool }
180182

181-
let BindVal cenv (v:Val) =
183+
let BindVal cenv env (v:Val) =
182184
//printfn "binding %s..." v.DisplayName
183185
let alreadyDone = cenv.boundVals.ContainsKey v.Stamp
184186
cenv.boundVals.[v.Stamp] <- 1
185-
if not alreadyDone &&
187+
if not env.external &&
188+
not alreadyDone &&
186189
cenv.reportErrors &&
187190
not v.HasBeenReferenced &&
188191
not v.IsCompiledAsTopLevel &&
@@ -195,7 +198,7 @@ let BindVal cenv (v:Val) =
195198
| _ ->
196199
warning (Error(FSComp.SR.chkUnusedValue v.DisplayName, v.Range))
197200

198-
let BindVals cenv vs = List.iter (BindVal cenv) vs
201+
let BindVals cenv env vs = List.iter (BindVal cenv env) vs
199202

200203
//--------------------------------------------------------------------------
201204
// approx walk of type
@@ -529,7 +532,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) =
529532

530533
| Expr.Let (bind,body,_,_) ->
531534
CheckBinding cenv env false bind
532-
BindVal cenv bind.Var
535+
BindVal cenv env bind.Var
533536
CheckExpr cenv env body context
534537

535538
| Expr.Const (_,m,ty) ->
@@ -700,7 +703,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) =
700703
CheckDecisionTreeTargets cenv env targets context
701704

702705
| Expr.LetRec (binds,e,_,_) ->
703-
BindVals cenv (valsOfBinds binds)
706+
BindVals cenv env (valsOfBinds binds)
704707
CheckBindings cenv env binds
705708
CheckExprNoByrefs cenv env e
706709

@@ -943,7 +946,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn
943946
restArgs |> List.iter (fun arg -> if isByrefTy cenv.g arg.Type then arg.SetHasBeenReferenced())
944947

945948
syntacticArgs |> List.iter (CheckValSpec cenv env)
946-
syntacticArgs |> List.iter (BindVal cenv)
949+
syntacticArgs |> List.iter (BindVal cenv env)
947950

948951
// Trigger a test hook
949952
match memInfo with
@@ -1014,7 +1017,7 @@ and CheckDecisionTreeTargets cenv env targets context =
10141017
targets |> Array.iter (CheckDecisionTreeTarget cenv env context)
10151018

10161019
and CheckDecisionTreeTarget cenv env context (TTarget(vs,e,_)) =
1017-
BindVals cenv vs
1020+
BindVals cenv env vs
10181021
vs |> List.iter (CheckValSpec cenv env)
10191022
CheckExpr cenv env e context
10201023

@@ -1136,6 +1139,8 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) =
11361139
let isTop = Option.isSome bind.Var.ValReprInfo
11371140
//printfn "visiting %s..." v.DisplayName
11381141

1142+
let env = { env with external = env.external || cenv.g.attrib_DllImportAttribute |> Option.exists (fun attr -> HasFSharpAttribute cenv.g attr v.Attribs) }
1143+
11391144
// Check that active patterns don't have free type variables in their result
11401145
match TryGetActivePatternInfo (mkLocalValRef v) with
11411146
| Some _apinfo when _apinfo.ActiveTags.Length > 1 ->
@@ -1669,13 +1674,13 @@ and CheckDefnInModule cenv env x =
16691674
match x with
16701675
| TMDefRec(isRec,tycons,mspecs,m) ->
16711676
CheckNothingAfterEntryPoint cenv m
1672-
if isRec then BindVals cenv (allValsOfModDef x |> Seq.toList)
1677+
if isRec then BindVals cenv env (allValsOfModDef x |> Seq.toList)
16731678
CheckEntityDefns cenv env tycons
16741679
List.iter (CheckModuleSpec cenv env) mspecs
16751680
| TMDefLet(bind,m) ->
16761681
CheckNothingAfterEntryPoint cenv m
16771682
CheckModuleBinding cenv env bind
1678-
BindVal cenv bind.Var
1683+
BindVal cenv env bind.Var
16791684
| TMDefDo(e,m) ->
16801685
CheckNothingAfterEntryPoint cenv m
16811686
CheckNoReraise cenv None e
@@ -1686,7 +1691,7 @@ and CheckDefnInModule cenv env x =
16861691
and CheckModuleSpec cenv env x =
16871692
match x with
16881693
| ModuleOrNamespaceBinding.Binding bind ->
1689-
BindVals cenv (valsOfBinds [bind])
1694+
BindVals cenv env (valsOfBinds [bind])
16901695
CheckModuleBinding cenv env bind
16911696
| ModuleOrNamespaceBinding.Module (mspec, rhs) ->
16921697
CheckEntityDefn cenv env mspec
@@ -1726,7 +1731,8 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu
17261731
boundTyparNames=[]
17271732
argVals = ValMap.Empty
17281733
boundTypars= TyparMap.Empty
1729-
reflect=false }
1734+
reflect=false
1735+
external=false }
17301736

17311737
CheckModuleExpr cenv env mexpr
17321738
CheckAttribs cenv env extraAttribs
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//<Expects status="success" ></Expects>
2+
open System
3+
open System.Runtime.InteropServices
4+
5+
module Test =
6+
7+
[<DllImport("shell32.dll", CharSet=CharSet.Auto)>]
8+
extern int32 ExtractIconEx(string szFileName, int nIconIndex,IntPtr[] phiconLarge, IntPtr[] phiconSmall,uint32 nIcons)
9+
10+
[<DllImport("user32.dll", EntryPoint="DestroyIcon", SetLastError=true)>]
11+
extern int DestroyIcon(IntPtr hIcon)
12+
13+
[<EntryPoint>]
14+
let main _argv =
15+
let _ = Test.DestroyIcon IntPtr.Zero
16+
17+
let _ = Test.ExtractIconEx("", 0, [| |], [| |], 0u)
18+
19+
0

tests/fsharpqa/Source/Warnings/env.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
SOURCE=AccessOfTypeAbbreviation4.fs # AccessOfTypeAbbreviation4.fs
2121
SOURCE=AccessOfTypeAbbreviation5.fs # AccessOfTypeAbbreviation5.fs
2222
SOURCE=AccessOfTypeAbbreviation6.fs # AccessOfTypeAbbreviation6.fs
23+
SOURCE=DontWarnExternalFunctionAsUnused.fs SCFLAGS="--warnon:1182 --warnaserror+" # DontWarnExternalFunctionAsUnused.fs
2324
SOURCE=SuggestTypesInModule.fs # SuggestTypesInModule.fs
2425
SOURCE=SuggestGenericType.fs # SuggestGenericType.fs
2526
SOURCE=SuggestTypeParameters.fs # SuggestTypeParameters.fs

0 commit comments

Comments
 (0)