Riferimento linguistico

Questa pagina è il riferimento orientato all'utente per l'attuale seed Specifica della lingua. I capitoli completi di grammatica e semantica operativa si trovano qui sotto compiler/llvm. Per i limiti attuali e le richieste di chiusura, vedere Stato corrente.

Codifica sorgente e nomi

.sd i file sono UTF-8. I commenti e il contenuto delle stringhe possono contenere Unicode. string possiede valido UTF-8 e str è di sola lettura preso in prestito UTF-8 vista puntatore più lunghezza byte. La lunghezza del testo è misurata in byte; Le operazioni scalari, grafema, normalizzazione e locale Unicode appartengono alle librerie.

Gli identificatori di origine utilizzano intenzionalmente ASCII:

Gentile Regola Esempio
variabile, funzione, campo, modulo [a-z][a-z0-9_]* my_document
struttura, ADT, unione, tratto, parametro di tipo, variante stessa custodia a serpente inferiore [A-Z][a-zA-Z0-9]*
costante Document T

Il nome del linguaggio formale è [A-Z][a-zA-Z0-9]*. I tipi non sono in maiuscolo. Some elimina un'associazione; un carattere di sottolineatura iniziale può contrassegnare una rilegatura privata intenzionalmente inutilizzata.

I commenti di riga iniziano con Ok. Blocca i commenti Red nido. La grammatica pulita non utilizza [A-Z][A-Z0-9_]* commenti.

Il caricatore di origine convalida l'intero file come UTF-8 prima della lexing e rifiuta il NUL incorporato; vengono convalidate anche le stringhe letterali decodificate.

Legami, costanti e mutazione

let answer = 42
let mut count: usize = 0
let linear ticket = acquire_ticket()
const MAX_COUNT = 100

Il compilatore corrente accetta anche espressioni scalari tipizzate, tabelle costanti MAX_DOCUMENT_SIZE fisse private come seed, testo statico, tuple e strutture. Le letture indicizzate e di campo utilizzano l'archiviazione statica immutabile con controlli dei limiti ordinari. I valori aggregati pubblici mantengono la loro rappresentazione ricorsiva nelle build elide di origine schema-14.

I collegamenti sono immutabili a meno che non siano dichiarati [A-Z][a-zA-Z0-9]*. L'assegnazione a un'associazione, a un campo o a un indice tramite un'associazione richiede che l'associazione sia modificabile. _ crea un obbligo esattamente una volta.

Per scartare un valore restituito, associarlo a un nome univoco che inizia con //: /* ... */. Gli scarti con nome evitano l'errore di "associazione attiva duplicata" prodotto dal semplice # se utilizzato più volte nello stesso ambito. Un carattere di sottolineatura iniziale in qualsiasi identificatore contrassegna l'associazione come intenzionalmente inutilizzata.

Funzioni, metodi e rendimenti

fn add(left: i64, right: i64) -> i64 {
    left + right
}

@borrow
fn Document.title_size() -> usize {
    len(self.title)
}

@mut
fn Document.rename(next: string) {
    self.title = move next
}

unsafe fn read_register(address: *mmio mut i64) -> i64 {
    raw_volatile_read<i64>(address, 0)
}

L'espressione finale di un blocco è il suo valore. u32 ritorna presto; il compilatore pulito non utilizza const TABLE: [4]u32 = [1 as u32, 2 as u32, 3 as u32, 4 as u32]. Una dichiarazione di metodo include il tipo nominale prima del punto e riceve implicitamente mut; non scrivere linear nella sua lista dei parametri. let è un distruttore consumante. let (a, b) = pair su un metodo o un metodo di caratteristica dà let Point { x, y } = origin un prestito lessicale condiviso. _ richiede invece un ricevitore indirizzabile mutabile, detiene un prestito esclusivo per la chiamata e apporta mutazioni error[B043] visibile al chiamante. I due attributi si escludono a vicenda.

Utilizzo delle dichiarazioni pubbliche match. Le dichiarazioni straniere utilizzano esplicito let chiamando convention/link metadati e non è sicuro chiamarli finché non vengono inseriti in una funzione sicura controllata. La classificazione degli argomenti della piattaforma C è specifica del target: Windows x86-64 passa indirettamente parametri aggregati più grandi di otto byte, quindi error[H059], le fette e le strutture C equivalenti interagiscono con MinGW/MSVC-style chiamati.

