Skip to content

Commit

Permalink
Add warnings for extra arguments of failwithf function
Browse files Browse the repository at this point in the history
  • Loading branch information
dungpa committed Sep 6, 2015
1 parent 4794492 commit 9fd0610
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 22 deletions.
20 changes: 15 additions & 5 deletions src/fsharp/CheckFormatStrings.fs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ let newInfo ()=
addZeros = false;
precision = false}

let ParseFormatString m g fmt bty cty dty =
let parseFormatStringInternal m g fmt bty cty =
let len = String.length fmt

let rec parseLoop acc i =
Expand All @@ -58,10 +58,7 @@ let ParseFormatString m g fmt bty cty dty =
acc |> List.map snd |> List.rev
else
failwithf "%s" <| FSComp.SR.forPositionalSpecifiersNotPermitted()

let aty = List.foldBack (-->) argtys dty
let ety = mkTupledTy g argtys
aty,ety
argtys
elif System.Char.IsSurrogatePair(fmt,i) then
parseLoop acc (i+2)
else
Expand Down Expand Up @@ -230,3 +227,16 @@ let ParseFormatString m g fmt bty cty dty =
| _ -> parseLoop acc (i+1)
parseLoop [] 0

let ParseFormatString m g fmt bty cty dty =
let argtys = parseFormatStringInternal m g fmt bty cty
let aty = List.foldBack (-->) argtys dty
let ety = mkTupledTy g argtys
aty, ety

let TryCountFormatStringArguments m g fmt bty cty =
try
parseFormatStringInternal m g fmt bty cty
|> List.length
|> Some
with _ ->
None
2 changes: 2 additions & 0 deletions src/fsharp/CheckFormatStrings.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ open Microsoft.FSharp.Compiler.TcGlobals
open Microsoft.FSharp.Compiler.AbstractIL.Internal

val ParseFormatString : Range.range -> TcGlobals -> string -> TType -> TType -> TType -> TType * TType

val TryCountFormatStringArguments : m:Range.range -> g:TcGlobals -> fmt:string -> bty:TType -> cty:TType -> int option
2 changes: 1 addition & 1 deletion src/fsharp/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1343,4 +1343,4 @@ estApplyStaticArgumentsForMethodNotImplemented,"A type provider implemented GetS
3186,pickleMissingDefinition,"An error occurred while reading the F# metadata node at position %d in table '%s' of assembly '%s'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using."
3187,checkNotSufficientlyGenericBecauseOfScope,"Type inference caused the type variable %s to escape its scope. Consider adding an explicit type parameter declaration or adjusting your code to be less generic."
3188,checkNotSufficientlyGenericBecauseOfScopeAnon,"Type inference caused an inference type variable to escape its scope. Consider adding type annotations to make your code less generic."
3189,checkRaiseFamilyFunctionArgumentCount,"Function '%s' applies to at most %d argument(s). Remaining arguments are being ignored."
3189,checkRaiseFamilyFunctionArgumentCount,"Redundant arguments are being ignored in function '%s'. Expected %d but got %d arguments."
34 changes: 23 additions & 11 deletions src/fsharp/PostInferenceChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -584,22 +584,34 @@ and CheckExprInContext (cenv:cenv) (env:env) expr (context:ByrefCallContext) =

