Skip to content

Commit

Permalink
Support range MIR lowering
Browse files Browse the repository at this point in the history
  • Loading branch information
HKalbasi committed Mar 17, 2023
1 parent 9ad83de commit 558c896
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
13 changes: 13 additions & 0 deletions crates/hir-ty/src/consteval/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,19 @@ fn for_loops() {
);
}

#[test]
fn ranges() {
check_number(
r#"
//- minicore: range
const GOAL: i32 = (1..2).start + (20..10).end + (100..=200).start + (2000..=1000).end
+ (10000..).start + (..100000).end + (..=1000000).end;
"#,
1111111,
);
}


#[test]
fn recursion() {
check_number(
Expand Down
9 changes: 6 additions & 3 deletions crates/hir-ty/src/infer/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,15 +633,18 @@ impl<'a> InferenceTable<'a> {
) -> Option<(Option<FnTrait>, Vec<Ty>, Ty)> {
match ty.callable_sig(self.db) {
Some(sig) => Some((None, sig.params().to_vec(), sig.ret().clone())),
None => self.callable_sig_from_fn_trait(ty, num_args),
None => {
let (f, args_ty, return_ty) = self.callable_sig_from_fn_trait(ty, num_args)?;
Some((Some(f), args_ty, return_ty))
}
}
}

fn callable_sig_from_fn_trait(
&mut self,
ty: &Ty,
num_args: usize,
) -> Option<(Option<FnTrait>, Vec<Ty>, Ty)> {
) -> Option<(FnTrait, Vec<Ty>, Ty)> {
let krate = self.trait_env.krate;
let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
let trait_data = self.db.trait_data(fn_once_trait);
Expand Down Expand Up @@ -693,7 +696,7 @@ impl<'a> InferenceTable<'a> {
};
let canonical = self.canonicalize(obligation.clone());
if self.db.trait_solve(krate, canonical.value.cast(Interner)).is_some() {
return Some((Some(fn_x), arg_tys, return_ty));
return Some((fn_x, arg_tys, return_ty));
}
}
unreachable!("It should at least implement FnOnce at this point");
Expand Down
49 changes: 46 additions & 3 deletions crates/hir-ty/src/mir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use hir_def::{
layout::LayoutError,
path::Path,
resolver::{resolver_for_expr, ResolveValueResult, ValueNs},
DefWithBodyId, EnumVariantId, HasModule, ItemContainerId, LocalFieldId, TraitId,
DefWithBodyId, EnumVariantId, HasModule, ItemContainerId, LocalFieldId, TraitId, AdtId,
};
use hir_expand::name::Name;
use la_arena::ArenaMap;
Expand Down Expand Up @@ -643,7 +643,7 @@ impl MirLowerCtx<'_> {
},
}
}).collect(),
None => operands.into_iter().map(|x| x).collect::<Option<_>>().ok_or(
None => operands.into_iter().collect::<Option<_>>().ok_or(
MirLowerError::TypeError("missing field in record literal"),
)?,
},
Expand Down Expand Up @@ -761,7 +761,50 @@ impl MirLowerCtx<'_> {
);
Ok(Some(current))
}
Expr::Range { .. } => not_supported!("range"),
&Expr::Range { lhs, rhs, range_type: _ } => {
let ty = self.expr_ty(expr_id);
let Some((adt, subst)) = ty.as_adt() else {
dbg!(&ty);
return Err(MirLowerError::TypeError("Range type is not adt"));
};
let AdtId::StructId(st) = adt else {
return Err(MirLowerError::TypeError("Range type is not struct"));
};
let mut lp = None;
let mut rp = None;
if let Some(x) = lhs {
let Some((o, c)) = self.lower_expr_to_some_operand(x, current)? else {
return Ok(None);
};
lp = Some(o);
current = c;
}
if let Some(x) = rhs {
let Some((o, c)) = self.lower_expr_to_some_operand(x, current)? else {
return Ok(None);
};
rp = Some(o);
current = c;
}
self.push_assignment(
current,
place,
Rvalue::Aggregate(
AggregateKind::Adt(st.into(), subst.clone()),
self.db.struct_data(st).variant_data.fields().iter().map(|x| {
let o = match x.1.name.as_str() {
Some("start") => lp.take(),
Some("end") => rp.take(),
Some("exhausted") => Some(Operand::from_bytes(vec![0], TyBuilder::bool())),
_ => None,
};
o.ok_or(MirLowerError::UnresolvedField)
}).collect::<Result<_>>()?,
),
expr_id.into(),
);
Ok(Some(current))
},
Expr::Closure { .. } => not_supported!("closure"),
Expr::Tuple { exprs, is_assignee_expr: _ } => {
let Some(values) = exprs
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,15 @@ impl FnTrait {
}
}

pub fn method_name(&self) -> Name {
pub fn method_name(self) -> Name {
match self {
FnTrait::FnOnce => name!(call_once),
FnTrait::FnMut => name!(call_mut),
FnTrait::Fn => name!(call),
}
}

pub fn get_id(&self, db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
pub fn get_id(self, db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
let target = db.lang_item(krate, self.lang_item())?;
match target {
LangItemTarget::Trait(t) => Some(t),
Expand Down

0 comments on commit 558c896

Please sign in to comment.