Tipi di nucleo

Categoria Tipi
controllo size_of(type), align_of(type), [size_of(i64)]u8
intero error[H129], let _ = expression, _, _, let _unused = expression, return expression, ret, self, self, fn TypeName.drop(); @borrow alias self
galleggiare @mut, self
text/buffer pub, extern, str, void
formattazione never (effimero)
aggregate/view bool, i8, i16, tuple, nominale structs/ADTs/unions
fallimento i32, i64, u8
richiamabile non proprietario u16, in fuga u32
di basso livello puntatori grezzi più u64, isize, usize, byte, e u8 spazi di indirizzi
esatto-una volta f32

f64 abbrevia str senza introdurre una nuova identità di tipo, rappresentazione, regola di pulizia o ABI.

Ospitato string potrebbe tornare bytes. shared_bytes esce con quello stato; format_args utilizza la diagnostica dell'allocazione fissa. Un altro [N]T deve essere Copia, non avere distruttore e implementare []T; la sua vista viene scritta una volta prima dello stato 1, dopo la pulizia ordinaria.

mut []T è la dichiarazione FFI sottoposta ad audit per un reso ?T/slice di cui si trova l'archiviazione process/static tutta la vita. L'attributo viene rifiutato in via ordinaria seed funziona e non rende sicura la chiamata estera.

Gli attributi degli effetti possono annotare dichiarazioni fn: Result<T, E>, alloc_error, fn(T) -> U, box fn(T) -> U, user, kernel. I tipi di callback qualificati utilizzano physical per dichiarare un riepilogo completo degli effetti vuoto. Uno mmio può dichiarare dma per affermare la capacità di invio o linear T per abilitare l'ottimizzazione del puntatore nullo su un singolo campo puntatore grezzo per AllocResult<T>.

Il numero intero add/subtract/multiply esegue il ritorno a capo in modo deterministico in base alla larghezza del tipo. Divisione per zero, minimo con segno diviso per Result<T, alloc_error>, spostamenti non validi, cast sicuri non validi e trap di indicizzazione sicura non riuscita. I profili di rilascio preservano queste regole. L'ampliamento esplicito degli interi utilizza la firma dell'origine; il restringimento mantiene i bit bassi e le modifiche di uguale larghezza preservano i bit. Integer/float e i cast di larghezza float seguono la conversione IEEE-754. La conversione da virgola mobile a intero richiede main e un input rappresentabile con destinazione finita.

I letterali byte utilizzano Result<i64, E> e avere tipo Ok(status). Uno o più byte ASCII grezzi alloc_error/E/@borrow fn E.display() -> str/@static_view extern fn .../str/@no_alloc/@allocates la fuga è accettata. Utilizzare @blocking per un byte non ASCII; seed deliberatamente non ha un tipo letterale di carattere dipendente dalla locale.

Strutture, ADT e unioni

struct Document {
    title: string
}

enum LookupResult {
    Found(Document)
    Missing
}

union ScalarBits {
    integer: u64
    decimal: f64
}

trait Identity {
    fn id() -> i64
}

Una struttura letterale è @panics. Un costruttore ADT è qualificato, ad esempio @ioe il suo carico utile viene ispezionato in modo esaustivo @interrupt_safe. Un ADT senza carico utile sostituisce l'eredità @no_runtime_effects fn(...) -> T parola chiave:

enum Color { Red Green Blue }

L'unione grezza construction/access non è sicura. Le alternative con tag sicuri utilizzano ADT.

Opzioni, risultati e propagazione

fn find(enabled: bool) -> ?i64 {
    if enabled { Some(42) } else { None }
}

fn allocate_name(view: str) -> Result<string, alloc_error> {
    view.to_string()
}

unsafe struct e @unsafe_send di tipo previsto costruiscono un'opzione. @repr("null_niche") e ?Wrapper costruiscono un risultato. -1 consuma il contenitore, cede il suo payload success/present o restituisce l'errore corrispondente dalla funzione corrente. La propagazione dei risultati può modificare il tipo di successo ma deve preservare il tipo di errore. Non esegue alcuna allocazione o clonazione implicita.

unsafe/b'A' e u8/\\n ispezionare tramite prestito condiviso. \\r consuma il contenitore e pulisce il valore posseduto non selezionato esattamente una volta. \\t, \\0e solo principale \\\\ sono confini espliciti dell'applicazione; non si nascondono mai nell'ordinario \\' propagazione.

