Add TyBuilder::unit() and TyExt::is_unit()

This commit is contained in:
Florian Diebold 2021-04-03 20:22:59 +02:00
parent b15152c430
commit b0fe3d929f
7 changed files with 39 additions and 25 deletions

View file

@ -0,0 +1,13 @@
//! Various extensions traits for Chalk types.
use crate::{Interner, Ty, TyKind};
pub trait TyExt {
fn is_unit(&self) -> bool;
}
impl TyExt for Ty {
fn is_unit(&self) -> bool {
matches!(self.kind(&Interner), TyKind::Tuple(0, _))
}
}

View file

@ -15,7 +15,7 @@ use crate::{
MissingPatFields, RemoveThisSemicolon, MissingPatFields, RemoveThisSemicolon,
}, },
utils::variant_data, utils::variant_data,
AdtId, InferenceResult, Interner, Ty, TyKind, AdtId, InferenceResult, Interner, TyExt, TyKind,
}; };
pub(crate) use hir_def::{ pub(crate) use hir_def::{
@ -423,7 +423,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
None => return, None => return,
}; };
if mismatch.actual != Ty::unit() || mismatch.expected != *possible_tail_ty { if !mismatch.actual.is_unit() || mismatch.expected != *possible_tail_ty {
return; return;
} }

View file

