Add all types u8 -> i128 and fix signedness in icmp
This commit is contained in:
parent
14283afe59
commit
46560d8541
@ -260,9 +260,17 @@ impl ConstValue {
|
|||||||
pub fn get_type(&self) -> Type {
|
pub fn get_type(&self) -> Type {
|
||||||
use Type::*;
|
use Type::*;
|
||||||
match self {
|
match self {
|
||||||
ConstValue::I32(_) => I32,
|
ConstValue::I8(_) => I8,
|
||||||
ConstValue::I16(_) => I16,
|
ConstValue::I16(_) => I16,
|
||||||
|
ConstValue::I32(_) => I32,
|
||||||
|
ConstValue::I64(_) => I64,
|
||||||
|
ConstValue::I128(_) => I128,
|
||||||
|
ConstValue::U8(_) => U8,
|
||||||
|
ConstValue::U16(_) => U16,
|
||||||
ConstValue::U32(_) => U32,
|
ConstValue::U32(_) => U32,
|
||||||
|
ConstValue::U64(_) => U64,
|
||||||
|
ConstValue::U128(_) => U128,
|
||||||
|
ConstValue::Bool(_) => Bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,9 +278,16 @@ impl ConstValue {
|
|||||||
impl Type {
|
impl Type {
|
||||||
pub fn comparable(&self) -> bool {
|
pub fn comparable(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Type::I32 => true,
|
Type::I8 => true,
|
||||||
Type::I16 => true,
|
Type::I16 => true,
|
||||||
|
Type::I32 => true,
|
||||||
|
Type::I64 => true,
|
||||||
|
Type::I128 => true,
|
||||||
|
Type::U8 => true,
|
||||||
|
Type::U16 => true,
|
||||||
Type::U32 => true,
|
Type::U32 => true,
|
||||||
|
Type::U64 => true,
|
||||||
|
Type::U128 => true,
|
||||||
Type::Bool => true,
|
Type::Bool => true,
|
||||||
Type::Void => false,
|
Type::Void => false,
|
||||||
}
|
}
|
||||||
@ -280,9 +295,16 @@ impl Type {
|
|||||||
|
|
||||||
pub fn signed(&self) -> bool {
|
pub fn signed(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Type::I32 => true,
|
Type::I8 => true,
|
||||||
Type::I16 => true,
|
Type::I16 => true,
|
||||||
|
Type::I32 => true,
|
||||||
|
Type::I64 => true,
|
||||||
|
Type::I128 => true,
|
||||||
|
Type::U8 => false,
|
||||||
|
Type::U16 => false,
|
||||||
Type::U32 => false,
|
Type::U32 => false,
|
||||||
|
Type::U64 => false,
|
||||||
|
Type::U128 => false,
|
||||||
Type::Bool => false,
|
Type::Bool => false,
|
||||||
Type::Void => false,
|
Type::Void => false,
|
||||||
}
|
}
|
||||||
|
@ -264,12 +264,13 @@ impl InstructionHolder {
|
|||||||
LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, c"sub".as_ptr())
|
LLVMBuildSub(module.builder_ref, lhs_val, rhs_val, c"sub".as_ptr())
|
||||||
}
|
}
|
||||||
ICmp(pred, lhs, rhs) => {
|
ICmp(pred, lhs, rhs) => {
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
let lhs = module.values.get(&lhs).unwrap();
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
||||||
LLVMBuildICmp(
|
LLVMBuildICmp(
|
||||||
module.builder_ref,
|
module.builder_ref,
|
||||||
pred.as_llvm(_ty.signed()),
|
// Signedness from LHS
|
||||||
lhs_val,
|
pred.as_llvm(lhs._ty.signed()),
|
||||||
|
lhs.value_ref,
|
||||||
rhs_val,
|
rhs_val,
|
||||||
c"icmp".as_ptr(),
|
c"icmp".as_ptr(),
|
||||||
)
|
)
|
||||||
@ -370,9 +371,17 @@ impl ConstValue {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let t = self.get_type().as_llvm(context);
|
let t = self.get_type().as_llvm(context);
|
||||||
match *self {
|
match *self {
|
||||||
ConstValue::I32(val) => LLVMConstInt(t, val as u64, 1),
|
ConstValue::Bool(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::I8(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
ConstValue::I16(val) => LLVMConstInt(t, val as u64, 1),
|
ConstValue::I16(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
ConstValue::U32(val) => LLVMConstInt(t, val as u64, 0),
|
ConstValue::I32(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::I64(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::I128(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::U8(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::U16(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::U32(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::U64(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
|
ConstValue::U128(val) => LLVMConstInt(t, val as u64, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -380,13 +389,16 @@ impl ConstValue {
|
|||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
fn as_llvm(&self, context: LLVMContextRef) -> LLVMTypeRef {
|
fn as_llvm(&self, context: LLVMContextRef) -> LLVMTypeRef {
|
||||||
|
use Type::*;
|
||||||
unsafe {
|
unsafe {
|
||||||
match self {
|
match self {
|
||||||
Type::I32 => LLVMInt32TypeInContext(context),
|
I8 | U8 => LLVMInt8TypeInContext(context),
|
||||||
Type::I16 => LLVMInt16TypeInContext(context),
|
I16 | U16 => LLVMInt16TypeInContext(context),
|
||||||
Type::U32 => LLVMInt32TypeInContext(context),
|
I32 | U32 => LLVMInt32TypeInContext(context),
|
||||||
Type::Bool => LLVMInt1TypeInContext(context),
|
I64 | U64 => LLVMInt64TypeInContext(context),
|
||||||
Type::Void => LLVMVoidType(),
|
I128 | U128 => LLVMInt128TypeInContext(context),
|
||||||
|
Bool => LLVMInt1TypeInContext(context),
|
||||||
|
Void => LLVMVoidType(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,18 +158,33 @@ pub enum InstructionKind {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
I32,
|
I8,
|
||||||
I16,
|
I16,
|
||||||
|
I32,
|
||||||
|
I64,
|
||||||
|
I128,
|
||||||
|
U8,
|
||||||
|
U16,
|
||||||
U32,
|
U32,
|
||||||
|
U64,
|
||||||
|
U128,
|
||||||
Bool,
|
Bool,
|
||||||
Void,
|
Void,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
pub enum ConstValue {
|
pub enum ConstValue {
|
||||||
I32(i32),
|
I8(i8),
|
||||||
I16(i16),
|
I16(i16),
|
||||||
|
I32(i32),
|
||||||
|
I64(i64),
|
||||||
|
I128(i128),
|
||||||
|
U8(u8),
|
||||||
|
U16(u16),
|
||||||
U32(u32),
|
U32(u32),
|
||||||
|
U64(u64),
|
||||||
|
U128(u128),
|
||||||
|
Bool(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Hash)]
|
#[derive(Clone, Hash)]
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
// Main
|
// Main
|
||||||
fn main() -> i32 {
|
fn main() -> u8 {
|
||||||
let a = fibonacci(3);
|
let a = fibonacci(3);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fibonacci
|
// Fibonacci
|
||||||
fn fibonacci(value: i32) -> i32 {
|
fn fibonacci(value: u8) -> u8 {
|
||||||
if value < 3 {
|
if value < 3 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,17 @@ pub struct Type(pub TypeKind, pub TokenRange);
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum TypeKind {
|
pub enum TypeKind {
|
||||||
|
Bool,
|
||||||
|
I8,
|
||||||
|
I16,
|
||||||
I32,
|
I32,
|
||||||
|
I64,
|
||||||
|
I128,
|
||||||
|
U8,
|
||||||
|
U16,
|
||||||
|
U32,
|
||||||
|
U64,
|
||||||
|
U128,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -15,7 +15,17 @@ impl Parse for Type {
|
|||||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||||
let kind = if let Some(Token::Identifier(ident)) = stream.next() {
|
let kind = if let Some(Token::Identifier(ident)) = stream.next() {
|
||||||
Ok(match &*ident {
|
Ok(match &*ident {
|
||||||
|
"bool" => TypeKind::Bool,
|
||||||
|
"i8" => TypeKind::I8,
|
||||||
|
"i16" => TypeKind::I16,
|
||||||
"i32" => TypeKind::I32,
|
"i32" => TypeKind::I32,
|
||||||
|
"i64" => TypeKind::I64,
|
||||||
|
"i128" => TypeKind::I128,
|
||||||
|
"u8" => TypeKind::U8,
|
||||||
|
"u16" => TypeKind::U16,
|
||||||
|
"u32" => TypeKind::U32,
|
||||||
|
"u64" => TypeKind::U64,
|
||||||
|
"u128" => TypeKind::U128,
|
||||||
_ => panic!("asd"),
|
_ => panic!("asd"),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,7 +168,17 @@ impl ast::Literal {
|
|||||||
impl From<ast::TypeKind> for mir::TypeKind {
|
impl From<ast::TypeKind> for mir::TypeKind {
|
||||||
fn from(value: ast::TypeKind) -> Self {
|
fn from(value: ast::TypeKind) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
ast::TypeKind::Bool => mir::TypeKind::Bool,
|
||||||
|
ast::TypeKind::I8 => mir::TypeKind::I8,
|
||||||
|
ast::TypeKind::I16 => mir::TypeKind::I16,
|
||||||
ast::TypeKind::I32 => mir::TypeKind::I32,
|
ast::TypeKind::I32 => mir::TypeKind::I32,
|
||||||
|
ast::TypeKind::I64 => mir::TypeKind::I64,
|
||||||
|
ast::TypeKind::I128 => mir::TypeKind::I128,
|
||||||
|
ast::TypeKind::U8 => mir::TypeKind::U8,
|
||||||
|
ast::TypeKind::U16 => mir::TypeKind::U16,
|
||||||
|
ast::TypeKind::U32 => mir::TypeKind::U32,
|
||||||
|
ast::TypeKind::U64 => mir::TypeKind::U64,
|
||||||
|
ast::TypeKind::U128 => mir::TypeKind::U128,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,8 +323,16 @@ impl mir::Literal {
|
|||||||
|
|
||||||
pub fn as_const_kind(&self) -> InstructionKind {
|
pub fn as_const_kind(&self) -> InstructionKind {
|
||||||
InstructionKind::Constant(match *self {
|
InstructionKind::Constant(match *self {
|
||||||
mir::Literal::I32(val) => ConstValue::I32(val),
|
mir::Literal::I8(val) => ConstValue::I8(val),
|
||||||
mir::Literal::I16(val) => ConstValue::I16(val),
|
mir::Literal::I16(val) => ConstValue::I16(val),
|
||||||
|
mir::Literal::I32(val) => ConstValue::I32(val),
|
||||||
|
mir::Literal::I64(val) => ConstValue::I64(val),
|
||||||
|
mir::Literal::I128(val) => ConstValue::I128(val),
|
||||||
|
mir::Literal::U8(val) => ConstValue::U8(val),
|
||||||
|
mir::Literal::U16(val) => ConstValue::U16(val),
|
||||||
|
mir::Literal::U32(val) => ConstValue::U32(val),
|
||||||
|
mir::Literal::U64(val) => ConstValue::U64(val),
|
||||||
|
mir::Literal::U128(val) => ConstValue::U128(val),
|
||||||
mir::Literal::Vague(_) => panic!("Got vague literal!"),
|
mir::Literal::Vague(_) => panic!("Got vague literal!"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -333,8 +341,16 @@ impl mir::Literal {
|
|||||||
impl TypeKind {
|
impl TypeKind {
|
||||||
fn get_type(&self) -> Type {
|
fn get_type(&self) -> Type {
|
||||||
match &self {
|
match &self {
|
||||||
TypeKind::I32 => Type::I32,
|
TypeKind::I8 => Type::I8,
|
||||||
TypeKind::I16 => Type::I16,
|
TypeKind::I16 => Type::I16,
|
||||||
|
TypeKind::I32 => Type::I32,
|
||||||
|
TypeKind::I64 => Type::I64,
|
||||||
|
TypeKind::I128 => Type::I128,
|
||||||
|
TypeKind::U8 => Type::U8,
|
||||||
|
TypeKind::U16 => Type::U16,
|
||||||
|
TypeKind::U32 => Type::U32,
|
||||||
|
TypeKind::U64 => Type::U64,
|
||||||
|
TypeKind::U128 => Type::U128,
|
||||||
TypeKind::Bool => Type::Bool,
|
TypeKind::Bool => Type::Bool,
|
||||||
TypeKind::Void => panic!("Void not a supported type"),
|
TypeKind::Void => panic!("Void not a supported type"),
|
||||||
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
|
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
|
||||||
|
@ -36,12 +36,28 @@ impl From<TokenRange> for Metadata {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
|
||||||
pub enum TypeKind {
|
pub enum TypeKind {
|
||||||
#[error("i32")]
|
|
||||||
I32,
|
|
||||||
#[error("i16")]
|
|
||||||
I16,
|
|
||||||
#[error("bool")]
|
#[error("bool")]
|
||||||
Bool,
|
Bool,
|
||||||
|
#[error("i8")]
|
||||||
|
I8,
|
||||||
|
#[error("i16")]
|
||||||
|
I16,
|
||||||
|
#[error("i32")]
|
||||||
|
I32,
|
||||||
|
#[error("i64")]
|
||||||
|
I64,
|
||||||
|
#[error("i128")]
|
||||||
|
I128,
|
||||||
|
#[error("u8")]
|
||||||
|
U8,
|
||||||
|
#[error("u16")]
|
||||||
|
U16,
|
||||||
|
#[error("u32")]
|
||||||
|
U32,
|
||||||
|
#[error("u64")]
|
||||||
|
U64,
|
||||||
|
#[error("u128")]
|
||||||
|
U128,
|
||||||
#[error("void")]
|
#[error("void")]
|
||||||
Void,
|
Void,
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
@ -71,15 +87,33 @@ impl TypeKind {
|
|||||||
match self {
|
match self {
|
||||||
TypeKind::Void => false,
|
TypeKind::Void => false,
|
||||||
TypeKind::Vague(_) => false,
|
TypeKind::Vague(_) => false,
|
||||||
_ => true,
|
TypeKind::Bool => false,
|
||||||
|
TypeKind::I8 => false,
|
||||||
|
TypeKind::I16 => false,
|
||||||
|
TypeKind::I32 => false,
|
||||||
|
TypeKind::I64 => false,
|
||||||
|
TypeKind::I128 => false,
|
||||||
|
TypeKind::U8 => false,
|
||||||
|
TypeKind::U16 => false,
|
||||||
|
TypeKind::U32 => false,
|
||||||
|
TypeKind::U64 => false,
|
||||||
|
TypeKind::U128 => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_maths(&self) -> bool {
|
pub fn is_maths(&self) -> bool {
|
||||||
use TypeKind::*;
|
use TypeKind::*;
|
||||||
match &self {
|
match &self {
|
||||||
I32 => true,
|
I8 => true,
|
||||||
I16 => true,
|
I16 => true,
|
||||||
|
I32 => true,
|
||||||
|
I64 => true,
|
||||||
|
I128 => true,
|
||||||
|
U8 => true,
|
||||||
|
U16 => true,
|
||||||
|
U32 => true,
|
||||||
|
U64 => true,
|
||||||
|
U128 => true,
|
||||||
Bool => true,
|
Bool => true,
|
||||||
Vague(_) => false,
|
Vague(_) => false,
|
||||||
Void => false,
|
Void => false,
|
||||||
@ -89,8 +123,16 @@ impl TypeKind {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
I32(i32),
|
I8(i8),
|
||||||
I16(i16),
|
I16(i16),
|
||||||
|
I32(i32),
|
||||||
|
I64(i64),
|
||||||
|
I128(i128),
|
||||||
|
U8(u8),
|
||||||
|
U16(u16),
|
||||||
|
U32(u32),
|
||||||
|
U64(u64),
|
||||||
|
U128(u128),
|
||||||
Vague(VagueLiteral),
|
Vague(VagueLiteral),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +144,16 @@ pub enum VagueLiteral {
|
|||||||
impl Literal {
|
impl Literal {
|
||||||
pub fn as_type(self: &Literal) -> TypeKind {
|
pub fn as_type(self: &Literal) -> TypeKind {
|
||||||
match self {
|
match self {
|
||||||
Literal::I32(_) => TypeKind::I32,
|
Literal::I8(_) => TypeKind::I8,
|
||||||
Literal::I16(_) => TypeKind::I16,
|
Literal::I16(_) => TypeKind::I16,
|
||||||
|
Literal::I32(_) => TypeKind::I32,
|
||||||
|
Literal::I64(_) => TypeKind::I64,
|
||||||
|
Literal::I128(_) => TypeKind::I128,
|
||||||
|
Literal::U8(_) => TypeKind::U8,
|
||||||
|
Literal::U16(_) => TypeKind::U16,
|
||||||
|
Literal::U32(_) => TypeKind::U32,
|
||||||
|
Literal::U64(_) => TypeKind::U64,
|
||||||
|
Literal::U128(_) => TypeKind::U128,
|
||||||
Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number),
|
Literal::Vague(VagueLiteral::Number(_)) => TypeKind::Vague(VagueType::Number),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,10 +244,26 @@ impl Literal {
|
|||||||
use Literal as L;
|
use Literal as L;
|
||||||
use VagueLiteral as VagueL;
|
use VagueLiteral as VagueL;
|
||||||
Ok(match (self, hint) {
|
Ok(match (self, hint) {
|
||||||
(L::I32(_), I32) => self,
|
(L::I8(_), I8) => self,
|
||||||
(L::I16(_), I16) => self,
|
(L::I16(_), I16) => self,
|
||||||
(L::Vague(VagueL::Number(v)), I32) => L::I32(v as i32),
|
(L::I32(_), I32) => self,
|
||||||
|
(L::I64(_), I64) => self,
|
||||||
|
(L::I128(_), I128) => self,
|
||||||
|
(L::U8(_), U8) => self,
|
||||||
|
(L::U16(_), U16) => self,
|
||||||
|
(L::U32(_), U32) => self,
|
||||||
|
(L::U64(_), U64) => self,
|
||||||
|
(L::U128(_), U128) => self,
|
||||||
|
(L::Vague(VagueL::Number(v)), I8) => L::I8(v as i8),
|
||||||
(L::Vague(VagueL::Number(v)), I16) => L::I16(v as i16),
|
(L::Vague(VagueL::Number(v)), I16) => L::I16(v as i16),
|
||||||
|
(L::Vague(VagueL::Number(v)), I32) => L::I32(v as i32),
|
||||||
|
(L::Vague(VagueL::Number(v)), I64) => L::I64(v as i64),
|
||||||
|
(L::Vague(VagueL::Number(v)), I128) => L::I128(v as i128),
|
||||||
|
(L::Vague(VagueL::Number(v)), U8) => L::U8(v as u8),
|
||||||
|
(L::Vague(VagueL::Number(v)), U16) => L::U16(v as u16),
|
||||||
|
(L::Vague(VagueL::Number(v)), U32) => L::U32(v as u32),
|
||||||
|
(L::Vague(VagueL::Number(v)), U64) => L::U64(v as u64),
|
||||||
|
(L::Vague(VagueL::Number(v)), U128) => L::U128(v as u128),
|
||||||
// Default type for number literal if unable to find true type.
|
// Default type for number literal if unable to find true type.
|
||||||
(L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32),
|
(L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32),
|
||||||
(_, Vague(_)) => self,
|
(_, Vague(_)) => self,
|
||||||
@ -310,8 +326,7 @@ impl Collapsable for TypeKind {
|
|||||||
(Vague(Number), other) | (other, Vague(Number)) => match other {
|
(Vague(Number), other) | (other, Vague(Number)) => match other {
|
||||||
Vague(Unknown) => Ok(Vague(Number)),
|
Vague(Unknown) => Ok(Vague(Number)),
|
||||||
Vague(Number) => Ok(Vague(Number)),
|
Vague(Number) => Ok(Vague(Number)),
|
||||||
I32 => Ok(I32),
|
I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => Ok(*other),
|
||||||
I16 => Ok(I16),
|
|
||||||
_ => Err(ErrorKind::TypesIncompatible(*self, *other)),
|
_ => Err(ErrorKind::TypesIncompatible(*self, *other)),
|
||||||
},
|
},
|
||||||
(Vague(Unknown), other) | (other, Vague(Unknown)) => Ok(other.clone()),
|
(Vague(Unknown), other) | (other, Vague(Unknown)) => Ok(other.clone()),
|
||||||
|
Loading…
Reference in New Issue
Block a user