Draft
Conversation
Migrate build.zig and supporting build files to Zig 0.16 APIs: - std.fs.cwd() -> std.Io.Dir.cwd() with io parameter threading - Dir/File methods now require io parameter (open, close, read, write, stat, iterate) - makePath -> createDirPath, readFileAlloc args reordered - File positional I/O replaces seek+read/write pattern - std.process.Child.init/run -> std.process.spawn/run - std.process.getEnvVarOwned -> b.graph.environ_map.get - Compile methods moved to root_module (addObjectFile, linkLibrary, etc.) - linkFramework/linkSystemLibrary now require options arg - GeneralPurposeAllocator -> DebugAllocator (21 files) - Remove discard captures (=> |_| -> =>) per new Zig rules (19 files) - std.mem.trimRight -> std.mem.trimEnd - ArrayList.writer() removed (use Io.Writer.Allocating) - Optional pointer alignment (p.alignment orelse 0) - std.process.argsAlloc -> Args.Iterator via Init parameter Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ArrayList init: .{} -> .empty for unmanaged ArrayLists (items field required)
- Thread.Mutex -> std.atomic.Mutex with spin-lock for debug tracking
- std.fs.File -> std.Io.File, file I/O uses positional writes
- Managed(u8).writer() removed: add managedWriter/managedWriterFinish helpers
- TypeWriter: ByteWrite type changed to std.Io.Writer, writer.write -> writeAll
- CompactWriter.writeGather: replace pwritev with sequential positional writes
- @typeof(undefined) -> @FieldType for nested field type access
- std.process.argsAlloc -> Args.Iterator via Init parameter
- Error sets: WriteFailed added where Io.Writer is used
- builtin_compiler main accepts std.process.Init for io/gpa access
All compilation errors resolved. Runtime crash remains in builtin_compiler
due to unimplemented io threading for file imports in canonicalization
(uses undefined Io as placeholder).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mechanical replacements across ~99 files:
- std.fs.File -> std.Io.File (36 files)
- std.fs.cwd() -> std.Io.Dir.cwd() (50 files)
- std.fs.Dir -> std.Io.Dir (type references)
- std.fs.openDirAbsolute -> std.Io.Dir.openDirAbsolute
- std.fs.max_path_bytes -> std.Io.Dir.max_path_bytes
- std.fs.accessAbsolute/createFileAbsolute/selfExePath -> std.Io.Dir.*
- std.process.Child.run -> std.process.run
- std.process.Child.RunResult -> std.process.RunResult
- std.Thread.Mutex -> std.Io.Mutex
- std.mem.trimRight -> std.mem.trimEnd
- ArrayList(T){} -> ArrayList(T) = .empty (85+ occurrences)
- ArrayList field defaults .{} -> .empty
- @type(.{ .int = ... }) -> std.meta.Int() (layout.zig, interpreter_layout)
- Test platform hosts: deprecatedWriter -> std.debug.print
Many files still need io parameter threading for Dir/File method calls.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- @type(.{ .int = ... }) -> std.meta.Int() (interpreter_layout) - std.AutoArrayHashMap -> std.AutoArrayHashMapUnmanaged - makePath -> createDirPath - posix.exit -> std.process.exit - ScalarUnion packed union: pad fields to uniform 4-bit width - ArrayList .{} -> .empty in backend/dev object files - Fix remaining ArrayList init patterns Remaining: File I/O io threading, realpathAlloc removal, test host file writeAll/read methods, signal handler types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Layout packed unions: pad void fields to uniform bit width (28 bits) - ScalarUnion: pad all fields to 4 bits for packed union compatibility - Scalar: add padding to fill 28-bit LayoutUnion width - AutoArrayHashMapUnmanaged: fix deinit to pass allocator - Fix remaining ArrayList .empty patterns in backend/dev Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zig 0.16 requires all packed union fields to have the same bit width. Converted Layout's packed unions to the idiomatic Zig 0.16 pattern: raw integer data + tag with typed accessor methods (wrap/unwrap pattern). - LayoutUnion (packed union) -> LayoutData (u28 raw integer) - ScalarUnion (packed union) -> ScalarData (u4 raw integer) - Added accessor methods: getScalar(), getIdx(), getStruct(), etc. - Added Scalar constructors: initStr(), initInt(), initFrac() - Updated ~594 access sites across 24 files via mechanical replacement - Layout still fits in exactly 32 bits (28 data + 4 tag) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
std.posix.write/read removed in Zig 0.16. For test platform hosts:
- stderr writes: use std.debug.print("{s}", .{msg})
- stdout writes: use std.Io.File.stdout().writeStreamingAll(std.Options.debug_io, msg)
- stdin reads: use std.Io.File.stdin().readStreaming(std.Options.debug_io, &.{buf})
std.Options.debug_io provides a global Io instance usable even in
library builds without a Zig standard entry point.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- posix.write(STDERR_FILENO, msg) -> std.debug.print("{s}", .{msg})
- posix.exit(code) -> std.process.exit(code)
- ArrayList field default .{} -> .empty in fx host
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace Layout{.data=.{.scalar=...}} construction with Layout.int/frac/str/etc constructors
- Fix Scalar field access: scalar.data.int -> scalar.getInt(), scalar.data.frac -> scalar.getFrac()
- Fix @bitcast size mismatch: Scalar is now 28 bits padded, use @truncate for 7-bit extraction
- Fix Layout test assertions for new Scalar structure
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zig 0.16 replaced implicit syscall-based I/O with an explicit std.Io
parameter. This commit threads io through all file, directory, and
process operations across the codebase (~140 errors resolved).
Key changes:
- All test files: add `const io = std.testing.io` and pass to file/dir ops
- File ops: createFile(io, ...), close(io), openDir(io, ...), stat(io), etc.
- Replace removed APIs: realpathAlloc -> realPathFileAlloc, seekTo -> positional
read, getEndPos -> writer.total_bytes, readAll -> readPositionalAll,
writeAll -> writeStreamingAll, mprotect -> std.c.mprotect
- fmt.zig: thread io through formatPath/formatFilePath/formatStdin
- unbundle.zig: add io field to DirExtractWriter
- coordination.zig: selfExePathAlloc -> std.process.executablePathAlloc
- platform.zig: crypto.random -> io.random, ftruncate -> std.c.ftruncate
- handlers.zig: signal handler param i32 -> posix.SIG
- stack_overflow.zig: posix.write -> std.c.write (signal-safe)
- Networking: std.net -> std.Io.net with updated APIs
- download.zig: preserve localhost loopback security check via getaddrinfo
- test_runner.zig: accept std.process.Init
- PROT: bitwise OR -> packed struct initializer
- Various: std.io -> std.Io, LayoutUnion/ScalarUnion removal,
refAllDeclsRecursive -> refAllDecls, ArrayList .{} -> .empty
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zig 0.16's shrinkRetainingCapacity now poisons freed memory with 0xAA (undefined), exposing a latent use-after-shrink bug. The code took a slice from scratch_free_vars, then called clearFrom (which shrinks and now poisons), then iterated the now-poisoned slice. Fix by copying the slice to a temporary buffer before clearing. This affected both guard and body free variable filtering in match branches. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…uild
- Fix use-after-shrink in match branch free variable filtering (Can.zig)
Zig 0.16 shrinkRetainingCapacity now poisons freed memory, exposing
a latent bug where slices into scratch lists were read after clearing
- Convert interpreter_layout packed unions to raw-data-with-accessors
- Thread std.Io through io/Io.zig OS implementations
- Fix roc CLI main to accept std.process.Init
- Thread io through cli/main.zig, CliContext, compile_build, cache_cleanup
- Fix LLVM Variable.Index.setLinkage -> global.setLinkage
- Fix std.Io.Mutex/Condition init and lock/unlock signatures
- Various: ArrayList .{} -> .empty, makeDir -> createDir, trimRight -> trimEnd,
crypto.random -> io.random, getCwdAlloc -> realPathFileAlloc,
stat.mtime -> stat.mtime.nanoseconds, time.nanoTimestamp -> Io.Timestamp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Thread std.Io through remaining CLI, compile, LSP, and eval modules.
All roc source code now compiles cleanly. Remaining errors are only in
external dependencies (bytebox, stable_array) which need separate updates.
Key changes across 30 files:
- Mutex/Condition: .lock()/.unlock()/.wait()/.signal() now take io param
- All Dir/File operations: thread std.Options.debug_io
- time.nanoTimestamp -> Io.Timestamp.now(io, .real).nanoseconds
- process.Child -> process.spawn/run with new signatures
- std.io -> std.Io, std.net -> std.Io.net
- LLVM Variable.Index.setLinkage -> .global.setLinkage
- ArrayList init .{} -> .empty, Mutex/Condition init -> .init
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… roc binary - Update bytebox to zig-0.16.0 branch (rdunnington/bytebox#90) - Fix stable_array build.zig addTest API (root_source_file -> root_module) - Fix stable_array PROT packed struct (NONE/READ|WRITE -> .{} / .{.READ=true,...}) zig build roc now succeeds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… API changes Fix TypeWriter.writeWhereClause double-free and empty where clause caused by managedWriter bridge pattern: move buf_tmp pre-allocation before writer creation and track positions via writer.end instead of buf_tmp.items.len. Update eval tests for Zig 0.16 API changes: Dir.createDirPath/writeFile now require io parameter, ArrayList init uses .empty, posix.pipe/fork/close replaced with std.c equivalents, waitpid status parsing uses @bitcast. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…win target Update glue platform host for Zig 0.16 File/Dir API changes: - File.writeAll → File.writeStreamingAll with Io parameter - File.writer → File.writer with Io parameter - Dir.createDirPath/writeFile now require Io parameter - ArrayListUnmanaged init requires explicit fields - panicImpl uses std.debug.print (matches fx host pattern) Disable arm64win cross-compile target due to Zig 0.16 stdlib bug (@ptrCast alignment error in std/debug/SelfInfo/Windows.zig:569). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Initialize debug_threaded_io in CLI and test runner so std.Options.debug_io has a real allocator for process spawning - Update LSP tests: std.io.fixedBufferStream → std.Io.Reader/Writer.fixed - Fix LSP sentinel-terminated path handling (realPathFileAlloc returns [:0]u8) - Update transport.zig readSome for new Io.Reader API - Fix repl_test: posix.fork → std.c.fork, posix.waitpid → std.c.waitpid - Fix snapshot_tool: getCwdAlloc → currentPathAlloc, iter.next() → iter.next(io) - Fix CLI: signal type u32 → std.posix.SIG, makeDir → createDir, writeFile io param - Remove leftover debug prints from LSP syntax tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix ci/tidy.zig: ArrayHashMap API changes, process.Child → process.run, readFile/Dir io params, accept Init for proper IO setup - Remove dead code flagged by tidy: unused constants, functions, imports Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace File.writeAll trace calls with std.debug.print in StackValue.zig and interpreter.zig - Add io parameter to File.writer() in eval_test.zig and helpers.zig - Add io parameter to Dir.deleteFile() in llvm_evaluator.zig Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix ci/zig_lints.zig for Zig 0.16: accept Init for IO, thread io through walkTree/readSourceFile/check functions, replace Child.init with process.run, update readFileAllocOptions API, rename trimLeft/trimRight to trimStart/trimEnd, fix ArrayList init - Add doc comments to pub std_options_debug_threaded_io declarations - Auto-format changes from zig fmt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update for Zig 0.16 API changes: Init for IO, Dir.openDir/close/iterate io params, readFileAllocOptions, statFile, relativePosix, ArrayList init. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace argsAlloc with Init args iterator, use Dir.readFileAllocOptions instead of File.readToEndAlloc. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- playground_wasm: std.io.Writer → std.Io.Writer, handle WriteFailed error, replace ArrayList.writer() with bufPrint - playground integration: replace argsAlloc with Init args iterator, nanoTimestamp with clock_gettime, readFileAlloc io param Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Snapshot tool: - Accept Init for args, dumpCurrentStackTrace field rename, signal handler SIG type, ArrayList.writer → Io.Writer.Allocating, trimRight → trimEnd, Dir io params for createDirPath/deleteTree/ writeFile/deleteFile, iterator.next io param Playground: - std.io.Writer → std.Io.Writer, handle WriteFailed, bufPrint for error JSON, nanoTimestamp replacement, readFileAlloc io param, argsAlloc → Init args Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…h codebase Rename Roc's Io abstraction to RocIo (type) / roc_io (fields) to avoid confusion with Zig 0.16's std.Io, and thread std.Io as an explicit runtime parameter through the compiler pipeline. Key changes: - Rename Io -> RocIo across ~20 files (module root, imports, fields, params) - Add sys_io: std.Io field to Channel, Coordinator, PackageEnv, BuildEnv - Replace all 413 std.Options.debug_io code references with either self.sys_io (struct fields) or app_sys_io (module-level vars) - Add io module as build dependency for can module - Entry points initialize app_sys_io from std.process.Init.io Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rough params Replace module-level mutable `app_sys_io` vars with proper parameter threading, following Zig 0.16's explicit-IO design pattern. - CLI: add sys_io field to CliContext.Io, access via ctx.io.sys_io - LSP: add sys_io field to Server, SyntaxChecker, Transport structs - Hosts: add sys_io field to HostEnv, access via env cast in callbacks - Compiler internals: thread sys_io as function parameter - Tests: use std.testing.io - Standalone mains: use local const from init.io Only 4 justified module-level vars remain: - Io.zig sys_io (vtable OS impl, signature-constrained) - compile_build.zig build_sys_io (vtable callback, same) - dev_shim/interpreter_shim (shared libs, no main()) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…zig global Pass std.Io through the RocIo vtable instead of using a module-level global. Every vtable function now receives sys_io as its second parameter, and wrapper methods pass self.sys_io automatically. This eliminates: - var sys_io global in Io.zig (and initSysIo/getSysIo API) - var build_sys_io global in compile_build.zig RocIo.default()/os() now require a sys_io argument. The sys_io field is carried on the struct and threaded through vtable calls invisibly to callers — the public API (roc_io.readFile, etc.) is unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…icalize APIs Replace removed readToEndAlloc with readerStreaming loop pattern. Update fuzz-canonicalize for Zig 0.16 Dir/process API changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…straction Add tidy check that bans `std.Io` usage in core compiler modules, enforcing that they use Roc's Io abstraction instead. Exceptions are made for `std.Io.Writer` and `std.Io.Reader` which are generic I/O interfaces not tied to the OS. Extend RocIo with new operations: - deleteFile, deleteDir, deleteTree, createDir, copyFile - timestampNow (returns nanoseconds since epoch) Migrate core modules to use RocIo methods instead of std.Io directly: - Replace std.Io.Timestamp.now() with roc_io.timestampNow() - Replace std.Io.Dir.cwd().deleteFile/deleteTree/etc with RocIo methods - Replace std.Io.Threaded.global_single_threaded.io() defaults with proper Io threading from callers or RocIo.os(std.testing.io) in tests - Use SysIo = @FieldType(RocIo, "sys_io") alias for threading primitives that genuinely need the raw type without the banned string Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Unify the separate Allocators (gpa + arena) and RocIo (filesystem/stdio vtable) into a single RocCtx context struct. This consolidates 9 structs and 12+ functions that previously accepted both into a single roc_ctx parameter, reducing parameter counts across the compiler. - Rename src/io/ → src/ctx/, Io.zig → RocCtx.zig, RocIo → RocCtx - Add gpa/arena allocator fields to RocCtx - Parse takes raw gpa: Allocator (no IO needed) - Canonicalize takes roc_ctx: RocCtx (needs both allocators and IO) - Delete Allocators struct from base/mod.zig - Update ~66 files across the codebase Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ldEnv and evaluators Remove unused `base` imports in canonicalize/mod.zig and compile_module.zig. Add sys_io parameter to BuildEnv.init so callers thread their IO context through instead of using a testing stub that panics on real filesystem operations. Make roc_ctx optional in DevRocEnv and ComptimeEvaluator so null is handled gracefully instead of panicking. Fix echo.zig to pass EchoEnv to makeDefaultRocOps. Replace std.testing.tmpDir in fuzz-canonicalize with std.Io.Dir APIs that work outside test mode. Update snapshot tool to use app_io from main instead of testing RocCtx. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ys_io→std_io Standardize context naming and enforce proper context threading: - Rename RocCtx to CoreCtx and CliContext to CliCtx for consistency - Rename sys_io field/param to std_io, remove all SysIo type aliases - Add CliCtx.coreCtx() helper, replace 16 inline CoreCtx.default() calls - Remove dead CliErrorContext backward-compat alias - Add tidy lint banning CoreCtx.default()/os() outside entrypoints - Refine std.Io ban to target OS entry points (Dir.cwd, File.stderr, etc.) - Fix 18 pre-existing violations: cache_cleanup uses CoreCtx.listDir(), fmt threads stdin/stdout/stderr as params, Builder/MonoLlvmCodeGen avoid global I/O, test helpers accept std.Io parameter - Remove dead mmap code path in cache_module.zig Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, min version bump, TODO markers - Use @round/@floor/@ceil directly with integer result types instead of @intFromFloat(math.round/floor/ceil(...)) in builtins/num.zig - Rename error.EnvironmentVariableNotFound to EnvironmentVariableMissing to match Zig 0.16 std library naming - Update minimum_zig_version to 0.16.0 in build.zig.zon - Add TODO ZIG 16 comments at all remaining 0.15.x reference sites (CI workflows, docs, build.zig workarounds, bootstrap dep URLs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s, fix memory leak, update expected Restore 7 snapshot files that were accidentally emptied in ee0ae23. Fix args memory leak in snapshot tool main (missing defer free). Update inline_ingested_file.md EXPECTED section to match the renamed FILE IMPORT ERROR tag. Migrate std.mem index functions to Zig 0.16 API (indexOfScalar→findScalar, lastIndexOf→findLast, etc). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adopt idiomatic Zig 0.16 names for std.mem search functions. The old names are deprecated aliases that still compile, but the new names are the canonical API going forward. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…crash Fix multiple test failures from the Zig 0.16 migration: - snapshot_tool: set app_io = std.testing.io before snapshot validation test to avoid segfault on undefined IO vtable - cache_manager: propagate roc_ctx from CacheManager.init into CacheConfig so env var lookups (ROC_CACHE_DIR, HOME) work instead of hitting the testing stub that always returns NoHomeDirectory - cli tests: Io.init() → Io.create(std.testing.io) for Zig 0.16 API - targets_validator: add missing std.testing.io arg to validateTargetFilesExist Fix dev backend crash in List.map (and any builtin using receiver-style dispatch). MIR lowering of dot-access and type-var dispatch now emits run_low_level directly when the resolved proc is a trivial low-level wrapper, matching the existing namespace-lookup path. Previously the dispatch path generated a normal call, causing the RC pass to insert a decref of the borrowed list argument, freeing it before the walk loop. Improve signal handler stack overflow detection: capture actual stack bounds via pthread APIs at install time instead of the overly broad "any address > 4GB" heuristic that misclassified heap segfaults as stack overflows on macOS arm64. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Collaborator
Author
There was a problem hiding this comment.
Moved this logic into src/ctx/CoreCtx.zig
…fixes Fix segfault in Set.insert eval test caused by dangling slice into monotype store. lowerDotAccess obtained expected_arg_monotypes slice before lowering the receiver; recursive dot access grew the store via importMonotypeFromStore, invalidating the outer slice. Move the slice acquisition after receiver lowering and dupe both lowerDotAccess and lowerTypeVarDispatch slices to guard against in-loop invalidation. Also fix Io.init() → Io.create(std.testing.io) in libc_finder test, and correct rc_insert test expectation for retain-via-temp mechanism. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update all 8 roc_deps_* bootstrap URLs and hashes from zig-0.15.1 to zig-0.16.0. Add LLVMDebugInfoDWARFLowLevel to link list (new library in updated LLVM where DWARF symbols were split out). Nix sha256 hashes are placeholders pending nix build verification. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… doc comments - Add src/shim_io.zig: minimal std.Io vtable for shims/platform hosts that avoids pulling std.Io.Threaded (and its filesystem/stat/timestamp deps) into user program links - Update all shims and platform hosts to import shim_io and declare the three std_options_* overrides; switch app_std_io from Threaded to shim_io - Enable link_libc=true uniformly across RocModules (Zig 0.16 requires it for any compile unit touching std.c.*) - CI: bump Zig version from 0.15.2 to 0.16.0 - linker.zig: add cross-platform selfExePath (Linux /proc/self/exe, macOS _NSGetExecutablePath, Windows PEB) replacing the macOS-only call - watch.zig: use std.os.linux.inotify_* syscalls directly (std.posix wrappers removed in 0.16) - Add /// doc comments required by zig_lints.zig pub-declaration check Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.