505 lines
9.6 KiB
Rust
505 lines
9.6 KiB
Rust
#![crate_type = "lib"]
|
|
#![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs)]
|
|
#![feature(fundamental)]
|
|
#![feature(const_trait_impl, effects, const_mut_refs)]
|
|
#![allow(internal_features)]
|
|
#![no_std]
|
|
#![no_core]
|
|
|
|
// known-bug: #110395
|
|
|
|
#[lang = "sized"]
|
|
trait Sized {}
|
|
#[lang = "copy"]
|
|
trait Copy {}
|
|
|
|
#[lang = "add"]
|
|
#[const_trait]
|
|
trait Add<Rhs = Self> {
|
|
type Output;
|
|
|
|
fn add(self, rhs: Rhs) -> Self::Output;
|
|
}
|
|
|
|
// FIXME we shouldn't need to have to specify `Rhs`.
|
|
impl const Add<i32> for i32 {
|
|
type Output = i32;
|
|
fn add(self, rhs: i32) -> i32 {
|
|
loop {}
|
|
}
|
|
}
|
|
|
|
fn foo() {
|
|
let x = 42_i32 + 43_i32;
|
|
}
|
|
|
|
const fn bar() {
|
|
let x = 42_i32 + 43_i32;
|
|
}
|
|
|
|
|
|
#[lang = "Try"]
|
|
#[const_trait]
|
|
trait Try: FromResidual {
|
|
type Output;
|
|
type Residual;
|
|
|
|
#[lang = "from_output"]
|
|
fn from_output(output: Self::Output) -> Self;
|
|
|
|
#[lang = "branch"]
|
|
fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
|
|
}
|
|
|
|
// FIXME
|
|
// #[const_trait]
|
|
trait FromResidual<R = <Self as Try>::Residual> {
|
|
#[lang = "from_residual"]
|
|
fn from_residual(residual: R) -> Self;
|
|
}
|
|
|
|
enum ControlFlow<B, C = ()> {
|
|
#[lang = "Continue"]
|
|
Continue(C),
|
|
#[lang = "Break"]
|
|
Break(B),
|
|
}
|
|
|
|
#[const_trait]
|
|
#[lang = "fn"]
|
|
#[rustc_paren_sugar]
|
|
trait Fn<Args: Tuple>: ~const FnMut<Args> {
|
|
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
|
|
}
|
|
|
|
#[const_trait]
|
|
#[lang = "fn_mut"]
|
|
#[rustc_paren_sugar]
|
|
trait FnMut<Args: Tuple>: ~const FnOnce<Args> {
|
|
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
|
}
|
|
|
|
#[const_trait]
|
|
#[lang = "fn_once"]
|
|
#[rustc_paren_sugar]
|
|
trait FnOnce<Args: Tuple> {
|
|
type Output;
|
|
|
|
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
|
|
}
|
|
|
|
struct ConstFnMutClosure<CapturedData, Function> {
|
|
data: CapturedData,
|
|
func: Function,
|
|
}
|
|
|
|
#[lang = "tuple_trait"]
|
|
pub trait Tuple {}
|
|
|
|
macro_rules! impl_fn_mut_tuple {
|
|
($($var:ident)*) => {
|
|
impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
|
|
FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
|
|
where
|
|
Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue,
|
|
Function: ~const Destruct,
|
|
{
|
|
type Output = ClosureReturnValue;
|
|
|
|
extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
|
|
self.call_mut(args)
|
|
}
|
|
}
|
|
impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
|
|
FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
|
|
where
|
|
Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
|
|
Function: ~const Destruct,
|
|
{
|
|
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
|
|
#[allow(non_snake_case)]
|
|
let ($($var),*) = &mut self.data;
|
|
(self.func)(($($var),*), args)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
//impl_fn_mut_tuple!(A);
|
|
//impl_fn_mut_tuple!(A B);
|
|
//impl_fn_mut_tuple!(A B C);
|
|
//impl_fn_mut_tuple!(A B C D);
|
|
//impl_fn_mut_tuple!(A B C D E);
|
|
|
|
#[lang = "receiver"]
|
|
trait Receiver {}
|
|
|
|
impl<T: ?Sized> Receiver for &T {}
|
|
|
|
impl<T: ?Sized> Receiver for &mut T {}
|
|
|
|
#[lang = "destruct"]
|
|
#[const_trait]
|
|
trait Destruct {}
|
|
|
|
#[lang = "freeze"]
|
|
unsafe auto trait Freeze {}
|
|
|
|
#[lang = "drop"]
|
|
#[const_trait]
|
|
trait Drop {
|
|
fn drop(&mut self);
|
|
}
|
|
|
|
/*
|
|
#[const_trait]
|
|
trait Residual<O> {
|
|
type TryType: ~const Try<Output = O, Residual = Self> + Try<Output = O, Residual = Self>;
|
|
}
|
|
*/
|
|
|
|
const fn size_of<T>() -> usize {
|
|
42
|
|
}
|
|
|
|
impl Copy for u8 {}
|
|
|
|
impl usize {
|
|
#[rustc_allow_incoherent_impl]
|
|
const fn repeat_u8(x: u8) -> usize {
|
|
usize::from_ne_bytes([x; size_of::<usize>()])
|
|
}
|
|
#[rustc_allow_incoherent_impl]
|
|
const fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
|
|
loop {}
|
|
}
|
|
}
|
|
|
|
#[rustc_do_not_const_check] // hooked by const-eval
|
|
const fn panic_display() {
|
|
panic_fmt();
|
|
}
|
|
|
|
fn panic_fmt() {}
|
|
|
|
#[lang = "index"]
|
|
#[const_trait]
|
|
trait Index<Idx: ?Sized> {
|
|
type Output: ?Sized;
|
|
|
|
fn index(&self, index: Idx) -> &Self::Output;
|
|
}
|
|
|
|
|
|
#[const_trait]
|
|
unsafe trait SliceIndex<T: ?Sized> {
|
|
type Output: ?Sized;
|
|
fn index(self, slice: &T) -> &Self::Output;
|
|
}
|
|
|
|
impl<T, I> const Index<I> for [T]
|
|
where
|
|
I: ~const SliceIndex<[T]>,
|
|
{
|
|
type Output = I::Output;
|
|
|
|
#[inline]
|
|
fn index(&self, index: I) -> &I::Output {
|
|
index.index(self)
|
|
}
|
|
}
|
|
/* FIXME
|
|
impl<T, I, const N: usize> const Index<I> for [T; N]
|
|
where
|
|
[T]: ~const Index<I>,
|
|
{
|
|
type Output = <[T] as Index<I>>::Output;
|
|
|
|
#[inline]
|
|
// FIXME: make `Self::Output` act like `<Self as ~const Index<I>>::Output`
|
|
fn index(&self, index: I) -> &<[T] as Index<I>>::Output {
|
|
Index::index(self as &[T], index)
|
|
}
|
|
}
|
|
*/
|
|
|
|
#[lang = "unsize"]
|
|
trait Unsize<T: ?Sized> {
|
|
}
|
|
|
|
#[lang = "coerce_unsized"]
|
|
trait CoerceUnsized<T: ?Sized> {
|
|
}
|
|
|
|
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
|
|
|
|
|
#[lang = "deref"]
|
|
// #[const_trait] FIXME
|
|
trait Deref {
|
|
#[lang = "deref_target"]
|
|
type Target: ?Sized;
|
|
|
|
fn deref(&self) -> &Self::Target;
|
|
}
|
|
|
|
|
|
impl<T: ?Sized> /* const */ Deref for &T {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &T {
|
|
*self
|
|
}
|
|
}
|
|
|
|
impl<T: ?Sized> /* const */ Deref for &mut T {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &T {
|
|
*self
|
|
}
|
|
}
|
|
|
|
enum Option<T> {
|
|
#[lang = "None"]
|
|
None,
|
|
#[lang = "Some"]
|
|
Some(T),
|
|
}
|
|
|
|
impl<T> Option<T> {
|
|
const fn as_ref(&self) -> Option<&T> {
|
|
match *self {
|
|
Some(ref x) => Some(x),
|
|
None => None,
|
|
}
|
|
}
|
|
|
|
const fn as_mut(&mut self) -> Option<&mut T> {
|
|
match *self {
|
|
Some(ref mut x) => Some(x),
|
|
None => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
use Option::*;
|
|
|
|
/*
|
|
const fn as_deref<T>(opt: &Option<T>) -> Option<&T::Target>
|
|
where
|
|
T: ~const Deref,
|
|
{
|
|
match opt {
|
|
Option::Some(t) => Option::Some(t.deref()),
|
|
Option::None => Option::None,
|
|
}
|
|
}
|
|
*/
|
|
|
|
#[const_trait]
|
|
trait Into<T>: Sized {
|
|
fn into(self) -> T;
|
|
}
|
|
|
|
#[const_trait]
|
|
trait From<T>: Sized {
|
|
fn from(value: T) -> Self;
|
|
}
|
|
|
|
impl<T, U> const Into<U> for T
|
|
where
|
|
U: ~const From<T>,
|
|
{
|
|
fn into(self) -> U {
|
|
U::from(self)
|
|
}
|
|
}
|
|
|
|
impl<T> const From<T> for T {
|
|
fn from(t: T) -> T {
|
|
t
|
|
}
|
|
}
|
|
|
|
enum Result<T, E> {
|
|
Ok(T),
|
|
Err(E),
|
|
}
|
|
use Result::*;
|
|
|
|
fn from_str(s: &str) -> Result<bool, ()> {
|
|
match s {
|
|
"true" => Ok(true),
|
|
"false" => Ok(false),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
|
|
#[lang = "eq"]
|
|
#[const_trait]
|
|
trait PartialEq<Rhs: ?Sized = Self> {
|
|
fn eq(&self, other: &Rhs) -> bool;
|
|
fn ne(&self, other: &Rhs) -> bool {
|
|
!self.eq(other)
|
|
}
|
|
}
|
|
|
|
// FIXME(effects): again, this should not error without Rhs specified
|
|
impl PartialEq<str> for str {
|
|
fn eq(&self, other: &str) -> bool {
|
|
loop {}
|
|
}
|
|
}
|
|
|
|
|
|
#[lang = "not"]
|
|
#[const_trait]
|
|
trait Not {
|
|
type Output;
|
|
fn not(self) -> Self::Output;
|
|
}
|
|
|
|
impl const Not for bool {
|
|
type Output = bool;
|
|
fn not(self) -> bool {
|
|
!self
|
|
}
|
|
}
|
|
|
|
impl Copy for bool {}
|
|
impl<'a> Copy for &'a str {}
|
|
|
|
#[lang = "pin"]
|
|
#[fundamental]
|
|
#[repr(transparent)]
|
|
struct Pin<P> {
|
|
pointer: P,
|
|
}
|
|
|
|
impl<P> Pin<P> {
|
|
#[lang = "new_unchecked"]
|
|
const unsafe fn new_unchecked(pointer: P) -> Pin<P> {
|
|
Pin { pointer }
|
|
}
|
|
}
|
|
|
|
impl<'a, T: ?Sized> Pin<&'a T> {
|
|
const fn get_ref(self) -> &'a T {
|
|
self.pointer
|
|
}
|
|
}
|
|
|
|
|
|
impl<P: Deref> Pin<P> {
|
|
/* const */ fn as_ref(&self) -> Pin<&P::Target>
|
|
where
|
|
P: /* ~const */ Deref,
|
|
{
|
|
unsafe { Pin::new_unchecked(&*self.pointer) }
|
|
}
|
|
}
|
|
|
|
|
|
impl<'a, T: ?Sized> Pin<&'a mut T> {
|
|
const unsafe fn get_unchecked_mut(self) -> &'a mut T {
|
|
self.pointer
|
|
}
|
|
}
|
|
/* FIXME lol
|
|
impl<T> Option<T> {
|
|
const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
|
|
match Pin::get_ref(self).as_ref() {
|
|
Some(x) => unsafe { Some(Pin::new_unchecked(x)) },
|
|
None => None,
|
|
}
|
|
}
|
|
|
|
const fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
|
|
unsafe {
|
|
match Pin::get_unchecked_mut(self).as_mut() {
|
|
Some(x) => Some(Pin::new_unchecked(x)),
|
|
None => None,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
impl<P: /* ~const */ Deref> /* const */ Deref for Pin<P> {
|
|
type Target = P::Target;
|
|
fn deref(&self) -> &P::Target {
|
|
Pin::get_ref(Pin::as_ref(self))
|
|
}
|
|
}
|
|
|
|
impl<T> /* const */ Deref for Option<T> {
|
|
type Target = T;
|
|
fn deref(&self) -> &T {
|
|
loop {}
|
|
}
|
|
}
|
|
|
|
impl<P: Receiver> Receiver for Pin<P> {}
|
|
|
|
impl<T: Clone> Clone for RefCell<T> {
|
|
fn clone(&self) -> RefCell<T> {
|
|
RefCell::new(self.borrow().clone())
|
|
}
|
|
}
|
|
|
|
struct RefCell<T: ?Sized> {
|
|
borrow: UnsafeCell<()>,
|
|
value: UnsafeCell<T>,
|
|
}
|
|
impl<T> RefCell<T> {
|
|
const fn new(value: T) -> RefCell<T> {
|
|
loop {}
|
|
}
|
|
}
|
|
impl<T: ?Sized> RefCell<T> {
|
|
fn borrow(&self) -> Ref<'_, T> {
|
|
loop {}
|
|
}
|
|
}
|
|
|
|
#[lang = "unsafe_cell"]
|
|
#[repr(transparent)]
|
|
struct UnsafeCell<T: ?Sized> {
|
|
value: T,
|
|
}
|
|
|
|
struct Ref<'b, T: ?Sized + 'b> {
|
|
value: *const T,
|
|
borrow: &'b UnsafeCell<()>,
|
|
}
|
|
|
|
impl<T: ?Sized> Deref for Ref<'_, T> {
|
|
type Target = T;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &T {
|
|
loop {}
|
|
}
|
|
}
|
|
|
|
#[lang = "clone"]
|
|
#[rustc_trivial_field_reads]
|
|
#[const_trait]
|
|
trait Clone: Sized {
|
|
fn clone(&self) -> Self;
|
|
fn clone_from(&mut self, source: &Self)
|
|
where
|
|
Self: ~const Destruct,
|
|
{
|
|
*self = source.clone()
|
|
}
|
|
}
|
|
|
|
#[lang = "structural_peq"]
|
|
trait StructuralPartialEq {}
|
|
|
|
#[lang = "structural_teq"]
|
|
trait StructuralEq {}
|
|
|
|
const fn drop<T: ~const Destruct>(_: T) {}
|