Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-expand/src/name.rs1
-rw-r--r--crates/hir-ty/src/builder.rs17
-rw-r--r--crates/hir-ty/src/infer.rs26
-rw-r--r--crates/hir-ty/src/infer/expr.rs42
-rw-r--r--crates/hir-ty/src/infer/unify.rs25
-rw-r--r--crates/hir-ty/src/tests/method_resolution.rs9
-rw-r--r--crates/hir-ty/src/tests/traits.rs75
-rw-r--r--crates/hir/src/lib.rs39
-rw-r--r--crates/hir/src/source_analyzer.rs2
-rw-r--r--crates/ide-db/src/defs.rs2
-rw-r--r--crates/ide/src/inlay_hints/bind_pat.rs4
-rw-r--r--crates/ide/src/inlay_hints/chaining.rs6
-rw-r--r--crates/test-utils/src/minicore.rs18
13 files changed, 163 insertions, 103 deletions
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index b515472501..0e4d20c07e 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -347,6 +347,7 @@ pub mod known {
recursion_limit,
feature,
// known methods of lang items
+ call_once,
eq,
ne,
ge,
diff --git a/crates/hir-ty/src/builder.rs b/crates/hir-ty/src/builder.rs
index d5ef0c22de..8faef7bf71 100644
--- a/crates/hir-ty/src/builder.rs
+++ b/crates/hir-ty/src/builder.rs
@@ -63,7 +63,7 @@ impl<D> TyBuilder<D> {
}
fn build_internal(self) -> (D, Substitution) {
- assert_eq!(self.vec.len(), self.param_kinds.len());
+ assert_eq!(self.vec.len(), self.param_kinds.len(), "{:?}", &self.param_kinds);
for (a, e) in self.vec.iter().zip(self.param_kinds.iter()) {
self.assert_match_kind(a, e);
}
@@ -282,6 +282,21 @@ impl TyBuilder<Tuple> {
let (Tuple(size), subst) = self.build_internal();
TyKind::Tuple(size, subst).intern(Interner)
}
+
+ pub fn tuple_with<I>(elements: I) -> Ty
+ where
+ I: IntoIterator<Item = Ty>,
+ <I as IntoIterator>::IntoIter: ExactSizeIterator,
+ {
+ let elements = elements.into_iter();
+ let len = elements.len();
+ let mut b =
+ TyBuilder::new(Tuple(len), iter::repeat(ParamKind::Type).take(len).collect(), None);
+ for e in elements {
+ b = b.push(e);
+ }
+ b.build()
+ }
}
impl TyBuilder<TraitId> {
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 4402c75947..571b3e9686 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -938,19 +938,24 @@ impl<'a> InferenceContext<'a> {
self.db.trait_data(trait_).associated_type_by_name(&name![Item])
}
- fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
- let trait_ = self.resolve_lang_item(LangItem::Try)?.as_trait()?;
+ fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
}
+ fn resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId> {
+ self.resolve_lang_item(lang)?.as_trait()
+ }
+
+ fn resolve_ops_try_output(&self) -> Option<TypeAliasId> {
+ self.resolve_output_on(self.resolve_lang_trait(LangItem::Try)?)
+ }
+
fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
- let trait_ = self.resolve_lang_item(LangItem::Neg)?.as_trait()?;
- self.db.trait_data(trait_).associated_type_by_name(&name![Output])
+ self.resolve_output_on(self.resolve_lang_trait(LangItem::Neg)?)
}
fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
- let trait_ = self.resolve_lang_item(LangItem::Not)?.as_trait()?;
- self.db.trait_data(trait_).associated_type_by_name(&name![Output])
+ self.resolve_output_on(self.resolve_lang_trait(LangItem::Not)?)
}
fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
@@ -960,7 +965,7 @@ impl<'a> InferenceContext<'a> {
.lookup(self.db.upcast())
.container
else { return None };
- self.db.trait_data(trait_).associated_type_by_name(&name![Output])
+ self.resolve_output_on(trait_)
}
fn resolve_boxed_box(&self) -> Option<AdtId> {
@@ -998,13 +1003,8 @@ impl<'a> InferenceContext<'a> {
Some(struct_.into())
}
- fn resolve_ops_index(&self) -> Option<TraitId> {
- self.resolve_lang_item(LangItem::Index)?.as_trait()
- }
-
fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
- let trait_ = self.resolve_ops_index()?;
- self.db.trait_data(trait_).associated_type_by_name(&name![Output])
+ self.resolve_output_on(self.resolve_lang_trait(LangItem::Index)?)
}
fn resolve_va_list(&self) -> Option<AdtId> {
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 7ae85d2061..7b9bf0c5cf 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -13,11 +13,12 @@ use hir_def::{
ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp,
},
generics::TypeOrConstParamData,
+ lang_item::LangItem,
path::{GenericArg, GenericArgs},
resolver::resolver_for_expr,
ConstParamId, FieldId, ItemContainerId, Lookup,
};
-use hir_expand::name::Name;
+use hir_expand::name::{name, Name};
use stdx::always;
use syntax::ast::RangeOp;
@@ -157,7 +158,8 @@ impl<'a> InferenceContext<'a> {
}
// The ok-ish type that is expected from the last expression
- let ok_ty = self.resolve_associated_type(try_ty.clone(), self.resolve_ops_try_ok());
+ let ok_ty =
+ self.resolve_associated_type(try_ty.clone(), self.resolve_ops_try_output());
self.with_breakable_ctx(BreakableKind::Block, ok_ty.clone(), None, |this| {
this.infer_expr(*body, &Expectation::has_type(ok_ty));
@@ -331,11 +333,18 @@ impl<'a> InferenceContext<'a> {
derefed_callee.callable_sig(self.db).map_or(false, |sig| sig.is_varargs)
|| res.is_none();
let (param_tys, ret_ty) = match res {
- Some(res) => {
+ Some((func, params, ret_ty)) => {
let adjustments = auto_deref_adjust_steps(&derefs);
// FIXME: Handle call adjustments for Fn/FnMut
self.write_expr_adj(*callee, adjustments);
- res
+ if let Some((trait_, func)) = func {
+ let subst = TyBuilder::subst_for_def(self.db, trait_, None)
+ .push(callee_ty.clone())
+ .push(TyBuilder::tuple_with(params.iter().cloned()))
+ .build();
+ self.write_method_resolution(tgt_expr, func, subst.clone());
+ }
+ (params, ret_ty)
}
None => (Vec::new(), self.err_ty()), // FIXME diagnostic
};
@@ -587,7 +596,18 @@ impl<'a> InferenceContext<'a> {
}
Expr::Try { expr } => {
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
- self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok())
+ if let Some(trait_) = self.resolve_lang_trait(LangItem::Try) {
+ if let Some(func) = self.db.trait_data(trait_).method_by_name(&name!(branch)) {
+ let subst = TyBuilder::subst_for_def(self.db, trait_, None)
+ .push(inner_ty.clone())
+ .build();
+ self.write_method_resolution(tgt_expr, func, subst.clone());
+ }
+ let try_output = self.resolve_output_on(trait_);
+ self.resolve_associated_type(inner_ty, try_output)
+ } else {
+ self.err_ty()
+ }
}
Expr::Cast { expr, type_ref } => {
// FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary)
@@ -626,6 +646,7 @@ impl<'a> InferenceContext<'a> {
Expr::UnaryOp { expr, op } => {
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
let inner_ty = self.resolve_ty_shallow(&inner_ty);
+ // FIXME: Note down method resolution her
match op {
UnaryOp::Deref => {
autoderef::deref(&mut self.table, inner_ty).unwrap_or_else(|| self.err_ty())
@@ -735,7 +756,7 @@ impl<'a> InferenceContext<'a> {
let base_ty = self.infer_expr_inner(*base, &Expectation::none());
let index_ty = self.infer_expr(*index, &Expectation::none());
- if let Some(index_trait) = self.resolve_ops_index() {
+ if let Some(index_trait) = self.resolve_lang_trait(LangItem::Index) {
let canonicalized = self.canonicalize(base_ty.clone());
let receiver_adjustments = method_resolution::resolve_indexing_op(
self.db,
@@ -748,6 +769,15 @@ impl<'a> InferenceContext<'a> {
adj.apply(&mut self.table, base_ty)
});
self.write_expr_adj(*base, adj);
+ if let Some(func) =
+ self.db.trait_data(index_trait).method_by_name(&name!(index))
+ {
+ let substs = TyBuilder::subst_for_def(self.db, index_trait, None)
+ .push(self_ty.clone())
+ .push(index_ty.clone())
+ .build();
+ self.write_method_resolution(tgt_expr, func, substs.clone());
+ }
self.resolve_associated_type_with_params(
self_ty,
self.resolve_ops_index_output(),
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index e7ddd1591f..46ed3533c8 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -8,6 +8,7 @@ use chalk_ir::{
};
use chalk_solve::infer::ParameterEnaVariableExt;
use ena::unify::UnifyKey;
+use hir_def::{FunctionId, TraitId};
use hir_expand::name;
use stdx::never;
@@ -626,18 +627,26 @@ impl<'a> InferenceTable<'a> {
}
}
- pub(crate) fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
+ pub(crate) fn callable_sig(
+ &mut self,
+ ty: &Ty,
+ num_args: usize,
+ ) -> Option<(Option<(TraitId, FunctionId)>, Vec<Ty>, Ty)> {
match ty.callable_sig(self.db) {
- Some(sig) => Some((sig.params().to_vec(), sig.ret().clone())),
+ Some(sig) => Some((None, sig.params().to_vec(), sig.ret().clone())),
None => self.callable_sig_from_fn_trait(ty, num_args),
}
}
- fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
+ fn callable_sig_from_fn_trait(
+ &mut self,
+ ty: &Ty,
+ num_args: usize,
+ ) -> Option<(Option<(TraitId, FunctionId)>, Vec<Ty>, Ty)> {
let krate = self.trait_env.krate;
let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
- let output_assoc_type =
- self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
+ let trait_data = self.db.trait_data(fn_once_trait);
+ let output_assoc_type = trait_data.associated_type_by_name(&name![Output])?;
let mut arg_tys = vec![];
let arg_ty = TyBuilder::tuple(num_args)
@@ -675,7 +684,11 @@ impl<'a> InferenceTable<'a> {
if self.db.trait_solve(krate, canonical.value.cast(Interner)).is_some() {
self.register_obligation(obligation.goal);
let return_ty = self.normalize_projection_ty(projection);
- Some((arg_tys, return_ty))
+ Some((
+ Some(fn_once_trait).zip(trait_data.method_by_name(&name!(call_once))),
+ arg_tys,
+ return_ty,
+ ))
} else {
None
}
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index 42fb685abf..41c53701df 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -986,14 +986,13 @@ fn main() {
}
#[test]
-fn method_resolution_encountering_fn_type() {
+fn explicit_fn_once_call_fn_item() {
check_types(
r#"
-//- /main.rs
+//- minicore: fn
fn foo() {}
-trait FnOnce { fn call(self); }
-fn test() { foo.call(); }
- //^^^^^^^^^^ {unknown}
+fn test() { foo.call_once(); }
+ //^^^^^^^^^^^^^^^ ()
"#,
);
}
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 88670364bd..015085bde4 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -1757,25 +1757,19 @@ fn test() {
fn fn_trait() {
check_infer_with_mismatches(
r#"
-trait FnOnce<Args> {
- type Output;
-
- fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
-}
+//- minicore: fn
fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
f.call_once((1, 2));
}"#,
expect![[r#"
- 56..60 'self': Self
- 62..66 'args': Args
- 149..150 'f': F
- 155..183 '{ ...2)); }': ()
- 161..162 'f': F
- 161..180 'f.call...1, 2))': u128
- 173..179 '(1, 2)': (u32, u64)
- 174..175 '1': u32
- 177..178 '2': u64
+ 38..39 'f': F
+ 44..72 '{ ...2)); }': ()
+ 50..51 'f': F
+ 50..69 'f.call...1, 2))': u128
+ 62..68 '(1, 2)': (u32, u64)
+ 63..64 '1': u32
+ 66..67 '2': u64
"#]],
);
}
@@ -1784,12 +1778,7 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
fn fn_ptr_and_item() {
check_infer_with_mismatches(
r#"
-#[lang="fn_once"]
-trait FnOnce<Args> {
- type Output;
-
- fn call_once(self, args: Args) -> Self::Output;
-}
+//- minicore: fn
trait Foo<T> {
fn foo(&self) -> T;
@@ -1815,27 +1804,25 @@ fn test() {
opt.map(f);
}"#,
expect![[r#"
- 74..78 'self': Self
- 80..84 'args': Args
- 139..143 'self': &Self
- 243..247 'self': &Bar<F>
- 260..271 '{ loop {} }': (A1, R)
- 262..269 'loop {}': !
- 267..269 '{}': ()
- 355..359 'self': Opt<T>
- 361..362 'f': F
- 377..388 '{ loop {} }': Opt<U>
- 379..386 'loop {}': !
- 384..386 '{}': ()
- 402..518 '{ ...(f); }': ()
- 412..415 'bar': Bar<fn(u8) -> u32>
- 441..444 'bar': Bar<fn(u8) -> u32>
- 441..450 'bar.foo()': (u8, u32)
- 461..464 'opt': Opt<u8>
- 483..484 'f': fn(u8) -> u32
- 505..508 'opt': Opt<u8>
- 505..515 'opt.map(f)': Opt<u32>
- 513..514 'f': fn(u8) -> u32
+ 28..32 'self': &Self
+ 132..136 'self': &Bar<F>
+ 149..160 '{ loop {} }': (A1, R)
+ 151..158 'loop {}': !
+ 156..158 '{}': ()
+ 244..248 'self': Opt<T>
+ 250..251 'f': F
+ 266..277 '{ loop {} }': Opt<U>
+ 268..275 'loop {}': !
+ 273..275 '{}': ()
+ 291..407 '{ ...(f); }': ()
+ 301..304 'bar': Bar<fn(u8) -> u32>
+ 330..333 'bar': Bar<fn(u8) -> u32>
+ 330..339 'bar.foo()': (u8, u32)
+ 350..353 'opt': Opt<u8>
+ 372..373 'f': fn(u8) -> u32
+ 394..397 'opt': Opt<u8>
+ 394..404 'opt.map(f)': Opt<u32>
+ 402..403 'f': fn(u8) -> u32
"#]],
);
}
@@ -2308,10 +2295,8 @@ fn unselected_projection_in_trait_env_no_cycle() {
// this is not a cycle
check_types(
r#"
-//- /main.rs
-trait Index {
- type Output;
-}
+//- minicore: index
+use core::ops::Index;
type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4415bef4bb..39589bf8bc 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2411,7 +2411,7 @@ impl Local {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct DeriveHelper {
pub(crate) derive: MacroId,
- pub(crate) idx: usize,
+ pub(crate) idx: u32,
}
impl DeriveHelper {
@@ -2421,15 +2421,18 @@ impl DeriveHelper {
pub fn name(&self, db: &dyn HirDatabase) -> Name {
match self.derive {
- MacroId::Macro2Id(it) => {
- db.macro2_data(it).helpers.as_deref().and_then(|it| it.get(self.idx)).cloned()
- }
+ MacroId::Macro2Id(it) => db
+ .macro2_data(it)
+ .helpers
+ .as_deref()
+ .and_then(|it| it.get(self.idx as usize))
+ .cloned(),
MacroId::MacroRulesId(_) => None,
MacroId::ProcMacroId(proc_macro) => db
.proc_macro_data(proc_macro)
.helpers
.as_deref()
- .and_then(|it| it.get(self.idx))
+ .and_then(|it| it.get(self.idx as usize))
.cloned(),
}
.unwrap_or_else(|| Name::missing())
@@ -2440,7 +2443,7 @@ impl DeriveHelper {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct BuiltinAttr {
krate: Option<CrateId>,
- idx: usize,
+ idx: u32,
}
impl BuiltinAttr {
@@ -2449,7 +2452,8 @@ impl BuiltinAttr {
if let builtin @ Some(_) = Self::builtin(name) {
return builtin;
}
- let idx = db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)?;
+ let idx =
+ db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)? as u32;
Some(BuiltinAttr { krate: Some(krate.id), idx })
}
@@ -2457,21 +2461,21 @@ impl BuiltinAttr {
hir_def::builtin_attr::INERT_ATTRIBUTES
.iter()
.position(|tool| tool.name == name)
- .map(|idx| BuiltinAttr { krate: None, idx })
+ .map(|idx| BuiltinAttr { krate: None, idx: idx as u32 })
}
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
// FIXME: Return a `Name` here
match self.krate {
- Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx].clone(),
- None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].name),
+ Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(),
+ None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx as usize].name),
}
}
pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
match self.krate {
Some(_) => None,
- None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].template),
+ None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx as usize].template),
}
}
}
@@ -2479,7 +2483,7 @@ impl BuiltinAttr {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ToolModule {
krate: Option<CrateId>,
- idx: usize,
+ idx: u32,
}
impl ToolModule {
@@ -2488,7 +2492,8 @@ impl ToolModule {
if let builtin @ Some(_) = Self::builtin(name) {
return builtin;
}
- let idx = db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)?;
+ let idx =
+ db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)? as u32;
Some(ToolModule { krate: Some(krate.id), idx })
}
@@ -2496,14 +2501,14 @@ impl ToolModule {
hir_def::builtin_attr::TOOL_MODULES
.iter()
.position(|&tool| tool == name)
- .map(|idx| ToolModule { krate: None, idx })
+ .map(|idx| ToolModule { krate: None, idx: idx as u32 })
}
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
// FIXME: Return a `Name` here
match self.krate {
- Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx].clone(),
- None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx]),
+ Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx as usize].clone(),
+ None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx as usize]),
}
}
}
@@ -2831,7 +2836,7 @@ impl Impl {
}
}
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct TraitRef {
env: Arc<TraitEnvironment>,
trait_ref: hir_ty::TraitRef,
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 5e0c9933a7..3b39e9fa91 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -628,7 +628,7 @@ impl SourceAnalyzer {
{
return Some(PathResolution::DeriveHelper(DeriveHelper {
derive: *macro_id,
- idx,
+ idx: idx as u32,
}));
}
}
diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs
index 6c13c03972..ed7f04fd8e 100644
--- a/crates/ide-db/src/defs.rs
+++ b/crates/ide-db/src/defs.rs
@@ -34,8 +34,8 @@ pub enum Definition {
TypeAlias(TypeAlias),
BuiltinType(BuiltinType),
SelfType(Impl),
- Local(Local),
GenericParam(GenericParam),
+ Local(Local),
Label(Label),
DeriveHelper(DeriveHelper),
BuiltinAttr(BuiltinAttr),
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index 971168aa28..da44d95297 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -325,7 +325,7 @@ fn main(a: SliceIter<'_, Container>) {
file_id: FileId(
1,
),
- range: 2248..2256,
+ range: 2611..2619,
},
),
tooltip: "",
@@ -338,7 +338,7 @@ fn main(a: SliceIter<'_, Container>) {
file_id: FileId(
1,
),
- range: 2248..2256,
+ range: 2611..2619,
},
),
tooltip: "",
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index b522450310..222ee59be8 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -435,7 +435,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 2248..2256,
+ range: 2611..2619,
},
),
tooltip: "",
@@ -455,7 +455,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 2248..2256,
+ range: 2611..2619,
},
),
tooltip: "",
@@ -475,7 +475,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 2248..2256,
+ range: 2611..2619,
},
),
tooltip: "",
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 5634bafd06..3b033e1aae 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -106,6 +106,11 @@ pub mod marker {
impl<T: ?Sized> Copy for &T {}
}
// endregion:copy
+
+ // region:fn
+ #[lang = "tuple_trait"]
+ pub trait Tuple {}
+ // endregion:fn
}
// region:default
@@ -347,19 +352,26 @@ pub mod ops {
// region:fn
mod function {
+ use crate::marker::Tuple;
+
#[lang = "fn"]
#[fundamental]
- pub trait Fn<Args>: FnMut<Args> {}
+ pub trait Fn<Args: Tuple>: FnMut<Args> {
+ extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+ }
#[lang = "fn_mut"]
#[fundamental]
- pub trait FnMut<Args>: FnOnce<Args> {}
+ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
+ extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+ }
#[lang = "fn_once"]
#[fundamental]
- pub trait FnOnce<Args> {
+ pub trait FnOnce<Args: Tuple> {
#[lang = "fn_once_output"]
type Output;
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
}
pub use self::function::{Fn, FnMut, FnOnce};