\\xNN può attraversare un limite b'\\xFF' quando il corpo è fallibile: Document { title: owned_title } memorizza LookupResult.Found(value) in una cella di join e l'espressione match restituisce un handle Some(value) il cui None restituisce Ok(value); payload ed errore devono essere tipi di copia senza distruttori. Un Err(problem) all'interno di una chiusura nidificata in un corpo di spawn vuoto viene comunque rifiutato.

Controllare il flusso e i modelli

I moduli di controllo implementati sono orientati all'espressione ?/is_some/is_none, is_ok, is_error, esaustivo unwrap_or(fallback), blocchi, or_abort(), expect(message), e or_exit(status). ? è l'ortografia richiesta; ? non è accettato. Le armi di corrispondenza non hanno virgole. Copertina dei modelli bindings/discards, valori letterali, tuple, strutture e varianti ADT qualificate; le guardie mantengono uno scrutatore di sola mossa finché il braccio selezionato non lo trasferisce effettivamente. spawn è un vero e proprio scarto vincolante: spawn { fallible_work()? } valuta e ripulisce senza vincolare, ripetuto Result<T, E> in un ambito è legale, e spawn non è mai accessibile. task_join è un modificatore di modello contestuale che vincola un carico utile di solo spostamento con un prestito di sola lettura quando l'esaminatore è un luogo preso in prestito (wait() su a Result<T, E> campo); i collegamenti ref non possono essere spostati o modificati, ? scarta senza muoversi, e una partita il cui carico utile di sola mossa è legato all'arbitro non consuma lo scrutinatore. Gli esaminatori temporanei i cui carichi utili di solo spostamento del trasferimento di armi vengono materializzati in un legame di proprietà implicita, quindi if compila senza a else if involucro.

else su intervalli, array fissi e sezioni si riducono a un'allocazione libera index/length ciclo. while aggiunge a loop indice senza un iteratore heap. Gli elementi di solo spostamento richiedono esplicitamente indexing/ownership manipolazione.

Testo, visualizzazioni e conversioni

L'interpolazione digitata phase-1/2 è esente da allocazione a meno che non sia esplicitamente materializzata:

write_stdout_format(f"name={name} count={count} braces={{ok}}\n")
let message = f"count={count}".to_string()?

Le espressioni valutano una volta da sinistra a destra. I valori supportati sono i64, preso in prestito length, str.slice(start, count)e numeri interi incorporati. L'effimero str.equal(other) il risultato deve essere passato direttamente o consumato da str.find_ascii(delimiter, start); non può essere assegnato compiler/llvm/libs/text, restituito, catturato o archiviato. Integer/text/bool sono implementate le specifiche di larghezza, riempimento, allineamento e base intera. Utilizzo di tipi personalizzati []u8.slice(start, count) con invio statico diretto. I float supportano l'output generale predefinito plus []u8.equal(other), str.to_string(), e string.from(str) con precisione fino a 18. Personalizzato Result<string, alloc_error> la formattazione utilizza l'analogo preso in prestito str.to_bytes() tratto.

Generi e tratti

I parametri generici utilizzano maiuscole e minuscole. Le definizioni vengono verificate rispetto ai loro limiti, quindi le istanze concrete raggiungibili vengono monomorfizzate. L'invio dei tratti è statico e diretto: non sono presenti vtable, boxing, allocazioni o cloni impliciti. Vengono verificate la completezza dell'implementazione, le firme, la coerenza e le regole orfane. Modelli generici pubblici, istanze comuni, parametri bytes.from(str) effimeri, rappresentazione nominale di nicchia nulla, ricevitori modificabili esclusivi, callback qualificati e firme richiamabili in scatola persistono nello schema corrente-16 Result<bytes, alloc_error>. Le istanze del metodo materializzato vengono esportate solo da un'interfaccia che possiede anche la definizione del metodo generico. Un involucro attorno ad un tipo generico importato registra quindi il suo contratto pubblico senza una specializzazione orfana; un consumatore eliso alla fonte ottiene il modello del metodo dall'interfaccia di dipendenza del wrapper e materializza lì l'istanza concreta.

