Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable contracts for const functions #138374

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

celinval
Copy link
Contributor

@celinval celinval commented Mar 11, 2025

Use const_eval_select!() macro to enable contract checking only at runtime. The existing contract logic relies on closures, which are not supported in constant functions.

This commit also removes one level of indirection for ensures clauses since we no longer build a closure around the ensures predicate.

Resolves #136925

Call-out: This is still a draft PR since CI is broken due to a new warning message for unreachable code when the bottom of the function is indeed unreachable. It's not clear to me why the warning wasn't triggered before.

r? @compiler-errors

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 11, 2025
Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what case is the unreachable error being generated? Can you turn it into a minimal example? I'm not totally sure what's going on with the code generation.

@celinval
Copy link
Contributor Author

I am still trying to understand why the new logic triggers the new warning, when the old one didn't.

In what case is the unreachable error being generated? Can you turn it into a minimal example? I'm not totally sure what's going on with the code generation.

So, if you look at the following example from one of the tests:

#![feature(contracts)]

pub struct Baz { baz: i32 }

#[core::contracts::requires(x.baz > 0)]
#[core::contracts::ensures(|ret| *ret > 100)]
pub fn nest(x: Baz) -> i32
{
    loop {
        return x.baz + 50;
    }
}

with the existing changes, you will get a warning:

warning: unreachable expression
  --> bar.rs:6:1
   |
6  | #[core::contracts::ensures(|ret| *ret > 100)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable expression
...
10 |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |

which in a way it makes sense, since we do add a call to check the post-condition after the loop statement. What I don't get is why it wasn't being triggered before, and whether I can mark the new code as allow(unreachable_code).

If I compile with Z unpretty=hir, this is what I get with this PR:

fn nest(x: Baz) -> i32 {
    #[lang = "contract_check_requires"](|| x.baz > 0);
    let __ensures_checker = #[lang = "contract_build_check_ensures"](|ret| *ret > 100);
    #[lang = "contract_check_ensures"]({
            loop { return #[lang = "contract_check_ensures"](x.baz + 50, __ensures_checker); }
    }, __ensures_checker)
}

before the changes, we had:

fn nest(x: Baz) -> i32 {
    #[lang = "contract_check_requires"](|| x.baz > 0);
    let __ensures_checker = #[lang = "contract_build_check_ensures"](|ret| *ret > 100);
    __ensures_checker({ loop { return __ensures_checker(x.baz + 50); } })
}

Use `const_eval_select!()` macro to enable contract checking only at
runtime. The existing contract logic relies on closures,
which are not supported in constant functions.

This commit also removes one level of indirection for ensures clauses,
however, it currently has a spurious warning message when the bottom
of the function is unreachable.
@celinval celinval force-pushed the issue-136925-const-contract branch from 2ff3baa to 4dd0bca Compare March 12, 2025 06:04
@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-18 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
#19 exporting to docker image format
#19 sending tarball 22.2s done
#19 DONE 29.0s
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-18]
[CI_JOB_NAME=x86_64-gnu-llvm-18]
debug: `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` configured.
---
sccache: Listening on address 127.0.0.1:4226
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-18', '--enable-llvm-link-shared', '--set', 'rust.randomize-layout=true', '--set', 'rust.thin-lto-import-instr-limit=10', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--set', 'rust.lld=false', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--enable-new-symbol-mangling']
configure: build.build          := x86_64-unknown-linux-gnu
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-18/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.randomize-layout := True
configure: rust.thin-lto-import-instr-limit := 10
---
  Number of decisions:   4447
  longest path:          1159 (code:    152)
  longest backtrack:       66 (code:    428)
