Skip to content

Commit

Permalink
beginning of MIR
Browse files Browse the repository at this point in the history
  • Loading branch information
HKalbasi committed Feb 27, 2023
1 parent b881deb commit cd67589
Show file tree
Hide file tree
Showing 41 changed files with 4,447 additions and 697 deletions.
10 changes: 9 additions & 1 deletion crates/hir-def/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,21 @@ pub type LabelId = Idx<Label>;
// We convert float values into bits and that's how we don't need to deal with f32 and f64.
// For PartialEq, bits comparison should work, as ordering is not important
// https://github.com/rust-lang/rust-analyzer/issues/12380#issuecomment-1137284360
#[derive(Default, Debug, Clone, Eq, PartialEq)]
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
pub struct FloatTypeWrapper(u64);

impl FloatTypeWrapper {
pub fn new(value: f64) -> Self {
Self(value.to_bits())
}

pub fn into_f64(self) -> f64 {
f64::from_bits(self.0)
}

pub fn into_f32(self) -> f32 {
f64::from_bits(self.0) as f32
}
}

impl fmt::Display for FloatTypeWrapper {
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-def/src/lang_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,15 @@ impl LangItems {
T: Into<AttrDefId> + Copy,
{
let _p = profile::span("collect_lang_item");
if let Some(lang_item) = lang_attr(db, item).and_then(|it| LangItem::from_str(&it)) {
if let Some(lang_item) = lang_attr(db, item) {
self.items.entry(lang_item).or_insert_with(|| constructor(item));
}
}
}

pub fn lang_attr(db: &dyn DefDatabase, item: impl Into<AttrDefId> + Copy) -> Option<SmolStr> {
pub fn lang_attr(db: &dyn DefDatabase, item: impl Into<AttrDefId> + Copy) -> Option<LangItem> {
let attrs = db.attrs(item.into());
attrs.by_key("lang").string_value().cloned()
attrs.by_key("lang").string_value().cloned().and_then(|it| LangItem::from_str(&it))
}

pub enum GenericRequirement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ macro_rules! assert {
fn main() {
{
if !true {
if !(true ) {
$crate::panic!("{} {:?}", arg1(a, b, c), arg2);
}
};
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-def/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{

use crate::{
body::LowerCtx,
type_ref::{ConstScalarOrPath, LifetimeRef},
type_ref::{ConstRefOrPath, LifetimeRef},
};
use hir_expand::name::Name;
use intern::Interned;
Expand Down Expand Up @@ -85,7 +85,7 @@ pub struct AssociatedTypeBinding {
pub enum GenericArg {
Type(TypeRef),
Lifetime(LifetimeRef),
Const(ConstScalarOrPath),
Const(ConstRefOrPath),
}

impl Path {
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-def/src/path/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::iter;

use crate::type_ref::ConstScalarOrPath;
use crate::type_ref::ConstRefOrPath;

use either::Either;
use hir_expand::name::{name, AsName};
Expand Down Expand Up @@ -212,7 +212,7 @@ pub(super) fn lower_generic_args(
}
}
ast::GenericArg::ConstArg(arg) => {
let arg = ConstScalarOrPath::from_expr_opt(arg.expr());
let arg = ConstRefOrPath::from_expr_opt(arg.expr());
args.push(GenericArg::Const(arg))
}
}
Expand Down
62 changes: 31 additions & 31 deletions crates/hir-def/src/type_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub enum TypeRef {
Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
// FIXME: for full const generics, the latter element (length) here is going to have to be an
// expression that is further lowered later in hir_ty.
Array(Box<TypeRef>, ConstScalarOrPath),
Array(Box<TypeRef>, ConstRefOrPath),
Slice(Box<TypeRef>),
/// A fn pointer. Last element of the vector is the return type.
Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
Expand Down Expand Up @@ -188,7 +188,7 @@ impl TypeRef {
// `hir_def::body::lower` to lower this into an `Expr` and then evaluate it at the
// `hir_ty` level, which would allow knowing the type of:
// let v: [u8; 2 + 2] = [0u8; 4];
let len = ConstScalarOrPath::from_expr_opt(inner.expr());
let len = ConstRefOrPath::from_expr_opt(inner.expr());
TypeRef::Array(Box::new(TypeRef::from_ast_opt(ctx, inner.ty())), len)
}
ast::Type::SliceType(inner) => {
Expand Down Expand Up @@ -378,25 +378,25 @@ impl TypeBound {
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ConstScalarOrPath {
Scalar(ConstScalar),
pub enum ConstRefOrPath {
Scalar(ConstRef),
Path(Name),
}

impl std::fmt::Display for ConstScalarOrPath {
impl std::fmt::Display for ConstRefOrPath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ConstScalarOrPath::Scalar(s) => s.fmt(f),
ConstScalarOrPath::Path(n) => n.fmt(f),
ConstRefOrPath::Scalar(s) => s.fmt(f),
ConstRefOrPath::Path(n) => n.fmt(f),
}
}
}

impl ConstScalarOrPath {
impl ConstRefOrPath {
pub(crate) fn from_expr_opt(expr: Option<ast::Expr>) -> Self {
match expr {
Some(x) => Self::from_expr(x),
None => Self::Scalar(ConstScalar::Unknown),
None => Self::Scalar(ConstRef::Unknown),
}
}

Expand All @@ -407,16 +407,16 @@ impl ConstScalarOrPath {
ast::Expr::PathExpr(p) => {
match p.path().and_then(|x| x.segment()).and_then(|x| x.name_ref()) {
Some(x) => Self::Path(x.as_name()),
None => Self::Scalar(ConstScalar::Unknown),
None => Self::Scalar(ConstRef::Unknown),
}
}
ast::Expr::PrefixExpr(prefix_expr) => match prefix_expr.op_kind() {
Some(ast::UnaryOp::Neg) => {
let unsigned = Self::from_expr_opt(prefix_expr.expr());
// Add sign
match unsigned {
Self::Scalar(ConstScalar::UInt(num)) => {
Self::Scalar(ConstScalar::Int(-(num as i128)))
Self::Scalar(ConstRef::UInt(num)) => {
Self::Scalar(ConstRef::Int(-(num as i128)))
}
other => other,
}
Expand All @@ -425,22 +425,22 @@ impl ConstScalarOrPath {
},
ast::Expr::Literal(literal) => Self::Scalar(match literal.kind() {
ast::LiteralKind::IntNumber(num) => {
num.value().map(ConstScalar::UInt).unwrap_or(ConstScalar::Unknown)
num.value().map(ConstRef::UInt).unwrap_or(ConstRef::Unknown)
}
ast::LiteralKind::Char(c) => {
c.value().map(ConstScalar::Char).unwrap_or(ConstScalar::Unknown)
c.value().map(ConstRef::Char).unwrap_or(ConstRef::Unknown)
}
ast::LiteralKind::Bool(f) => ConstScalar::Bool(f),
_ => ConstScalar::Unknown,
ast::LiteralKind::Bool(f) => ConstRef::Bool(f),
_ => ConstRef::Unknown,
}),
_ => Self::Scalar(ConstScalar::Unknown),
_ => Self::Scalar(ConstRef::Unknown),
}
}
}

/// A concrete constant value
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ConstScalar {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ConstRef {
Int(i128),
UInt(u128),
Bool(bool),
Expand All @@ -454,18 +454,18 @@ pub enum ConstScalar {
Unknown,
}

impl ConstScalar {
impl ConstRef {
pub fn builtin_type(&self) -> BuiltinType {
match self {
ConstScalar::UInt(_) | ConstScalar::Unknown => BuiltinType::Uint(BuiltinUint::U128),
ConstScalar::Int(_) => BuiltinType::Int(BuiltinInt::I128),
ConstScalar::Char(_) => BuiltinType::Char,
ConstScalar::Bool(_) => BuiltinType::Bool,
ConstRef::UInt(_) | ConstRef::Unknown => BuiltinType::Uint(BuiltinUint::U128),
ConstRef::Int(_) => BuiltinType::Int(BuiltinInt::I128),
ConstRef::Char(_) => BuiltinType::Char,
ConstRef::Bool(_) => BuiltinType::Bool,
}
}
}

impl From<Literal> for ConstScalar {
impl From<Literal> for ConstRef {
fn from(literal: Literal) -> Self {
match literal {
Literal::Char(c) => Self::Char(c),
Expand All @@ -477,14 +477,14 @@ impl From<Literal> for ConstScalar {
}
}

impl std::fmt::Display for ConstScalar {
impl std::fmt::Display for ConstRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
ConstScalar::Int(num) => num.fmt(f),
ConstScalar::UInt(num) => num.fmt(f),
ConstScalar::Bool(flag) => flag.fmt(f),
ConstScalar::Char(c) => write!(f, "'{c}'"),
ConstScalar::Unknown => f.write_char('_'),
ConstRef::Int(num) => num.fmt(f),
ConstRef::UInt(num) => num.fmt(f),
ConstRef::Bool(flag) => flag.fmt(f),
ConstRef::Char(c) => write!(f, "'{c}'"),
ConstRef::Unknown => f.write_char('_'),
}
}
}
2 changes: 1 addition & 1 deletion crates/hir-expand/src/builtin_fn_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ fn assert_expand(
let cond = cond.clone();
let panic_args = itertools::Itertools::intersperse(panic_args.iter().cloned(), comma);
quote! {{
if !#cond {
if !(#cond) {
#DOLLAR_CRATE::panic!(##panic_args);
}
}}
Expand Down
9 changes: 9 additions & 0 deletions crates/hir-ty/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ impl TyBuilder<()> {
TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner)
}

// FIXME: rustc's ty is dependent on the adt type, maybe we need to do that as well
pub fn discr_ty() -> Ty {
TyKind::Scalar(chalk_ir::Scalar::Int(chalk_ir::IntTy::I128)).intern(Interner)
}

pub fn bool() -> Ty {
TyKind::Scalar(chalk_ir::Scalar::Bool).intern(Interner)
}

pub fn usize() -> Ty {
TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)).intern(Interner)
}
Expand Down
3 changes: 1 addition & 2 deletions crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,7 @@ pub(crate) fn trait_datum_query(
let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
let associated_ty_ids = trait_data.associated_types().map(to_assoc_type_id).collect();
let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses };
let well_known = lang_attr(db.upcast(), trait_)
.and_then(|name| well_known_trait_from_lang_item(LangItem::from_str(&name)?));
let well_known = lang_attr(db.upcast(), trait_).and_then(well_known_trait_from_lang_item);
let trait_datum = TraitDatum {
id: trait_id,
binders: make_binders(db, &generic_params, trait_datum_bound),
Expand Down
Loading

0 comments on commit cd67589

Please sign in to comment.