@ -19,7 +19,8 @@ use crate::{
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy, CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy,
ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyExt, TyKind,
WhereClause,
}; };
pub struct HirFormatter<'a> { pub struct HirFormatter<'a> {
@ -423,7 +424,7 @@ impl HirDisplay for Ty {
f.write_joined(sig.params(), ", ")?; f.write_joined(sig.params(), ", ")?;
write!(f, ")")?; write!(f, ")")?;
let ret = sig.ret(); let ret = sig.ret();
if *ret != Ty::unit() { if !ret.is_unit() {
let ret_display = ret.into_displayable( let ret_display = ret.into_displayable(
f.db, f.db,
f.max_size, f.max_size,
@ -663,7 +664,7 @@ impl HirDisplay for CallableSig {
} }
write!(f, ")")?; write!(f, ")")?;
let ret = self.ret(); let ret = self.ret();
if *ret != Ty::unit() { if !ret.is_unit() {
let ret_display = let ret_display =
ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
write!(f, " -> {}", ret_display)?; write!(f, " -> {}", ret_display)?;

View file

@ -23,7 +23,7 @@ use crate::{
traits::{chalk::from_chalk, FnTrait, InEnvironment}, traits::{chalk::from_chalk, FnTrait, InEnvironment},
utils::{generics, variant_data, Generics}, utils::{generics, variant_data, Generics},
AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar,
Substitution, TraitRef, Ty, TyKind, Substitution, TraitRef, Ty, TyBuilder, TyKind,
}; };
use super::{ use super::{
@ -138,7 +138,7 @@ impl<'a> InferenceContext<'a> {
both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
let else_ty = match else_branch { let else_ty = match else_branch {
Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
None => Ty::unit(), None => TyBuilder::unit(),
}; };
both_arms_diverge &= self.diverges; both_arms_diverge &= self.diverges;
@ -193,7 +193,7 @@ impl<'a> InferenceContext<'a> {
break_ty: self.table.new_type_var(), break_ty: self.table.new_type_var(),
label: label.map(|label| self.body[label].name.clone()), label: label.map(|label| self.body[label].name.clone()),
}); });
self.infer_expr(*body, &Expectation::has_type(Ty::unit())); self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
let ctxt = self.breakables.pop().expect("breakable stack broken"); let ctxt = self.breakables.pop().expect("breakable stack broken");
if ctxt.may_break { if ctxt.may_break {
@ -217,11 +217,11 @@ impl<'a> InferenceContext<'a> {
*condition, *condition,
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
); );
self.infer_expr(*body, &Expectation::has_type(Ty::unit())); self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
let _ctxt = self.breakables.pop().expect("breakable stack broken"); let _ctxt = self.breakables.pop().expect("breakable stack broken");
// the body may not run, so it diverging doesn't mean we diverge // the body may not run, so it diverging doesn't mean we diverge
self.diverges = Diverges::Maybe; self.diverges = Diverges::Maybe;
Ty::unit() TyBuilder::unit()
} }
Expr::For { iterable, body, pat, label } => { Expr::For { iterable, body, pat, label } => {
let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@ -236,11 +236,11 @@ impl<'a> InferenceContext<'a> {
self.infer_pat(*pat, &pat_ty, BindingMode::default()); self.infer_pat(*pat, &pat_ty, BindingMode::default());
self.infer_expr(*body, &Expectation::has_type(Ty::unit())); self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
let _ctxt = self.breakables.pop().expect("breakable stack broken"); let _ctxt = self.breakables.pop().expect("breakable stack broken");
// the body may not run, so it diverging doesn't mean we diverge // the body may not run, so it diverging doesn't mean we diverge
self.diverges = Diverges::Maybe; self.diverges = Diverges::Maybe;
Ty::unit() TyBuilder::unit()
} }
Expr::Lambda { body, args, ret_type, arg_types } => { Expr::Lambda { body, args, ret_type, arg_types } => {
assert_eq!(args.len(), arg_types.len()); assert_eq!(args.len(), arg_types.len());
@ -360,7 +360,7 @@ impl<'a> InferenceContext<'a> {
let val_ty = if let Some(expr) = expr { let val_ty = if let Some(expr) = expr {
self.infer_expr(*expr, &Expectation::none()) self.infer_expr(*expr, &Expectation::none())
} else { } else {
Ty::unit() TyBuilder::unit()
}; };
let last_ty = let last_ty =
@ -386,7 +386,7 @@ impl<'a> InferenceContext<'a> {
if let Some(expr) = expr { if let Some(expr) = expr {
self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
} else { } else {
let unit = Ty::unit(); let unit = TyBuilder::unit();
self.coerce(&unit, &self.return_ty.clone()); self.coerce(&unit, &self.return_ty.clone());
} }
TyKind::Never.intern(&Interner) TyKind::Never.intern(&Interner)
@ -828,8 +828,8 @@ impl<'a> InferenceContext<'a> {
// we don't even make an attempt at coercion // we don't even make an attempt at coercion
self.table.new_maybe_never_var() self.table.new_maybe_never_var()
} else { } else {
self.coerce(&Ty::unit(), &expected.coercion_target()); self.coerce(&TyBuilder::unit(), &expected.coercion_target());
Ty::unit() TyBuilder::unit()
} }
}; };
ty ty

View file

@ -23,6 +23,7 @@ pub mod diagnostics;
mod tests; mod tests;
#[cfg(test)] #[cfg(test)]
mod test_db; mod test_db;
mod chalk_ext;
use std::{iter, mem, sync::Arc}; use std::{iter, mem, sync::Arc};
@ -42,6 +43,7 @@ use crate::{
}; };
pub use autoderef::autoderef; pub use autoderef::autoderef;
pub use chalk_ext::TyExt;
pub use infer::{could_unify, InferenceResult, InferenceVar}; pub use infer::{could_unify, InferenceResult, InferenceVar};
pub use lower::{ pub use lower::{
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
@ -813,14 +815,12 @@ impl TypeWalk for CallableSig {
struct TyBuilder {} struct TyBuilder {}
impl TyBuilder { impl TyBuilder {
pub fn unit() -> Ty {
TyKind::Tuple(0, Substitution::empty(&Interner)).intern(&Interner)
}
} }
impl Ty { impl Ty {
pub fn unit() -> Self {
TyKind::Tuple(0, Substitution::empty(&Interner)).intern(&Interner)
}
pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty { pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty {
TyKind::Adt(AdtId(adt), substs).intern(&Interner) TyKind::Adt(AdtId(adt), substs).intern(&Interner)
} }

View file

@ -2,12 +2,12 @@
use chalk_ir::TyVariableKind; use chalk_ir::TyVariableKind;
use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
use crate::{Interner, Scalar, Ty, TyKind}; use crate::{Interner, Scalar, Ty, TyBuilder, TyKind};
pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
match op { match op {
BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner), BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
BinaryOp::Assignment { .. } => Ty::unit(), BinaryOp::Assignment { .. } => TyBuilder::unit(),
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
match lhs_ty.kind(&Interner) { match lhs_ty.kind(&Interner) {
TyKind::Scalar(Scalar::Int(_)) TyKind::Scalar(Scalar::Int(_))

View file

@ -22,7 +22,7 @@ use crate::{
to_assoc_type_id, to_chalk_trait_id, to_assoc_type_id, to_chalk_trait_id,
utils::generics, utils::generics,
AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
TraitRef, Ty, TyKind, WhereClause, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
}; };
use mapping::{ use mapping::{
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@ -300,7 +300,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
_closure_id: chalk_ir::ClosureId<Interner>, _closure_id: chalk_ir::ClosureId<Interner>,
_substs: &chalk_ir::Substitution<Interner>, _substs: &chalk_ir::Substitution<Interner>,
) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
let ty = Ty::unit().to_chalk(self.db); let ty = TyBuilder::unit().to_chalk(self.db);
make_binders(ty, 0) make_binders(ty, 0)
} }
fn closure_fn_substitution( fn closure_fn_substitution(