Shared 86733 out of 152951 states by creating 14756 new states, saving 71977
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/expmed.cc: In function ‘rtx_def* extract_bit_field_1(rtx, poly_uint64, poly_uint64, int, rtx, machine_mode, machine_mode, bool, bool, rtx_def**)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/expmed.cc:1864:45: warning: ‘*(unsigned int*)((char*)&imode + offsetof(scalar_int_mode, scalar_int_mode::m_mode))’ may be used uninitialized [-Wmaybe-uninitialized]
 1864 |       rtx sub = extract_bit_field_as_subreg (mode1, op0, imode,
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
 1865 |                                              bitsize, bitnum);
      |                                              ~~~~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/expmed.cc:1824:19: note: ‘*(unsigned int*)((char*)&imode + offsetof(scalar_int_mode, scalar_int_mode::m_mode))’ was declared here
 1824 |   scalar_int_mode imode;
      |                   ^~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/gimple-range-gori.cc: In member function ‘void range_def_chain::dump(FILE*, basic_block, const char*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/gimple-range-gori.cc:319:19: warning: format not a string literal and no format arguments [-Wformat-security]
---
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
In file included from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-playback.h:31,
                 from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/dummy-frontend.cc:25:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h: In member function ‘virtual bool gcc::jit::recording::type::is_same_type_as(gcc::jit::recording::type*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h:640:20: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
  640 |     if ((is_int () && other->is_int () || is_float() && other->is_float())
      |          ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
In file included from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/libgccjit.cc:30:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h: In member function ‘virtual bool gcc::jit::recording::type::is_same_type_as(gcc::jit::recording::type*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h:640:20: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
  640 |     if ((is_int () && other->is_int () || is_float() && other->is_float())
      |          ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/libgccjit.cc: In function ‘gcc_jit_type* gcc_jit_context_new_array_type(gcc_jit_context*, gcc_jit_location*, gcc_jit_type*, long unsigned int)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/libgccjit.cc:807:37: warning: comparison of unsigned expression in ‘>= 0’ is always true [-Wtype-limits]
  807 |   RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size");
---
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
In file included from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-playback.h:31,
                 from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-builtins.cc:24:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h: In member function ‘virtual bool gcc::jit::recording::type::is_same_type_as(gcc::jit::recording::type*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h:640:20: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
  640 |     if ((is_int () && other->is_int () || is_float() && other->is_float())
      |          ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/omp-builtins.def: At global scope:
./options.h:6899:37: warning: narrowing conversion of ‘global_options.gcc_options::x_flag_openacc’ from ‘int’ to ‘bool’ [-Wnarrowing]
 6899 | #define flag_openacc global_options.x_flag_openacc
      |                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-builtins.cc:58:23: note: in definition of macro ‘DEF_BUILTIN’
   58 |   {NAME, CLASS, TYPE, BOTH_P, FALLBACK_P, ATTRS, IMPLICIT},
      |                       ^~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/builtins.def:223:16: note: in expansion of macro ‘flag_openacc’
  223 |                flag_openacc, true, true, ATTRS, false, true)
      |                ^~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/omp-builtins.def:55:1: note: in expansion of macro ‘DEF_GOACC_BUILTIN_COMPILER’
   55 | DEF_GOACC_BUILTIN_COMPILER (BUILT_IN_ACC_ON_DEVICE, "acc_on_device",
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~
./options.h:6911:36: warning: narrowing conversion of ‘global_options.gcc_options::x_flag_openmp’ from ‘int’ to ‘bool’ [-Wnarrowing]
 6911 | #define flag_openmp global_options.x_flag_openmp
      |                     ~~~~~~~~~~~~~~~^~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-builtins.cc:58:23: note: in definition of macro ‘DEF_BUILTIN’
   58 |   {NAME, CLASS, TYPE, BOTH_P, FALLBACK_P, ATTRS, IMPLICIT},
      |                       ^~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/builtins.def:238:16: note: in expansion of macro ‘flag_openmp’
  238 |                flag_openmp, true, true, ATTRS, false, flag_openmp)
      |                ^~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/omp-builtins.def:72:1: note: in expansion of macro ‘DEF_GOMP_BUILTIN_COMPILER’
   72 | DEF_GOMP_BUILTIN_COMPILER (BUILT_IN_OMP_IS_INITIAL_DEVICE,
      | ^~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/../libgcc/libgcov-util.c: In function ‘gcov_info* gcov_read_profile_dir(const char*, int)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/../libgcc/libgcov-util.c:456:9: warning: ignoring return value of ‘int chdir(const char*)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  456 |   chdir (pwd);
      |   ~~~~~~^~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
In file included from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-playback.h:31,
                 from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-playback.cc:49:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h: In member function ‘virtual bool gcc::jit::recording::type::is_same_type_as(gcc::jit::recording::type*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h:640:20: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
  640 |     if ((is_int () && other->is_int () || is_float() && other->is_float())
      |          ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/gengtype-lex.l: In function ‘int yylex(const char**)’:
---
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/gcc.cc:7930:9: warning: ignoring return value of ‘ssize_t write(int, const void*, size_t)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
 7930 |   write (fd, "\n\n", 2);
      |   ~~~~~~^~~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/gcc.cc: In member function ‘void driver::final_actions() const’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/gcc.cc:9307:13: warning: ignoring return value of ‘int truncate(const char*, __off_t)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
 9307 |     truncate(totruncate_file, 0);
      |     ~~~~~~~~^~~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/lto-wrapper.cc: In function ‘bool find_and_merge_options(int, off_t, const char*, vec<cl_decoded_option>, bool, vec<cl_decoded_option>*, const char*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/lto-wrapper.cc:1165:8: warning: ignoring return value of ‘ssize_t read(int, void*, size_t)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
---
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/lto/lto-common.cc: In function ‘void lto_resolution_read(splay_tree, FILE*, lto_file*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/lto/lto-common.cc:2091:10: warning: ignoring return value of ‘int fscanf(FILE*, const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
 2091 |   fscanf (resolution, " ");   /* Read white space.  */
      |   ~~~~~~~^~~~~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/lto/lto-common.cc:2093:9: warning: ignoring return value of ‘size_t fread(void*, size_t, size_t, FILE*)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
 2093 |   fread (obj_name, sizeof (char), name_len, resolution);
      |   ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/lto/lto-common.cc:2113:10: warning: ignoring return value of ‘int fscanf(FILE*, const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
 2113 |   fscanf (resolution, "%u", &num_symbols);
      |   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-everything’ may have been intended to silence earlier diagnostics
In file included from /checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.cc:32:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h: In member function ‘virtual bool gcc::jit::recording::type::is_same_type_as(gcc::jit::recording::type*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.h:640:20: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
  640 |     if ((is_int () && other->is_int () || is_float() && other->is_float())
      |          ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.cc: In member function ‘virtual void gcc::jit::recording::memento_of_set_personality_function::replay_into(gcc::jit::replayer*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/gcc/jit/jit-recording.cc:7595:72: warning: unused parameter ‘r’ [-Wunused-parameter]
 7595 | recording::memento_of_set_personality_function::replay_into (replayer *r)
---
Applying io_quotes_use            to linux/blkzoned.h
Applying io_quotes_use            to linux/ipmi.h
Applying io_quotes_use            to linux/psp-dbc.h
Applying io_quotes_use            to linux/bt-bmc.h
Applying io_quotes_use            to linux/tps6594_pfsm.h
Applying io_quotes_use            to linux/cxl_mem.h
Applying io_quotes_use            to linux/wmi.h
Applying io_quotes_use            to linux/auto_fs.h
Applying io_quotes_use            to linux/mmtimer.h
Applying io_quotes_use            to linux/f2fs.h
Applying io_quotes_use            to linux/vhost.h
---
Applying machine_name             to x86_64-linux-gnu/bits/unistd_ext.h
Applying io_quotes_use            to x86_64-linux-gnu/asm/mtrr.h
Applying io_quotes_use            to x86_64-linux-gnu/asm/amd_hsmp.h
Applying machine_name             to openssl/e_os2.h
Applying io_quotes_use            to drm/xe_drm.h
Applying io_quotes_use            to drm/radeon_drm.h
Applying io_quotes_use            to drm/panfrost_drm.h
Applying io_quotes_use            to drm/etnaviv_drm.h
Applying io_quotes_use            to drm/lima_drm.h
Applying io_quotes_use            to drm/qaic_accel.h
Applying io_quotes_use            to drm/vc4_drm.h
Applying io_quotes_use            to drm/i915_drm.h
Applying io_quotes_use            to drm/omap_drm.h
Applying io_quotes_use            to drm/pvr_drm.h
Applying io_quotes_use            to drm/amdgpu_drm.h
Applying io_quotes_use            to drm/vgem_drm.h
Applying io_quotes_use            to drm/msm_drm.h
Applying io_quotes_use            to drm/v3d_drm.h
Applying io_quotes_use            to drm/exynos_drm.h
Applying io_quotes_use            to drm/nouveau_drm.h
Applying io_quotes_use            to drm/drm.h
Applying io_quotes_use            to drm/habanalabs_accel.h
Applying io_quotes_use            to drm/tegra_drm.h
Applying io_quotes_use            to rdma/rdma_user_ioctl.h
cc1: note: self-tests are not enabled in this build
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/c++tools/server.cc: In function ‘void server(bool, int, module_resolver*)’:
/checkout/obj/build/x86_64-unknown-linux-gnu/gcc/src/c++tools/server.cc:620:10: warning: ignoring return value of ‘int pipe(int*)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
---
failures:

---- [ui] tests/ui/contracts/contract-attributes-nest.rs#chk_fail_post stdout ----

error in revision `chk_fail_post`: /checkout/tests/ui/contracts/contract-attributes-nest.rs:23: expected warning not found: unreachable expression [unreachable_code]

error in revision `chk_fail_post`: 0 unexpected errors found, 1 expected errors not found
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/contract-attributes-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "chk_fail_post" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/contract-attributes-nest.chk_fail_post/a" "-A" "unused" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=yes"

--- not found errors (from test file) ---
WARNING   line  23: unreachable expression [unreachable_code]
---


thread '[ui] tests/ui/contracts/contract-attributes-nest.rs#chk_fail_post' panicked at src/tools/compiletest/src/runtest.rs:799:13:
errors differ from expected
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- [ui] tests/ui/contracts/contract-attributes-nest.rs#chk_fail_pre stdout ----

error in revision `chk_fail_pre`: /checkout/tests/ui/contracts/contract-attributes-nest.rs:23: expected warning not found: unreachable expression [unreachable_code]

error in revision `chk_fail_pre`: 0 unexpected errors found, 1 expected errors not found
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/contract-attributes-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "chk_fail_pre" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/contract-attributes-nest.chk_fail_pre/a" "-A" "unused" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=yes"

--- not found errors (from test file) ---
WARNING   line  23: unreachable expression [unreachable_code]
---


thread '[ui] tests/ui/contracts/contract-attributes-nest.rs#chk_fail_pre' panicked at src/tools/compiletest/src/runtest.rs:799:13:
errors differ from expected

---- [ui] tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs#chk_pass stdout ----
Saved the actual stderr to "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/internal_machinery/contract-ast-extensions-nest.chk_pass/contract-ast-extensions-nest.chk_pass.stderr"
normalized stderr:
warning: unreachable expression
##[warning]  --> $DIR/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
---
The actual stderr differed from the expected stderr.
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args contracts/internal_machinery/contract-ast-extensions-nest.rs`

error in revision `chk_pass`: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "chk_pass" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "-O" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/internal_machinery/contract-ast-extensions-nest.chk_pass/a" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=yes"
stdout: none
--- stderr -------------------------------
warning: unreachable expression
##[warning]  --> /checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
---
normalized stderr:
warning: unreachable expression
##[warning]  --> $DIR/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
---
To only update this specific test, also pass `--test-args contracts/internal_machinery/contract-ast-extensions-nest.rs`

error in revision `unchk_fail_pre`: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "unchk_fail_pre" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "-O" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/internal_machinery/contract-ast-extensions-nest.unchk_fail_pre/a" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=no"
stdout: none
--- stderr -------------------------------
warning: unreachable expression
##[warning]  --> /checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
---
normalized stderr:
warning: unreachable expression
##[warning]  --> $DIR/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
---
To only update this specific test, also pass `--test-args contracts/internal_machinery/contract-ast-extensions-nest.rs`

error in revision `unchk_fail_post`: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "unchk_fail_post" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "-O" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/internal_machinery/contract-ast-extensions-nest.unchk_fail_post/a" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=no"
stdout: none
--- stderr -------------------------------
warning: unreachable expression
##[warning]  --> /checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
---
normalized stderr:
warning: unreachable expression
##[warning]  --> $DIR/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
---
To only update this specific test, also pass `--test-args contracts/internal_machinery/contract-ast-extensions-nest.rs`

error in revision `unchk_pass`: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "unchk_pass" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "-O" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/internal_machinery/contract-ast-extensions-nest.unchk_pass/a" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=no"
stdout: none
--- stderr -------------------------------
warning: unreachable expression
##[warning]  --> /checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs:23:21
   |
LL |     contract_ensures(|ret| *ret > 100)
   |                     ^^^^^^^^^^^^^^^^^^ unreachable expression
...
LL |         return x.baz + 50;
   |         ----------------- any code following this expression is unreachable
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 1 warning emitted
------------------------------------------


---- [ui] tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs#chk_fail_pre stdout ----

error in revision `chk_fail_pre`: /checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs:23: expected warning not found: unreachable expression [unreachable_code]

error in revision `chk_fail_pre`: 0 unexpected errors found, 1 expected errors not found
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "chk_fail_pre" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/internal_machinery/contract-ast-extensions-nest.chk_fail_pre/a" "-A" "unused" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=yes"

--- not found errors (from test file) ---
WARNING   line  23: unreachable expression [unreachable_code]
---


thread '[ui] tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs#chk_fail_pre' panicked at src/tools/compiletest/src/runtest.rs:799:13:
errors differ from expected

---- [ui] tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs#chk_fail_post stdout ----

error in revision `chk_fail_post`: /checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs:23: expected warning not found: unreachable expression [unreachable_code]

error in revision `chk_fail_post`: 0 unexpected errors found, 1 expected errors not found
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "chk_fail_post" "--check-cfg" "cfg(test,FALSE,unchk_pass,unchk_fail_pre,unchk_fail_post,chk_pass,chk_fail_pre,chk_fail_post)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/contracts/internal_machinery/contract-ast-extensions-nest.chk_fail_post/a" "-A" "unused" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zcontract-checks=yes"

--- not found errors (from test file) ---
WARNING   line  23: unreachable expression [unreachable_code]
---


thread '[ui] tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs#chk_fail_post' panicked at src/tools/compiletest/src/runtest.rs:799:13:
errors differ from expected

@celinval
Copy link
Contributor Author

@compiler-errors any thoughts?

@compiler-errors
Copy link
Member

No, I didn't look at it yet

@@ -5,16 +5,15 @@ pub use crate::macros::builtin::{contracts_ensures as ensures, contracts_require
/// Emitted by rustc as a desugaring of `#[ensures(PRED)] fn foo() -> R { ... [return R;] ... }`
/// into: `fn foo() { let _check = build_check_ensures(|ret| PRED) ... [return _check(R);] ... }`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now outdated, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me see if we can get rid of it completely

}

/// This is the old version of contract_check_ensures kept here for bootstrap only.
#[cfg(bootstrap)]
#[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)]
#[rustc_intrinsic]
pub fn contract_check_ensures<'a, Ret, C: Fn(&'a Ret) -> bool>(ret: &'a Ret, cond: C) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't you just add the Copy here? Why is cfg(bootstrap) needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we changed the return value and the arguments of this function.

Comment on lines +3318 to +3319
#[unstable(feature = "contracts_internals", issue = "128044")]
#[rustc_const_unstable(feature = "contracts", issue = "128044")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you using two different feature gates here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, for some reason the const stability check isn't working with contracts_internal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "isn't working" mean?

We used to have a bug where using a language feature for const stability didn't work (the feature would not get enabled properly), but I thought we had fixed that...

Comment on lines +14 to 15
pub const fn build_check_ensures<Ret, C>(cond: C) -> C
where
Copy link
Member

@RalfJung RalfJung Mar 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of this function? It's just the identity function?

This call helps with type inference for the predicate.

Surely there's a better way to do that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely. Let me give it a try

@fpoli
Copy link
Contributor

fpoli commented Mar 20, 2025

I am still trying to understand why the new logic triggers the new warning, when the old one didn't.

In the example, __ensures_checker is an unreachable expression because it's after the argument whose evaluation always returns. Normally, the compiler would highlight __ensures_checker. For example (playground):

warning: unreachable expression
  --> src/lib.rs:22:8
   |
21 |             loop { return contract_check_ensures(x.baz + 50, __ensures_checker); }
   |                    ------------------------------------------------------------ any code following this expression is unreachable
22 |     }, __ensures_checker)
   |        ^^^^^^^^^^^^^^^^^ unreachable expression
   |
   = note: `#[warn(unreachable_code)]` on by default

My understanding is that __ensures_checker is generated by a procedural macro, which attaches the span information of the ensures attribute to __ensures_checker. So, when the compiler tries to highlight __ensures_checker it actually highlights #[core::contracts::ensures(|ret| *ret > 100)]. If this explanation is correct, adding #[allow(unreachable_code)] just before the __ensures_checker in the generated code should suppress the warning:

fn nest(x: Baz) -> i32 {
    #[lang = "contract_check_requires"](|| x.baz > 0);
    let __ensures_checker = #[lang = "contract_build_check_ensures"](|ret| *ret > 100);
    #[lang = "contract_check_ensures"]({
            loop { return #[lang = "contract_check_ensures"](x.baz + 50, __ensures_checker); }
    }, #[allow(unreachable_code)] __ensures_checker)
}

@celinval
Copy link
Contributor Author

I am still trying to understand why the new logic triggers the new warning, when the old one didn't.

In the example, __ensures_checker is an unreachable expression because it's after the argument whose evaluation always returns. Normally, the compiler would highlight __ensures_checker. For example (playground):

warning: unreachable expression
  --> src/lib.rs:22:8
   |
21 |             loop { return contract_check_ensures(x.baz + 50, __ensures_checker); }
   |                    ------------------------------------------------------------ any code following this expression is unreachable
22 |     }, __ensures_checker)
   |        ^^^^^^^^^^^^^^^^^ unreachable expression
   |
   = note: `#[warn(unreachable_code)]` on by default

My understanding is that __ensures_checker is generated by a procedural macro, which attaches the span information of the ensures attribute to __ensures_checker. So, when the compiler tries to highlight __ensures_checker it actually highlights #[core::contracts::ensures(|ret| *ret > 100)]. If this explanation is correct, adding #[allow(unreachable_code)] just before the __ensures_checker in the generated code should suppress the warning:

fn nest(x: Baz) -> i32 {
    #[lang = "contract_check_requires"](|| x.baz > 0);
    let __ensures_checker = #[lang = "contract_build_check_ensures"](|ret| *ret > 100);
    #[lang = "contract_check_ensures"]({
            loop { return #[lang = "contract_check_ensures"](x.baz + 50, __ensures_checker); }
    }, #[allow(unreachable_code)] __ensures_checker)
}

The call is added as part of lowering the AST today. We can reconsider it though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Contract cannot be applied to const functions
6 participants