Skip to content

Commit 2a1ef34

Browse files
More robust debug assertions for Instance::resolve on built-in traits with custom items
1 parent 82cd953 commit 2a1ef34

File tree

3 files changed

+73
-14
lines changed

3 files changed

+73
-14
lines changed

compiler/rustc_middle/src/ty/instance.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ impl<'tcx> Instance<'tcx> {
385385
/// couldn't complete due to errors elsewhere - this is distinct
386386
/// from `Ok(None)` to avoid misleading diagnostics when an error
387387
/// has already been/will be emitted, for the original cause
388-
#[instrument(level = "debug", skip(tcx))]
388+
#[instrument(level = "debug", skip(tcx), ret)]
389389
pub fn resolve(
390390
tcx: TyCtxt<'tcx>,
391391
param_env: ty::ParamEnv<'tcx>,

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,7 @@ symbols! {
12031203
require,
12041204
residual,
12051205
result,
1206+
resume,
12061207
return_position_impl_trait_in_trait,
12071208
return_type_notation,
12081209
rhs,

compiler/rustc_ty_utils/src/instance.rs

+71-13
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,55 @@ fn resolve_associated_item<'tcx>(
177177

178178
Some(ty::Instance::new(leaf_def.item.def_id, substs))
179179
}
180-
traits::ImplSource::Generator(generator_data) => Some(Instance {
181-
def: ty::InstanceDef::Item(generator_data.generator_def_id),
182-
substs: generator_data.substs,
183-
}),
184-
traits::ImplSource::Future(future_data) => Some(Instance {
185-
def: ty::InstanceDef::Item(future_data.generator_def_id),
186-
substs: future_data.substs,
187-
}),
180+
traits::ImplSource::Generator(generator_data) => {
181+
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
182+
// For compiler developers who'd like to add new items to `Generator`,
183+
// you either need to generate a shim body, or perhaps return
184+
// `InstanceDef::Item` pointing to a trait default method body if
185+
// it is given a default implementation by the trait.
186+
span_bug!(
187+
tcx.def_span(generator_data.generator_def_id),
188+
"no definition for `{trait_ref}::{}` for built-in generator type",
189+
tcx.item_name(trait_item_id)
190+
)
191+
}
192+
Some(Instance {
193+
def: ty::InstanceDef::Item(generator_data.generator_def_id),
194+
substs: generator_data.substs,
195+
})
196+
}
197+
traits::ImplSource::Future(future_data) => {
198+
if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::poll {
199+
// For compiler developers who'd like to add new items to `Future`,
200+
// you either need to generate a shim body, or perhaps return
201+
// `InstanceDef::Item` pointing to a trait default method body if
202+
// it is given a default implementation by the trait.
203+
span_bug!(
204+
tcx.def_span(future_data.generator_def_id),
205+
"no definition for `{trait_ref}::{}` for built-in async generator type",
206+
tcx.item_name(trait_item_id)
207+
)
208+
}
209+
Some(Instance {
210+
def: ty::InstanceDef::Item(future_data.generator_def_id),
211+
substs: future_data.substs,
212+
})
213+
}
188214
traits::ImplSource::Closure(closure_data) => {
215+
if cfg!(debug_assertions)
216+
&& ![sym::call, sym::call_mut, sym::call_once]
217+
.contains(&tcx.item_name(trait_item_id))
218+
{
219+
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
220+
// you either need to generate a shim body, or perhaps return
221+
// `InstanceDef::Item` pointing to a trait default method body if
222+
// it is given a default implementation by the trait.
223+
span_bug!(
224+
tcx.def_span(closure_data.closure_def_id),
225+
"no definition for `{trait_ref}::{}` for built-in closure type",
226+
tcx.item_name(trait_item_id)
227+
)
228+
}
189229
let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
190230
Instance::resolve_closure(
191231
tcx,
@@ -195,11 +235,29 @@ fn resolve_associated_item<'tcx>(
195235
)
196236
}
197237
traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
198-
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
199-
def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty),
200-
substs: rcvr_substs,
201-
}),
202-
_ => None,
238+
ty::FnDef(..) | ty::FnPtr(..) => {
239+
if cfg!(debug_assertions)
240+
&& ![sym::call, sym::call_mut, sym::call_once]
241+
.contains(&tcx.item_name(trait_item_id))
242+
{
243+
// For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
244+
// you either need to generate a shim body, or perhaps return
245+
// `InstanceDef::Item` pointing to a trait default method body if
246+
// it is given a default implementation by the trait.
247+
bug!(
248+
"no definition for `{trait_ref}::{}` for built-in fn type",
249+
tcx.item_name(trait_item_id)
250+
)
251+
}
252+
Some(Instance {
253+
def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty),
254+
substs: rcvr_substs,
255+
})
256+
}
257+
_ => bug!(
258+
"no built-in definition for `{trait_ref}::{}` for non-fn type",
259+
tcx.item_name(trait_item_id)
260+
),
203261
},
204262
traits::ImplSource::Object(ref data) => {
205263
traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| {

0 commit comments

Comments
 (0)