#等价 #类型 #元编程 #类型级别 #不等价

nightly spidermeme

用于测试类型等价和类型不等价的特性

1 个不稳定版本

0.1.0 2021 年 5 月 13 日

#1698 in Rust 模式

MIT/Apache

18KB

警告:该crate目前依赖于nightly rust不稳定功能。

spidermeme

Rust 特性,用于检查类型等价和类型不等价。
可以作为更复杂编译时约束的构建块。

docs.rs ci Coverage


 ______________________________________________________________________________
|_________________________ _______      |    |                              ___|
| ______________   ___    |  ___  |     |    |             ___           .-` | |
||                /   \   | |   | |     |    |            /   \         | _..| |
||                | o o   | |   | |     |    |            o   |         ||  || |
||  N  Y  P  D    \   / __  |___| |     |    |         __ \   / __      ||  || |
||             ..-'   ''  \    o--|     |    |        |  |______  \     ||  || |
||____________ |   \______\_____  |     |    |       .'  |      \  \    ||  || |
|_____________ |---__________/    |     |  _______.-' _.-/      \  |    ||  || |
|              \         | \____  |     |    \_____.-' \        /\ |    ||_ || |
|               \       / \____|  |     |               \       /| | ___|  ''| |
|                \     /          |     |    |           \      /__/ --..'--.| |
|       _____     =====   |_______|     |    |            ======\   ..   `-----|
|      /     \   /     \  |____________ |    |           /       \  | ''| |   _|
|     /  ___  \  /  _   \ |             |____|_________ /         | |   | |  | |
|    |  |   |   /  / \   \                             /    //   /  |   | |  | |
|___ |  |___|  /  / __ \  \                           /   / /   / | '-. | |  | |
|     \       /_/        \_\                         /  /'  /  /   `-. '' |  |_|
|      \____ / /          \ \                       |  /    \  \      `-. |    |
|            //           \ \__                     \__\     \__\        `-----|
|           /|             \___\                     \  |     \ \              |
|          /_|                                       \ /      \ /              |
|____________________________________________________\_/______|_|______________|

提供的特性

spidermeme::SameTypeAs<T>

一个自动实现的标记特性,用于检查两个类型是否相等。

spidermeme::NotSameTypeAs<T>

一个自动实现的标记特性,用于检查两个类型是否不相等。

示例

use spidermeme::{SameTypeAs, NotSameTypeAs};

struct MyPair<T1, T2>(T1, T2);

trait ProcessPair {
    fn process(&self);
}

impl<T1, T2> ProcessPair for MyPair<T1, T2> {
    fn process(&self) {
        println!("Pair of two different types.");
    }
}

impl<T1, T2> MyPair<T1, T2>
where
    T1: SameTypeAs<T2>,
{
    fn process(&self) {
        println!("Pair of same type.");
    }
}

struct UniquePair<T1, T2>
where
    T1: NotSameTypeAs<T2>,
{
    a: T1,
    b: T2,
}

impl<T1, T2> UniquePair<T1, T2>
where
    T1: NotSameTypeAs<T2>,
{
    pub fn new(a: T1, b: T2) -> Self {
        Self { a, b }
    }
}

fn main() {
    // Prints "Pair of same type."
    MyPair(1_i32, 2_i32).process();

    // Prints "Pair of two different types."
    MyPair(1_i32, 2_i16).process();

    // Valid.
    let x = UniquePair::<i32, f64>::new(1, 2.0);

    // The following fails to compile:
    // let y = UniquePair::<i32, i32>::new(1, 2);
}

类型等价的工作方式

类型等价非常直接。`SameTypeAs` 特性使用相同的泛型参数有一个空白实现。当简化时,基本原理如下

pub trait Same<T> {}
impl<T> Same<T> for T {}

这受到了网络上许多评论的启发。

类型不等价的工作方式

类型不等价使用 negative_implsauto_traits。一个简单的实现可能如下所示

#![feature(negative_impls)]
#![feature(auto_traits)]
pub auto trait DifferentNaive {}
impl<T> !DifferentNaive for (T, T) {}

然而,这将导致错误的阴性结果,因为对于包含(T, T)类型的自动特性将不会实现。例如,在以下示例中,原始实现将失败,因为((i32, i32), (f64, f64))包含(i32, i32)(f64, f64),它们都实现了DifferentNaive特性

use static_assertions::assert_impl_all;
assert_impl_all!(((i32, i32), (f64, f64)): DifferentNaive);

这个crate通过使用私有命名元组而不是原始元组来解决这个问题,因此可以保证下游crate不会测试包含此命名元组的类型。

已知问题/怪癖

  1. 使用SameTypeAsNotSameTypeAs同时实现同一类型的两个impl将导致:error[E0119]: conflicting implementations,这可能是由于Rust当前限制(?)。

  2. 对同一类型的引用,但具有不同的生命周期,被当作相同对待。如果你足够用力地眯眼,这可能被认为是一个“特性”。

  3. 对于重大项目中类型相等的问题,你可能会尝试一些由可能更了解类型理论和Rust类型系统的人编写的其他crate。

不稳定的功能

#![feature(negative_impls)]
#![feature(auto_traits)]
#![feature(extended_key_value_attributes)]

无运行时依赖