| Expr.App(f,fty,tyargs,argsl,m) ->
let (|OptionalCoerce|) = function
| Expr.Op(TOp.Coerce _,_,[Expr.App(f, _, _, [], _)],_) -> f
| Expr.Op(TOp.Coerce _, _, [Expr.App(f, _, _, [], _)], _) -> f
| x -> x
if cenv.reportErrors then
let g = cenv.g
match f with
| OptionalCoerce(Expr.Val(v, _, m'))
| OptionalCoerce(Expr.Val(v, _, funcRange))
when (valRefEq g v g.raise_vref || valRefEq g v g.failwith_vref || valRefEq g v g.null_arg_vref || valRefEq g v g.invalid_op_vref) ->
match argsl with
| [] | [_] -> ()
| _ :: _ :: _ ->
warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 1), m'))
| OptionalCoerce(Expr.Val(v, _, m')) when valRefEq g v g.invalid_arg_vref ->
match argsl with
| [] | [_] | [_; _] -> ()
| _ :: _ :: _ :: _ ->
warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 2), m'))
match argsl with
| [] | [_] -> ()
| _ :: _ :: _ ->
warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 1, List.length argsl), funcRange))
| OptionalCoerce(Expr.Val(v, _, funcRange)) when valRefEq g v g.invalid_arg_vref ->
match argsl with
| [] | [_] | [_; _] -> ()
| _ :: _ :: _ :: _ ->
warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 2, List.length argsl), funcRange))
| OptionalCoerce(Expr.Val(failwithfFunc, _, funcRange)) when valRefEq g failwithfFunc g.failwithf_vref ->
match argsl with
| Expr.App (Expr.Val(newFormat, _, _), _, [_; typB; typC; _; _], [Expr.Const(Const.String formatString, formatRange, _)], _) :: xs when valRefEq g newFormat g.new_format_vref ->
match CheckFormatStrings.TryCountFormatStringArguments formatRange g formatString typB typC with
| Some n ->
let expected = n + 1
let actual = List.length xs + 1
if expected < actual then
warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(failwithfFunc.DisplayName, expected, actual), funcRange))
| None -> ()
| _ ->
()
| _ ->
()

Expand Down
16 changes: 11 additions & 5 deletions src/fsharp/TcGlobals.fs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,9 @@ type public TcGlobals =
null_arg_vref : ValRef
invalid_op_info : IntrinsicValRef
invalid_op_vref : ValRef
failwithf_info : IntrinsicValRef
failwithf_vref : ValRef

lazy_force_info : IntrinsicValRef
lazy_create_info : IntrinsicValRef

Expand Down Expand Up @@ -920,11 +923,12 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
let unchecked_unary_minus_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_UnaryNegation" ,None ,None ,[vara], mk_unop_ty varaTy)
let unchecked_unary_not_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "not" ,None ,Some "Not" ,[], mk_unop_ty bool_ty)

let raise_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "raise" ,None ,Some "Raise" ,[vara],([[mkSysNonGenericTy sys "Exception"]],varaTy))
let failwith_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "failwith" ,None ,Some "FailWith",[vara],([[string_ty]],varaTy))
let invalid_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidArg" ,None ,Some "InvalidArg",[vara],([[string_ty]; [string_ty]],varaTy))
let null_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nullArg" ,None ,Some "NullArg",[vara],([[string_ty]],varaTy))
let invalid_op_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidOp" ,None ,Some "InvalidOp",[vara],([[string_ty]],varaTy))
let raise_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "raise" ,None ,Some "Raise" ,[vara], ([[mkSysNonGenericTy sys "Exception"]],varaTy))
let failwith_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "failwith" ,None ,Some "FailWith" ,[vara], ([[string_ty]],varaTy))
let invalid_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidArg" ,None ,Some "InvalidArg" ,[vara], ([[string_ty]; [string_ty]],varaTy))
let null_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nullArg" ,None ,Some "NullArg" ,[vara], ([[string_ty]],varaTy))
let invalid_op_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidOp" ,None ,Some "InvalidOp" ,[vara], ([[string_ty]],varaTy))
let failwithf_info = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref, "failwithf" ,None, Some "PrintFormatToStringThenFail" ,[vara;varb],([[mk_format4_ty varaTy unit_ty string_ty string_ty]], varaTy))

let reraise_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "reraise" ,None ,Some "Reraise",[vara], ([[unit_ty]],varaTy))
let typeof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "typeof" ,None ,Some "TypeOf" ,[vara], ([],system_Type_typ))
Expand Down Expand Up @@ -1375,6 +1379,8 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa
null_arg_vref = ValRefForIntrinsic null_arg_info
invalid_op_info = invalid_op_info
invalid_op_vref = ValRefForIntrinsic invalid_op_info
failwithf_info = failwithf_info
failwithf_vref = ValRefForIntrinsic failwithf_info

reraise_info = reraise_info
reraise_vref = ValRefForIntrinsic reraise_info
Expand Down

0 comments on commit 9fd0610

Please sign in to comment.