6251: Semantic Highlight: Add Callable modifier for variables r=matklad a=GrayJack

This PR added the `HighlightModifier::Callable` variant and assigned it to variables and parameters that are fn pointers, closures and implements FnOnce trait.

This allows to colorize these variables/parameters when used in call expression.



6310: Rewrite algo::diff to support insertion and deletion r=matklad a=Veykril

This in turn also makes `algo::diff` generate finer diffs(maybe even minimal diffs?) as insertions and deletions aren't always represented as as replacements of parent nodes now.

Required for #6287 to go on.

Co-authored-by: GrayJack <gr41.j4ck@gmail.com>
Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2020-10-23 22:12:15 +00:00 committed by GitHub
commit 2fa942ad30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 468 additions and 31 deletions

View file

@ -31,8 +31,7 @@ use hir_ty::{
autoderef,
display::{HirDisplayError, HirFormatter},
method_resolution,
traits::Solution,
traits::SolutionVariables,
traits::{FnTrait, Solution, SolutionVariables},
ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty,
TyDefId, TyKind, TypeCtor,
@ -1386,6 +1385,28 @@ impl Type {
)
}
/// Checks that particular type `ty` implements `std::ops::FnOnce`.
///
/// This function can be used to check if a particular type is callable, since FnOnce is a
/// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
pub fn impls_fnonce(&self, db: &dyn HirDatabase) -> bool {
let krate = self.krate;
let fnonce_trait = match FnTrait::FnOnce.get_id(db, krate) {
Some(it) => it,
None => return false,
};
let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
method_resolution::implements_trait(
&canonical_ty,
db,
self.ty.environment.clone(),
krate,
fnonce_trait,
)
}
pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
let trait_ref = hir_ty::TraitRef {
trait_: trait_.id,