Unnamed repository; edit this file 'description' to name the repository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Inference of closure parameter types based on the closure's expected type.

use chalk_ir::{cast::Cast, AliasEq, AliasTy, FnSubst, WhereClause};
use hir_def::{expr::ExprId, HasModule};
use smallvec::SmallVec;

use crate::{
    to_chalk_trait_id, utils, ChalkTraitId, DynTy, FnPointer, FnSig, Interner, Substitution, Ty,
    TyExt, TyKind,
};

use super::{Expectation, InferenceContext};

impl InferenceContext<'_> {
    pub(super) fn deduce_closure_type_from_expectations(
        &mut self,
        closure_expr: ExprId,
        closure_ty: &Ty,
        sig_ty: &Ty,
        expectation: &Expectation,
    ) {
        let expected_ty = match expectation.to_option(&mut self.table) {
            Some(ty) => ty,
            None => return,
        };

        // Deduction from where-clauses in scope, as well as fn-pointer coercion are handled here.
        let _ = self.coerce(Some(closure_expr), closure_ty, &expected_ty);

        // Deduction based on the expected `dyn Fn` is done separately.
        if let TyKind::Dyn(dyn_ty) = expected_ty.kind(Interner) {
            if let Some(sig) = self.deduce_sig_from_dyn_ty(dyn_ty) {
                let expected_sig_ty = TyKind::Function(sig).intern(Interner);

                self.unify(sig_ty, &expected_sig_ty);
            }
        }
    }

    fn deduce_sig_from_dyn_ty(&self, dyn_ty: &DynTy) -> Option<FnPointer> {
        // Search for a predicate like `<$self as FnX<Args>>::Output == Ret`

        let fn_traits: SmallVec<[ChalkTraitId; 3]> =
            utils::fn_traits(self.db.upcast(), self.owner.module(self.db.upcast()).krate())
                .map(to_chalk_trait_id)
                .collect();

        let self_ty = TyKind::Error.intern(Interner);
        let bounds = dyn_ty.bounds.clone().substitute(Interner, &[self_ty.cast(Interner)]);
        for bound in bounds.iter(Interner) {
            // NOTE(skip_binders): the extracted types are rebound by the returned `FnPointer`
            if let WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection), ty }) =
                bound.skip_binders()
            {
                let assoc_data = self.db.associated_ty_data(projection.associated_ty_id);
                if !fn_traits.contains(&assoc_data.trait_id) {
                    return None;
                }

                // Skip `Self`, get the type argument.
                let arg = projection.substitution.as_slice(Interner).get(1)?;
                if let Some(subst) = arg.ty(Interner)?.as_tuple() {
                    let generic_args = subst.as_slice(Interner);
                    let mut sig_tys = Vec::new();
                    for arg in generic_args {
                        sig_tys.push(arg.ty(Interner)?.clone());
                    }
                    sig_tys.push(ty.clone());

                    cov_mark::hit!(dyn_fn_param_informs_call_site_closure_signature);
                    return Some(FnPointer {
                        num_binders: bound.len(Interner),
                        sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
                        substitution: FnSubst(Substitution::from_iter(Interner, sig_tys)),
                    });
                }
            }
        }

        None
    }
}
-body pre { background-color: #282E3B; border: 1px solid #8A9199; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-radius: 3px; } .markdown-body pre code, .markdown-body pre tt { margin: 0; padding: 0; background-color: transparent; border: none; } pre { line-height: 125%; } td.linenos .normal { color: #8a919966; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: #8a919966; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #363C48 } .highlight .c { color: #6E7C8E } /* Comment */ .highlight .err { color: #FF6666 } /* Error */ .highlight .g { color: #CCCAC2 } /* Generic */ .highlight .k { color: #FFAD66 } /* Keyword */ .highlight .o { color: #F29E74 } /* Operator */ .highlight .ch { color: #6E7C8E } /* Comment.Hashbang */ .highlight .cm { color: #6E7C8E; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #FFAD66 } /* Comment.Preproc */ .highlight .cpf { color: #D5FF80 } /* Comment.PreprocFile */ .highlight .c1 { color: #6E7C8E; font-style: italic } /* Comment.Single */ .highlight .cs { color: #6E7C8E } /* Comment.Special */ .highlight .gd { color: #F27983 } /* Generic.Deleted */ .highlight .ge { color: #FFD173; font-style: italic } /* Generic.Emph */ .highlight .gr { color: #FF6666 } /* Generic.Error */ .highlight .gh { color: #FFD173; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #87D96C } /* Generic.Inserted */ .highlight .go { color: #D5FF80 } /* Generic.Output */ .highlight .gp { color: #F29E74 } /* Generic.Prompt */ .highlight .gs { color: #FFD173; font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #CCCAC2 } /* Generic.Subheading */ .highlight .gt { color: #FF6666 } /* Generic.Traceback */ .highlight .kc { color: #DFBFFF } /* Keyword.Constant */ .highlight .kd { color: #FFCC66 } /* Keyword.Declaration */ .highlight .kn { color: #FFAD66 } /* Keyword.Namespace */ .highlight .kp { color: #FFAD66 } /* Keyword.Pseudo */ .highlight .kr { color: #FFAD66 } /* Keyword.Reserved */ .highlight .kt { color: #73D0FF } /* Keyword.Type */ .highlight .m { color: #DFBFFF } /* Literal.Number */ .highlight .s { color: #D5FF80 } /* Literal.String */ .highlight .na { color: #FFD173 } /* Name.Attribute */ .highlight .nb { color: #F28779 } /* Name.Builtin */ .highlight .nc { color: #5CCFE6 } /* Name.Class */ .highlight .no { color: #DFBFFF } /* Name.Constant */ .highlight .nd { color: #FFDFB3 } /* Name.Decorator */ .highlight .nf { color: #FFD173 } /* Name.Function */ .highlight .nt { color: #5CCFE6 } /* Name.Tag */ .highlight .ow { color: #F29E74 } /* Operator.Word */ .highlight .w { color: #CCCAC2 } /* Text.Whitespace */ .highlight .mb { color: #DFBFFF } /* Literal.Number.Bin */ .highlight .mf { color: #DFBFFF } /* Literal.Number.Float */ .highlight .mh { color: #DFBFFF } /* Literal.Number.Hex */ .highlight .mi { color: #DFBFFF } /* Literal.Number.Integer */ .highlight .mo { color: #DFBFFF } /* Literal.Number.Oct */ .highlight .sa { color: #D5FF80 } /* Literal.String.Affix */ .highlight .sb { color: #F29E74 } /* Literal.String.Backtick */ .highlight .sc { color: #D5FF80 } /* Literal.String.Char */ .highlight .dl { color: #D5FF80 } /* Literal.String.Delimiter */ .highlight .sd { color: #95E6CB; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #D5FF80 } /* Literal.String.Double */ .highlight .se { color: #D5FF80 } /* Literal.String.Escape */ .highlight .sh { color: #D5FF80 } /* Literal.String.Heredoc */ .highlight .si { color: #D5FF80 } /* Literal.String.Interpol */ .highlight .sx { color: #D5FF80 } /* Literal.String.Other */ .highlight .sr { color: #95E6CB } /* Literal.String.Regex */ .highlight .s1 { color: #D5FF80 } /* Literal.String.Single */ .highlight .ss { color: #D5FF80 } /* Literal.String.Symbol */ .highlight .bp { color: #F28779 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #FFD173 } /* Name.Function.Magic */ .highlight .vi { color: #FFCC66 } /* Name.Variable.Instance */ .highlight .vm { color: #5CCFE6; font-style: italic } /* Name.Variable.Magic */ .highlight .il { color: #DFBFFF } /* Literal.Number.Integer.Long */

22.05 (2022-05-28)

An even bigger shout out than usual to all the contributors - we had a whopping 110 contributors in this release! That's more than double the number of contributors as last release!

Check out some of the highlights in the news section.

As usual, the following is a summary of each of the changes since the last release. For the full log, check out the git log.

Breaking Changes:

Features:

Commands:

Usability improvements and fixes:

Themes:

LSP:

New Languages:

Updated Languages and Queries:

Packaging:

22.03 (2022-03-28)

A big shout out to all the contributors! We had 51 contributors in this release.

This release is particularly large and featureful. Check out some of the highlights in the news section.

As usual, the following is a summary of each of the changes since the last release. For the full log, check out the git log.

Breaking changes:

Features:

Commands:

Usability improvements and fixes:

Themes:

LSP:

New Languages:

Updated Languages and Queries:

Packaging:

0.6.0 (2022-01-04)

Happy new year and a big shout out to all the contributors! We had 55 contributors in this release.

Helix has popped up in DPorts and Fedora Linux via COPR (#1270)

As usual the following is a brief summary, refer to the git history for a full log:

Breaking changes:

Features:

Commands:

Usability improvements and fixes:

LSP: - Implement MarkedString rendering (e128a8702) - Don't panic if init fails (d31bef7) - Configurable diagnostic severity (#1325) - Resolve completion item (#1315) - Code action command support (#1304)

Grammars:

New themes:

0.5.0 (2021-10-28)

A big shout out to all the contributors! We had 46 contributors in this release.

Helix has popped up in Scoop, FreeBSD Ports and Gentu GURU!

The following is a quick rundown of the larger changes, there were many more (check the git history for more details).

Breaking changes:

Features:

New grammars:

New themes:

Fixes:

0.4.1 (2021-08-14)

A minor release that includes:

0.4.0 (2021-08-13)

A big shout out to all the contributors! We had 28 contributors in this release.

Two months have passed, so this is another big release. A big thank you to all the contributors and package maintainers!

Helix has popped up in Arch, Manjaro, Nix, MacPorts and Parabola and Termux repositories!

A large scale refactor landed that allows us to support zero width (empty) selections in the future as well as resolves many bugs and edge cases.

0.3.0 (2021-06-27)

A big shout out to all the contributors! We had 24 contributors in this release.

Another big release.

Highlights:

Features:

Fixes:

0.2.1

Includes a fix where wq/wqa could exit before file saving completed.

0.2.0

A big shout out to all the contributors! We had 18 contributors in this release.

Enough has changed to bump the version. We're skipping 0.1.x because previously the CLI would always report version as 0.1.0, and we'd like to distinguish it in bug reports..

0.0.10

Keymaps: - Add mappings to jump to diagnostics - Add gt/gm/gb mappings to jump to top/middle/bottom of screen - ^ and $ are now gh, gl