Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Claire Neveu
    @ClaireNeveu
    If you are a contributor and you would like to become a maintainer, send me your Sonatype account and I'll give you publish rights for the org.wartremover namespace on Maven Central.
    lysium
    @lysium
    Greetings! I'm new to wartremover and love it! I was wondering how you handle situations where the caller of a function provides illegal arguments, eg. calls toMyClass on a string that does not represent MyClass.
    Wartremover correctly dislikes using throw, so let's say I rewrite toMyClass to return an Either. But then what is the caller supposed to do? Call System.exit(1) if toMyClass returnsLeft? I'd like the program to crash (with a stack trace, if possible). Generally, I'd like to know how you handle situations where you used to throw IllegalArgumentException.
    ritschwumm
    @ritschwumm
    ideally they wouldn't compile, right?
    lysium
    @lysium
    Thanks for the insight, @ritschwumm! I think yes and no.
    Yes, because if I'd like it to crash with a stack trace, I wish it did not happen in the first place.
    No, because you cannot control everything: say you read a serialization from a db and that is corrupted for some awful reason. You don't want to continue the program because clearly something is terribly wrong. You don't want your program to not compile, either, though, because usually it is supposed to work.
    Using Wartremover, I cannot throw (which is a good thing!), but what do you do instead?
    ritschwumm
    @ritschwumm
    @lysium it depends - for programming errors i indeed use exceptions. but for every other error conditions i use Either/EitherT/MonadError or something like that.
    lysium
    @lysium
    @ritschwumm So you supress the warning to wartremover in the case of programming errors?
    Rob Norris
    @tpolecat
    If you really do need to throw just suppress the warning. That's completely valid.
    lysium
    @lysium
    I see, thank you.
    Rob Norris
    @tpolecat
    Really there should also be a warning on catch … that's the problematic one.
    lysium
    @lysium
    Good point; there should probably be only a warning on catch, now that I think about it... :-)
    Rob Norris
    @tpolecat
    Yeah from a theoretic point of view throw introduces nontermination, which is fine in the sense that :shrug: there's nothing we can do about it; and catch is a problem because it lets you observe nontermination.
    But in practice you probably don't want to be throwing. ;-)
    lysium
    @lysium
    Yes, I'd like to avoid throwing, too, but how do I do that eg., in the case of programming errors where a function is called with invalid arguments or the serialization in the DB is corrupted?
    Rob Norris
    @tpolecat
    That's when you want to throw. Your program can't continue and should crash.
    Although note that the invalid argument problem can often be prevented by using more precise types.
    lysium
    @lysium
    :thumbsup:
    Edmund Noble
    @edmundnoble
    I have a null pointer exception in ForbidInference.scala:30 in wart remover. Is there any way I can stop this file from being called into?
    I have no idea what's causing this but this is just another compiler crash in a series of compiler stupidities and I just want it all to stop.
    Here's what doesn't work:
      wartremoverExcluded += baseDirectory.value,
      wartremoverErrors in (Compile, compile) := Seq.empty
    lysium
    @lysium
    The comma after .value looks suspicious...
    @edmundnoble ^
    To exclude a file or directory from all checks, use wartremoverExcluded in your build.sbt file:
    wartremoverExcluded += baseDirectory.value / "src" / "main" / "scala" / "SomeFile.scala"
    wartremoverExcluded += sourceManaged.value
    Seems to be the correct syntax?
    Edmund Noble
    @edmundnoble
    No, this is in my settings
    I don't use the bare DslEntry stuff
    Philippe Derome
    @phderome
    is there an easy way to exclude some warts in scope test but using Maven rather than sbt as being recently discussed? I am using Maven compilerPlugin wartremover_2.11
    Some warts such as NonUnitStatements get flagged all the time with Scalatest Matchers.
    Philippe Derome
    @phderome
    I can simply put some disabling annotation at the top of each test class while I use Maven. It does the job.
    Sanjiv Sahayam
    @ssanj
    I'm seeing some false positive inferred type containing Nothing errors even when the Scala compiler can infer the correct types. Anyone seen this before? I logged an Issue: wartremover/wartremover#418
    Dmitry Polienko
    @nigredo-tori
    @ssanj, are you positive the compiler infers the types at constructor calls here? As I understand it, it leaves Right[Nothing, Int] and Left[String, Nothing] (you wrote this much yourself), and then calculates a meet at the level of the if expression, without propagating this back to the calls themselves. And in that case the wart does work as intended.
    However the whole thing is too ephemeral, so it's hard to reason about it without some more data. You could try using -X:typerto see what exactly happens in your toy example - that's described in wartremover Readme.
    Sanjiv Sahayam
    @ssanj
    I guess the question I have at the moment is whether to fix the errors outlined by the wart, because even though at the definition point Right and Left infer Nothing, when actually returned through the function in which they are defined in, the types are correct. So any code using the function would get the correct types. But I will have a look with the typer to see what's going on.
    Greg Pfeil
    @sellout
    wartremover/wartremover#263
    Dmitry Polienko
    @nigredo-tori
    @ssanj, here it is. Works as expected.
        def withTypes(value: Int): Either[String,Int] = if (value.>(10))
          scala.`package`.Right.apply[Nothing, Int](value)
        else
          scala.`package`.Left.apply[String, Nothing](scala.StringContext.apply("less than 10: ", "").s(value))
    Greg Pfeil
    @sellout
    @ssanj Ah, couldn’t figure out your handle via the iOS app. But that issue number is for you.
    Sanjiv Sahayam
    @ssanj
    @sellout Thanks! :)
    Sanjiv Sahayam
    @ssanj
    @nigredo-tori Your sample does work as expected, but the version I presented earlier doesn't. I wonder why?
    Dmitry Polienko
    @nigredo-tori
    @ssanj, I probably was not clear enough. The sample I gave is what the typer produces, and it's what wartremover sees. So as expected it sees Nothing and complains.
    However if you feed this fully typed code to the compiler from the start, the typer does not mark the Nothing node as an inferred type, so wartremover assumes it was provided by the user, and does not raise any warnings.
    Sanjiv Sahayam
    @ssanj

    @nigredo-tori oh right. Cool. Yeah, I'm trying to avoid giving the compiler the full definition of Right and Left. If I do I can give it the correct types from the start as you mentioned. I don't have to because the compiler infers the correct types to return from withTypes which is how the callers of this method see it and nothing within the withTypes method uses the incorrectly inferred types. Not sure if that makes sense? So I guess what I'm saying is that even if the compiler infers Nothing for a Left or Right, if that expression has an explicit Either type defined (either via a type ascription or return type) that doesn't have Nothing in it, then wartremover can relax because the expected type will be chosen.

    example:

    val l: Either[String, Int] = Left("error") 
    //I don't expect WR to complain because the type ascription sets the correct type for all intents and purposes for the use of l.
    Dmitry Polienko
    @nigredo-tori

    @ssanj, here, again, the typer infers Nothing...

    if that expression has an explicit Either type defined (either via a type ascription or return type) that doesn't have Nothing in it, then wartremover can relax because the expected type will be chosen.

    It would be nice, but that means the wart would have to analyze the parent nodes, and to somehow guess that the types are explicit enough (whatever this means), which sounds kind of arbitrary and needlessly complicated (read "fragile"). It gets more difficult the more possibilities we consider, and before long we're basically reimplementing the typer...
    It seems like the only sane way to disable the warning for such cases is to disable it for all or some contravariant positions, which arguably defeats the point.
    As an aside, you might want to challenge yourself by using the combinators that don't need covariance. E.g. with the mouse library (complementing cats), your initial example turns to this:

    def withTypes(value: Int): Either[String, Int] =
      (value > 10).either(s"less than 10: $value", value)

    which does not include any type arguments that can be Nothing.

    Sanjiv Sahayam
    @ssanj
    @nigredo-tori Thanks for taking the time to talk this through. I see what you mean. I would like not to turn this wart off. I like the either usage from mouse. I'll give that a go. :)
    Ghost
    @ghost~54f4b69115522ed4b3dcb16d
    Trying to build current master with fresh clone, does anyone else see:
    [error] Modules were resolved with conflicting cross-version suffixes in {file:/Users/andrew/tmp/wartremover/}sbt-plugin:
    [error]    org.scala-lang.modules:scala-xml _2.13.0-M3, _2.12
    java.lang.RuntimeException: Conflicting cross-version suffixes in: org.scala-lang.modules:scala-xml
        at scala.sys.package$.error(package.scala:27)
        at sbt.ConflictWarning$.processCrossVersioned(ConflictWarning.scala:46)
        at sbt.ConflictWarning$.apply(ConflictWarning.scala:32)
    Martin
    @mrt181
    hi, I can't configure the wartremoverExclude correctly
    this is wHat i have configured:
     lazy val wartremoverSettings =                               
       Seq(                                                       
         wartremoverErrors in (Compile, compile) ++= Warts.unsafe,
         wartremoverExcluded += sourceManaged.value               
       )
    and this is what I get (abbreviated)
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthProvider.scala:81:11: [wartremover:Var] var is disabled
    [error]       var _done__ = false
    [error]           ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:118:19: [wartremover:Any] Inferred type containing Any
    [error]       __fieldsMap.getOrElse(__fields.get(0), "").asInstanceOf[_root_.scala.Predef.String],
    [error]                   ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:119:19: [wartremover:Any] Inferred type containing Any
    [error]       __fieldsMap.getOrElse(__fields.get(1), "").asInstanceOf[_root_.scala.Predef.String]
    [error]                   ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:118:50: [wartremover:AsInstanceOf] asInstanceOf is disabled
    [error]       __fieldsMap.getOrElse(__fields.get(0), "").asInstanceOf[_root_.scala.Predef.String],
    [error]                                                  ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:119:50: [wartremover:AsInstanceOf] asInstanceOf is disabled
    [error]       __fieldsMap.getOrElse(__fields.get(1), "").asInstanceOf[_root_.scala.Predef.String]
    [error]                                                  ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:34:5: [wartremover:DefaultArguments] Function has default arguments
    [error]     providerId: _root_.scala.Predef.String = "",
    [error]     ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:71:24: [wartremover:NonUnitStatements] Statements must return Unit
    [error]       while (!_done__) {
    [error]                        ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:93:35: [wartremover:Null] null is disabled
    [error]           if (__t != "") __t else null
    [error]                                   ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:97:35: [wartremover:Null] null is disabled
    [error]           if (__t != "") __t else null
    [error]                                   ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:126:62: [wartremover:OptionPartial] Option#get is disabled - use Option#fold instead
    [error]         __fieldsMap.get(scalaDescriptor.findFieldByNumber(1).get).map(_.as[_root_.scala.Predef.String]).getOrElse(""),
    [error]                                                              ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:127:62: [wartremover:OptionPartial] Option#get is disabled - use Option#fold instead
    [error]         __fieldsMap.get(scalaDescriptor.findFieldByNumber(2).get).map(_.as[_root_.scala.Predef.String]).getOrElse("")
    [error]                                                              ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:129:15: [wartremover:Throw] throw is disabled
    [error]     case _ => throw new RuntimeException("Expected PMessage")
    [error]               ^
    [error] C:\cygwin64\home\r892107\sourcecode\topgun\target\scala-2.12\src_managed\main\com\google\api\AuthRequirement.scala:133:113: [wartremover:Throw] throw is disabled
    [error]   def messageCompanionForFieldNumber(__number: _root_.scala.Int): _root_.scalapb.GeneratedMessageCompanion[_] = throw new MatchError(__number)
    [error]
    I can't ignore the generated code
    Martin
    @mrt181
    nevermind found the solution: wartremoverExcluded ++= PathFinder(sourceManaged.value).**("*.scala").get
    Dmitry Bugakov
    @dmitrybugakov
    Hello,
    I have subprojects in sbt file, how I can add them in wartremover?
    Can you help?
    ritschwumm
    @ritschwumm
    @dmitrybugakov with the latest version i just have sth like this in my build.sbt: inThisBuild(Seq(wartremoverErrors ++= Seq( ... )))
    Dmitry Bugakov
    @dmitrybugakov
    @ritschwumm thank you)