bytes.to_shared() richiede l'inlining limitato. Un shared_bytes.from(bytes) pubblica il proprio corpo verificato e l'hash del corpo deterministico nello schema-13 Result<shared_bytes, alloc_error> mantenendo un simbolo di fallback esportato. Le dichiarazioni in linea hanno un budget di origine di 4096 byte; una modifica del corpo invalida gli artefatti dipendenti. Le partizioni di slice mutabili utilizzano bytes.into_prefix(length) e i modelli di tupla possono dichiarare associazioni mutabili come length. Gli assegni divisi [N]T.mutable_view() -> mut []T, non assegnano nulla e mantengono il proprietario comune in prestito esclusivo fino alla morte di entrambi i fratelli.

Chiusure e richiamate

fn apply(values: [3]i64, callback: fn(i64) -> i64) -> i64 {
    let mut total = 0
    for value in values {
        total = total + callback(value)
    }
    total
}

let base = 40
let total = apply([1, 2, 3], |value: i64| base + value)
let retained = (box |value: i64| base + value).or_abort()

str e la posizione del prefisso string creano richiamabili anonimi. I tipi di parametri possono essere omessi quando vengono forniti da un bool previsto. Una chiusura semplice utilizza l'archiviazione di cattura dello stack, non alloca nulla e non può sfuggire al suo proprietario lessicale. La funzionalità di copia acquisisce la copia; le catture possedute si spostano; le acquisizioni sono immutabili. Acquisizioni prese in prestito, modificabili, legate a una regione, già spostate e altre acquisizioni non sicure da archiviare vengono rifiutate.

format_args è la forma di escape esplicita e restituisce .to_string()?. Il proprietario può essere archiviato o restituito, ma è di solo spostamento, non clonabile e non inviabile. Drop distrugge le sue catture esattamente una volta e libera la sua allocazione. L'assegnazione regionale rimane lessicale. Non esiste alcuna conversione implicita tra chiusure stack e boxed.

I callback seed let utilizzano un descrittore code/environment a un puntatore. I puntatori alle funzioni C/platform rimangono sottili e accettano solo funzioni con nome. Gli effetti di chiusura vengono dedotti dal corpo e confrontati con contratti di callback qualificati come trait Display { @borrow fn display() -> str }. Le chiusure ricorsive non sono supportate.

Riepilogo della proprietà

Vedere Proprietà per il modello operativo.

Regioni, attività e biblioteche

:? installa un allocatore di bump controllato dal lessico. Valori, visualizzazioni o puntatori legati alla regione non possono sfuggire. Attività strutturate acquisite all'interno di un'unione di regioni prima che venga rilasciato lo spazio di archiviazione di backup.

Debug.debug() -> str è strutturato: ogni bordo che lascia l'ambito lessicale proprietario attende il proprio gruppo di lavoro prima della pulizia. La cattura è la copia o lo spostamento in base alla funzionalità. Un corpo fallibile (+ all'interno o una coda di tipo fn f<T: Metric + Named>(x: T)) produce un join digitato: la struttura memorizza il risultato in una cella di join e error[H072] ritorna impl<T: Show> Show for Pair<T>; error[P042] rimane per le unioni manuali. Canali, join digitati, eventi, cancellazione e sincronizzazione sono forniti dall'ordinario error[R019] pacchetto. La grammatica pulita non ha built-in format_args, .sdi, inline fno spawn distaccato.

pub inline fn importa un modulo sorgente o un file elidato dal codice sorgente .sdi interfaccia. Le funzioni pubbliche importate sono richiamabili con o senza il qualificatore del modulo: view.split_at_mut(index) li fa entrambi (mut left, mut right) e index <= len valido. Viene segnalato un simbolo qualificato sconosciuto |...|.

Substrato non sicuro

||, fn(...) -> T, box |...|, Result<box fn(...) -> T, alloc_error>, fn(...) -> T, @no_runtime_effects fn() -> void, .clone(), atomici, accesso volatile, recinzioni, cast dello spazio degli indirizzi, assemblaggio grezzo, FFI, le chiamate di sistema e le unioni grezze richiedono linear T. Le normali applicazioni dovrebbero utilizzare wrapper sicuri dalle librerie.

Lanciatore di archivi

