Not so Trivial Casts
By Nikita Bishonen • 1 minute read •
Not so Trivial Casts
There is an interestion lint in Rust called trivial_casts, yet it turns out to be not so trivial.
It may be possible that this will become a warning in the future
so let’s explore some code examples where I will compare:
- Trivial casts
- Variables types definitions
- Implicit coercion
I will not add any comments, except compiler outputs, so you will be able to see difference by yourself and decide when and how to use types casting in Rust code. I will only say that trivial_cast_supertype_with_shadowing seems to be a good example on how trivial_casts can become not so trivial even in small example (imagine what it can do in a bigger chain of calls and transformations/casts).
#![allow(dead_code)]
#![warn(trivial_casts)]
trait Polygon {}
trait TwoSidedPolygon: Polygon {}
struct Square([u32; 8]);
impl Polygon for Square {}
impl TwoSidedPolygon for Square {}
struct Triangle([u32; 6]);
impl Polygon for Triangle {}
#[cfg(test)]
mod tests {
use crate::{Polygon, Square, Triangle, TwoSidedPolygon};
#[test]
fn explicit_definition_supertype() {
let square = Square([2; 8]);
let square: &dyn Polygon = □
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
// process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &(dyn Polygon + 'static)
}
#[test]
fn explicit_definition_subtype() {
let square = Square([2; 8]);
let square: &dyn TwoSidedPolygon = □
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
process3(square);
// process_square(square); expected &Square, found &(dyn TwoSidedPolygon + 'static)
}
#[test]
fn trivial_cast_supertype() {
let square = Square([2; 8]);
let square = &square as &dyn Polygon; // trivial cast: `&Square` as `&dyn Polygon`
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
// process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &dyn Polygon
}
#[test]
fn trivial_cast_subtype() {
let square = Square([2; 8]);
let square = &square as &dyn TwoSidedPolygon; // trivial cast: `&Square` as `&dyn TwoSidedPolygon`
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
process3(square);
// process_square(square); expected &Square, found &(dyn TwoSidedPolygon + 'static)
}
#[test]
fn trivial_cast_struct_type() {
let square = Square([2; 8]);
let square = &square as □ // trivial cast: `&Square` as `&Square`
process(square);
process2(square);
process3(square);
process_square(square);
}
#[test]
fn auto_coercion() {
let square = Square([2; 8]);
let polygon = □
process(polygon);
process2(polygon);
process3(polygon);
process_square(polygon);
}
#[test]
fn shadowed_auto_coercion() {
let square = Square([2; 8]);
let square = Triangle([3; 6]);
let square = □
process(square);
process2(square);
// process3(square); the trait bound `Triangle: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &Triangle
process_triangle(square);
}
#[test]
fn trivial_cast_supertype_with_shadowing() {
let square = Square([2; 8]);
let square = Triangle([3; 6]);
let square = &square as &dyn Polygon; // trivial cast: `&Square` as `&Square`
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
// process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &dyn Polygon
}
fn process_square(_square: &Square) {}
fn process_triangle(_triangle: &Triangle) {}
fn process(_polygon: &(impl Polygon + ?Sized)) {}
fn process2(_polygon: &impl Polygon) {}
fn process3(_polygon: &(impl TwoSidedPolygon + ?Sized)) {}
}
Comments
You can comment on this blog post by publicly replying to this post using a Mastodon or other ActivityPub/Fediverse account. Known non-private replies are displayed below.