CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-lang-modules--scala-collection-compat

A library that makes some Scala 2.13 APIs available on Scala 2.11 and 2.12, facilitating cross-building Scala 2.13 and 3.0 code on older versions

Pending
Overview
Eval results
Files

annotation-backports.mddocs/

Annotation Backports

Scala 2.13 annotations made available on earlier Scala versions to enable forward compatibility and consistent code across versions.

@nowarn Annotation

class nowarn extends scala.annotation.StaticAnnotation

Suppresses compiler warnings for the annotated element. This annotation was introduced in Scala 2.13.2 and 2.12.13.

Compatibility Behavior

  • Scala 2.13.2+ and 2.12.13+: Full warning suppression functionality
  • Scala 2.11 and earlier 2.12 versions: No-op annotation (present but does not suppress warnings)
  • Purpose: Enables forward compatibility when writing code that targets multiple Scala versions

Usage

Method-Level Suppression

import scala.annotation.nowarn

class Example {
  @nowarn
  def deprecatedMethodUsage(): String = {
    // This would normally produce a deprecation warning
    someDeprecatedMethod()
  }
  
  @nowarn("cat=deprecation")
  def specificWarningSuppress(): Int = {
    // Suppress only deprecation warnings
    anotherDeprecatedMethod()
  }
}

Expression-Level Suppression

import scala.annotation.nowarn

def processData(): Unit = {
  val result = (computeValue(): @nowarn)
  
  // Suppress warnings for a specific expression
  val x = {
    someOperationWithWarnings()
  }: @nowarn
}

Class-Level Suppression

import scala.annotation.nowarn

@nowarn
class LegacyClass {
  // All warnings in this class are suppressed
  def method1(): Unit = deprecatedCall1()
  def method2(): Unit = deprecatedCall2()
}

Warning Categories

On Scala versions that support it, @nowarn can target specific warning categories:

@nowarn("cat=deprecation")      // Suppress deprecation warnings
@nowarn("cat=unused")           // Suppress unused warnings  
@nowarn("cat=lint")             // Suppress linting warnings
@nowarn("cat=other")            // Suppress other warnings

// Multiple categories
@nowarn("cat=deprecation&unused")

// Pattern-based suppression
@nowarn("msg=.*is deprecated.*")

@unused Annotation

class unused extends scala.annotation.StaticAnnotation

Indicates that the annotated element is intentionally unused, suppressing "unused" warnings from the compiler.

Usage

Parameter Suppression

import scala.annotation.unused

def processCallback(
    data: String, 
    @unused metadata: Map[String, String]  // Metadata not used but part of API
): String = {
  data.toUpperCase
}

// Function with unused parameters
def eventHandler(
    event: Event,
    @unused timestamp: Long,  // Timestamp for future use
    @unused source: String   // Source for debugging
): Unit = {
  println(s"Processing event: $event")
}

Variable Suppression

import scala.annotation.unused

def complexComputation(): Int = {
  val result = expensiveComputation()
  @unused val debugInfo = gatherDebugInfo()  // For debugging, not used in production
  result
}

Import Suppression

import scala.annotation.unused
import scala.collection.mutable.Map  // Used in code
@unused import scala.util.Random     // Imported for conditional compilation

Cross-Version Compatibility Examples

Conditional Compilation with @nowarn

import scala.annotation.nowarn

class CrossVersionCode {
  def parseNumber(s: String): Option[Int] = {
    // Different implementations for different Scala versions
    
    // Scala 2.13+ has toIntOption
    try {
      s.toIntOption  // This method exists in 2.13+
    } catch {
      case _: NoSuchMethodError =>
        // Fallback for older versions
        (try { Some(s.toInt) } catch { case _: NumberFormatException => None }): @nowarn
    }
  }
  
  @nowarn("cat=deprecation")
  def legacyApiUsage(): String = {
    // Using deprecated API that we need for backward compatibility
    someDeprecatedApiCall()
  }
}

Library Migration Support

import scala.annotation.{nowarn, unused}
import scala.collection.compat._

class MigrationHelper {
  @nowarn("cat=unused")
  def processCollection[T](
      data: Traversable[T],
      @unused processingHint: String = "default"  // Future parameter
  ): List[T] = {
    
    // Use compat library for cross-version support
    data.toList
      .tap(list => println(s"Processing ${list.size} items"))
      .filter(_ != null)
  }
  
