Skip to content

Commit

Permalink
Rollup merge of rust-lang#114670 - compiler-errors:issue-114660, r=cj…
Browse files Browse the repository at this point in the history
…gillot

Don't use `type_of` to determine if item has intrinsic shim

When we're calling `resolve_instance` on an inline const, we were previously looking at the `type_of` for that const, seeing that it was an `extern "intrinsic"` fn def, and treating it as if we were computing the instance of that intrinsic itself. This is incorrect.

Instead, we should be using the def-id of the item we're computing to determine if it's an intrinsic.

Fixes rust-lang#114660
  • Loading branch information
matthiaskrgr authored Aug 9, 2023
2 parents bbc1109 + d8e3986 commit a87dda3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 35 deletions.
65 changes: 30 additions & 35 deletions compiler/rustc_ty_utils/src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::query::Providers;
Expand All @@ -15,54 +16,48 @@ fn resolve_instance<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>,
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
let (param_env, (def, args)) = key.into_parts();
let (param_env, (def_id, args)) = key.into_parts();

let result = if let Some(trait_def_id) = tcx.trait_of_item(def) {
let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
resolve_associated_item(
tcx,
def,
def_id,
param_env,
trait_def_id,
tcx.normalize_erasing_regions(param_env, args),
)
} else {
let ty = tcx.type_of(def);
let item_type = tcx.subst_and_normalize_erasing_regions(args, param_env, ty);
let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.is_intrinsic(def_id) {
debug!(" => intrinsic");
ty::InstanceDef::Intrinsic(def_id)
} else if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
let ty = args.type_at(0);

let def = match *item_type.kind() {
ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => {
debug!(" => intrinsic");
ty::InstanceDef::Intrinsic(def)
}
ty::FnDef(def_id, args) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => {
let ty = args.type_at(0);

if ty.needs_drop(tcx, param_env) {
debug!(" => nontrivial drop glue");
match *ty.kind() {
ty::Closure(..)
| ty::Generator(..)
| ty::Tuple(..)
| ty::Adt(..)
| ty::Dynamic(..)
| ty::Array(..)
| ty::Slice(..) => {}
// Drop shims can only be built from ADTs.
_ => return Ok(None),
}

ty::InstanceDef::DropGlue(def_id, Some(ty))
} else {
debug!(" => trivial drop glue");
ty::InstanceDef::DropGlue(def_id, None)
if ty.needs_drop(tcx, param_env) {
debug!(" => nontrivial drop glue");
match *ty.kind() {
ty::Closure(..)
| ty::Generator(..)
| ty::Tuple(..)
| ty::Adt(..)
| ty::Dynamic(..)
| ty::Array(..)
| ty::Slice(..) => {}
// Drop shims can only be built from ADTs.
_ => return Ok(None),
}

ty::InstanceDef::DropGlue(def_id, Some(ty))
} else {
debug!(" => trivial drop glue");
ty::InstanceDef::DropGlue(def_id, None)
}
_ => {
debug!(" => free item");
ty::InstanceDef::Item(def)
}
} else {
debug!(" => free item");
ty::InstanceDef::Item(def_id)
};

Ok(Some(Instance { def, args }))
};
debug!("inner_resolve_instance: result={:?}", result);
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/inline-const/instance-doesnt-depend-on-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// check-pass
// issue: 114660

#![feature(inline_const)]

fn main() {
const { core::mem::transmute::<u8, u8> };
// Don't resolve the instance of this inline constant to be an intrinsic,
// even if the type of the constant is `extern "intrinsic" fn(u8) -> u8`.
}

0 comments on commit a87dda3

Please sign in to comment.