1
Fork 0

refactor(rustc_middle): Substs -> GenericArg

This commit is contained in:
Mahdi Dibaiee 2023-07-11 22:35:29 +01:00
parent df5c2cf9bc
commit e55583c4b8
466 changed files with 4574 additions and 4604 deletions

View file

@ -61,7 +61,7 @@ use rustc_hir::{Body, FnDecl, ForeignItemKind, GenericParamKind, Node, PatKind,
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef};
use rustc_session::config::ExpectedValues;
@ -181,9 +181,11 @@ impl<'tcx> LateLintPass<'tcx> for BoxPointers {
| hir::ItemKind::TyAlias(..)
| hir::ItemKind::Enum(..)
| hir::ItemKind::Struct(..)
| hir::ItemKind::Union(..) => {
self.check_heap_type(cx, it.span, cx.tcx.type_of(it.owner_id).subst_identity())
}
| hir::ItemKind::Union(..) => self.check_heap_type(
cx,
it.span,
cx.tcx.type_of(it.owner_id).instantiate_identity(),
),
_ => (),
}
@ -194,7 +196,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxPointers {
self.check_heap_type(
cx,
field.span,
cx.tcx.type_of(field.def_id).subst_identity(),
cx.tcx.type_of(field.def_id).instantiate_identity(),
);
}
}
@ -591,7 +593,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
// If the method is an impl for an item with docs_hidden, don't doc.
MethodLateContext::PlainImpl => {
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
let impl_ty = cx.tcx.type_of(parent).subst_identity();
let impl_ty = cx.tcx.type_of(parent).instantiate_identity();
let outerdef = match impl_ty.kind() {
ty::Adt(def, _) => Some(def.did()),
ty::Foreign(def_id) => Some(*def_id),
@ -700,7 +702,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
// and recommending Copy might be a bad idea.
for field in def.all_fields() {
let did = field.did;
if cx.tcx.type_of(did).subst_identity().is_unsafe_ptr() {
if cx.tcx.type_of(did).instantiate_identity().is_unsafe_ptr() {
return;
}
}
@ -798,7 +800,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
if self.impling_types.is_none() {
let mut impls = LocalDefIdSet::default();
cx.tcx.for_each_impl(debug, |d| {
if let Some(ty_def) = cx.tcx.type_of(d).subst_identity().ty_adt_def() {
if let Some(ty_def) = cx.tcx.type_of(d).instantiate_identity().ty_adt_def() {
if let Some(def_id) = ty_def.did().as_local() {
impls.insert(def_id);
}
@ -2455,12 +2457,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
cx: &LateContext<'tcx>,
ty: Ty<'tcx>,
variant: &VariantDef,
substs: ty::SubstsRef<'tcx>,
args: ty::GenericArgsRef<'tcx>,
descr: &str,
init: InitKind,
) -> Option<InitError> {
let mut field_err = variant.fields.iter().find_map(|field| {
ty_find_init_error(cx, field.ty(cx.tcx, substs), init).map(|mut err| {
ty_find_init_error(cx, field.ty(cx.tcx, args), init).map(|mut err| {
if !field.did.is_local() {
err
} else if err.span.is_none() {
@ -2537,14 +2539,14 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
Some("raw pointers must be initialized".into())
}
// Recurse and checks for some compound types. (but not unions)
Adt(adt_def, substs) if !adt_def.is_union() => {
Adt(adt_def, args) if !adt_def.is_union() => {
// Handle structs.
if adt_def.is_struct() {
return variant_find_init_error(
cx,
ty,
adt_def.non_enum_variant(),
substs,
args,
"struct field",
init,
);
@ -2554,7 +2556,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
let mut potential_variants = adt_def.variants().iter().filter_map(|variant| {
let definitely_inhabited = match variant
.inhabited_predicate(cx.tcx, *adt_def)
.subst(cx.tcx, substs)
.instantiate(cx.tcx, args)
.apply_any_module(cx.tcx, cx.param_env)
{
// Entirely skip uninhabited variants.
@ -2578,7 +2580,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
cx,
ty,
&first_variant.0,
substs,
args,
"field of the only potentially inhabited enum variant",
init,
);
@ -2778,7 +2780,7 @@ impl ClashingExternDeclarations {
// type unless the newtype makes the type non-null.
let non_transparent_ty = |mut ty: Ty<'tcx>| -> Ty<'tcx> {
loop {
if let ty::Adt(def, substs) = *ty.kind() {
if let ty::Adt(def, args) = *ty.kind() {
let is_transparent = def.repr().transparent();
let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, def);
debug!(
@ -2791,7 +2793,7 @@ impl ClashingExternDeclarations {
// continue with `ty`'s non-ZST field,
// otherwise `ty` is a ZST and we can return
if let Some(field) = transparent_newtype_field(tcx, v) {
ty = field.ty(tcx, substs);
ty = field.ty(tcx, args);
continue;
}
}
@ -2857,8 +2859,8 @@ impl ClashingExternDeclarations {
structurally_same_type_impl(
seen_types,
cx,
tcx.type_of(a_did).subst_identity(),
tcx.type_of(b_did).subst_identity(),
tcx.type_of(a_did).instantiate_identity(),
tcx.type_of(b_did).instantiate_identity(),
ckind,
)
},
@ -2905,8 +2907,8 @@ impl ClashingExternDeclarations {
ckind,
)
}
(Tuple(a_substs), Tuple(b_substs)) => {
a_substs.iter().eq_by(b_substs.iter(), |a_ty, b_ty| {
(Tuple(a_args), Tuple(b_args)) => {
a_args.iter().eq_by(b_args.iter(), |a_ty, b_ty| {
structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
})
}
@ -2960,7 +2962,7 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations {
let tcx = cx.tcx;
if let Some(existing_did) = self.insert(tcx, this_fi) {
let existing_decl_ty = tcx.type_of(existing_did).skip_binder();
let this_decl_ty = tcx.type_of(this_fi.owner_id).subst_identity();
let this_decl_ty = tcx.type_of(this_fi.owner_id).instantiate_identity();
debug!(
"ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}",
existing_did, existing_decl_ty, this_fi.owner_id, this_decl_ty

View file

@ -35,7 +35,7 @@ use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::middle::stability;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_middle::ty::{self, print::Printer, GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_session::config::ExpectedValues;
use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId};
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
@ -1273,8 +1273,8 @@ impl<'tcx> LateContext<'tcx> {
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
if trait_ref.is_none() {
if let ty::Adt(def, substs) = self_ty.kind() {
return self.print_def_path(def.did(), substs);
if let ty::Adt(def, args) = self_ty.kind() {
return self.print_def_path(def.did(), args);
}
}

View file

@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
// `Deref` is being implemented for `t`
if let hir::ItemKind::Impl(impl_) = item.kind
&& let Some(trait_) = &impl_.of_trait
&& let t = cx.tcx.type_of(item.owner_id).subst_identity()
&& let t = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let opt_did @ Some(did) = trait_.trait_def_id()
&& opt_did == cx.tcx.lang_items().deref_trait()
// `t` is `dyn t_principal`

View file

@ -51,7 +51,7 @@ fn enforce_mem_discriminant(
expr_span: Span,
args_span: Span,
) {
let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0);
let ty_param = cx.typeck_results().node_args(func_expr.hir_id).type_at(0);
if is_non_enum(ty_param) {
cx.emit_spanned_lint(
ENUM_INTRINSICS_NON_ENUMS,
@ -62,7 +62,7 @@ fn enforce_mem_discriminant(
}
fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, span: Span) {
let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0);
let ty_param = cx.typeck_results().node_args(func_expr.hir_id).type_at(0);
if is_non_enum(ty_param) {
cx.emit_spanned_lint(
ENUM_INTRINSICS_NON_ENUMS,

View file

@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
let ty = cx.typeck_results().expr_ty(arg);
let &ty::Adt(adt, substs) = ty.kind() else { return };
let &ty::Adt(adt, args) = ty.kind() else { return };
let (article, ty, var) = match adt.did() {
did if cx.tcx.is_diagnostic_item(sym::Option, did) => ("an", "Option", "Some"),
@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
} else {
ForLoopsOverFalliblesLoopSub::UseWhileLet { start_span: expr.span.with_hi(pat.span.lo()), end_span: pat.span.between(arg.span), var }
} ;
let question_mark = suggest_question_mark(cx, adt, substs, expr.span)
let question_mark = suggest_question_mark(cx, adt, args, expr.span)
.then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
let suggestion = ForLoopsOverFalliblesSuggestion {
var,
@ -115,7 +115,7 @@ fn extract_iterator_next_call<'tcx>(
fn suggest_question_mark<'tcx>(
cx: &LateContext<'tcx>,
adt: ty::AdtDef<'tcx>,
substs: &List<ty::GenericArg<'tcx>>,
args: &List<ty::GenericArg<'tcx>>,
span: Span,
) -> bool {
let Some(body_id) = cx.enclosing_body else { return false };
@ -137,7 +137,7 @@ fn suggest_question_mark<'tcx>(
}
}
let ty = substs.type_at(0);
let ty = args.type_at(0);
let infcx = cx.tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);

View file

@ -52,20 +52,20 @@ impl LateLintPass<'_> for DefaultHashTypes {
}
/// Helper function for lints that check for expressions with calls and use typeck results to
/// get the `DefId` and `SubstsRef` of the function.
/// get the `DefId` and `GenericArgsRef` of the function.
fn typeck_results_of_method_fn<'tcx>(
cx: &LateContext<'tcx>,
expr: &Expr<'_>,
) -> Option<(Span, DefId, ty::subst::SubstsRef<'tcx>)> {
) -> Option<(Span, DefId, ty::GenericArgsRef<'tcx>)> {
match expr.kind {
ExprKind::MethodCall(segment, ..)
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) =>
{
Some((segment.ident.span, def_id, cx.typeck_results().node_substs(expr.hir_id)))
Some((segment.ident.span, def_id, cx.typeck_results().node_args(expr.hir_id)))
},
_ => {
match cx.typeck_results().node_type(expr.hir_id).kind() {
&ty::FnDef(def_id, substs) => Some((expr.span, def_id, substs)),
&ty::FnDef(def_id, args) => Some((expr.span, def_id, args)),
_ => None,
}
}
@ -89,8 +89,8 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]);
impl LateLintPass<'_> for QueryStability {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some((span, def_id, substs)) = typeck_results_of_method_fn(cx, expr) else { return };
if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) {
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, args) {
let def_id = instance.def_id();
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
cx.emit_spanned_lint(
@ -232,7 +232,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
}
// Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).subst_identity().kind() {
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() {
if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
{
// NOTE: This path is currently unreachable as `Ty<'tcx>` is
@ -241,7 +241,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
//
// I(@lcnr) still kept this branch in so we don't miss this
// if we ever change it in the future.
return Some(format!("{}<{}>", name, substs[0]));
return Some(format!("{}<{}>", name, args[0]));
}
}
}
@ -379,9 +379,9 @@ declare_lint_pass!(Diagnostics => [ UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSID
impl LateLintPass<'_> for Diagnostics {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some((span, def_id, substs)) = typeck_results_of_method_fn(cx, expr) else { return };
debug!(?span, ?def_id, ?substs);
let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs)
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
debug!(?span, ?def_id, ?args);
let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, args)
.ok()
.flatten()
.is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics));
@ -414,7 +414,7 @@ impl LateLintPass<'_> for Diagnostics {
}
let mut found_diagnostic_message = false;
for ty in substs.types() {
for ty in args.types() {
debug!(?ty);
if let Some(adt_def) = ty.ty_adt_def() &&
let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did()) &&

View file

@ -53,9 +53,9 @@ fn lint_cstring_as_ptr(
unwrap: &rustc_hir::Expr<'_>,
) {
let source_type = cx.typeck_results().expr_ty(source);
if let ty::Adt(def, substs) = source_type.kind() {
if let ty::Adt(def, args) = source_type.kind() {
if cx.tcx.is_diagnostic_item(sym::Result, def.did()) {
if let ty::Adt(adt, _) = substs.type_at(0).kind() {
if let ty::Adt(adt, _) = args.type_at(0).kind() {
if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) {
cx.emit_spanned_lint(
TEMPORARY_CSTRING_AS_PTR,

View file

@ -93,11 +93,11 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
return;
};
let substs = cx
let args = cx
.tcx
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_substs(expr.hir_id));
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_args(expr.hir_id));
// Resolve the trait method instance.
let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, substs) else { return };
let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, args) else { return };
// (Re)check that it implements the noop diagnostic.
let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };

View file

@ -76,7 +76,9 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// For every projection predicate in the opaque type's explicit bounds,
// check that the type that we're assigning actually satisfies the bounds
// of the associated type.
for (pred, pred_span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() {
for (pred, pred_span) in
cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied()
{
// Liberate bound regions in the predicate since we
// don't actually care about lifetimes in this check.
let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind());
@ -99,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
}
let proj_ty =
Ty::new_projection(cx.tcx, proj.projection_ty.def_id, proj.projection_ty.substs);
Ty::new_projection(cx.tcx, proj.projection_ty.def_id, proj.projection_ty.args);
// For every instance of the projection type in the bounds,
// replace them with the term we're assigning to the associated
// type in our opaque type.
@ -115,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
for (assoc_pred, assoc_pred_span) in cx
.tcx
.explicit_item_bounds(proj.projection_ty.def_id)
.subst_iter_copied(cx.tcx, &proj.projection_ty.substs)
.arg_iter_copied(cx.tcx, &proj.projection_ty.args)
{
let assoc_pred = assoc_pred.fold_with(proj_replacer);
let Ok(assoc_pred) = traits::fully_normalize(
@ -154,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
ty: Ty::new_opaque(
cx.tcx,
def_id,
ty::InternalSubsts::identity_for_item(cx.tcx, def_id),
ty::GenericArgs::identity_for_item(cx.tcx, def_id),
),
proj_ty: proj_term,
assoc_pred_span,

View file

@ -50,9 +50,9 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
return Some(format!("{}{}", name, gen_args(cx, path_segment)));
}
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).subst_identity().kind() {
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() {
if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) {
return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs));
return Some(cx.tcx.def_path_str_with_args(adt.did(), args));
}
}
}

View file

@ -17,7 +17,7 @@ use rustc_errors::DiagnosticMessage;
use rustc_hir as hir;
use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{
self, AdtKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
@ -808,7 +808,7 @@ pub fn transparent_newtype_field<'a, 'tcx>(
) -> Option<&'a ty::FieldDef> {
let param_env = tcx.param_env(variant.def_id);
variant.fields.iter().find(|field| {
let field_ty = tcx.type_of(field.did).subst_identity();
let field_ty = tcx.type_of(field.did).instantiate_identity();
let is_zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_zst());
!is_zst
})
@ -821,7 +821,7 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
ty::FnPtr(_) => true,
ty::Ref(..) => true,
ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
ty::Adt(def, substs) if def.repr().transparent() && !def.is_union() => {
ty::Adt(def, args) if def.repr().transparent() && !def.is_union() => {
let marked_non_null = nonnull_optimization_guaranteed(tcx, *def);
if marked_non_null {
@ -836,7 +836,7 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
def.variants()
.iter()
.filter_map(|variant| transparent_newtype_field(cx.tcx, variant))
.any(|field| ty_is_known_nonnull(cx, field.ty(tcx, substs), mode))
.any(|field| ty_is_known_nonnull(cx, field.ty(tcx, args), mode))
}
_ => false,
}
@ -847,7 +847,7 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
let tcx = cx.tcx;
Some(match *ty.kind() {
ty::Adt(field_def, field_substs) => {
ty::Adt(field_def, field_args) => {
let inner_field_ty = {
let mut first_non_zst_ty = field_def
.variants()
@ -861,7 +861,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
first_non_zst_ty
.next_back()
.expect("No non-zst fields in transparent type.")
.ty(tcx, field_substs)
.ty(tcx, field_args)
};
return get_nullable_type(cx, inner_field_ty);
}
@ -900,10 +900,10 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
ckind: CItemKind,
) -> Option<Ty<'tcx>> {
debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty);
if let ty::Adt(ty_def, substs) = ty.kind() {
if let ty::Adt(ty_def, args) = ty.kind() {
let field_ty = match &ty_def.variants().raw[..] {
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
([], [field]) | ([field], []) => field.ty(cx.tcx, substs),
([], [field]) | ([field], []) => field.ty(cx.tcx, args),
_ => return None,
},
_ => return None,
@ -963,9 +963,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
&self,
cache: &mut FxHashSet<Ty<'tcx>>,
field: &ty::FieldDef,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> FfiResult<'tcx> {
let field_ty = field.ty(self.cx.tcx, substs);
let field_ty = field.ty(self.cx.tcx, args);
if field_ty.has_opaque_types() {
self.check_type_for_ffi(cache, field_ty)
} else {
@ -981,7 +981,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
ty: Ty<'tcx>,
def: ty::AdtDef<'tcx>,
variant: &ty::VariantDef,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> FfiResult<'tcx> {
use FfiResult::*;
@ -989,7 +989,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
// Can assume that at most one field is not a ZST, so only check
// that field's type for FFI-safety.
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
return self.check_field_type_for_ffi(cache, field, substs);
return self.check_field_type_for_ffi(cache, field, args);
} else {
// All fields are ZSTs; this means that the type should behave
// like (), which is FFI-unsafe... except if all fields are PhantomData,
@ -1001,7 +1001,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
// actually safe.
let mut all_phantom = !variant.fields.is_empty();
for field in &variant.fields {
match self.check_field_type_for_ffi(cache, &field, substs) {
match self.check_field_type_for_ffi(cache, &field, args) {
FfiSafe => {
all_phantom = false;
}
@ -1036,7 +1036,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
match *ty.kind() {
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
if def.is_box() && matches!(self.mode, CItemKind::Definition) {
if ty.boxed_ty().is_sized(tcx, self.cx.param_env) {
return FfiSafe;
@ -1099,7 +1099,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
};
}
self.check_variant_for_ffi(cache, ty, def, def.non_enum_variant(), substs)
self.check_variant_for_ffi(cache, ty, def, def.non_enum_variant(), args)
}
AdtKind::Enum => {
if def.variants().is_empty() {
@ -1140,7 +1140,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
};
}
match self.check_variant_for_ffi(cache, ty, def, variant, substs) {
match self.check_variant_for_ffi(cache, ty, def, variant, args) {
FfiSafe => (),
r => return r,
}
@ -1387,7 +1387,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
/// For a external ABI function, argument types and the result type are walked to find fn-ptr
/// types that have external ABIs, as these still need checked.
fn check_fn(&mut self, def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>) {
let sig = self.cx.tcx.fn_sig(def_id).subst_identity();
let sig = self.cx.tcx.fn_sig(def_id).instantiate_identity();
let sig = self.cx.tcx.erase_late_bound_regions(sig);
for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) {
@ -1405,7 +1405,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
/// Check if a function's argument types and result type are "ffi-safe".
fn check_foreign_fn(&mut self, def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>) {
let sig = self.cx.tcx.fn_sig(def_id).subst_identity();
let sig = self.cx.tcx.fn_sig(def_id).instantiate_identity();
let sig = self.cx.tcx.erase_late_bound_regions(sig);
for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) {
@ -1418,7 +1418,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
fn check_foreign_static(&mut self, id: hir::OwnerId, span: Span) {
let ty = self.cx.tcx.type_of(id).subst_identity();
let ty = self.cx.tcx.type_of(id).instantiate_identity();
self.check_type_for_ffi_and_report_errors(span, ty, true, false);
}
@ -1524,7 +1524,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
self.check_ty_maybe_containing_foreign_fnptr(
cx,
ty,
cx.tcx.type_of(item.owner_id).subst_identity(),
cx.tcx.type_of(item.owner_id).instantiate_identity(),
);
}
// See `check_fn`..
@ -1549,7 +1549,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
self.check_ty_maybe_containing_foreign_fnptr(
cx,
field.ty,
cx.tcx.type_of(field.def_id).subst_identity(),
cx.tcx.type_of(field.def_id).instantiate_identity(),
);
}
@ -1584,7 +1584,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
if let hir::ItemKind::Enum(ref enum_definition, _) = it.kind {
let t = cx.tcx.type_of(it.owner_id).subst_identity();
let t = cx.tcx.type_of(it.owner_id).instantiate_identity();
let ty = cx.tcx.erase_regions(t);
let Ok(layout) = cx.layout_of(ty) else { return };
let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, ref variants, .. } =
@ -1704,7 +1704,7 @@ impl InvalidAtomicOrdering {
&& recognized_names.contains(&method_path.ident.name)
&& let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
&& let Some(impl_did) = cx.tcx.impl_of_method(m_def_id)
&& let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def()
&& let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def()
// skip extension traits, only lint functions from the standard library
&& cx.tcx.trait_id_of_impl(impl_did).is_none()
&& let parent = cx.tcx.parent(adt.did())

View file

@ -286,22 +286,25 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
}
ty::Adt(def, _) => is_def_must_use(cx, def.did(), span),
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
elaborate(cx.tcx, cx.tcx.explicit_item_bounds(def).subst_identity_iter_copied())
// We only care about self bounds for the impl-trait
.filter_only_self()
.find_map(|(pred, _span)| {
// We only look at the `DefId`, so it is safe to skip the binder here.
if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
pred.kind().skip_binder()
{
let def_id = poly_trait_predicate.trait_ref.def_id;
elaborate(
cx.tcx,
cx.tcx.explicit_item_bounds(def).instantiate_identity_iter_copied(),
)
// We only care about self bounds for the impl-trait
.filter_only_self()
.find_map(|(pred, _span)| {
// We only look at the `DefId`, so it is safe to skip the binder here.
if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
pred.kind().skip_binder()
{
let def_id = poly_trait_predicate.trait_ref.def_id;
is_def_must_use(cx, def_id, span)
} else {
None
}
})
.map(|inner| MustUsePath::Opaque(Box::new(inner)))
is_def_must_use(cx, def_id, span)
} else {
None
}
})
.map(|inner| MustUsePath::Opaque(Box::new(inner)))
}
ty::Dynamic(binders, _, _) => binders.iter().find_map(|predicate| {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()