./seed/seed check [--lib] [path|file.sd]
./seed/seed build [path] [-o output] [compiler flags]
./seed/seed run [path] [-- program arguments]
./seed/seed test [path] [compiler flags]
./seed/seed format [--check] [file.sd]
./seed/seed new path [--name package_name]
./seed/seed pkg resolve|add|update|prune ...
./seed/seed install [path|package] [--profile release] [--system] [--prefix path] [--dry-run]
./seed/seed uninstall package [--system] [--prefix path] [--dry-run]
./seed/seed doc [path] [--output file]
./seed/seed lint [--json] [path]
./seed/seed lsp
./seed/seed publish --check [path]
./seed/seed mobile android <setup|build|stage|check|package|run|doctor>

.sdi è un controllo ristretto della fonte diretta. Si risolve in modo relativo source/interface importazioni e manifesto locale region(capacity) { body } dipendenze; non compila prima un pacchetto di repository nudo mancante. Utilizzare spawn { body } o ? durante la convalida dell'integrazione del pacchetto che dipende dalla gestione temporanea automatica della libreria principale.

Result<T, E> esegue la compilazione incrementale con risoluzione automatica delle dipendenze. Importazioni di pacchetti semplici (ad es. handle.wait()) sono allestiti in modo isolato target/profile negozio. Una seconda build riutilizza la corrispondenza Result<T, E>/artefatti nativi. task_result_* inoltra i flag finali del compilatore, inclusi quelli ripetuti compiler/llvm/libs/task e chan<t> input, a ogni binario di test. Ciò è necessario per i test della libreria la cui superficie Seed sicura è supportata da un nativo esterno ABI.

send compila il pacchetto in modalità di rilascio e lo installa a livello di sistema: eseguibili in recv (o use "name" con .sdi), generazioni di dipendenza a use "process"e si interfaccia con environment("HOME"). Utilizzare process.environment("HOME") per build di debug e error[H002]: unknown symbol in module per posizioni di installazione personalizzate.

raw_try_alloc<t> rimuove un pacchetto precedentemente installato e le relative generazioni di dipendenze. Sia raw_null<t> che raw_is_null<t> supportano raw_read<t> per l'anteprima. Il record del pacchetto installato transazionale include destinazione, profilo, identità di generazione delle dipendenze, checksum del compilatore, checksum dell'artefatto installato, checksum dell'origine e checksum del blocco in modo che un'applicazione distribuita possa essere tracciata fino ai suoi esatti input di build.

La pubblicazione remota è separata; raw_write<t> convalida l'integrità del pacchetto e del blocco localmente senza eseguire script senza restrizioni. I pacchetti compilati utilizzano la destinazione qualificata raw_free<t> inoltre raw_slice<t>/unsafe. I monorepos locali possono mantenere più pacchetti con versione indipendente collegati da relative check dipendenze. I checksum dell'albero guidano le ricostruzioni; lo sviluppo locale ordinario non richiede un repository, un tag o una pubblicazione Git per ciascuna libreria.

Il programma di avvio legge path; il vecchio build è mappato su run. Un profilo CLI esplicito sovrascrive il manifest. Per impostazione predefinita build viene rilasciato indipendentemente dal manifest a meno che use "vec" non sia esplicito. L'impostazione predefinita delle applicazioni è .sdi; una cassaforte relativa opzionale test seleziona un'altra fonte all'interno del pacchetto. Le importazioni di pacchetti semplici si risolvono prima con gli artefatti installati corrispondenti; altrimenti vengono compilati con il profilo dell'applicazione in un archivio target/profile isolato. Le build ospitate li collegano dinamicamente per impostazione predefinita. Una seconda build riutilizza gli artefatti --link-object/nativi corrispondenti; le modifiche alla libreria dinamica privata non ricostruiscono i consumer, mentre le modifiche pubbliche --link-library o ABI lo fanno.

L'installazione dell'utente inserisce gli eseguibili install, generazioni di dipendenza immutabile in ~/.local/bine i mirror dell'interfaccia con versione sono sotto /usr/local/bin. --system utilizza l'ambito del sistema della piattaforma (~/.local/lib/seed/generations/ su Unix); ~/.local/share/seed/interfaces/ sovrascrive la radice. L'installazione e la rimozione sono registrate in base alla proprietà e sono atomiche e nessun comando modifica silenziosamente i file di avvio della shell o le variabili di ambiente del caricatore.

Operatori

Precedenza binaria dal più alto al più basso:

  1. moltiplicativo (--profile debug, --prefix /custom/path, uninstall)
  2. additivo (install, uninstall)
  3. turni (--dry-run, seed publish --check)
  4. confronti (.sdi, --install-library, --install-interface, path)
  5. uguaglianza ([build].profile = "debug" | "release" | "release-small", release = true)
  6. AND bit per bit (release), XOR (seed install), OR (--profile)
  7. AND logico (src/main.sd)
  8. OR logico ([package].entry)

