Skip to content

Commit

Permalink
Merge branch 'rust-analyzer:master' into rust-dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
bruno-ortiz authored Feb 26, 2022
2 parents 01b0fd8 + 719babd commit 700af65
Show file tree
Hide file tree
Showing 58 changed files with 2,652 additions and 1,390 deletions.
104 changes: 55 additions & 49 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1388,9 +1388,13 @@ impl Function {
let loc = self.id.lookup(db.upcast());
let krate = loc.krate(db);
let def_map = db.crate_def_map(krate.into());
let name = &function_data.name;
let ast_id =
InFile::new(loc.id.file_id(), loc.id.item_tree(db.upcast())[loc.id.value].ast_id);

let mut exported_proc_macros = def_map.exported_proc_macros();
exported_proc_macros.find(|(_, mac_name)| mac_name == name).map(|(id, _)| MacroDef { id })
exported_proc_macros
.find(|&(id, _)| matches!(id.kind, MacroDefKind::ProcMacro(_, _, id) if id == ast_id))
.map(|(id, _)| MacroDef { id })
}

/// A textual representation of the HIR of this function for debugging purposes.
Expand Down Expand Up @@ -2436,7 +2440,7 @@ impl Impl {

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Type {
krate: CrateId,
krate: CrateId, // FIXME this is probably redundant with the TraitEnvironment
env: Arc<TraitEnvironment>,
ty: Ty,
}
Expand Down Expand Up @@ -2503,6 +2507,10 @@ impl Type {
matches!(self.ty.kind(Interner), TyKind::Ref(..))
}

pub fn is_slice(&self) -> bool {
matches!(self.ty.kind(Interner), TyKind::Slice(..))
}

pub fn is_usize(&self) -> bool {
matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
}
Expand All @@ -2525,36 +2533,25 @@ impl Type {
/// Checks that particular type `ty` implements `std::future::Future`.
/// This function is used in `.await` syntax completion.
pub fn impls_future(&self, db: &dyn HirDatabase) -> bool {
// No special case for the type of async block, since Chalk can figure it out.

let krate = self.krate;

let std_future_trait =
db.lang_item(krate, SmolStr::new_inline("future_trait")).and_then(|it| it.as_trait());
let std_future_trait = db
.lang_item(self.krate, SmolStr::new_inline("future_trait"))
.and_then(|it| it.as_trait());
let std_future_trait = match std_future_trait {
Some(it) => it,
None => return false,
};

let canonical_ty =
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
method_resolution::implements_trait(
&canonical_ty,
db,
self.env.clone(),
krate,
std_future_trait,
)
method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), std_future_trait)
}

/// 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) {
let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.krate) {
Some(it) => it,
None => return false,
};
Expand All @@ -2565,7 +2562,6 @@ impl Type {
&canonical_ty,
db,
self.env.clone(),
krate,
fnonce_trait,
)
}
Expand Down Expand Up @@ -2736,9 +2732,8 @@ impl Type {
pub fn autoderef_<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Ty> + 'a {
// There should be no inference vars in types passed here
let canonical = hir_ty::replace_errors_with_variables(&self.ty);
let environment = self.env.env.clone();
let ty = InEnvironment { goal: canonical, environment };
autoderef(db, Some(self.krate), ty).map(|canonical| canonical.value)
let environment = self.env.clone();
autoderef(db, environment, canonical).map(|canonical| canonical.value)
}

