1
Fork 0

Add GenericArgKind::as_{type,const,region}

This commit is contained in:
Maybe Waffle 2023-04-19 14:13:22 +00:00
parent d7f9e81650
commit 3f15521396
8 changed files with 88 additions and 98 deletions

View file

@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
}; };
@ -1182,12 +1181,12 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
let names = get_parameter_names(cx, generics); let names = get_parameter_names(cx, generics);
let template_params: SmallVec<_> = iter::zip(substs, names) let template_params: SmallVec<_> = iter::zip(substs, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
if let GenericArgKind::Type(ty) = kind.unpack() { kind.unpack().as_type().map(|ty| {
let actual_type = let actual_type =
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
let actual_type_di_node = type_di_node(cx, actual_type); let actual_type_di_node = type_di_node(cx, actual_type);
let name = name.as_str(); let name = name.as_str();
Some(unsafe { unsafe {
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
DIB(cx), DIB(cx),
None, None,
@ -1195,10 +1194,8 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
name.len(), name.len(),
actual_type_di_node, actual_type_di_node,
) )
}) }
} else { })
None
}
}) })
.collect(); .collect();

View file

@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
use rustc_session::config::{self, DebugInfo}; use rustc_session::config::{self, DebugInfo};
use rustc_session::Session; use rustc_session::Session;
@ -461,12 +461,12 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let names = get_parameter_names(cx, generics); let names = get_parameter_names(cx, generics);
iter::zip(substs, names) iter::zip(substs, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
if let GenericArgKind::Type(ty) = kind.unpack() { kind.unpack().as_type().map(|ty| {
let actual_type = let actual_type =
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
let actual_type_metadata = type_di_node(cx, actual_type); let actual_type_metadata = type_di_node(cx, actual_type);
let name = name.as_str(); let name = name.as_str();
Some(unsafe { unsafe {
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
DIB(cx), DIB(cx),
None, None,
@ -474,10 +474,8 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
name.len(), name.len(),
actual_type_metadata, actual_type_metadata,
)) ))
}) }
} else { })
None
}
}) })
.collect() .collect()
} else { } else {

View file

@ -67,10 +67,10 @@ impl<'a, 'tcx> VirtualIndex {
/// ref of the type. /// ref of the type.
fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> { fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
for arg in ty.peel_refs().walk() { for arg in ty.peel_refs().walk() {
if let GenericArgKind::Type(ty) = arg.unpack() { if let GenericArgKind::Type(ty) = arg.unpack()
if let ty::Dynamic(data, _, _) = ty.kind() { && let ty::Dynamic(data, _, _) = ty.kind()
return data.principal().expect("expected principal trait object"); {
} return data.principal().expect("expected principal trait object");
} }
} }

View file

@ -17,7 +17,6 @@ use rustc_infer::infer;
use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
@ -250,16 +249,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
} }
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
if let Some(param) = param { match param {
if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() { Some(param) => self.var_for_def(span, param).unpack().as_type().unwrap(),
return ty; None => self.next_ty_var(TypeVariableOrigin {
}
unreachable!()
} else {
self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference, kind: TypeVariableOriginKind::TypeInference,
span, span,
}) }),
} }
} }
@ -269,16 +264,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
param: Option<&ty::GenericParamDef>, param: Option<&ty::GenericParamDef>,
span: Span, span: Span,
) -> Const<'tcx> { ) -> Const<'tcx> {
if let Some(param) = param { match param {
if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() { Some(param) => self.var_for_def(span, param).unpack().as_const().unwrap(),
return ct; None => self.next_const_var(
}
unreachable!()
} else {
self.next_const_var(
ty, ty,
ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span }, ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
) ),
} }
} }

View file

@ -166,10 +166,8 @@ declare_lint_pass!(BoxPointers => [BOX_POINTERS]);
impl BoxPointers { impl BoxPointers {
fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) {
for leaf in ty.walk() { for leaf in ty.walk() {
if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && leaf_ty.is_box() {
if leaf_ty.is_box() { cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
}
} }
} }
} }

View file

