Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc improvements #931

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions crates/flux-infer/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use flux_middle::{
fold::TypeFoldable,
AliasKind, AliasTy, BaseTy, Binder, BoundVariableKinds, CoroutineObligPredicate, ESpan,
EVar, EVarGen, EarlyBinder, Expr, ExprKind, GenericArg, GenericArgs, HoleKind, InferMode,
Lambda, List, Loc, Mutability, Path, PolyVariant, PtrKind, Ref, RefineArgs, RefineArgsExt,
Lambda, List, Loc, Mutability, Path, PolyVariant, PtrKind, RefineArgs, RefineArgsExt,
Region, Sort, Ty, TyKind, Var,
},
};
Expand Down Expand Up @@ -184,7 +184,7 @@ impl<'infcx, 'genv, 'tcx> InferCtxt<'infcx, 'genv, 'tcx> {
let kvar = self.fresh_kvar(&[vars], KVarEncoding::Single);
Expr::abs(Lambda::bind_with_fsort(kvar, fsort))
}
InferMode::EVar => self.fresh_evars(sort),
InferMode::EVar => self.fresh_evar(),
}
}

Expand All @@ -195,11 +195,11 @@ impl<'infcx, 'genv, 'tcx> InferCtxt<'infcx, 'genv, 'tcx> {
) -> Expr {
match kind {
HoleKind::Pred => self.fresh_kvar(binders, KVarEncoding::Conj),
HoleKind::Expr(sort) => {
HoleKind::Expr(_) => {
// We only use expression holes to infer early param arguments for opaque types
// at function calls. These should be well-scoped in the current scope, so we ignore
// the extra `binders` around the hole.
self.fresh_evars(&sort)
self.fresh_evar()
}
}
}
Expand All @@ -212,9 +212,9 @@ impl<'infcx, 'genv, 'tcx> InferCtxt<'infcx, 'genv, 'tcx> {
.fresh(binders, inner.evars.current_data().iter(), encoding)
}

fn fresh_evars(&self, sort: &Sort) -> Expr {
fn fresh_evar(&self) -> Expr {
let evars = &mut self.inner.borrow_mut().evars;
Expr::fold_sort(sort, |_| Expr::evar(evars.fresh_in_current()))
Expr::evar(evars.fresh_in_current())
}

pub fn unify_exprs(&self, e1: &Expr, e2: &Expr) {
Expand Down Expand Up @@ -521,9 +521,16 @@ impl Sub {
infcx.unify_exprs(&path1.to_expr(), &path2.to_expr());
self.tys(infcx, &ty1, ty2)
}
(TyKind::Ptr(PtrKind::Mut(re), path), Ref!(_, bound, Mutability::Mut)) => {
(
TyKind::Ptr(PtrKind::Mut(re), path),
TyKind::Indexed(BaseTy::Ref(_, bound, Mutability::Mut), idx),
) => {
// We sometimes generate evars for the index of references so we need to make sure
// we solve them.
self.idxs_eq(infcx, &Expr::unit(), idx);

let mut at = infcx.at(self.span);
env.ptr_to_ref(&mut at, ConstrReason::Call, *re, path, bound.clone())?;
env.ptr_to_ref(&mut at, self.reason, *re, path, bound.clone())?;
Ok(())
}
_ => self.tys(infcx, a, b),
Expand Down
8 changes: 4 additions & 4 deletions crates/flux-middle/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ pub struct PrettyCx<'genv, 'tcx> {
pub hide_refinements: bool,
pub hide_regions: bool,
pub hide_sorts: bool,
env: Env,
env: BoundVarEnv,
}

newtype_index! {
Expand All @@ -193,12 +193,12 @@ newtype_index! {
}

#[derive(Default)]
struct Env {
struct BoundVarEnv {
name_gen: IndexGen<BoundVarName>,
layers: RefCell<Vec<FxHashMap<BoundVar, BoundVarName>>>,
}

impl Env {
impl BoundVarEnv {
fn lookup(&self, debruijn: DebruijnIndex, var: BoundVar) -> Option<BoundVarName> {
let layers = self.layers.borrow();
layers
Expand Down Expand Up @@ -283,7 +283,7 @@ impl<'genv, 'tcx> PrettyCx<'genv, 'tcx> {
hide_refinements: false,
hide_regions: false,
hide_sorts: true,
env: Env::default(),
env: BoundVarEnv::default(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/flux-middle/src/rty/canonicalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ impl CanonicalTy {
{
let ctor = poly_constr_ty
.as_ref()
.map(|constr| SubsetTy::new(bty.clone(), Expr::nu(), &constr.pred));
.map(|constr| SubsetTy::new(bty.clone(), idx, &constr.pred));
TyOrBase::Base(ctor)
} else {
TyOrBase::Ty(self.to_ty())
Expand Down
4 changes: 4 additions & 0 deletions crates/flux-middle/src/rty/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ pub enum HoleKind {
Pred,
/// A hole used as a refinement argument or index. It will be inferred by generating an evar.
/// The expression filling the hole must have the provided sort.
///
/// NOTE(nilehmann) we used to require the `Sort` for generating the evar because we needed it
/// to eta-expand aggregate sorts. We've since removed this behavior but I'm keeping it here
/// just in case. We could remove in case it becomes too problematic.
Expr(Sort),
}

Expand Down
24 changes: 24 additions & 0 deletions crates/flux-middle/src/rty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,30 @@ impl BaseTy {
tracked_span_bug!("expected adt `{self:?}`")
}
}

/// A type is an *atom* if it is "self-delimiting", i.e., it has a clear boundary
/// when printed. This is used to avoid unnecessary parenthesis when pretty printing.
pub fn is_atom(&self) -> bool {
// (nilehmann) I'm not sure about this list, please adjust if you get any odd behavior
matches!(
self,
BaseTy::Int(_)
| BaseTy::Uint(_)
| BaseTy::Slice(_)
| BaseTy::Bool
| BaseTy::Char
| BaseTy::Str
| BaseTy::Adt(..)
| BaseTy::Tuple(..)
// opaque alias are atoms the way we print them now, but they won't
// be if we print them as `impl Trait`
| BaseTy::Alias(..)
| BaseTy::Array(..)
| BaseTy::Never
| BaseTy::Closure(..)
| BaseTy::Coroutine(..)
)
}
}

impl<'tcx> ToRustc<'tcx> for BaseTy {
Expand Down
7 changes: 3 additions & 4 deletions crates/flux-middle/src/rty/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ impl Pretty for Ty {
define_scoped!(cx, f);
match self.kind() {
TyKind::Indexed(bty, idx) => {
w!("{:?}", bty)?;
w!("{:?}", parens!(bty, !bty.is_atom()))?;
if cx.hide_refinements {
return Ok(());
}
Expand Down Expand Up @@ -300,15 +300,14 @@ impl Pretty for Ty {
}
TyKind::Param(param_ty) => w!("{}", ^param_ty),
TyKind::Downcast(adt, .., variant_idx, fields) => {
let is_struct = adt.is_struct();
// base-name
w!("{:?}", adt.did())?;
// variant-name: if it is not a struct
if !is_struct {
if !adt.is_struct() {
w!("::{}", ^adt.variant(*variant_idx).name)?;
}
// fields: use curly-braces + names for structs, otherwise use parens
if is_struct {
if adt.is_struct() {
let field_binds = iter::zip(&adt.variant(*variant_idx).fields, fields)
.map(|(field_def, value)| FieldBind { name: field_def.name, value });
w!(" {{ {:?} }}", join!(", ", field_binds))?;
Expand Down
7 changes: 2 additions & 5 deletions crates/flux-refineck/src/type_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,6 @@ impl<'a> TypeEnv<'a> {
// t1 <: t2
let t2 = match bound {
PtrToRefBound::Ty(t2) => {
// FIXME(nilehmann) we could match regions against `t1` instead of mapping the path
// to a place which requires annoying bookkeping.
// let place = self.bindings.path_to_place(path);
// let rust_ty = place.ty(infcx.genv, self.local_decls)?.ty;
let t2 = rty_match_regions(&t2, &t1);
infcx.subtyping(&t1, &t2, reason)?;
t2
Expand Down Expand Up @@ -715,7 +711,8 @@ impl BasicBlockEnvShape {
(GenericArg::Base(ctor1), GenericArg::Base(ctor2)) => {
let sty1 = ctor1.as_ref().skip_binder();
let sty2 = ctor2.as_ref().skip_binder();
debug_assert_eq3!(&sty1.idx, &sty2.idx, &Expr::nu());
debug_assert!(sty1.idx.is_nu());
debug_assert!(sty2.idx.is_nu());

let bty = self.join_bty(&sty1.bty, &sty2.bty);
let pred = if self.scope.has_free_vars(&sty2.pred) || sty1.pred != sty2.pred {
Expand Down
Loading