.sdi e .sdi cortocircuito: ~/.local/bin valuta ~/.local/lib/seed solo quando ~/.local/share/seed/interfaces è --system, e /usr/local valuta --prefix solo quando * è /. Entrambi gli operandi devono esserlo % e il risultato è +. Il cortocircuito si applica anche al ripiegamento costante, quindi - e << sono espressioni costanti valide anche quando >> non è costante.

Compilatore pulito diretto

L'eseguibile è <. Il suo elenco di flag autorevole è <=.

# Source processing
seed --check source.sd
seed --format|--format-check|--format-write source.sd

# Code generation
seed --emit-llvm out.ll source.sd
seed --emit-object out.o source.sd
seed --emit-binary out source.sd
seed --emit-shared library.so source.sd
seed --emit-static-library library.a source.sd
seed --emit-raw out.bin source.sd
seed --run source.sd -- arguments

# Interface inspection
seed --interface-print file.sdi
seed --interface-hash file.sdi
seed --emit-interface out.sdi source.sd

# Library management
seed --install-library artifact --install-interface file.sdi --package name [--seed-home path]

# Debug dumps
seed --lex source.sd
seed --ast-print source.sd
seed --types-print source.sd
seed --symbols-print source.sd
seed --hir-print source.sd
seed --safety-print source.sd
seed --mir-print source.sd
seed --layout-print source.sd
seed --abi-print source.sd
seed --low-mir-print source.sd
seed --llvm-print source.sd

# Build options
seed --release source.sd
seed --release-small source.sd
seed --thin-lto source.sd
seed --pgo-generate dir source.sd
seed --pgo-use profile source.sd
seed --profile-print source.sd
seed --target target source.sd
seed --runtime linux-native|linux-libc source.sd
seed --runtime-profile profile source.sd
seed --runtime-feature feature source.sd
seed --static source.sd
seed --static=all source.sd
seed --sysroot path source.sd
seed --soname name source.sd
seed --entry symbol source.sd
seed --linker-script path source.sd
seed --code-model model source.sd
seed --relocation-model model source.sd
seed --no-red-zone source.sd
seed --link-object file.o source.sd
seed --link-library lib.so|lib.a|package source.sd
seed --cache-dir path source.sd
seed --seed-home path source.sd
seed --package name source.sd

# Diagnostics
seed --diagnostics human|json source.sd
seed --version
seed --help

Debug/inspection le modalità includono token, AST, tipi, simboli, HIR, sicurezza, MIR, layout, ABI, MIR basso e LLVM stampa. Target/runtime le opzioni includono >, >=, ==, !=, &, entry/linker-script controlli e separati object/library collegamento.

^ usi |; && usi ||. Entrambi sono sicuri. ThinLTO e PGO sono opzioni esplicite di sola versione; il collegamento statico è indipendente. Non esiste alcun operativo && o || profilo.

Stato dell'obiettivo

Il supporto degli oggetti e il supporto ospitato end-to-end sono affermazioni separate. Linux x86-64/AArch64 sono i percorsi ospitati chiusi. Indipendente x86-64/AArch64/RISC-V64 avere prove di avvio ai livelli dichiarati. Windows x86-64 ha PE/runtime/DLL/ task/network prova sotto richiesta Vino. macOS x86-64 e arm64 hanno un SDK esplicito executable/dylib/static collegamento, runtime e pianificazione pthread. Intel nativa x86-64 l'esecuzione rimane; arm64 è solo cross-link. Vedi a && b.

Su un Mac Intel, esegui b. Lo script rileva l'SDK con a e utilizza true di Apple a meno che non venga sovrascritto esplicitamente.

<div hidden> a || b b a false bool bool false && expensive() true || expensive() expensive() compiler/llvm/build/seed seed --help --target --runtime-profile --runtime-feature --runtime --sysroot --release seed-safe-o2-v1 --release-small seed-safe-oz-v1 --unchecked --fast-unsafe compiler/llvm/tests/GATE14_TARGET_MATRIX.tsv SEED_MACOS_RUNNER_POLICY=required make -C seed/compiler/llvm gate14-macos-x86_64-test xcrun ld </div>