E8011
E8011 — A pointer clause that is not well formed:requires valid(p, n),requires initialized(p, n)orrequires !overlaps(p, q, n), wherepandqare raw pointer parameters, and each clause is arequiresof its own. A call through a function value or a trait would not prove the clause, so a safe function with one cannot be a function value, and a safe method of a trait impl cannot have one.
What the compiler reports
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:12: `fill` is a method of an impl of `Fills`, so it must be an `unsafe fn` to have a pointer clause: a call through the trait would not prove the clause
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:9: a pointer clause in `ensures` is not supported yet: write it as a `requires`
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:10: write each pointer clause as a `requires` of its own, as in `requires valid(p, n)`
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:10: `valid` takes a raw pointer parameter and a length, as in `valid(p, n)`
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:10: only `!overlaps(p, q, n)` says something that the body can use
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:11: `!valid` says nothing that the body can use
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:10: `z` is not a parameter of `no_such_parameter`
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:10: `valid` needs a raw pointer, but `r` is `&i64`
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:11: `overlaps` needs two different pointers, but both are `p`
Error[E8011] at {{.*}}.vx:[[@LINE+2]]:12: `safe_with_a_clause` has a pointer `requires`, so it cannot be a function value yet: a call through the value would not prove the clause
10 error(s) emitted
The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.
A program that triggers it
//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
// A pointer clause is a `requires` of its own: `valid(p, n)`, `initialized(p, n)` or
// `!overlaps(p, q, n)`, where `p` and `q` are raw pointer parameters. A safe function with one
// cannot be a function value, and a safe method of a trait impl cannot have one, because a call
// through the value or the trait would not prove the clause.
// The checks of the whole program come before the checks of the bodies.
trait Fills {
fn fill(self : &Self, p : *mut i64, n : i64) -> void;
}
struct Filler {
k : i64,
}
impl Fills for Filler {
fn fill(self : &Filler, p : *mut i64, n : i64) -> void
requires valid(p, n)
{
return;
}
}
unsafe fn in_ensures(p : *mut i64) -> *mut i64
ensures valid(return, 1)
{
return p;
}
unsafe fn inside_another_clause(p : *mut i64, n : i64) -> void
requires valid(p, n) && n > 0
{
return;
}
unsafe fn no_length(p : *mut i64) -> void
requires valid(p)
{
return;
}
unsafe fn overlaps_without_not(p : *mut i64, q : *mut i64) -> void
requires overlaps(p, q, 4)
{
return;
}
unsafe fn not_valid(p : *mut i64) -> void
requires !valid(p, 4)
{
return;
}
unsafe fn no_such_parameter(_p : *mut i64) -> void
requires valid(z, 4)
{
return;
}
unsafe fn not_a_raw_pointer(r : &i64) -> void
requires valid(r, 1)
{
return;
}
unsafe fn one_pointer_twice(p : *mut i64) -> void
requires !overlaps(p, p, 4)
{
return;
}
fn safe_with_a_clause(p : *mut i64, n : i64) -> void
requires valid(p, n)
{
return;
}
fn as_a_function_value() -> void {
let _f = safe_with_a_clause;
}
fn main() -> i32 {
return 0;
}
From tests/frontend/fail/pointer_clause_that_is_written_wrong.vx, which asserts this diagnostic on every commit.
Related
Contracts and verificationThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E8010An
mlir! block whose dialects list does not match its body: the body uses an operation of a dialect that the list does not name, or the list names something that is not a dialect. The list is what the block says it uses, so it must be right.