Testowanie twierdzenia, że ​​coś nie może się skompilować

Problem

Kiedy pracuję z bibliotekami, które obsługują programowanie na poziomie typu, często piszę komentarze takie jak poniżej (zprzykład Przedstawione przezPaul Snively na Strange Loop 2012):

// But these invalid sequences don't compile:
// isValid(_3 :: _1 :: _5 :: _8 :: _8 :: _2 :: _8 :: _6 :: _5 :: HNil)
// isValid(_3 :: _4 :: _5 :: _8 :: _8 :: _2 :: _8 :: _6 :: HNil)

Albo to odprzykład wBezkształtny magazyn:

/**
 * If we wanted to confirm that the list uniquely contains `Foo` or any
 * subtype of `Foo`, we could first use `unifySubtypes` to upcast any
 * subtypes of `Foo` in the list to `Foo`.
 *
 * The following would not compile, for example:
 */
 //stuff.unifySubtypes[Foo].unique[Foo]

Jest to bardzo szorstki sposób na wskazanie jakiegoś faktu na temat zachowania tych metod i możemy sobie wyobrazić, że chcemy sprawić, by te twierdzenia stały się bardziej formalne - dla testów jednostkowych lub regresji itp.

Aby podać konkretny przykład, dlaczego może to być przydatne w kontekście biblioteki takiej jak Shapeless, kilka dni temu napisałem poniższe jako szybką pierwszą próbę odpowiedzi nato pytanie:

import shapeless._

implicit class Uniqueable[L <: HList](l: L) {
  def unique[A](implicit ev: FilterAux[L, A, A :: HNil]) = ev(l).head
}

Tam, gdzie ma się to skompilować:

('a' :: 'b :: HNil).unique[Char]

Chociaż to nie będzie:

('a' :: 'b' :: HNil).unique[Char]

Byłem zaskoczony, że ta implementacja poziomu typuunique dlaHList nie działał, ponieważ Shapeless chętnie znalazłbyFilterAux przykład w drugim przypadku. Innymi słowy, poniższe dane zostaną skompilowane, nawet jeśli prawdopodobnie spodziewałbyś się, że nie:

implicitly[FilterAux[Char :: Char :: HNil, Char, Char :: HNil]]

W tym przypadku widziałem tobłąd- lub przynajmniej coś takiego jak robak - i tozostał naprawiony.

Mówiąc bardziej ogólnie, możemy sobie wyobrazić, że chcemy sprawdzić rodzaj niezmiennika, który był ukryty w moich oczekiwaniach dotyczących tego, jakFilterAux powinien pracować z czymś w rodzaju testu jednostkowego - tak dziwnie, jak mogłoby się wydawać mówienie o testowaniu takiego kodu na poziomie typu, z wszystkimi niedawnymi debatami na temat względnej wartości typówvs. testy.

Moje pytanie

Problem polega na tym, że nie znam żadnego rodzaju platformy testowej (dla jakiejkolwiek platformy), która pozwala programiście stwierdzić, że coś nie możeskompilować.

Jedno podejście, które mogę sobie wyobrazić dlaFilterAux przypadkiem byłoby użycie staregosztuczka implicit-argument-with-null-default:

def assertNoInstanceOf[T](implicit instance: T = null) = assert(instance == null)

Które pozwoliłyby ci napisać poniższe w teście jednostkowym:

assertNoInstanceOf[FilterAux[Char :: Char :: HNil, Char, Char :: HNil]]

Następujące byłoby jednak dużo wygodniejsze i bardziej ekspresyjne:

assertDoesntCompile(('a' :: 'b' :: HNil).unique[Char])

Chcę to. Moje pytanie brzmi, czy ktoś wie o jakiejkolwiek bibliotece testowej lub frameworku, który obsługuje coś podobnego - idealnie dla Scali, ale zadowolę się wszystkim.

questionAnswers(5)

yourAnswerToTheQuestion