diff --git a/.gitignore b/.gitignore index 98b77490f..2a5d32757 100755 --- a/.gitignore +++ b/.gitignore @@ -107,7 +107,6 @@ windows/ZeroTierOne/Debug/ *.swp *~.nib DerivedData/ -build/ *.pbxuser *.mode1v3 *.mode2v3 @@ -118,7 +117,6 @@ build/ !default.perspectivev3 *.xccheckout xcuserdata/ -ext/librethinkdbxx/build .vscode __pycache__ *~ diff --git a/zeroidc/Cargo.lock b/zeroidc/Cargo.lock index 61de3d820..0633da9d5 100644 --- a/zeroidc/Cargo.lock +++ b/zeroidc/Cargo.lock @@ -1143,9 +1143,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ "cfg-if", "pin-project-lite", diff --git a/zeroidc/vendor/openssl-sys/build/cfgs.rs b/zeroidc/vendor/openssl-sys/build/cfgs.rs new file mode 100644 index 000000000..9ae7748cc --- /dev/null +++ b/zeroidc/vendor/openssl-sys/build/cfgs.rs @@ -0,0 +1,88 @@ +pub fn get(openssl_version: Option, libressl_version: Option) -> Vec<&'static str> { + let mut cfgs = vec![]; + + if let Some(libressl_version) = libressl_version { + cfgs.push("libressl"); + + if libressl_version >= 0x2_05_01_00_0 { + cfgs.push("libressl251"); + } + if libressl_version >= 0x2_05_02_00_0 { + cfgs.push("libressl252"); + } + if libressl_version >= 0x2_06_01_00_0 { + cfgs.push("libressl261"); + } + if libressl_version >= 0x2_07_00_00_0 { + cfgs.push("libressl270"); + } + if libressl_version >= 0x2_07_01_00_0 { + cfgs.push("libressl271"); + } + if libressl_version >= 0x2_07_03_00_0 { + cfgs.push("libressl273"); + } + if libressl_version >= 0x2_08_00_00_0 { + cfgs.push("libressl280"); + } + if libressl_version >= 0x2_08_01_00_0 { + cfgs.push("libressl281"); + } + if libressl_version >= 0x2_09_01_00_0 { + cfgs.push("libressl291"); + } + if libressl_version >= 0x3_02_01_00_0 { + cfgs.push("libressl321"); + } + if libressl_version >= 0x3_03_02_00_0 { + cfgs.push("libressl332"); + } + if libressl_version >= 0x3_04_00_00_0 { + cfgs.push("libressl340"); + } + if libressl_version >= 0x3_05_00_00_0 { + cfgs.push("libressl350"); + } + } else { + let openssl_version = openssl_version.unwrap(); + + if openssl_version >= 0x3_00_00_00_0 { + cfgs.push("ossl300"); + } + if openssl_version >= 0x1_00_01_00_0 { + cfgs.push("ossl101"); + } + if openssl_version >= 0x1_00_02_00_0 { + cfgs.push("ossl102"); + } + if openssl_version >= 0x1_00_02_06_0 { + cfgs.push("ossl102f"); + } + if openssl_version >= 0x1_00_02_08_0 { + cfgs.push("ossl102h"); + } + if openssl_version >= 0x1_01_00_00_0 { + cfgs.push("ossl110"); + } + if openssl_version >= 0x1_01_00_06_0 { + cfgs.push("ossl110f"); + } + if openssl_version >= 0x1_01_00_07_0 { + cfgs.push("ossl110g"); + } + if openssl_version >= 0x1_01_00_08_0 { + cfgs.push("ossl110h"); + } + if openssl_version >= 0x1_01_01_00_0 { + cfgs.push("ossl111"); + } + if openssl_version >= 0x1_01_01_02_0 { + cfgs.push("ossl111b"); + } + if openssl_version >= 0x1_01_01_03_0 { + cfgs.push("ossl111c"); + } + } + + cfgs +} diff --git a/zeroidc/vendor/openssl-sys/build/expando.c b/zeroidc/vendor/openssl-sys/build/expando.c new file mode 100644 index 000000000..300c50bb0 --- /dev/null +++ b/zeroidc/vendor/openssl-sys/build/expando.c @@ -0,0 +1,104 @@ +#include +#include + +#define VERSION2(n, v) RUST_VERSION_##n##_##v +#define VERSION(n, v) VERSION2(n, v) + +#define NEW_VERSION2(a, b, c) RUST_VERSION_NEW_OPENSSL_##a##_##b##_##c +#define NEW_VERSION(a, b, c) NEW_VERSION2(a, b, c) + +#ifdef LIBRESSL_VERSION_NUMBER +VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER) +#elif defined OPENSSL_VERSION_MAJOR +NEW_VERSION(OPENSSL_VERSION_MAJOR, OPENSSL_VERSION_MINOR, OPENSSL_VERSION_PATCH) +#else +VERSION(OPENSSL, OPENSSL_VERSION_NUMBER) +#endif + +#ifdef OPENSSL_NO_BF +RUST_CONF_OPENSSL_NO_BF +#endif + +#ifdef OPENSSL_NO_BUF_FREELISTS +RUST_CONF_OPENSSL_NO_BUF_FREELISTS +#endif + +#ifdef OPENSSL_NO_CHACHA +RUST_CONF_OPENSSL_NO_CHACHA +#endif + +#ifdef OPENSSL_NO_CMS +RUST_CONF_OPENSSL_NO_CMS +#endif + +#ifdef OPENSSL_NO_COMP +RUST_CONF_OPENSSL_NO_COMP +#endif + +#ifdef OPENSSL_NO_EC +RUST_CONF_OPENSSL_NO_EC +#endif + +#ifdef OPENSSL_NO_EC2M +RUST_CONF_OPENSSL_NO_EC2M +#endif + +#ifdef OPENSSL_NO_ENGINE +RUST_CONF_OPENSSL_NO_ENGINE +#endif + +#ifdef OPENSSL_NO_KRB5 +RUST_CONF_OPENSSL_NO_KRB5 +#endif + +#ifdef OPENSSL_NO_NEXTPROTONEG +RUST_CONF_OPENSSL_NO_NEXTPROTONEG +#endif + +#ifdef OPENSSL_NO_OCSP +RUST_CONF_OPENSSL_NO_OCSP +#endif + +#ifdef OPENSSL_NO_PSK +RUST_CONF_OPENSSL_NO_PSK +#endif + +#ifdef OPENSSL_NO_RFC3779 +RUST_CONF_OPENSSL_NO_RFC3779 +#endif + +#ifdef OPENSSL_NO_RMD160 +RUST_CONF_OPENSSL_NO_RMD160 +#endif + +#ifdef OPENSSL_NO_SHA +RUST_CONF_OPENSSL_NO_SHA +#endif + +#ifdef OPENSSL_NO_SRP +RUST_CONF_OPENSSL_NO_SRP +#endif + +#ifdef OPENSSL_NO_SSL3_METHOD +RUST_CONF_OPENSSL_NO_SSL3_METHOD +#endif + +#ifdef OPENSSL_NO_TLSEXT +RUST_CONF_OPENSSL_NO_TLSEXT +#endif + +#ifdef OPENSSL_NO_STDIO +RUST_CONF_OPENSSL_NO_STDIO +#endif + +#ifdef OPENSSL_NO_SM3 +RUST_CONF_OPENSSL_NO_SM3 +#endif + +#ifdef OPENSSL_NO_DEPRECATED_3_0 +RUST_CONF_OPENSSL_NO_DEPRECATED_3_0 +#endif + +#ifdef OPENSSL_NO_SEED +RUST_CONF_OPENSSL_NO_SEED +#endif diff --git a/zeroidc/vendor/openssl-sys/build/find_normal.rs b/zeroidc/vendor/openssl-sys/build/find_normal.rs new file mode 100644 index 000000000..df451438a --- /dev/null +++ b/zeroidc/vendor/openssl-sys/build/find_normal.rs @@ -0,0 +1,276 @@ +use pkg_config; +use std::ffi::OsString; +use std::path::{Path, PathBuf}; +use std::process::{self, Command}; + +use super::env; + +pub fn get_openssl(target: &str) -> (Vec, PathBuf) { + let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from); + let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from); + + match (lib_dir, include_dir) { + (Some(lib_dir), Some(include_dir)) => (vec![lib_dir], include_dir), + (lib_dir, include_dir) => { + let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(target)); + let openssl_dir = Path::new(&openssl_dir); + let lib_dir = lib_dir.map(|d| vec![d]).unwrap_or_else(|| { + let mut lib_dirs = vec![]; + // OpenSSL 3.0 now puts it's libraries in lib64/ by default, + // check for both it and lib/. + if openssl_dir.join("lib64").exists() { + lib_dirs.push(openssl_dir.join("lib64")); + } + if openssl_dir.join("lib").exists() { + lib_dirs.push(openssl_dir.join("lib")); + } + lib_dirs + }); + let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include")); + (lib_dir, include_dir) + } + } +} + +fn resolve_with_wellknown_homebrew_location(dir: &str) -> Option { + let versions = ["openssl@3", "openssl@1.1"]; + + // Check up default aarch 64 Homebrew installation location first + // for quick resolution if possible. + // `pkg-config` on brew doesn't necessarily contain settings for openssl apparently. + for version in &versions { + let homebrew = Path::new(dir).join(format!("opt/{}", version)); + if homebrew.exists() { + return Some(homebrew); + } + } + + for version in &versions { + // Calling `brew --prefix ` command usually slow and + // takes seconds, and will be used only as a last resort. + let output = execute_command_and_get_output("brew", &["--prefix", version]); + if let Some(ref output) = output { + let homebrew = Path::new(&output); + if homebrew.exists() { + return Some(homebrew.to_path_buf()); + } + } + } + + None +} + +fn resolve_with_wellknown_location(dir: &str) -> Option { + let root_dir = Path::new(dir); + let include_openssl = root_dir.join("include/openssl"); + if include_openssl.exists() { + Some(root_dir.to_path_buf()) + } else { + None + } +} + +fn find_openssl_dir(target: &str) -> OsString { + let host = env::var("HOST").unwrap(); + + if host == target && target.ends_with("-apple-darwin") { + let homebrew_dir = match target { + "aarch64-apple-darwin" => "/opt/homebrew", + _ => "/usr/local", + }; + + if let Some(dir) = resolve_with_wellknown_homebrew_location(homebrew_dir) { + return dir.into(); + } else if let Some(dir) = resolve_with_wellknown_location("/opt/pkg") { + // pkgsrc + return dir.into(); + } else if let Some(dir) = resolve_with_wellknown_location("/opt/local") { + // MacPorts + return dir.into(); + } + } + + try_pkg_config(); + try_vcpkg(); + + // FreeBSD ships with OpenSSL but doesn't include a pkg-config file :( + if host == target && target.contains("freebsd") { + return OsString::from("/usr"); + } + + // DragonFly has libressl (or openssl) in ports, but this doesn't include a pkg-config file + if host == target && target.contains("dragonfly") { + return OsString::from("/usr/local"); + } + + let mut msg = format!( + " + +Could not find directory of OpenSSL installation, and this `-sys` crate cannot +proceed without this knowledge. If OpenSSL is installed and this crate had +trouble finding it, you can set the `OPENSSL_DIR` environment variable for the +compilation process. + +Make sure you also have the development packages of openssl installed. +For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. + +If you're in a situation where you think the directory *should* be found +automatically, please open a bug at https://github.com/sfackler/rust-openssl +and include information about your system as well as this message. + +$HOST = {} +$TARGET = {} +openssl-sys = {} + +", + host, + target, + env!("CARGO_PKG_VERSION") + ); + + if host.contains("apple-darwin") && target.contains("apple-darwin") { + let system = Path::new("/usr/lib/libssl.0.9.8.dylib"); + if system.exists() { + msg.push_str( + " + +openssl-sys crate build failed: no supported version of OpenSSL found. + +Ways to fix it: +- Use the `vendored` feature of openssl-sys crate to build OpenSSL from source. +- Use Homebrew to install the `openssl` package. + +", + ); + } + } + + if host.contains("unknown-linux") + && target.contains("unknown-linux-gnu") + && Command::new("pkg-config").output().is_err() + { + msg.push_str( + " +It looks like you're compiling on Linux and also targeting Linux. Currently this +requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config` +could not be found. If you have OpenSSL installed you can likely fix this by +installing `pkg-config`. + +", + ); + } + + if host.contains("windows") && target.contains("windows-gnu") { + msg.push_str( + " +It looks like you're compiling for MinGW but you may not have either OpenSSL or +pkg-config installed. You can install these two dependencies with: + +pacman -S openssl-devel pkg-config + +and try building this crate again. + +", + ); + } + + if host.contains("windows") && target.contains("windows-msvc") { + msg.push_str( + " +It looks like you're compiling for MSVC but we couldn't detect an OpenSSL +installation. If there isn't one installed then you can try the rust-openssl +README for more information about how to download precompiled binaries of +OpenSSL: + +https://github.com/sfackler/rust-openssl#windows + +", + ); + } + + panic!("{}", msg); +} + +/// Attempt to find OpenSSL through pkg-config. +/// +/// Note that if this succeeds then the function does not return as pkg-config +/// typically tells us all the information that we need. +fn try_pkg_config() { + let target = env::var("TARGET").unwrap(); + let host = env::var("HOST").unwrap(); + + // If we're going to windows-gnu we can use pkg-config, but only so long as + // we're coming from a windows host. + // + // Otherwise if we're going to windows we probably can't use pkg-config. + if target.contains("windows-gnu") && host.contains("windows") { + env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); + } else if target.contains("windows") { + return; + } + + let lib = match pkg_config::Config::new() + .print_system_libs(false) + .find("openssl") + { + Ok(lib) => lib, + Err(e) => { + println!("run pkg_config fail: {:?}", e); + return; + } + }; + + super::postprocess(&lib.include_paths); + + for include in lib.include_paths.iter() { + println!("cargo:include={}", include.display()); + } + + process::exit(0); +} + +/// Attempt to find OpenSSL through vcpkg. +/// +/// Note that if this succeeds then the function does not return as vcpkg +/// should emit all of the cargo metadata that we need. +#[cfg(target_env = "msvc")] +fn try_vcpkg() { + // vcpkg will not emit any metadata if it can not find libraries + // appropriate for the target triple with the desired linkage. + + let lib = match vcpkg::Config::new() + .emit_includes(true) + .find_package("openssl") + { + Ok(lib) => lib, + Err(e) => { + println!("note: vcpkg did not find openssl: {}", e); + return; + } + }; + + super::postprocess(&lib.include_paths); + + println!("cargo:rustc-link-lib=user32"); + println!("cargo:rustc-link-lib=gdi32"); + println!("cargo:rustc-link-lib=crypt32"); + + process::exit(0); +} + +#[cfg(not(target_env = "msvc"))] +fn try_vcpkg() {} + +fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option { + let out = Command::new(cmd).args(args).output(); + if let Ok(ref r1) = out { + if r1.status.success() { + let r2 = String::from_utf8(r1.stdout.clone()); + if let Ok(r3) = r2 { + return Some(r3.trim().to_string()); + } + } + } + + None +} diff --git a/zeroidc/vendor/openssl-sys/build/find_vendored.rs b/zeroidc/vendor/openssl-sys/build/find_vendored.rs new file mode 100644 index 000000000..c92b2bd39 --- /dev/null +++ b/zeroidc/vendor/openssl-sys/build/find_vendored.rs @@ -0,0 +1,16 @@ +use openssl_src; +use std::path::PathBuf; + +pub fn get_openssl(_target: &str) -> (Vec, PathBuf) { + let artifacts = openssl_src::Build::new().build(); + println!("cargo:vendored=1"); + println!( + "cargo:root={}", + artifacts.lib_dir().parent().unwrap().display() + ); + + ( + vec![artifacts.lib_dir().to_path_buf()], + artifacts.include_dir().to_path_buf(), + ) +} diff --git a/zeroidc/vendor/openssl-sys/build/main.rs b/zeroidc/vendor/openssl-sys/build/main.rs new file mode 100644 index 000000000..2290e8c44 --- /dev/null +++ b/zeroidc/vendor/openssl-sys/build/main.rs @@ -0,0 +1,399 @@ +#![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)] + +extern crate autocfg; +#[cfg(feature = "bindgen")] +extern crate bindgen; +extern crate cc; +#[cfg(feature = "vendored")] +extern crate openssl_src; +extern crate pkg_config; +#[cfg(target_env = "msvc")] +extern crate vcpkg; + +use std::collections::HashSet; +use std::env; +use std::ffi::OsString; +use std::path::{Path, PathBuf}; +mod cfgs; + +mod find_normal; +#[cfg(feature = "vendored")] +mod find_vendored; +#[cfg(feature = "bindgen")] +mod run_bindgen; + +#[derive(PartialEq)] +enum Version { + Openssl3xx, + Openssl11x, + Openssl10x, + Libressl, +} + +fn env_inner(name: &str) -> Option { + let var = env::var_os(name); + println!("cargo:rerun-if-env-changed={}", name); + + match var { + Some(ref v) => println!("{} = {}", name, v.to_string_lossy()), + None => println!("{} unset", name), + } + + var +} + +fn env(name: &str) -> Option { + let prefix = env::var("TARGET").unwrap().to_uppercase().replace('-', "_"); + let prefixed = format!("{}_{}", prefix, name); + env_inner(&prefixed).or_else(|| env_inner(name)) +} + +fn find_openssl(target: &str) -> (Vec, PathBuf) { + #[cfg(feature = "vendored")] + { + // vendor if the feature is present, unless + // OPENSSL_NO_VENDOR exists and isn't `0` + if env("OPENSSL_NO_VENDOR").map_or(true, |s| s == "0") { + return find_vendored::get_openssl(target); + } + } + find_normal::get_openssl(target) +} + +fn main() { + check_rustc_versions(); + + let target = env::var("TARGET").unwrap(); + + let (lib_dirs, include_dir) = find_openssl(&target); + + if !lib_dirs.iter().all(|p| Path::new(p).exists()) { + panic!("OpenSSL library directory does not exist: {:?}", lib_dirs); + } + if !Path::new(&include_dir).exists() { + panic!( + "OpenSSL include directory does not exist: {}", + include_dir.to_string_lossy() + ); + } + + for lib_dir in lib_dirs.iter() { + println!( + "cargo:rustc-link-search=native={}", + lib_dir.to_string_lossy() + ); + } + println!("cargo:include={}", include_dir.to_string_lossy()); + + let version = postprocess(&[include_dir]); + + let libs_env = env("OPENSSL_LIBS"); + let libs = match libs_env.as_ref().and_then(|s| s.to_str()) { + Some(v) => { + if v.is_empty() { + vec![] + } else { + v.split(':').collect() + } + } + None => match version { + Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"], + Version::Openssl3xx | Version::Openssl11x if target.contains("windows-msvc") => { + vec!["libssl", "libcrypto"] + } + _ => vec!["ssl", "crypto"], + }, + }; + + let kind = determine_mode(&lib_dirs, &libs); + for lib in libs.into_iter() { + println!("cargo:rustc-link-lib={}={}", kind, lib); + } + + // https://github.com/openssl/openssl/pull/15086 + if version == Version::Openssl3xx + && kind == "static" + && (env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux" + || env::var("CARGO_CFG_TARGET_OS").unwrap() == "android") + && env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "32" + { + println!("cargo:rustc-link-lib=dylib=atomic"); + } + + if kind == "static" && target.contains("windows") { + println!("cargo:rustc-link-lib=dylib=gdi32"); + println!("cargo:rustc-link-lib=dylib=user32"); + println!("cargo:rustc-link-lib=dylib=crypt32"); + println!("cargo:rustc-link-lib=dylib=ws2_32"); + println!("cargo:rustc-link-lib=dylib=advapi32"); + } +} + +fn check_rustc_versions() { + let cfg = autocfg::new(); + + if cfg.probe_rustc_version(1, 31) { + println!("cargo:rustc-cfg=const_fn"); + } +} + +#[allow(clippy::let_and_return)] +fn postprocess(include_dirs: &[PathBuf]) -> Version { + let version = validate_headers(include_dirs); + #[cfg(feature = "bindgen")] + run_bindgen::run(&include_dirs); + + version +} + +/// Validates the header files found in `include_dir` and then returns the +/// version string of OpenSSL. +#[allow(clippy::manual_strip)] // we need to support pre-1.45.0 +fn validate_headers(include_dirs: &[PathBuf]) -> Version { + // This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, 1.1.0, 1.1.1 and 3.0.0. + // To correctly expose the right API from this crate, take a look at + // `opensslv.h` to see what version OpenSSL claims to be. + // + // OpenSSL has a number of build-time configuration options which affect + // various structs and such. Since OpenSSL 1.1.0 this isn't really a problem + // as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem. + // + // To handle all this conditional compilation we slurp up the configuration + // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines + // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can + // account for compile differences and such. + println!("cargo:rerun-if-changed=build/expando.c"); + let mut gcc = cc::Build::new(); + for include_dir in include_dirs { + gcc.include(include_dir); + } + let expanded = match gcc.file("build/expando.c").try_expand() { + Ok(expanded) => expanded, + Err(e) => { + panic!( + " +Header expansion error: +{:?} + +Failed to find OpenSSL development headers. + +You can try fixing this setting the `OPENSSL_DIR` environment variable +pointing to your OpenSSL installation or installing OpenSSL headers package +specific to your distribution: + + # On Ubuntu + sudo apt-get install libssl-dev + # On Arch Linux + sudo pacman -S openssl + # On Fedora + sudo dnf install openssl-devel + # On Alpine Linux + apk add openssl-dev + +See rust-openssl README for more information: + + https://github.com/sfackler/rust-openssl#linux +", + e + ); + } + }; + let expanded = String::from_utf8(expanded).unwrap(); + + let mut enabled = vec![]; + let mut openssl_version = None; + let mut libressl_version = None; + for line in expanded.lines() { + let line = line.trim(); + + let openssl_prefix = "RUST_VERSION_OPENSSL_"; + let new_openssl_prefix = "RUST_VERSION_NEW_OPENSSL_"; + let libressl_prefix = "RUST_VERSION_LIBRESSL_"; + let conf_prefix = "RUST_CONF_"; + if line.starts_with(openssl_prefix) { + let version = &line[openssl_prefix.len()..]; + openssl_version = Some(parse_version(version)); + } else if line.starts_with(new_openssl_prefix) { + let version = &line[new_openssl_prefix.len()..]; + openssl_version = Some(parse_new_version(version)); + } else if line.starts_with(libressl_prefix) { + let version = &line[libressl_prefix.len()..]; + libressl_version = Some(parse_version(version)); + } else if line.starts_with(conf_prefix) { + enabled.push(&line[conf_prefix.len()..]); + } + } + + for enabled in &enabled { + println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled); + } + println!("cargo:conf={}", enabled.join(",")); + + for cfg in cfgs::get(openssl_version, libressl_version) { + println!("cargo:rustc-cfg={}", cfg); + } + + if let Some(libressl_version) = libressl_version { + println!("cargo:libressl_version_number={:x}", libressl_version); + + let major = (libressl_version >> 28) as u8; + let minor = (libressl_version >> 20) as u8; + let fix = (libressl_version >> 12) as u8; + let (major, minor, fix) = match (major, minor, fix) { + (2, 5, 0) => ('2', '5', '0'), + (2, 5, 1) => ('2', '5', '1'), + (2, 5, 2) => ('2', '5', '2'), + (2, 5, _) => ('2', '5', 'x'), + (2, 6, 0) => ('2', '6', '0'), + (2, 6, 1) => ('2', '6', '1'), + (2, 6, 2) => ('2', '6', '2'), + (2, 6, _) => ('2', '6', 'x'), + (2, 7, _) => ('2', '7', 'x'), + (2, 8, 0) => ('2', '8', '0'), + (2, 8, 1) => ('2', '8', '1'), + (2, 8, _) => ('2', '8', 'x'), + (2, 9, 0) => ('2', '9', '0'), + (2, 9, _) => ('2', '9', 'x'), + (3, 0, 0) => ('3', '0', '0'), + (3, 0, 1) => ('3', '0', '1'), + (3, 0, _) => ('3', '0', 'x'), + (3, 1, 0) => ('3', '1', '0'), + (3, 1, _) => ('3', '1', 'x'), + (3, 2, 0) => ('3', '2', '0'), + (3, 2, 1) => ('3', '2', '1'), + (3, 2, _) => ('3', '2', 'x'), + (3, 3, 0) => ('3', '3', '0'), + (3, 3, 1) => ('3', '3', '1'), + (3, 3, _) => ('3', '3', 'x'), + (3, 4, 0) => ('3', '4', '0'), + (3, 4, _) => ('3', '4', 'x'), + (3, 5, _) => ('3', '5', 'x'), + _ => version_error(), + }; + + println!("cargo:libressl=true"); + println!("cargo:libressl_version={}{}{}", major, minor, fix); + println!("cargo:version=101"); + Version::Libressl + } else { + let openssl_version = openssl_version.unwrap(); + println!("cargo:version_number={:x}", openssl_version); + + if openssl_version >= 0x4_00_00_00_0 { + version_error() + } else if openssl_version >= 0x3_00_00_00_0 { + Version::Openssl3xx + } else if openssl_version >= 0x1_01_01_00_0 { + println!("cargo:version=111"); + Version::Openssl11x + } else if openssl_version >= 0x1_01_00_06_0 { + println!("cargo:version=110"); + println!("cargo:patch=f"); + Version::Openssl11x + } else if openssl_version >= 0x1_01_00_00_0 { + println!("cargo:version=110"); + Version::Openssl11x + } else if openssl_version >= 0x1_00_02_00_0 { + println!("cargo:version=102"); + Version::Openssl10x + } else if openssl_version >= 0x1_00_01_00_0 { + println!("cargo:version=101"); + Version::Openssl10x + } else { + version_error() + } + } +} + +fn version_error() -> ! { + panic!( + " + +This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3.0.0), or LibreSSL 2.5 +through 3.5, but a different version of OpenSSL was found. The build is now aborting +due to this version mismatch. + +" + ); +} + +// parses a string that looks like "0x100020cfL" +#[allow(deprecated)] // trim_right_matches is now trim_end_matches +#[allow(clippy::match_like_matches_macro)] // matches macro requires rust 1.42.0 +fn parse_version(version: &str) -> u64 { + // cut off the 0x prefix + assert!(version.starts_with("0x")); + let version = &version[2..]; + + // and the type specifier suffix + let version = version.trim_right_matches(|c: char| match c { + '0'..='9' | 'a'..='f' | 'A'..='F' => false, + _ => true, + }); + + u64::from_str_radix(version, 16).unwrap() +} + +// parses a string that looks like 3_0_0 +fn parse_new_version(version: &str) -> u64 { + println!("version: {}", version); + let mut it = version.split('_'); + let major = it.next().unwrap().parse::().unwrap(); + let minor = it.next().unwrap().parse::().unwrap(); + let patch = it.next().unwrap().parse::().unwrap(); + + (major << 28) | (minor << 20) | (patch << 4) +} + +/// Given a libdir for OpenSSL (where artifacts are located) as well as the name +/// of the libraries we're linking to, figure out whether we should link them +/// statically or dynamically. +fn determine_mode(libdirs: &[PathBuf], libs: &[&str]) -> &'static str { + // First see if a mode was explicitly requested + let kind = env("OPENSSL_STATIC"); + match kind.as_ref().and_then(|s| s.to_str()) { + Some("0") => return "dylib", + Some(_) => return "static", + None => {} + } + + // Next, see what files we actually have to link against, and see what our + // possibilities even are. + let mut files = HashSet::new(); + for dir in libdirs { + for path in dir + .read_dir() + .unwrap() + .map(|e| e.unwrap()) + .map(|e| e.file_name()) + .filter_map(|e| e.into_string().ok()) + { + files.insert(path); + } + } + let can_static = libs + .iter() + .all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))); + let can_dylib = libs.iter().all(|l| { + files.contains(&format!("lib{}.so", l)) + || files.contains(&format!("{}.dll", l)) + || files.contains(&format!("lib{}.dylib", l)) + }); + match (can_static, can_dylib) { + (true, false) => return "static", + (false, true) => return "dylib", + (false, false) => { + panic!( + "OpenSSL libdir at `{:?}` does not contain the required files \ + to either statically or dynamically link OpenSSL", + libdirs + ); + } + (true, true) => {} + } + + // Ok, we've got not explicit preference and can *either* link statically or + // link dynamically. In the interest of "security upgrades" and/or "best + // practices with security libs", let's link dynamically. + "dylib" +} diff --git a/zeroidc/vendor/openssl-sys/build/run_bindgen.rs b/zeroidc/vendor/openssl-sys/build/run_bindgen.rs new file mode 100644 index 000000000..9531e6e8b --- /dev/null +++ b/zeroidc/vendor/openssl-sys/build/run_bindgen.rs @@ -0,0 +1,129 @@ +use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks}; +use bindgen::RustTarget; +use std::env; +use std::path::PathBuf; + +const INCLUDES: &str = " +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this must be included after ssl.h for libressl! +#include + +#if !defined(LIBRESSL_VERSION_NUMBER) +#include +#endif + +#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 +#include +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x30000000 +#include +#endif +"; + +pub fn run(include_dirs: &[PathBuf]) { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + let mut builder = bindgen::builder() + .parse_callbacks(Box::new(OpensslCallbacks)) + .rust_target(RustTarget::Stable_1_47) + .ctypes_prefix("::libc") + .raw_line("use libc::*;") + .raw_line("type evp_pkey_st = EVP_PKEY;") + .allowlist_file(".*/openssl/[^/]+\\.h") + .allowlist_recursively(false) + // libc is missing pthread_once_t on macOS + .blocklist_type("CRYPTO_ONCE") + .blocklist_function("CRYPTO_THREAD_run_once") + // we don't want to mess with va_list + .blocklist_function("BIO_vprintf") + .blocklist_function("BIO_vsnprintf") + .blocklist_function("ERR_vset_error") + .blocklist_function("ERR_add_error_vdata") + .blocklist_function("EVP_KDF_vctrl") + .blocklist_type("OSSL_FUNC_core_vset_error_fn") + .blocklist_type("OSSL_FUNC_BIO_vprintf_fn") + .blocklist_type("OSSL_FUNC_BIO_vsnprintf_fn") + // Maintain compatibility for existing enum definitions + .rustified_enum("point_conversion_form_t") + // Maintain compatibility for pre-union definitions + .blocklist_type("GENERAL_NAME") + .blocklist_type("GENERAL_NAME_st") + .blocklist_type("EVP_PKEY") + .blocklist_type("evp_pkey_st") + .layout_tests(false) + .header_contents("includes.h", INCLUDES); + + for include_dir in include_dirs { + builder = builder + .clang_arg("-I") + .clang_arg(include_dir.display().to_string()); + } + + builder + .generate() + .unwrap() + .write_to_file(out_dir.join("bindgen.rs")) + .unwrap(); +} + +#[derive(Debug)] +struct OpensslCallbacks; + +impl ParseCallbacks for OpensslCallbacks { + // for now we'll continue hand-writing constants + fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { + MacroParsingBehavior::Ignore + } + + fn item_name(&self, original_item_name: &str) -> Option { + match original_item_name { + // Our original definitions of these are wrong, so rename to avoid breakage + "CRYPTO_EX_new" + | "CRYPTO_EX_dup" + | "CRYPTO_EX_free" + | "BIO_meth_set_write" + | "BIO_meth_set_read" + | "BIO_meth_set_puts" + | "BIO_meth_set_ctrl" + | "BIO_meth_set_create" + | "BIO_meth_set_destroy" + | "CRYPTO_set_locking_callback" + | "CRYPTO_set_id_callback" + | "SSL_CTX_set_tmp_dh_callback" + | "SSL_set_tmp_dh_callback" + | "SSL_CTX_set_tmp_ecdh_callback" + | "SSL_set_tmp_ecdh_callback" + | "SSL_CTX_callback_ctrl" + | "SSL_CTX_set_alpn_select_cb" => Some(format!("{}__fixed_rust", original_item_name)), + _ => None, + } + } +} diff --git a/zeroidc/vendor/tracing/.cargo-checksum.json b/zeroidc/vendor/tracing/.cargo-checksum.json index 80ea1c93f..404d4f3c0 100644 --- a/zeroidc/vendor/tracing/.cargo-checksum.json +++ b/zeroidc/vendor/tracing/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"1d82f1ac1540d9606314c56d1701d10fff72688b0bf458398846fa837a6b8209","Cargo.toml":"c924c5dd3ad8b58b4d65ec40f10a44b5352f89145c419d82dab9c647b5d363f3","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"39a30e68fd06cd90cdf232fb87cba82168797c9861739e9529fee68e72c26868","benches/global_subscriber.rs":"271213baed0e02054e506c1ec9c47b58696c78aaa46f0969a147f4c369f80e3d","benches/no_subscriber.rs":"495c9a91fb972ec61ced31ef8e19d2cca02ec8ffae4e98e3316e55f6a0074578","benches/subscriber.rs":"c609be119ed6e4d3fb79df77f15aa14effbd3e2f77c627a49229a50091d3ee6a","src/dispatcher.rs":"5732b1f228328cd41e77b04a27faf3b6054a8ed5cd5034a0dad8e1e694ca3889","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"c794108f5f37b5dc1609498afad5ebbb25ad5f80bf9e362c032a63d327429937","src/macros.rs":"1bf35f17cbb50fb92f60e5e60190faf5eeba03c328f754631fff6df183509491","src/span.rs":"e7c16999e8702bf1ff82aaa6803c81ac5b77ab96b754cac6e686acfc6adc14f9","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"ae879c373be7ee4935f7b02a345f92ccbeb7879d61c5d37e3cc1277b3d51ddb2","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"c4ec3ac338475e9e61675551eb99df1d8a7cbefb05a0d60203994f5c1df7c784","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"} \ No newline at end of file +{"files":{"CHANGELOG.md":"7d5517e1ac705d5d8574915b59a37bbd0ba5aa6e663fc272b75e5792eca572a9","Cargo.toml":"f6290faffd0bf079845dbd6c3c1ddb6c728bcf7225e3b56a4ba5a9478dc72a8b","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"a83e1a8287e3eca752383ae849872707dddfbd07b918806cc7c027a0824872c6","benches/global_subscriber.rs":"271213baed0e02054e506c1ec9c47b58696c78aaa46f0969a147f4c369f80e3d","benches/no_subscriber.rs":"495c9a91fb972ec61ced31ef8e19d2cca02ec8ffae4e98e3316e55f6a0074578","benches/subscriber.rs":"c609be119ed6e4d3fb79df77f15aa14effbd3e2f77c627a49229a50091d3ee6a","src/dispatcher.rs":"a8158e1901c50dc83d2f15b1773e6b9e31985d9af65e460be52dbf8be6874cd2","src/field.rs":"55c7a2798b9ad0269e7c738c3f15a5d0281bf34ac3a6196a3f0b15801e5278bd","src/instrument.rs":"1fe4de5c13b5ba048e9872d78d1fa4e85655f9f2ed10f79b72b5da881c9b8b45","src/level_filters.rs":"baae8e797897bae9cdd9ec64b8e9a3d71156e9c03261be17b5b18acba034e154","src/lib.rs":"a8ab6b578f93b5fb833942fc59642e67caca8d343670d64fb52d47d5507a67e4","src/macros.rs":"f1a83930cea322f1f2000548d91800c22a9e28d2daf3f178c7c7c3ac8da5a02d","src/span.rs":"96b6c86be09c97b15b2ab5c607013abc5b388c2870eb648bee2cfc07837fa6e9","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"ae879c373be7ee4935f7b02a345f92ccbeb7879d61c5d37e3cc1277b3d51ddb2","tests/enabled.rs":"1333339aace87ea9d701f2f76a1985820cc513a75013a7ed89669f7a2c635479","tests/event.rs":"c4ec3ac338475e9e61675551eb99df1d8a7cbefb05a0d60203994f5c1df7c784","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"d594266818a3461886da33bfcc76937d89a433ed6980226fc428706b216c093c","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"fa83397181d73d2cae09c16d9647a63d1e3bad0f2dbc5b3280f69f3d0180c488","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/macros_redefined_core.rs":"a6eac60522f71fe6c9a040b8b869d596f7eb9e907f5b49f4be4413a40c387676","tests/max_level_hint.rs":"9b366591d947ca0202fa0bdf797e1bb14534d3c896cf8b9674660cd2807c32ef","tests/multiple_max_level_hints.rs":"4d9ef0de9cccc787da8f5e3f6c233ac9db42a2a99cfe5e39997e1f4aa9df0c00","tests/no_subscriber.rs":"2f8f2ada5089d8e2e503394dfe8206598a11895907c53bf940b892f1e6afdd2f","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"806480a74c15e4d68bb7576050662b1e53ee765fd583d003f8b349f17ea63a4b","tests/span.rs":"f84ead5b1dad9b91e5cec9d8378ab932a942936374ba928fb381e67fab52cda0","tests/subscriber.rs":"1617c098f4fa6abed174fe062111444c7b67fa0f377d2b342176998e572480e3"},"package":"a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"} \ No newline at end of file diff --git a/zeroidc/vendor/tracing/CHANGELOG.md b/zeroidc/vendor/tracing/CHANGELOG.md index 8720d98ad..1c527f2de 100644 --- a/zeroidc/vendor/tracing/CHANGELOG.md +++ b/zeroidc/vendor/tracing/CHANGELOG.md @@ -1,3 +1,19 @@ +# 0.1.35 (June 8, 2022) + +This release reduces the overhead of callsite registration by using new +`tracing-core` APIs. + +### Added + +- Use `DefaultCallsite` to reduce callsite registration overhead ([#2083]) + +### Changed + +- `tracing-core`: updated to [0.1.27][core-0.1.27] + +[core-0.1.27]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.27 +[#2088]: https://github.com/tokio-rs/tracing/pull/2083 + # 0.1.34 (April 14, 2022) This release includes bug fixes for the "log" support feature and for the use of diff --git a/zeroidc/vendor/tracing/Cargo.toml b/zeroidc/vendor/tracing/Cargo.toml index 44df820f9..dd6f1fb47 100644 --- a/zeroidc/vendor/tracing/Cargo.toml +++ b/zeroidc/vendor/tracing/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.49.0" name = "tracing" -version = "0.1.34" +version = "0.1.35" authors = [ "Eliza Weisman ", "Tokio Contributors ", @@ -74,7 +74,7 @@ version = "0.1.20" optional = true [dependencies.tracing-core] -version = "0.1.22" +version = "0.1.27" default-features = false [dev-dependencies.criterion] diff --git a/zeroidc/vendor/tracing/README.md b/zeroidc/vendor/tracing/README.md index 6f1c07cc1..5da141a3a 100644 --- a/zeroidc/vendor/tracing/README.md +++ b/zeroidc/vendor/tracing/README.md @@ -16,9 +16,9 @@ Application-level tracing for Rust. [Documentation][docs-url] | [Chat][discord-url] [crates-badge]: https://img.shields.io/crates/v/tracing.svg -[crates-url]: https://crates.io/crates/tracing/0.1.34 +[crates-url]: https://crates.io/crates/tracing/0.1.35 [docs-badge]: https://docs.rs/tracing/badge.svg -[docs-url]: https://docs.rs/tracing/0.1.34 +[docs-url]: https://docs.rs/tracing/0.1.35 [docs-master-badge]: https://img.shields.io/badge/docs-master-blue [docs-master-url]: https://tracing-rs.netlify.com/tracing [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg @@ -250,7 +250,7 @@ my_future is as long as the future's. The second, and preferred, option is through the -[`#[instrument]`](https://docs.rs/tracing/0.1.34/tracing/attr.instrument.html) +[`#[instrument]`](https://docs.rs/tracing/0.1.35/tracing/attr.instrument.html) attribute: ```rust @@ -297,7 +297,7 @@ span.in_scope(|| { // Dropping the span will close it, indicating that it has ended. ``` -The [`#[instrument]`](https://docs.rs/tracing/0.1.34/tracing/attr.instrument.html) attribute macro +The [`#[instrument]`](https://docs.rs/tracing/0.1.35/tracing/attr.instrument.html) attribute macro can reduce some of this boilerplate: ```rust diff --git a/zeroidc/vendor/tracing/src/dispatcher.rs b/zeroidc/vendor/tracing/src/dispatcher.rs index 568a0314d..8817ac033 100644 --- a/zeroidc/vendor/tracing/src/dispatcher.rs +++ b/zeroidc/vendor/tracing/src/dispatcher.rs @@ -123,10 +123,6 @@ //! instrumentation. //! //! [`Subscriber`]: crate::Subscriber -//! [`with_default`]: with_default -//! [`set_global_default`]: set_global_default -//! [`get_default`]: get_default -//! [`Dispatch`]: Dispatch #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub use tracing_core::dispatcher::set_default; diff --git a/zeroidc/vendor/tracing/src/lib.rs b/zeroidc/vendor/tracing/src/lib.rs index e3424e040..4743eba20 100644 --- a/zeroidc/vendor/tracing/src/lib.rs +++ b/zeroidc/vendor/tracing/src/lib.rs @@ -119,8 +119,6 @@ //! tracing = "0.1" //! ``` //! -//! *Compiler support: [requires `rustc` 1.42+][msrv]* -//! //! ## Recording Spans and Events //! //! Spans and events are recorded using macros. @@ -437,9 +435,9 @@ //! [target]: Metadata::target //! [parent span]: span::Attributes::parent //! [determined contextually]: span::Attributes::is_contextual -//! [`fmt::Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html -//! [`fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html -//! [fmt]: https://doc.rust-lang.org/std/fmt/#usage +//! [`fmt::Debug`]: std::fmt::Debug +//! [`fmt::Display`]: std::fmt::Display +//! [fmt]: std::fmt#usage //! [`Empty`]: field::Empty //! //! ### Shorthand Macros @@ -466,7 +464,6 @@ //! [`info_span!`]: info_span! //! [`warn_span!`]: warn_span! //! [`error_span!`]: error_span! -//! [`Level`]: Level //! //! ### For `log` Users //! @@ -812,7 +809,7 @@ //! //! ```toml //! [dependencies] -//! tracing = { version = "0.1.34", default-features = false } +//! tracing = { version = "0.1.35", default-features = false } //! ``` //! //!
@@ -895,7 +892,7 @@
 //! [flags]: #crate-feature-flags
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::broken_intra_doc_links))]
-#![doc(html_root_url = "https://docs.rs/tracing/0.1.34")]
+#![doc(html_root_url = "https://docs.rs/tracing/0.1.35")]
 #![doc(
     html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
     issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