@ -103,6 +103,30 @@ impl<'tcx> GenericArgKind<'tcx> {
GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
} }
#[inline]
pub fn as_type(self) -> Option<Ty<'tcx>> {
match self {
GenericArgKind::Type(ty) => Some(ty),
_ => None,
}
}
#[inline]
pub fn as_region(self) -> Option<ty::Region<'tcx>> {
match self {
GenericArgKind::Lifetime(re) => Some(re),
_ => None,
}
}
#[inline]
pub fn as_const(self) -> Option<ty::Const<'tcx>> {
match self {
GenericArgKind::Const(ct) => Some(ct),
_ => None,
}
}
} }
impl<'tcx> fmt::Debug for GenericArg<'tcx> { impl<'tcx> fmt::Debug for GenericArg<'tcx> {
@ -379,22 +403,17 @@ impl<'tcx> InternalSubsts<'tcx> {
#[inline] #[inline]
pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx { pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx {
self.iter() self.iter().filter_map(|k| k.unpack().as_type())
.filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None })
} }
#[inline] #[inline]
pub fn regions(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'tcx { pub fn regions(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'tcx {
self.iter().filter_map(|k| { self.iter().filter_map(|k| k.unpack().as_region())
if let GenericArgKind::Lifetime(lt) = k.unpack() { Some(lt) } else { None }
})
} }
#[inline] #[inline]
pub fn consts(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'tcx { pub fn consts(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'tcx {
self.iter().filter_map(|k| { self.iter().filter_map(|k| k.unpack().as_const())
if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None }
})
} }
#[inline] #[inline]
@ -410,31 +429,28 @@ impl<'tcx> InternalSubsts<'tcx> {
#[inline] #[inline]
#[track_caller] #[track_caller]
pub fn type_at(&self, i: usize) -> Ty<'tcx> { pub fn type_at(&self, i: usize) -> Ty<'tcx> {
if let GenericArgKind::Type(ty) = self[i].unpack() { self[i]
ty .unpack()
} else { .as_type()
bug!("expected type for param #{} in {:?}", i, self); .unwrap_or_else(|| bug!("expected type for param #{} in {:?}", i, self))
}
} }
#[inline] #[inline]
#[track_caller] #[track_caller]
pub fn region_at(&self, i: usize) -> ty::Region<'tcx> { pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
if let GenericArgKind::Lifetime(lt) = self[i].unpack() { self[i]
lt .unpack()
} else { .as_region()
bug!("expected region for param #{} in {:?}", i, self); .unwrap_or_else(|| bug!("expected region for param #{} in {:?}", i, self))
}
} }
#[inline] #[inline]
#[track_caller] #[track_caller]
pub fn const_at(&self, i: usize) -> ty::Const<'tcx> { pub fn const_at(&self, i: usize) -> ty::Const<'tcx> {
if let GenericArgKind::Const(ct) = self[i].unpack() { self[i]
ct .unpack()
} else { .as_const()
bug!("expected const for param #{} in {:?}", i, self); .unwrap_or_else(|| bug!("expected const for param #{} in {:?}", i, self))
}
} }
#[inline] #[inline]

View file

@ -3,7 +3,7 @@ use rustc_errors::Applicability;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, EarlyBinder, GenericArgKind, PredicateKind, SubstsRef, Ty, TyCtxt}; use rustc_middle::ty::{self, EarlyBinder, PredicateKind, SubstsRef, Ty, TyCtxt};
use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES; use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
use rustc_span::{symbol::sym, Span}; use rustc_span::{symbol::sym, Span};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -45,14 +45,12 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> {
// Handle calls to `transmute` // Handle calls to `transmute`
if self.tcx.is_diagnostic_item(sym::transmute, def_id) { if self.tcx.is_diagnostic_item(sym::transmute, def_id) {
let arg_ty = args[0].ty(self.body, self.tcx); let arg_ty = args[0].ty(self.body, self.tcx);
for generic_inner_ty in arg_ty.walk() { for inner_ty in arg_ty.walk().filter_map(|arg| arg.unpack().as_type()) {
if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { if let Some((fn_id, fn_substs)) =
if let Some((fn_id, fn_substs)) = FunctionItemRefChecker::is_fn_ref(inner_ty)
FunctionItemRefChecker::is_fn_ref(inner_ty) {
{ let span = self.nth_arg_span(&args, 0);
let span = self.nth_arg_span(&args, 0); self.emit_lint(fn_id, fn_substs, source_info, span);
self.emit_lint(fn_id, fn_substs, source_info, span);
}
} }
} }
} else { } else {
@ -82,24 +80,22 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs(); let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs();
for (arg_num, arg_def) in arg_defs.iter().enumerate() { for (arg_num, arg_def) in arg_defs.iter().enumerate() {
// For all types reachable from the argument type in the fn sig // For all types reachable from the argument type in the fn sig
for generic_inner_ty in arg_def.walk() { for inner_ty in arg_def.walk().filter_map(|arg| arg.unpack().as_type()) {
if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { // If the inner type matches the type bound by `Pointer`
// If the inner type matches the type bound by `Pointer` if inner_ty == bound_ty {
if inner_ty == bound_ty { // Do a substitution using the parameters from the callsite
// Do a substitution using the parameters from the callsite let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref);
let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref); if let Some((fn_id, fn_substs)) =
if let Some((fn_id, fn_substs)) = FunctionItemRefChecker::is_fn_ref(subst_ty)
FunctionItemRefChecker::is_fn_ref(subst_ty) {
{ let mut span = self.nth_arg_span(args, arg_num);
let mut span = self.nth_arg_span(args, arg_num); if span.from_expansion() {
if span.from_expansion() { // The operand's ctxt wouldn't display the lint since it's inside a macro so
// The operand's ctxt wouldn't display the lint since it's inside a macro so // we have to use the callsite's ctxt.
// we have to use the callsite's ctxt. let callsite_ctxt = span.source_callsite().ctxt();
let callsite_ctxt = span.source_callsite().ctxt(); span = span.with_ctxt(callsite_ctxt);
span = span.with_ctxt(callsite_ctxt);
}
self.emit_lint(fn_id, fn_substs, source_info, span);
} }
self.emit_lint(fn_id, fn_substs, source_info, span);
} }
} }
} }

View file

@ -814,16 +814,10 @@ fn transform_substs<'tcx>(
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
options: TransformTyOptions, options: TransformTyOptions,
) -> SubstsRef<'tcx> { ) -> SubstsRef<'tcx> {
let substs = substs.iter().map(|subst| { let substs = substs.iter().map(|subst| match subst.unpack() {
if let GenericArgKind::Type(ty) = subst.unpack() { GenericArgKind::Type(ty) if is_c_void_ty(tcx, ty) => tcx.mk_unit().into(),
if is_c_void_ty(tcx, ty) { GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(),
tcx.mk_unit().into() _ => subst,
} else {
transform_ty(tcx, ty, options).into()
}
} else {
subst
}
}); });
tcx.mk_substs_from_iter(substs) tcx.mk_substs_from_iter(substs)
} }