  @nowarn("cat=deprecation")
  def bridgeOldAndNewApi(): Unit = {
    // Calling both old and new APIs during migration period
    val oldResult = callOldDeprecatedApi()
    val newResult = callNewApi() 
    reconcileResults(oldResult, newResult)
  }
}

Testing with Intentionally Unused Code

import scala.annotation.unused

class TestHelpers {
  // Test utilities that might not be used in all test suites
  @unused 
  def createTestUser(name: String = "test"): User = User(name)
  
  @unused
  def mockDatabase(): Database = new InMemoryDatabase()
  
  // Test that has setup code for future test cases
  @nowarn("cat=unused")
  def setupComplexTest(): Unit = {
    @unused val testData = generateLargeTestDataset()
    @unused val mockServices = setupMockServices()
    
    // Current test is simple, but setup is ready for expansion
    assertTrue(true)
  }
}

Conditional API Features

import scala.annotation.{nowarn, unused}

trait ApiTrait {
  def coreMethod(): String
  
  // Optional method that might not be implemented by all classes
  @unused  
  def optionalMethod(): Option[String] = None
}

class BasicImplementation extends ApiTrait {
  def coreMethod(): String = "basic"
  
  // Don't implement optional method - annotation prevents warning
}

class AdvancedImplementation extends ApiTrait {
  def coreMethod(): String = "advanced"
  
  @nowarn("cat=unused")  // May not use all parameters yet
  override def optionalMethod(): Option[String] = Some("advanced-feature")
}

Macro and Code Generation Support

import scala.annotation.nowarn

// Code that's generated or used by macros
class GeneratedCode {
  @nowarn  // Generated code may have unused elements
  def generatedMethod(
      @unused param1: String,
      @unused param2: Int,
      usedParam: Boolean
  ): String = {
    if (usedParam) "active" else "inactive"
  }
}

// Macro-supporting code
@nowarn("cat=other")  // Suppress macro-related warnings
object MacroSupport {
  // Methods used by macros at compile time
  def compiletimeHelper(): String = "helper"
}

Build Configuration Integration

SBT Configuration

For Scala 2.13+ you can also configure warning suppression at the build level:

// In build.sbt - complement to @nowarn annotations
scalacOptions ++= {
  CrossVersion.partialVersion(scalaVersion.value) match {
    case Some((2, n)) if n >= 13 =>
      Seq("-Wconf:cat=unused-imports:s")  // Suppress unused import warnings
    case _ =>
      Seq.empty
  }
}

Cross-Building with Annotations

// project/Dependencies.scala
val scalaCollectionCompat = Seq(
  "org.scala-lang.modules" %% "scala-collection-compat" % "2.13.0"
)

// Use annotations to handle version differences
import scala.annotation.nowarn

@nowarn("cat=unused")
object CrossVersionImports {
  // Import may be unused on some Scala versions
  import scala.collection.compat._
  
  def createList[T](items: T*): List[T] = {
    List.from(items)  // Available via compat library
  }
}

Migration Strategy

When migrating code across Scala versions:

  1. Add @nowarn annotations for deprecated API usage during transition periods
  2. Use @unused annotations for parameters/variables that will be used in the future
  3. Combine with collection-compat library for smooth API transitions
  4. Review and remove annotations after migration is complete
// Phase 1: Migration preparation
@nowarn("cat=deprecation")
def transitionMethod(): Unit = {
  oldApi()  // Still needed for some deployments
  newApi()  // New implementation
}

// Phase 2: After migration (clean up)
def transitionMethod(): Unit = {
  newApi()  // Only new implementation
  // @nowarn annotation removed
}

Implementation Notes

  • @nowarn is a no-op on Scala versions that don't support it
  • @unused helps with code clarity and prevents accidental removal of intentionally unused code
  • These annotations are compile-time only and have no runtime impact
  • They facilitate gradual migration and cross-version compatibility

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-lang-modules--scala-collection-compat

docs

annotation-backports.md

backported-collections.md

collection-extensions.md

collection-factories.md

index.md

iterator-size-ops.md

java-interop.md

map-extensions.md

method-chaining.md

option-converters.md

resource-management.md

string-parsing.md

tile.json