@@ -968,13 +965,8 @@ pub mod subscriber;
 #[doc(hidden)]
 pub mod __macro_support {
     pub use crate::callsite::Callsite;
-    use crate::stdlib::{
-        fmt,
-        sync::atomic::{AtomicUsize, Ordering},
-    };
     use crate::{subscriber::Interest, Metadata};
     pub use core::concat;
-    use tracing_core::Once;
 
     /// Callsite implementation used by macro-generated code.
     ///
@@ -984,138 +976,70 @@ pub mod __macro_support {
     /// by the `tracing` macros, but it is not part of the stable versioned API.
     /// Breaking changes to this module may occur in small-numbered versions
     /// without warning.
-    pub struct MacroCallsite {
-        interest: AtomicUsize,
-        meta: &'static Metadata<'static>,
-        registration: Once,
+    pub use tracing_core::callsite::DefaultCallsite as MacroCallsite;
+
+    /// /!\ WARNING: This is *not* a stable API! /!\
+    /// This function, and all code contained in the `__macro_support` module, is
+    /// a *private* API of `tracing`. It is exposed publicly because it is used
+    /// by the `tracing` macros, but it is not part of the stable versioned API.
+    /// Breaking changes to this module may occur in small-numbered versions
+    /// without warning.
+    pub fn __is_enabled(meta: &Metadata<'static>, interest: Interest) -> bool {
+        interest.is_always() || crate::dispatcher::get_default(|default| default.enabled(meta))
     }
 
-    impl MacroCallsite {
-        /// Returns a new `MacroCallsite` with the specified `Metadata`.
-        ///
-        /// /!\ WARNING: This is *not* a stable API! /!\
-        /// This method, and all code contained in the `__macro_support` module, is
-        /// a *private* API of `tracing`. It is exposed publicly because it is used
-        /// by the `tracing` macros, but it is not part of the stable versioned API.
-        /// Breaking changes to this module may occur in small-numbered versions
-        /// without warning.
-        pub const fn new(meta: &'static Metadata<'static>) -> Self {
-            Self {
-                interest: AtomicUsize::new(0xDEAD),
-                meta,
-                registration: Once::new(),
-            }
-        }
-
-        /// Registers this callsite with the global callsite registry.
-        ///
-        /// If the callsite is already registered, this does nothing.
-        ///
-        /// /!\ WARNING: This is *not* a stable API! /!\
-        /// This method, and all code contained in the `__macro_support` module, is
-        /// a *private* API of `tracing`. It is exposed publicly because it is used
-        /// by the `tracing` macros, but it is not part of the stable versioned API.
-        /// Breaking changes to this module may occur in small-numbered versions
-        /// without warning.
-        #[inline(never)]
-        // This only happens once (or if the cached interest value was corrupted).
-        #[cold]
-        pub fn register(&'static self) -> Interest {
-            self.registration
-                .call_once(|| crate::callsite::register(self));
-            match self.interest.load(Ordering::Relaxed) {
-                0 => Interest::never(),
-                2 => Interest::always(),
-                _ => Interest::sometimes(),
-            }
-        }
-
-        /// Returns the callsite's cached Interest, or registers it for the
-        /// first time if it has not yet been registered.
-        ///
-        /// /!\ WARNING: This is *not* a stable API! /!\
-        /// This method, and all code contained in the `__macro_support` module, is
-        /// a *private* API of `tracing`. It is exposed publicly because it is used
-        /// by the `tracing` macros, but it is not part of the stable versioned API.
-        /// Breaking changes to this module may occur in small-numbered versions
-        /// without warning.
-        #[inline]
-        pub fn interest(&'static self) -> Interest {
-            match self.interest.load(Ordering::Relaxed) {
-                0 => Interest::never(),
-                1 => Interest::sometimes(),
-                2 => Interest::always(),
-                _ => self.register(),
-            }
-        }
-
-        pub fn is_enabled(&self, interest: Interest) -> bool {
-            interest.is_always()
-                || crate::dispatcher::get_default(|default| default.enabled(self.meta))
-        }
-
-        #[inline]
-        #[cfg(feature = "log")]
-        pub fn disabled_span(&self) -> crate::Span {
-            crate::Span::new_disabled(self.meta)
-        }
-
-        #[inline]
-        #[cfg(not(feature = "log"))]
-        pub fn disabled_span(&self) -> crate::Span {
-            crate::Span::none()
-        }
-
-        #[cfg(feature = "log")]
-        pub fn log(
-            &self,
-            logger: &'static dyn log::Log,
-            log_meta: log::Metadata<'_>,
-            values: &tracing_core::field::ValueSet<'_>,
-        ) {
-            let meta = self.metadata();
-            logger.log(
-                &crate::log::Record::builder()
-                    .file(meta.file())
-                    .module_path(meta.module_path())
-                    .line(meta.line())
-                    .metadata(log_meta)
-                    .args(format_args!(
-                        "{}",
-                        crate::log::LogValueSet {
-                            values,
-                            is_first: true
-                        }
-                    ))
-                    .build(),
-            );
-        }
+    /// /!\ WARNING: This is *not* a stable API! /!\
+    /// This function, and all code contained in the `__macro_support` module, is
+    /// a *private* API of `tracing`. It is exposed publicly because it is used
+    /// by the `tracing` macros, but it is not part of the stable versioned API.
+    /// Breaking changes to this module may occur in small-numbered versions
+    /// without warning.
+    #[inline]
+    #[cfg(feature = "log")]
+    pub fn __disabled_span(meta: &'static Metadata<'static>) -> crate::Span {
+        crate::Span::new_disabled(meta)
     }
 
-    impl Callsite for MacroCallsite {
-        fn set_interest(&self, interest: Interest) {
-            let interest = match () {
-                _ if interest.is_never() => 0,
-                _ if interest.is_always() => 2,
-                _ => 1,
-            };
-            self.interest.store(interest, Ordering::SeqCst);
-        }
-
-        #[inline(always)]
-        fn metadata(&self) -> &Metadata<'static> {
-            self.meta
-        }
+    /// /!\ WARNING: This is *not* a stable API! /!\
+    /// This function, and all code contained in the `__macro_support` module, is
+    /// a *private* API of `tracing`. It is exposed publicly because it is used
+    /// by the `tracing` macros, but it is not part of the stable versioned API.
+    /// Breaking changes to this module may occur in small-numbered versions
+    /// without warning.
+    #[inline]
+    #[cfg(not(feature = "log"))]
+    pub fn __disabled_span(_: &'static Metadata<'static>) -> crate::Span {
+        crate::Span::none()
     }
 
-    impl fmt::Debug for MacroCallsite {
-        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            f.debug_struct("MacroCallsite")
-                .field("interest", &self.interest)
-                .field("meta", &self.meta)
-                .field("registration", &self.registration)
-                .finish()
-        }
+    /// /!\ WARNING: This is *not* a stable API! /!\
+    /// This function, and all code contained in the `__macro_support` module, is
+    /// a *private* API of `tracing`. It is exposed publicly because it is used
+    /// by the `tracing` macros, but it is not part of the stable versioned API.
+    /// Breaking changes to this module may occur in small-numbered versions
+    /// without warning.
+    #[cfg(feature = "log")]
+    pub fn __tracing_log(
+        meta: &Metadata<'static>,
+        logger: &'static dyn log::Log,
+        log_meta: log::Metadata<'_>,
+        values: &tracing_core::field::ValueSet<'_>,
+    ) {
+        logger.log(
+            &crate::log::Record::builder()
+                .file(meta.file())
+                .module_path(meta.module_path())
+                .line(meta.line())
+                .metadata(log_meta)
+                .args(format_args!(
+                    "{}",
+                    crate::log::LogValueSet {
+                        values,
+                        is_first: true
+                    }
+                ))
+                .build(),
+        );
     }
 }
 
diff --git a/zeroidc/vendor/tracing/src/macros.rs b/zeroidc/vendor/tracing/src/macros.rs
index 825c0d868..b134af6e8 100644
--- a/zeroidc/vendor/tracing/src/macros.rs
+++ b/zeroidc/vendor/tracing/src/macros.rs
@@ -24,7 +24,7 @@ macro_rules! span {
     (target: $target:expr, parent: $parent:expr, $lvl:expr, $name:expr, $($fields:tt)*) => {
         {
             use $crate::__macro_support::Callsite as _;
-            static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
+            static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
                 name: $name,
                 kind: $crate::metadata::Kind::SPAN,
                 target: $target,
@@ -34,7 +34,7 @@ macro_rules! span {
             let mut interest = $crate::subscriber::Interest::never();
             if $crate::level_enabled!($lvl)
                 && { interest = CALLSITE.interest(); !interest.is_never() }
-                && CALLSITE.is_enabled(interest)
+                && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
             {
                 let meta = CALLSITE.metadata();
                 // span with explicit parent
@@ -44,7 +44,7 @@ macro_rules! span {
                     &$crate::valueset!(meta.fields(), $($fields)*),
                 )
             } else {
-                let span = CALLSITE.disabled_span();
+                let span = $crate::__macro_support::__disabled_span(CALLSITE.metadata());
                 $crate::if_log_enabled! { $lvl, {
                     span.record_all(&$crate::valueset!(CALLSITE.metadata().fields(), $($fields)*));
                 }};
@@ -55,7 +55,7 @@ macro_rules! span {
     (target: $target:expr, $lvl:expr, $name:expr, $($fields:tt)*) => {
         {
             use $crate::__macro_support::Callsite as _;
-            static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
+            static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
                 name: $name,
                 kind: $crate::metadata::Kind::SPAN,
                 target: $target,
@@ -65,7 +65,7 @@ macro_rules! span {
             let mut interest = $crate::subscriber::Interest::never();
             if $crate::level_enabled!($lvl)
                 && { interest = CALLSITE.interest(); !interest.is_never() }
-                && CALLSITE.is_enabled(interest)
+                && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
             {
                 let meta = CALLSITE.metadata();
                 // span with contextual parent
@@ -74,7 +74,7 @@ macro_rules! span {
                     &$crate::valueset!(meta.fields(), $($fields)*),
                 )
             } else {
-                let span = CALLSITE.disabled_span();
+                let span = $crate::__macro_support::__disabled_span(CALLSITE.metadata());
                 $crate::if_log_enabled! { $lvl, {
                     span.record_all(&$crate::valueset!(CALLSITE.metadata().fields(), $($fields)*));
                 }};
@@ -584,7 +584,7 @@ macro_rules! error_span {
 macro_rules! event {
     (target: $target:expr, parent: $parent:expr, $lvl:expr, { $($fields:tt)* } )=> ({
         use $crate::__macro_support::Callsite as _;
-        static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
+        static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
             name: $crate::__macro_support::concat!(
                 "event ",
                 file!(),
@@ -599,7 +599,7 @@ macro_rules! event {
 
         let enabled = $crate::level_enabled!($lvl) && {
             let interest = CALLSITE.interest();
-            !interest.is_never() && CALLSITE.is_enabled(interest)
+            !interest.is_never() && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
         };
         if enabled {
             (|value_set: $crate::field::ValueSet| {
@@ -641,7 +641,7 @@ macro_rules! event {
     );
     (target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> ({
         use $crate::__macro_support::Callsite as _;
-        static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
+        static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
             name: $crate::__macro_support::concat!(
                 "event ",
                 file!(),
@@ -655,7 +655,7 @@ macro_rules! event {
         };
         let enabled = $crate::level_enabled!($lvl) && {
             let interest = CALLSITE.interest();
-            !interest.is_never() && CALLSITE.is_enabled(interest)
+            !interest.is_never() && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest)
         };
         if enabled {
             (|value_set: $crate::field::ValueSet| {
@@ -832,6 +832,8 @@ macro_rules! event {
 /// }
 /// ```
 ///
+/// [`enabled!`]: crate::enabled
+/// [`span_enabled!`]: crate::span_enabled
 #[macro_export]
 macro_rules! event_enabled {
     ($($rest:tt)*)=> (
@@ -864,6 +866,8 @@ macro_rules! event_enabled {
 /// }
 /// ```
 ///
+/// [`enabled!`]: crate::enabled
+/// [`span_enabled!`]: crate::span_enabled
 #[macro_export]
 macro_rules! span_enabled {
     ($($rest:tt)*)=> (
@@ -959,13 +963,14 @@ macro_rules! span_enabled {
 /// [`Metadata`]: crate::Metadata
 /// [`is_event`]: crate::Metadata::is_event
 /// [`is_span`]: crate::Metadata::is_span
-///
+/// [`enabled!`]: crate::enabled
+/// [`span_enabled!`]: crate::span_enabled
 #[macro_export]
 macro_rules! enabled {
     (kind: $kind:expr, target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> ({
         if $crate::level_enabled!($lvl) {
             use $crate::__macro_support::Callsite as _;
-            static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
+            static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite2! {
                 name: $crate::__macro_support::concat!(
                     "enabled ",
                     file!(),
@@ -978,7 +983,7 @@ macro_rules! enabled {
                 fields: $($fields)*
             };
             let interest = CALLSITE.interest();
-            if !interest.is_never() && CALLSITE.is_enabled(interest)  {
+            if !interest.is_never() && $crate::__macro_support::__is_enabled(CALLSITE.metadata(), interest) {
                 let meta = CALLSITE.metadata();
                 $crate::dispatcher::get_default(|current| current.enabled(meta))
             } else {
@@ -2096,7 +2101,6 @@ macro_rules! callsite {
         level: $lvl:expr,
         fields: $($fields:tt)*
     ) => {{
-        use $crate::__macro_support::MacroCallsite;
         static META: $crate::Metadata<'static> = {
             $crate::metadata! {
                 name: $name,
@@ -2107,7 +2111,7 @@ macro_rules! callsite {
                 kind: $kind,
             }
         };
-        static CALLSITE: MacroCallsite = MacroCallsite::new(&META);
+        static CALLSITE: $crate::callsite::DefaultCallsite = $crate::callsite::DefaultCallsite::new(&META);
         CALLSITE.register();
         &CALLSITE
     }};
@@ -2147,7 +2151,6 @@ macro_rules! callsite2 {
         level: $lvl:expr,
         fields: $($fields:tt)*
     ) => {{
-        use $crate::__macro_support::MacroCallsite;
         static META: $crate::Metadata<'static> = {
             $crate::metadata! {
                 name: $name,
@@ -2158,7 +2161,7 @@ macro_rules! callsite2 {
                 kind: $kind,
             }
         };
-        MacroCallsite::new(&META)
+        $crate::callsite::DefaultCallsite::new(&META)
     }};
 }
 
@@ -2428,13 +2431,14 @@ macro_rules! __tracing_log {
             use $crate::log;
             let level = $crate::level_to_log!($level);
             if level <= log::max_level() {
+                let meta = $callsite.metadata();
                 let log_meta = log::Metadata::builder()
                     .level(level)
-                    .target(CALLSITE.metadata().target())
+                    .target(meta.target())
                     .build();
                 let logger = log::logger();
                 if logger.enabled(&log_meta) {
-                    $callsite.log(logger, log_meta, $value_set)
+                    $crate::__macro_support::__tracing_log(meta, logger, log_meta, $value_set)
                 }
             }
         }}
diff --git a/zeroidc/vendor/tracing/src/span.rs b/zeroidc/vendor/tracing/src/span.rs
index 7278e6d17..21358eb27 100644
--- a/zeroidc/vendor/tracing/src/span.rs
+++ b/zeroidc/vendor/tracing/src/span.rs
@@ -718,8 +718,8 @@ impl Span {
     ///   ```
     ///
     /// [syntax]: https://rust-lang.github.io/async-book/01_getting_started/04_async_await_primer.html
-    /// [`Span::in_scope`]: #method.in_scope
-    /// [instrument]: https://docs.rs/tracing/latest/tracing/trait.Instrument.html
+    /// [`Span::in_scope`]: Span::in_scope()
+    /// [instrument]: crate::Instrument
     /// [attr]: macro@crate::instrument
     ///
     /// # Examples
@@ -1239,7 +1239,7 @@ impl Span {
     ///
     /// See also [`is_none`].
     ///
-    /// [`is_none`]: #method.is_none
+    /// [`is_none`]: Span::is_none()
     #[inline]
     pub fn is_disabled(&self) -> bool {
         self.inner.is_none()
@@ -1253,8 +1253,8 @@ impl Span {
     /// rather than constructed by `Span::none`, this method will return
     /// `false`, while `is_disabled` will return `true`.
     ///
-    /// [`Span::none`]: #method.none
-    /// [`is_disabled`]: #method.is_disabled
+    /// [`Span::none`]: Span::none()
+    /// [`is_disabled`]: Span::is_disabled()
     #[inline]
     pub fn is_none(&self) -> bool {
         self.is_disabled() && self.meta.is_none()
diff --git a/zeroidc/vendor/tracing/tests/register_callsite_deadlock.rs b/zeroidc/vendor/tracing/tests/register_callsite_deadlock.rs
new file mode 100644
index 000000000..e4c116c75
--- /dev/null
+++ b/zeroidc/vendor/tracing/tests/register_callsite_deadlock.rs
@@ -0,0 +1,47 @@
+use std::{sync::mpsc, thread, time::Duration};
+use tracing::{
+    metadata::Metadata,
+    span,
+    subscriber::{self, Interest, Subscriber},
+    Event,
+};
+
+#[test]
+fn register_callsite_doesnt_deadlock() {
+    pub struct EvilSubscriber;
+
+    impl Subscriber for EvilSubscriber {
+        fn register_callsite(&self, meta: &'static Metadata<'static>) -> Interest {
+            tracing::info!(?meta, "registered a callsite");
+            Interest::always()
+        }
+
+        fn enabled(&self, _: &Metadata<'_>) -> bool {
+            true
+        }
+        fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
+            span::Id::from_u64(1)
+        }
+        fn record(&self, _: &span::Id, _: &span::Record<'_>) {}
+        fn record_follows_from(&self, _: &span::Id, _: &span::Id) {}
+        fn event(&self, _: &Event<'_>) {}
+        fn enter(&self, _: &span::Id) {}
+        fn exit(&self, _: &span::Id) {}
+    }
+
+    subscriber::set_global_default(EvilSubscriber).unwrap();
+
+    // spawn a thread, and assert it doesn't hang...
+    let (tx, didnt_hang) = mpsc::channel();
+    let th = thread::spawn(move || {
+        tracing::info!("hello world!");
+        tx.send(()).unwrap();
+    });
+
+    didnt_hang
+        // Note: 60 seconds is *way* more than enough, but let's be generous in
+        // case of e.g. slow CI machines.
+        .recv_timeout(Duration::from_secs(60))
+        .expect("the thread must not have hung!");
+    th.join().expect("thread should join successfully");
+}
diff --git a/zeroidc/vendor/typenum/build/main.rs b/zeroidc/vendor/typenum/build/main.rs
new file mode 100644
index 000000000..03c4697d4
--- /dev/null
+++ b/zeroidc/vendor/typenum/build/main.rs
@@ -0,0 +1,186 @@
+use std::env;
+use std::fmt;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+
+mod op;
+mod tests;
+
+pub enum UIntCode {
+    Term,
+    Zero(Box),
+    One(Box),
+}
+
+pub enum IntCode {
+    Zero,
+    Pos(Box),
+    Neg(Box),
+}
+
+impl fmt::Display for UIntCode {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            UIntCode::Term => write!(f, "UTerm"),
+            UIntCode::Zero(ref inner) => write!(f, "UInt<{}, B0>", inner),
+            UIntCode::One(ref inner) => write!(f, "UInt<{}, B1>", inner),
+        }
+    }
+}
+
+impl fmt::Display for IntCode {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            IntCode::Zero => write!(f, "Z0"),
+            IntCode::Pos(ref inner) => write!(f, "PInt<{}>", inner),
+            IntCode::Neg(ref inner) => write!(f, "NInt<{}>", inner),
+        }
+    }
+}
+
+pub fn gen_uint(u: u64) -> UIntCode {
+    let mut result = UIntCode::Term;
+    let mut x = 1u64 << 63;
+    while x > u {
+        x >>= 1
+    }
+    while x > 0 {
+        result = if x & u > 0 {
+            UIntCode::One(Box::new(result))
+        } else {
+            UIntCode::Zero(Box::new(result))
+        };
+        x >>= 1;
+    }
+    result
+}
+
+pub fn gen_int(i: i64) -> IntCode {
+    use std::cmp::Ordering::{Equal, Greater, Less};
+
+    match i.cmp(&0) {
+        Greater => IntCode::Pos(Box::new(gen_uint(i as u64))),
+        Less => IntCode::Neg(Box::new(gen_uint(i.abs() as u64))),
+        Equal => IntCode::Zero,
+    }
+}
+
+#[cfg_attr(
+    feature = "no_std",
+    deprecated(
+        since = "1.3.0",
+        note = "the `no_std` flag is no longer necessary and will be removed in the future"
+    )
+)]
+pub fn no_std() {}
+
+// fixme: get a warning when testing without this
+#[allow(dead_code)]
+fn main() {
+    let highest: u64 = 1024;
+
+    // Use hardcoded values to avoid issues with cross-compilation.
+    // See https://github.com/paholg/typenum/issues/162
+    let first2: u32 = 11; // (highest as f64).log(2.0).round() as u32 + 1;
+    let first10: u32 = 4; // (highest as f64).log(10.0) as u32 + 1;
+    let uints = (0..(highest + 1))
+        .chain((first2..64).map(|i| 2u64.pow(i)))
+        .chain((first10..20).map(|i| 10u64.pow(i)));
+
+    let out_dir = env::var("OUT_DIR").unwrap();
+    let dest = Path::new(&out_dir).join("consts.rs");
+    println!("cargo:rustc-env=TYPENUM_BUILD_CONSTS={}", dest.display());
+
+    let mut f = File::create(&dest).unwrap();
+
+    no_std();
+
+    // Header stuff here!
+    write!(
+        f,
+        "
+/**
+Type aliases for many constants.
+
+This file is generated by typenum's build script.
+
+For unsigned integers, the format is `U` followed by the number. We define aliases for
+
+- Numbers 0 through {highest}
+- Powers of 2 below `u64::MAX`
+- Powers of 10 below `u64::MAX`
+
+These alias definitions look like this:
+
+```rust
+use typenum::{{B0, B1, UInt, UTerm}};
+
+# #[allow(dead_code)]
+type U6 = UInt, B1>, B0>;
+```
+
+For positive signed integers, the format is `P` followed by the number and for negative
+signed integers it is `N` followed by the number. For the signed integer zero, we use
+`Z0`. We define aliases for
+
+- Numbers -{highest} through {highest}
+- Powers of 2 between `i64::MIN` and `i64::MAX`
+- Powers of 10 between `i64::MIN` and `i64::MAX`
+
+These alias definitions look like this:
+
+```rust
+use typenum::{{B0, B1, UInt, UTerm, PInt, NInt}};
+
+# #[allow(dead_code)]
+type P6 = PInt, B1>, B0>>;
+# #[allow(dead_code)]
+type N6 = NInt, B1>, B0>>;
+```
+
+# Example
+```rust
+# #[allow(unused_imports)]
+use typenum::{{U0, U1, U2, U3, U4, U5, U6}};
+# #[allow(unused_imports)]
+use typenum::{{N3, N2, N1, Z0, P1, P2, P3}};
+# #[allow(unused_imports)]
+use typenum::{{U774, N17, N10000, P1024, P4096}};
+```
+
+We also define the aliases `False` and `True` for `B0` and `B1`, respectively.
+*/
+#[allow(missing_docs)]
+pub mod consts {{
+    use crate::uint::{{UInt, UTerm}};
+    use crate::int::{{PInt, NInt}};
+
+    pub use crate::bit::{{B0, B1}};
+    pub use crate::int::Z0;
+
+    pub type True = B1;
+    pub type False = B0;
+",
+        highest = highest
+    )
+    .unwrap();
+
+    for u in uints {
+        writeln!(f, "    pub type U{} = {};", u, gen_uint(u)).unwrap();
+        if u <= ::std::i64::MAX as u64 && u != 0 {
+            let i = u as i64;
+            writeln!(
+                f,
+                "    pub type P{i} = PInt; pub type N{i} = NInt;",
+                i = i
+            )
+            .unwrap();
+        }
+    }
+    write!(f, "}}").unwrap();
+
+    tests::build_tests().unwrap();
+
+    op::write_op_macro().unwrap();
+}
diff --git a/zeroidc/vendor/typenum/build/op.rs b/zeroidc/vendor/typenum/build/op.rs
new file mode 100644
index 000000000..756f37229
--- /dev/null
+++ b/zeroidc/vendor/typenum/build/op.rs
@@ -0,0 +1,559 @@
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum OpType {
+    Operator,
+    Function,
+}
+
+use self::OpType::*;
+
+struct Op {
+    token: &'static str,
+    operator: &'static str,
+    example: (&'static str, &'static str),
+    precedence: u8,
+    n_args: u8,
+    op_type: OpType,
+}
+
+pub fn write_op_macro() -> ::std::io::Result<()> {
+    let out_dir = ::std::env::var("OUT_DIR").unwrap();
+    let dest = ::std::path::Path::new(&out_dir).join("op.rs");
+    println!("cargo:rustc-env=TYPENUM_BUILD_OP={}", dest.display());
+    let mut f = ::std::fs::File::create(&dest).unwrap();
+
+    // Operator precedence is taken from
+    // https://doc.rust-lang.org/reference.html#operator-precedence
+    //
+    // We choose 16 as the highest precedence (functions are set to 255 but it doesn't matter
+    // for them).  We also only use operators that are left associative so we don't have to worry
+    // about that.
+    let ops = &[
+        Op {
+            token: "*",
+            operator: "Prod",
+            example: ("P2 * P3", "P6"),
+            precedence: 16,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "/",
+            operator: "Quot",
+            example: ("P6 / P2", "P3"),
+            precedence: 16,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "%",
+            operator: "Mod",
+            example: ("P5 % P3", "P2"),
+            precedence: 16,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "+",
+            operator: "Sum",
+            example: ("P2 + P3", "P5"),
+            precedence: 15,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "-",
+            operator: "Diff",
+            example: ("P2 - P3", "N1"),
+            precedence: 15,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "<<",
+            operator: "Shleft",
+            example: ("U1 << U5", "U32"),
+            precedence: 14,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: ">>",
+            operator: "Shright",
+            example: ("U32 >> U5", "U1"),
+            precedence: 14,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "&",
+            operator: "And",
+            example: ("U5 & U3", "U1"),
+            precedence: 13,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "^",
+            operator: "Xor",
+            example: ("U5 ^ U3", "U6"),
+            precedence: 12,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "|",
+            operator: "Or",
+            example: ("U5 | U3", "U7"),
+            precedence: 11,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "==",
+            operator: "Eq",
+            example: ("P5 == P3 + P2", "True"),
+            precedence: 10,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "!=",
+            operator: "NotEq",
+            example: ("P5 != P3 + P2", "False"),
+            precedence: 10,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "<=",
+            operator: "LeEq",
+            example: ("P6 <= P3 + P2", "False"),
+            precedence: 10,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: ">=",
+            operator: "GrEq",
+            example: ("P6 >= P3 + P2", "True"),
+            precedence: 10,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "<",
+            operator: "Le",
+            example: ("P4 < P3 + P2", "True"),
+            precedence: 10,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: ">",
+            operator: "Gr",
+            example: ("P5 < P3 + P2", "False"),
+            precedence: 10,
+            n_args: 2,
+            op_type: Operator,
+        },
+        Op {
+            token: "cmp",
+            operator: "Compare",
+            example: ("cmp(P2, P3)", "Less"),
+            precedence: !0,
+            n_args: 2,
+            op_type: Function,
+        },
+        Op {
+            token: "sqr",
+            operator: "Square",
+            example: ("sqr(P2)", "P4"),
+            precedence: !0,
+            n_args: 1,
+            op_type: Function,
+        },
+        Op {
+            token: "sqrt",
+            operator: "Sqrt",
+            example: ("sqrt(U9)", "U3"),
+            precedence: !0,
+            n_args: 1,
+            op_type: Function,
+        },
+        Op {
+            token: "abs",
+            operator: "AbsVal",
+            example: ("abs(N2)", "P2"),
+            precedence: !0,
+            n_args: 1,
+            op_type: Function,
+        },
+        Op {
+            token: "cube",
+            operator: "Cube",
+            example: ("cube(P2)", "P8"),
+            precedence: !0,
+            n_args: 1,
+            op_type: Function,
+        },
+        Op {
+            token: "pow",
+            operator: "Exp",
+            example: ("pow(P2, P3)", "P8"),
+            precedence: !0,
+            n_args: 2,
+            op_type: Function,
+        },
+        Op {
+            token: "min",
+            operator: "Minimum",
+            example: ("min(P2, P3)", "P2"),
+            precedence: !0,
+            n_args: 2,
+            op_type: Function,
+        },
+        Op {
+            token: "max",
+            operator: "Maximum",
+            example: ("max(P2, P3)", "P3"),
+            precedence: !0,
+            n_args: 2,
+            op_type: Function,
+        },
+        Op {
+            token: "log2",
+            operator: "Log2",
+            example: ("log2(U9)", "U3"),
+            precedence: !0,
+            n_args: 1,
+            op_type: Function,
+        },
+        Op {
+            token: "gcd",
+            operator: "Gcf",
+            example: ("gcd(U9, U21)", "U3"),
+            precedence: !0,
+            n_args: 2,
+            op_type: Function,
+        },
+    ];
+
+    use std::io::Write;
+    write!(
+        f,
+        "
+/**
+Convenient type operations.
+
+Any types representing values must be able to be expressed as `ident`s. That means they need to be
+in scope.
+
+For example, `P5` is okay, but `typenum::P5` is not.
+
+You may combine operators arbitrarily, although doing so excessively may require raising the
+recursion limit.
+
+# Example
+```rust
+#![recursion_limit=\"128\"]
+#[macro_use] extern crate typenum;
+use typenum::consts::*;
+
+fn main() {{
+    assert_type!(
+        op!(min((P1 - P2) * (N3 + N7), P5 * (P3 + P4)) == P10)
+    );
+}}
+```
+Operators are evaluated based on the operator precedence outlined
+[here](https://doc.rust-lang.org/reference.html#operator-precedence).
+
+The full list of supported operators and functions is as follows:
+
+{}
+
+They all expand to type aliases defined in the `operator_aliases` module. Here is an expanded list,
+including examples:
+
+",
+        ops.iter()
+            .map(|op| format!("`{}`", op.token))
+            .collect::>()
+            .join(", ")
+    )?;
+
+    //write!(f, "Token | Alias | Example\n ===|===|===\n")?;
+
+    for op in ops.iter() {
+        write!(
+            f,
+            "---\nOperator `{token}`. Expands to `{operator}`.
+
+```rust
+# #[macro_use] extern crate typenum;
+# use typenum::*;
+# fn main() {{
+assert_type_eq!(op!({ex0}), {ex1});
+# }}
+```\n
+",
+            token = op.token,
+            operator = op.operator,
+            ex0 = op.example.0,
+            ex1 = op.example.1
+        )?;
+    }
+
+    write!(
+        f,
+        "*/
+#[macro_export(local_inner_macros)]
+macro_rules! op {{
+    ($($tail:tt)*) => ( __op_internal__!($($tail)*) );
+}}
+
+    #[doc(hidden)]
+    #[macro_export(local_inner_macros)]
+    macro_rules! __op_internal__ {{
+"
+    )?;
+
+    // We first us the shunting-yard algorithm to produce our tokens in Polish notation.
+    // See: https://en.wikipedia.org/wiki/Shunting-yard_algorithm
+
+    // Note: Due to macro asymmetry, "the top of the stack" refers to the first element, not the
+    // last
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 1: There are tokens to be read:
+
+    // -------
+    // Case 1: Token is a function => Push it onto the stack:
+    for fun in ops.iter().filter(|f| f.op_type == Function) {
+        write!(
+            f,
+            "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {f_token} $($tail:tt)*) => (
+    __op_internal__!(@stack[{f_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);",
+            f_token = fun.token,
+            f_op = fun.operator
+        )?;
+    }
+
+    // -------
+    // Case 2: Token is a comma => Until the top of the stack is a LParen,
+    //                             Pop operators from stack to queue
+
+    // Base case: Top of stack is LParen, ditch comma and continue
+    write!(
+        f,
+        "
+(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
+    __op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);"
+    )?;
+    // Recursive case: Not LParen, pop from stack to queue
+    write!(
+        f,
+        "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: , $($tail)*)
+);"
+    )?;
+
+    // -------
+    // Case 3: Token is an operator, o1:
+    for o1 in ops.iter().filter(|op| op.op_type == Operator) {
+        // If top of stack is operator o2 with o1.precedence <= o2.precedence,
+        // Then pop o2 off stack onto queue:
+        for o2 in ops
+            .iter()
+            .filter(|op| op.op_type == Operator)
+            .filter(|o2| o1.precedence <= o2.precedence)
+        {
+            write!(
+                f,
+                "
+(@stack[{o2_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[{o2_op}, $($queue,)*] @tail: {o1_token} $($tail)*)
+);",
+                o2_op = o2.operator,
+                o1_token = o1.token
+            )?;
+        }
+        // Base case: push o1 onto stack
+        write!(
+            f,
+            "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
+    __op_internal__!(@stack[{o1_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);",
+            o1_op = o1.operator,
+            o1_token = o1.token
+        )?;
+    }
+
+    // -------
+    // Case 4: Token is "(": push it onto stack as "LParen". Also convert the ")" to "RParen" to
+    // appease the macro gods:
+    write!(
+        f,
+        "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: ( $($stuff:tt)* ) $($tail:tt)* )
+ => (
+    __op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*]
+                     @tail: $($stuff)* RParen $($tail)*)
+);"
+    )?;
+
+    // -------
+    // Case 5: Token is "RParen":
+    //     1. Pop from stack to queue until we see an "LParen",
+    //     2. Kill the "LParen",
+    //     3. If the top of the stack is a function, pop it onto the queue
+    // 2. Base case:
+    write!(
+        f,
+        "
+(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*) => (
+    __op_internal__!(@rp3 @stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);"
+    )?;
+    // 1. Recursive case:
+    write!(
+        f,
+        "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*)
+ => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: RParen $($tail)*)
+);"
+    )?;
+    // 3. Check for function:
+    for fun in ops.iter().filter(|f| f.op_type == Function) {
+        write!(
+            f,
+            "
+(@rp3 @stack[{fun_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[{fun_op}, $($queue,)*] @tail: $($tail)*)
+);",
+            fun_op = fun.operator
+        )?;
+    }
+    // 3. If no function found:
+    write!(
+        f,
+        "
+(@rp3 @stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);"
+    )?;
+
+    // -------
+    // Case 6: Token is a number: Push it onto the queue
+    write!(
+        f,
+        "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $num:ident $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$num, $($queue,)*] @tail: $($tail)*)
+);"
+    )?;
+
+    // -------
+    // Case 7: Out of tokens:
+    // Base case: Stack empty: Start evaluating
+    write!(
+        f,
+        "
+(@stack[] @queue[$($queue:ident,)*] @tail: ) => (
+    __op_internal__!(@reverse[] @input: $($queue,)*)
+);"
+    )?;
+    // Recursive case: Pop stack to queue
+    write!(
+        f,
+        "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail:) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: )
+);"
+    )?;
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 2: Reverse so we have RPN
+    write!(
+        f,
+        "
+(@reverse[$($revved:ident,)*] @input: $head:ident, $($tail:ident,)* ) => (
+    __op_internal__!(@reverse[$head, $($revved,)*] @input: $($tail,)*)
+);"
+    )?;
+    write!(
+        f,
+        "
+(@reverse[$($revved:ident,)*] @input: ) => (
+    __op_internal__!(@eval @stack[] @input[$($revved,)*])
+);"
+    )?;
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 3: Evaluate in Reverse Polish Notation
+    // Operators / Operators with 2 args:
+    for op in ops.iter().filter(|op| op.n_args == 2) {
+        // Note: We have to switch $a and $b here, otherwise non-commutative functions are backwards
+        write!(
+            f,
+            "
+(@eval @stack[$a:ty, $b:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
+    __op_internal__!(@eval @stack[$crate::{op}<$b, $a>, $($stack,)*] @input[$($tail,)*])
+);",
+            op = op.operator
+        )?;
+    }
+    // Operators with 1 arg:
+    for op in ops.iter().filter(|op| op.n_args == 1) {
+        write!(
+            f,
+            "
+(@eval @stack[$a:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
+    __op_internal__!(@eval @stack[$crate::{op}<$a>, $($stack,)*] @input[$($tail,)*])
+);",
+            op = op.operator
+        )?;
+    }
+
+    // Wasn't a function or operator, so must be a value => push onto stack
+    write!(
+        f,
+        "
+(@eval @stack[$($stack:ty,)*] @input[$head:ident, $($tail:ident,)*]) => (
+    __op_internal__!(@eval @stack[$head, $($stack,)*] @input[$($tail,)*])
+);"
+    )?;
+
+    // No input left:
+    write!(
+        f,
+        "
+(@eval @stack[$stack:ty,] @input[]) => (
+    $stack
+);"
+    )?;
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 0: Get it started
+    write!(
+        f,
+        "
+($($tail:tt)* ) => (
+    __op_internal__!(@stack[] @queue[] @tail: $($tail)*)
+);"
+    )?;
+
+    write!(
+        f,
+        "
+}}"
+    )?;
+
+    Ok(())
+}
diff --git a/zeroidc/vendor/typenum/build/tests.rs b/zeroidc/vendor/typenum/build/tests.rs
new file mode 100644
index 000000000..b0453a95f
--- /dev/null
+++ b/zeroidc/vendor/typenum/build/tests.rs
@@ -0,0 +1,328 @@
+use std::{env, fmt, fs, io, path};
+
+use super::{gen_int, gen_uint};
+
+/// Computes the greatest common divisor of two integers.
+fn gcdi(mut a: i64, mut b: i64) -> i64 {
+    a = a.abs();
+    b = b.abs();
+
+    while a != 0 {
+        let tmp = b % a;
+        b = a;
+        a = tmp;
+    }
+
+    b
+}
+
+fn gcdu(mut a: u64, mut b: u64) -> u64 {
+    while a != 0 {
+        let tmp = b % a;
+        b = a;
+        a = tmp;
+    }
+
+    b
+}
+
+fn sign(i: i64) -> char {
+    use std::cmp::Ordering::*;
+    match i.cmp(&0) {
+        Greater => 'P',
+        Less => 'N',
+        Equal => '_',
+    }
+}
+
+struct UIntTest {
+    a: u64,
+    op: &'static str,
+    b: Option,
+    r: u64,
+}
+
+impl fmt::Display for UIntTest {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.b {
+            Some(b) => write!(
+                f,
+                "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_{op}_{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+    type U{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type U{a}{op}U{b} = <>::Output as Same>::Output;
+
+    assert_eq!(::to_u64(), ::to_u64());
+}}",
+                gen_a = gen_uint(self.a),
+                gen_b = gen_uint(b),
+                r = self.r,
+                result = gen_uint(self.r),
+                a = self.a,
+                b = b,
+                op = self.op
+            ),
+            None => write!(
+                f,
+                "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_{op}() {{
+    type A = {gen_a};
+    type U{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type {op}U{a} = <::Output as Same>::Output;
+    assert_eq!(<{op}U{a} as Unsigned>::to_u64(), ::to_u64());
+}}",
+                gen_a = gen_uint(self.a),
+                r = self.r,
+                result = gen_uint(self.r),
+                a = self.a,
+                op = self.op
+            ),
+        }
+    }
+}
+
+fn uint_binary_test(left: u64, operator: &'static str, right: u64, result: u64) -> UIntTest {
+    UIntTest {
+        a: left,
+        op: operator,
+        b: Option::Some(right),
+        r: result,
+    }
+}
+
+// fn uint_unary_test(op: &'static str, a: u64, result: u64) -> UIntTest {
+//     UIntTest { a: a, op: op, b: Option::None, r: result }
+// }
+
+struct IntBinaryTest {
+    a: i64,
+    op: &'static str,
+    b: i64,
+    r: i64,
+}
+
+impl fmt::Display for IntBinaryTest {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_{op}_{sb}{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+    type {sr}{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type {sa}{a}{op}{sb}{b} = <>::Output as Same<{sr}{r}>>::Output;
+
+    assert_eq!(<{sa}{a}{op}{sb}{b} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
+}}",
+            gen_a = gen_int(self.a),
+            gen_b = gen_int(self.b),
+            r = self.r.abs(),
+            sr = sign(self.r),
+            result = gen_int(self.r),
+            a = self.a.abs(),
+            b = self.b.abs(),
+            sa = sign(self.a),
+            sb = sign(self.b),
+            op = self.op
+        )
+    }
+}
+
+fn int_binary_test(left: i64, operator: &'static str, right: i64, result: i64) -> IntBinaryTest {
+    IntBinaryTest {
+        a: left,
+        op: operator,
+        b: right,
+        r: result,
+    }
+}
+
+struct IntUnaryTest {
+    op: &'static str,
+    a: i64,
+    r: i64,
+}
+
+impl fmt::Display for IntUnaryTest {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_{op}() {{
+    type A = {gen_a};
+    type {sr}{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type {op}{sa}{a} = <::Output as Same<{sr}{r}>>::Output;
+    assert_eq!(<{op}{sa}{a} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
+}}",
+            gen_a = gen_int(self.a),
+            r = self.r.abs(),
+            sr = sign(self.r),
+            result = gen_int(self.r),
+            a = self.a.abs(),
+            sa = sign(self.a),
+            op = self.op
+        )
+    }
+}
+
+fn int_unary_test(operator: &'static str, num: i64, result: i64) -> IntUnaryTest {
+    IntUnaryTest {
+        op: operator,
+        a: num,
+        r: result,
+    }
+}
+
+fn uint_cmp_test(a: u64, b: u64) -> String {
+    format!(
+        "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_Cmp_{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+
+    #[allow(non_camel_case_types)]
+    type U{a}CmpU{b} = >::Output;
+    assert_eq!(::to_ordering(), Ordering::{result:?});
+}}",
+        a = a,
+        b = b,
+        gen_a = gen_uint(a),
+        gen_b = gen_uint(b),
+        result = a.cmp(&b)
+    )
+}
+
+fn int_cmp_test(a: i64, b: i64) -> String {
+    format!(
+        "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_Cmp_{sb}{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+
+    #[allow(non_camel_case_types)]
+    type {sa}{a}Cmp{sb}{b} = >::Output;
+    assert_eq!(<{sa}{a}Cmp{sb}{b} as Ord>::to_ordering(), Ordering::{result:?});
+}}",
+        a = a.abs(),
+        b = b.abs(),
+        sa = sign(a),
+        sb = sign(b),
+        gen_a = gen_int(a),
+        gen_b = gen_int(b),
+        result = a.cmp(&b)
+    )
+}
+
+// Allow for rustc 1.22 compatibility.
+#[allow(bare_trait_objects)]
+pub fn build_tests() -> Result<(), Box<::std::error::Error>> {
+    // will test all permutations of number pairs up to this (and down to its opposite for ints)
+    let high: i64 = 5;
+
+    let uints = (0u64..high as u64 + 1).flat_map(|a| (a..a + 1).cycle().zip(0..high as u64 + 1));
+    let ints = (-high..high + 1).flat_map(|a| (a..a + 1).cycle().zip(-high..high + 1));
+
+    let out_dir = env::var("OUT_DIR")?;
+    let dest = path::Path::new(&out_dir).join("tests.rs");
+    let f = fs::File::create(&dest)?;
+    let mut writer = io::BufWriter::new(&f);
+    use std::io::Write;
+    writer.write_all(
+        b"
+extern crate typenum;
+
+use std::ops::*;
+use std::cmp::Ordering;
+use typenum::*;
+",
+    )?;
+    use std::cmp;
+    // uint operators:
+    for (a, b) in uints {
+        write!(writer, "{}", uint_binary_test(a, "BitAnd", b, a & b))?;
+        write!(writer, "{}", uint_binary_test(a, "BitOr", b, a | b))?;
+        write!(writer, "{}", uint_binary_test(a, "BitXor", b, a ^ b))?;
+        write!(writer, "{}", uint_binary_test(a, "Shl", b, a << b))?;
+        write!(writer, "{}", uint_binary_test(a, "Shr", b, a >> b))?;
+        write!(writer, "{}", uint_binary_test(a, "Add", b, a + b))?;
+        write!(writer, "{}", uint_binary_test(a, "Min", b, cmp::min(a, b)))?;
+        write!(writer, "{}", uint_binary_test(a, "Max", b, cmp::max(a, b)))?;
+        write!(writer, "{}", uint_binary_test(a, "Gcd", b, gcdu(a, b)))?;
+        if a >= b {
+            write!(writer, "{}", uint_binary_test(a, "Sub", b, a - b))?;
+        }
+        write!(writer, "{}", uint_binary_test(a, "Mul", b, a * b))?;
+        if b != 0 {
+            write!(writer, "{}", uint_binary_test(a, "Div", b, a / b))?;
+            write!(writer, "{}", uint_binary_test(a, "Rem", b, a % b))?;
+            if a % b == 0 {
+                write!(writer, "{}", uint_binary_test(a, "PartialDiv", b, a / b))?;
+            }
+        }
+        write!(writer, "{}", uint_binary_test(a, "Pow", b, a.pow(b as u32)))?;
+        write!(writer, "{}", uint_cmp_test(a, b))?;
+    }
+    // int operators:
+    for (a, b) in ints {
+        write!(writer, "{}", int_binary_test(a, "Add", b, a + b))?;
+        write!(writer, "{}", int_binary_test(a, "Sub", b, a - b))?;
+        write!(writer, "{}", int_binary_test(a, "Mul", b, a * b))?;
+        write!(writer, "{}", int_binary_test(a, "Min", b, cmp::min(a, b)))?;
+        write!(writer, "{}", int_binary_test(a, "Max", b, cmp::max(a, b)))?;
+        write!(writer, "{}", int_binary_test(a, "Gcd", b, gcdi(a, b)))?;
+        if b != 0 {
+            write!(writer, "{}", int_binary_test(a, "Div", b, a / b))?;
+            write!(writer, "{}", int_binary_test(a, "Rem", b, a % b))?;
+            if a % b == 0 {
+                write!(writer, "{}", int_binary_test(a, "PartialDiv", b, a / b))?;
+            }
+        }
+        if b >= 0 || a.abs() == 1 {
+            let result = if b < 0 {
+                if a == 1 {
+                    a
+                } else if a == -1 {
+                    a.pow((-b) as u32)
+                } else {
+                    unreachable!()
+                }
+            } else {
+                a.pow(b as u32)
+            };
+            write!(writer, "{}", int_binary_test(a, "Pow", b, result))?;
+        }
+        write!(writer, "{}", int_cmp_test(a, b))?;
+    }
+
+    // int unary operators:
+    for n in -high..high + 1 {
+        write!(writer, "{}", int_unary_test("Neg", n, -n))?;
+        write!(writer, "{}", int_unary_test("Abs", n, n.abs()))?;
+    }
+
+    writer.flush()?;
+
+    Ok(())
+}