Arhn - архитектура программирования

Компилятор Swift зависает (возможно, при выводе типов общих параметров)

Недавно я написал функцию и некоторый связанный с ней код, который действует как своего рода выражение переключения (которое работало, как и ожидалось), и опубликовал его на CodeReview. .SE

С тех пор я начал пытаться улучшить свой собственный код и, похоже, уперся в стену, так как кажется, что мой код заставляет игровую площадку зависать и не будет компилироваться при добавлении в проект. Однако, когда я печатаю все в проекте, Xcode не жалуется, пока я не попытаюсь его построить. Вот что у меня есть:

func caze<T: Equatable, R>(vals: T..., @autoclosure(escaping) ret f: () -> R) -> (AnySequence<T>, () -> R) {
    return (AnySequence(vals), f)
}

func caze<T, R where T: Equatable, T: ForwardIndexType>(range: Range<T>, @autoclosure(escaping) ret f: () -> R) -> (AnySequence<T>, () -> R) {
    return (AnySequence(range), f)
}


func schwitch<T: Equatable, R>(value: T, _ cases: (AnySequence<T>, () -> R)..., @autoclosure def: () throws -> R) rethrows -> R {
    for (vals, f) in cases {
        if vals.contains(value) {
            return f()
        }
    }
    return try def()
}

func test() {
    schwitch(5,
         caze(0, ret: "hello"),
         caze(1, 2, ret: "test"),
         caze(3..<7, ret: "lol"),
         def: "nop")

    schwitch("helloo",
        caze("hello", "Hello", ret: "test"),
        def: "nop")
}

И это ошибка, которую я получаю при попытке построить проект:

Команда не выполнена из-за сигнала: Ошибка сегментации: 11

И трассировка стека:

0  swift                    0x000000010c7f366b llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 43
1  swift                    0x000000010c7f2956 llvm::sys::RunSignalHandlers() + 70
2  swift                    0x000000010c7f3ccf SignalHandler(int) + 287
3  libsystem_platform.dylib 0x00007fff87f0752a _sigtramp + 26
4  libsystem_platform.dylib 0x00007f82f4bf0418 _sigtramp + 1825476360
5  swift                    0x000000010ab9e994 (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 52
6  swift                    0x000000010ab9ea2b (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 203
7  swift                    0x000000010ab9f02a (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 1738
8  swift                    0x000000010ab9e56c (anonymous namespace)::ApplyClassifier::classifyApply(swift::ApplyExpr*) + 652
9  swift                    0x000000010ab9dc86 (anonymous namespace)::ErrorHandlingWalker<(anonymous namespace)::CheckErrorCoverage>::walkToExprPre(swift::Expr*) + 278
10 swift                    0x000000010ac45854 swift::ASTVisitor<(anonymous namespace)::Traversal, swift::Expr*, swift::Stmt*, bool, swift::Pattern*, bool, void>::visit(swift::Stmt*) + 148
11 swift                    0x000000010ac42ef7 swift::Stmt::walk(swift::ASTWalker&) + 87
12 swift                    0x000000010ab9d9d5 swift::TypeChecker::checkFunctionErrorHandling(swift::AbstractFunctionDecl*) + 405
13 swift                    0x000000010ab7ef1b typeCheckFunctionsAndExternalDecls(swift::TypeChecker&) + 1451
14 swift                    0x000000010ab7f665 swift::performTypeChecking(swift::SourceFile&, swift::TopLevelContext&, swift::OptionSet<swift::TypeCheckingFlags, unsigned int>, unsigned int) + 1765
15 swift                    0x000000010aa00eb4 swift::CompilerInstance::performSema() + 4580
16 swift                    0x000000010a543596 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&) + 934
17 swift                    0x000000010a54268d frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 2781
18 swift                    0x000000010a53e0ac main + 1932
19 libdyld.dylib            0x00007fff912a35ad start + 1

Проблема, похоже, связана с использованием функции, поскольку все компилируется нормально, если я пропущу эту часть. Просто использование caze также работает нормально, так как следующее работает, как и ожидалось:

caze(5, ret: "hello")
let test: (AnySequence<Int>, () -> String) = caze(0...5, ret: "hello") // Swift needs some help figuring out which function to use here

Это просто ошибка в компиляторе Swift или я что-то упустил?


  • Компилятор никогда не должен давать сбоев, даже если у вашего кода есть проблемы. Вы должны сообщить об ошибке. 07.06.2016
  • @BryanChen хорошая мысль, я займусь этим. Я все еще хотел бы выяснить, что происходит и как это обойти. 07.06.2016

Ответы:


1

Во-первых: как уже сказал Брайан, это, безусловно, ошибка компилятора, он никогда не должен падать.


Чтобы решить проблему: основная причина, по-видимому, заключается в rethrows, поскольку использование следующего компилируется и запускается без каких-либо проблем. Это соответствует трассировке стека 5 - 7 classifyRethrowsArgument.

func schwitch<T: Equatable, R>(value: T, cas cases: (AnySequence<T>, () -> R)..., @autoclosure def: () -> R) -> R {
    for (vals, f) in cases {
        if vals.contains(value) {
            return f()
        }
    }
    return def()
}

То же самое касается

func schwitch<T: Equatable, R>(value: T, cas cases: (AnySequence<T>, () -> R)..., @autoclosure def: () throws -> R) -> R {
    for (vals, f) in cases {
        if vals.contains(value) {
            return f()
        }
    }
    return try! def()
}

Я знаю, что это далеко не полный ответ, но я хотел дать хоть какой-то намек на то, что я узнал. Если вам не нужен случай по умолчанию, чтобы иметь возможность генерировать этот код, он должен работать для вас. Я попытаюсь выяснить, почему rethrows вызывает проблему.

TypeCheckError.cpp компилятора swift может помочь в определении это вне.

07.06.2016
  • Хороший улов, то, что я не могу повторно сгенерировать, это позор, но на данный момент это не так уж важно, так как я все равно не понял, как повторно сгенерировать ошибки из кейсов. 08.06.2016
  • @overactor выбрасывание из ящиков работает точно так же, вам просто нужно поставить throws во многих местах :D 08.06.2016
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..