// This would be nicer if it just returned an iterator, but that runs into
Expand Down Expand Up @@ -2793,24 +2788,26 @@ impl Type {
pub fn iterate_method_candidates<T>(
&self,
db: &dyn HirDatabase,
krate: Crate,
scope: &SemanticsScope,
// FIXME this can be retrieved from `scope`, except autoimport uses this
// to specify a different set, so the method needs to be split
traits_in_scope: &FxHashSet<TraitId>,
with_local_impls: Option<Module>,
name: Option<&Name>,
mut callback: impl FnMut(Type, Function) -> Option<T>,
mut callback: impl FnMut(Function) -> Option<T>,
) -> Option<T> {
let _p = profile::span("iterate_method_candidates");
let mut slot = None;

self.iterate_method_candidates_dyn(
db,
krate,
scope,
traits_in_scope,
with_local_impls,
name,
&mut |ty, assoc_item_id| {
&mut |assoc_item_id| {
if let AssocItemId::FunctionId(func) = assoc_item_id {
if let Some(res) = callback(self.derived(ty.clone()), func.into()) {
if let Some(res) = callback(func.into()) {
slot = Some(res);
return ControlFlow::Break(());
}
Expand All @@ -2824,50 +2821,55 @@ impl Type {
fn iterate_method_candidates_dyn(
&self,
db: &dyn HirDatabase,
krate: Crate,
scope: &SemanticsScope,
traits_in_scope: &FxHashSet<TraitId>,
with_local_impls: Option<Module>,
name: Option<&Name>,
callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>,
) {
// There should be no inference vars in types passed here
let canonical = hir_ty::replace_errors_with_variables(&self.ty);

let env = self.env.clone();
let krate = krate.id;
let krate = match scope.krate() {
Some(k) => k,
None => return,
};
let environment = scope.resolver().generic_def().map_or_else(
|| Arc::new(TraitEnvironment::empty(krate.id)),
|d| db.trait_environment(d),
);

method_resolution::iterate_method_candidates_dyn(
&canonical,
db,
env,
krate,
environment,
traits_in_scope,
with_local_impls.and_then(|b| b.id.containing_block()).into(),
name,
method_resolution::LookupMode::MethodCall,
&mut |ty, id| callback(&ty.value, id),
&mut |_adj, id| callback(id),
);
}

pub fn iterate_path_candidates<T>(
&self,
db: &dyn HirDatabase,
krate: Crate,
scope: &SemanticsScope,
traits_in_scope: &FxHashSet<TraitId>,
with_local_impls: Option<Module>,
name: Option<&Name>,
mut callback: impl FnMut(Type, AssocItem) -> Option<T>,
mut callback: impl FnMut(AssocItem) -> Option<T>,
) -> Option<T> {
let _p = profile::span("iterate_path_candidates");
let mut slot = None;
self.iterate_path_candidates_dyn(
db,
krate,
scope,
traits_in_scope,
with_local_impls,
name,
&mut |ty, assoc_item_id| {
if let Some(res) = callback(self.derived(ty.clone()), assoc_item_id.into()) {
&mut |assoc_item_id| {
if let Some(res) = callback(assoc_item_id.into()) {
slot = Some(res);
return ControlFlow::Break(());
}
Expand All @@ -2880,27 +2882,31 @@ impl Type {
fn iterate_path_candidates_dyn(
&self,
db: &dyn HirDatabase,
krate: Crate,
scope: &SemanticsScope,
traits_in_scope: &FxHashSet<TraitId>,
with_local_impls: Option<Module>,
name: Option<&Name>,
callback: &mut dyn FnMut(&Ty, AssocItemId) -> ControlFlow<()>,
callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>,
) {
let canonical = hir_ty::replace_errors_with_variables(&self.ty);

let env = self.env.clone();
let krate = krate.id;
let krate = match scope.krate() {
Some(k) => k,
None => return,
};
let environment = scope.resolver().generic_def().map_or_else(
|| Arc::new(TraitEnvironment::empty(krate.id)),
|d| db.trait_environment(d),
);

method_resolution::iterate_method_candidates_dyn(
method_resolution::iterate_path_candidates(
&canonical,
db,
env,
krate,
environment,
traits_in_scope,
with_local_impls.and_then(|b| b.id.containing_block()).into(),
name,
method_resolution::LookupMode::Path,
&mut |ty, id| callback(&ty.value, id),
&mut |id| callback(id),
);
}

Expand Down
4 changes: 4 additions & 0 deletions crates/hir/src/semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,10 @@ impl<'a> SemanticsScope<'a> {
Some(Crate { id: self.resolver.krate()? })
}

pub(crate) fn resolver(&self) -> &Resolver {
&self.resolver
}

/// Note: `FxHashSet<TraitId>` should be treated as an opaque type, passed into `Type
pub fn visible_traits(&self) -> FxHashSet<TraitId> {
let resolver = &self.resolver;
Expand Down
18 changes: 18 additions & 0 deletions crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,24 @@ fn main() { "foor0bar\nfalse"; }
);
}

#[test]
fn test_concat_bytes_expand() {
check(
r##"
#[rustc_builtin_macro]
macro_rules! concat_bytes {}
fn main() { concat_bytes!(b'A', b"BC", [68, b'E', 70]); }
"##,
expect![[r##"
#[rustc_builtin_macro]
macro_rules! concat_bytes {}
fn main() { [b'A', 66, 67, 68, b'E', 70]; }
"##]],
);
}

#[test]
fn test_concat_with_captured_expr() {
check(
Expand Down
Loading

0 comments on commit 700af65

Please sign in to comment.