Skip to content

Commit 17f6763

Browse files
authored
Rollup merge of #110545 - WaffleLapkin:generic_arg_as_x, r=cjgillot
Add `GenericArgKind::as_{type,const,region}` This allows to make code nicer in some cases
2 parents ae240e2 + 25b9263 commit 17f6763

File tree

8 files changed

+84
-110
lines changed

8 files changed

+84
-110
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind;
2929
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
3030
use rustc_middle::bug;
3131
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
32-
use rustc_middle::ty::subst::GenericArgKind;
3332
use rustc_middle::ty::{
3433
self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
3534
};
@@ -1182,23 +1181,21 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
11821181
let names = get_parameter_names(cx, generics);
11831182
let template_params: SmallVec<_> = iter::zip(substs, names)
11841183
.filter_map(|(kind, name)| {
1185-
if let GenericArgKind::Type(ty) = kind.unpack() {
1184+
kind.as_type().map(|ty| {
11861185
let actual_type =
11871186
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
11881187
let actual_type_di_node = type_di_node(cx, actual_type);
11891188
let name = name.as_str();
1190-
Some(unsafe {
1189+
unsafe {
11911190
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
11921191
DIB(cx),
11931192
None,
11941193
name.as_ptr().cast(),
11951194
name.len(),
11961195
actual_type_di_node,
11971196
)
1198-
})
1199-
} else {
1200-
None
1201-
}
1197+
}
1198+
})
12021199
})
12031200
.collect();
12041201

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap};
2727
use rustc_index::vec::IndexVec;
2828
use rustc_middle::mir;
2929
use rustc_middle::ty::layout::LayoutOf;
30-
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
30+
use rustc_middle::ty::subst::SubstsRef;
3131
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
3232
use rustc_session::config::{self, DebugInfo};
3333
use rustc_session::Session;
@@ -461,23 +461,21 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
461461
let names = get_parameter_names(cx, generics);
462462
iter::zip(substs, names)
463463
.filter_map(|(kind, name)| {
464-
if let GenericArgKind::Type(ty) = kind.unpack() {
464+
kind.as_type().map(|ty| {
465465
let actual_type =
466466
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
467467
let actual_type_metadata = type_di_node(cx, actual_type);
468468
let name = name.as_str();
469-
Some(unsafe {
469+
unsafe {
470470
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
471471
DIB(cx),
472472
None,
473473
name.as_ptr().cast(),
474474
name.len(),
475475
actual_type_metadata,
476476
))
477-
})
478-
} else {
479-
None
480-
}
477+
}
478+
})
481479
})
482480
.collect()
483481
} else {

compiler/rustc_codegen_ssa/src/meth.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ impl<'a, 'tcx> VirtualIndex {
6767
/// ref of the type.
6868
fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
6969
for arg in ty.peel_refs().walk() {
70-
if let GenericArgKind::Type(ty) = arg.unpack() {
71-
if let ty::Dynamic(data, _, _) = ty.kind() {
72-
return data.principal().expect("expected principal trait object");
73-
}
70+
if let GenericArgKind::Type(ty) = arg.unpack()
71+
&& let ty::Dynamic(data, _, _) = ty.kind()
72+
{
73+
return data.principal().expect("expected principal trait object");
7474
}
7575
}
7676

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+8-17
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use rustc_infer::infer;
1717
use rustc_infer::infer::error_reporting::TypeErrCtxt;
1818
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1919
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
20-
use rustc_middle::ty::subst::GenericArgKind;
2120
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
2221
use rustc_session::Session;
2322
use rustc_span::symbol::Ident;
@@ -250,16 +249,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
250249
}
251250

252251
fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
253-
if let Some(param) = param {
254-
if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
255-
return ty;
256-
}
257-
unreachable!()
258-
} else {
259-
self.next_ty_var(TypeVariableOrigin {
252+
match param {
253+
Some(param) => self.var_for_def(span, param).as_type().unwrap(),
254+
None => self.next_ty_var(TypeVariableOrigin {
260255
kind: TypeVariableOriginKind::TypeInference,
261256
span,
262-
})
257+
}),
263258
}
264259
}
265260

@@ -269,16 +264,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
269264
param: Option<&ty::GenericParamDef>,
270265
span: Span,
271266
) -> Const<'tcx> {
272-
if let Some(param) = param {
273-
if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
274-
return ct;
275-
}
276-
unreachable!()
277-
} else {
278-
self.next_const_var(
267+
match param {
268+
Some(param) => self.var_for_def(span, param).as_const().unwrap(),
269+
None => self.next_const_var(
279270
ty,
280271
ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
281-
)
272+
),
282273
}
283274
}
284275

compiler/rustc_lint/src/builtin.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,8 @@ declare_lint_pass!(BoxPointers => [BOX_POINTERS]);
166166
impl BoxPointers {
167167
fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) {
168168
for leaf in ty.walk() {
169-
if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
170-
if leaf_ty.is_box() {
171-
cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
172-
}
169+
if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && leaf_ty.is_box() {
170+
cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
173171
}
174172
}
175173
}

compiler/rustc_middle/src/ty/subst.rs

+35-35
Original file line numberDiff line numberDiff line change
@@ -167,30 +167,45 @@ impl<'tcx> GenericArg<'tcx> {
167167
}
168168
}
169169

170-
/// Unpack the `GenericArg` as a region when it is known certainly to be a region.
171-
pub fn expect_region(self) -> ty::Region<'tcx> {
170+
#[inline]
171+
pub fn as_type(self) -> Option<Ty<'tcx>> {
172+
match self.unpack() {
173+
GenericArgKind::Type(ty) => Some(ty),
174+
_ => None,
175+
}
176+
}
177+
178+
#[inline]
179+
pub fn as_region(self) -> Option<ty::Region<'tcx>> {
172180
match self.unpack() {
173-
GenericArgKind::Lifetime(lt) => lt,
174-
_ => bug!("expected a region, but found another kind"),
181+
GenericArgKind::Lifetime(re) => Some(re),
182+
_ => None,
175183
}
176184
}
177185

186+
#[inline]
187+
pub fn as_const(self) -> Option<ty::Const<'tcx>> {
188+
match self.unpack() {
189+
GenericArgKind::Const(ct) => Some(ct),
190+
_ => None,
191+
}
192+
}
193+
194+
/// Unpack the `GenericArg` as a region when it is known certainly to be a region.
195+
pub fn expect_region(self) -> ty::Region<'tcx> {
196+
self.as_region().unwrap_or_else(|| bug!("expected a region, but found another kind"))
197+
}
198+
178199
/// Unpack the `GenericArg` as a type when it is known certainly to be a type.
179200
/// This is true in cases where `Substs` is used in places where the kinds are known
180201
/// to be limited (e.g. in tuples, where the only parameters are type parameters).
181202
pub fn expect_ty(self) -> Ty<'tcx> {
182-
match self.unpack() {
183-
GenericArgKind::Type(ty) => ty,
184-
_ => bug!("expected a type, but found another kind"),
185-
}
203+
self.as_type().unwrap_or_else(|| bug!("expected a type, but found another kind"))
186204
}
187205

188206
/// Unpack the `GenericArg` as a const when it is known certainly to be a const.
189207
pub fn expect_const(self) -> ty::Const<'tcx> {
190-
match self.unpack() {
191-
GenericArgKind::Const(c) => c,
192-
_ => bug!("expected a const, but found another kind"),
193-
}
208+
self.as_const().unwrap_or_else(|| bug!("expected a const, but found another kind"))
194209
}
195210

196211
pub fn is_non_region_infer(self) -> bool {
@@ -369,22 +384,17 @@ impl<'tcx> InternalSubsts<'tcx> {
369384

370385
#[inline]
371386
pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx {
372-
self.iter()
373-
.filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None })
387+
self.iter().filter_map(|k| k.as_type())
374388
}
375389

376390
#[inline]
377391
pub fn regions(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'tcx {
378-
self.iter().filter_map(|k| {
379-
if let GenericArgKind::Lifetime(lt) = k.unpack() { Some(lt) } else { None }
380-
})
392+
self.iter().filter_map(|k| k.as_region())
381393
}
382394

383395
#[inline]
384396
pub fn consts(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'tcx {
385-
self.iter().filter_map(|k| {
386-
if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None }
387-
})
397+
self.iter().filter_map(|k| k.as_const())
388398
}
389399

390400
#[inline]
@@ -400,31 +410,21 @@ impl<'tcx> InternalSubsts<'tcx> {
400410
#[inline]
401411
#[track_caller]
402412
pub fn type_at(&self, i: usize) -> Ty<'tcx> {
403-
if let GenericArgKind::Type(ty) = self[i].unpack() {
404-
ty
405-
} else {
406-
bug!("expected type for param #{} in {:?}", i, self);
407-
}
413+
self[i].as_type().unwrap_or_else(|| bug!("expected type for param #{} in {:?}", i, self))
408414
}
409415

410416
#[inline]
411417
#[track_caller]
412418
pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
413-
if let GenericArgKind::Lifetime(lt) = self[i].unpack() {
414-
lt
415-
} else {
416-
bug!("expected region for param #{} in {:?}", i, self);
417-
}
419+
self[i]
420+
.as_region()
421+
.unwrap_or_else(|| bug!("expected region for param #{} in {:?}", i, self))
418422
}
419423

420424
#[inline]
421425
#[track_caller]
422426
pub fn const_at(&self, i: usize) -> ty::Const<'tcx> {
423-
if let GenericArgKind::Const(ct) = self[i].unpack() {
424-
ct
425-
} else {
426-
bug!("expected const for param #{} in {:?}", i, self);
427-
}
427+
self[i].as_const().unwrap_or_else(|| bug!("expected const for param #{} in {:?}", i, self))
428428
}
429429

430430
#[inline]

compiler/rustc_mir_transform/src/function_item_references.rs

+22-26
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_errors::Applicability;
33
use rustc_hir::def_id::DefId;
44
use rustc_middle::mir::visit::Visitor;
55
use rustc_middle::mir::*;
6-
use rustc_middle::ty::{self, EarlyBinder, GenericArgKind, PredicateKind, SubstsRef, Ty, TyCtxt};
6+
use rustc_middle::ty::{self, EarlyBinder, PredicateKind, SubstsRef, Ty, TyCtxt};
77
use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
88
use rustc_span::{symbol::sym, Span};
99
use rustc_target::spec::abi::Abi;
@@ -45,14 +45,12 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> {
4545
// Handle calls to `transmute`
4646
if self.tcx.is_diagnostic_item(sym::transmute, def_id) {
4747
let arg_ty = args[0].ty(self.body, self.tcx);
48-
for generic_inner_ty in arg_ty.walk() {
49-
if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() {
50-
if let Some((fn_id, fn_substs)) =
51-
FunctionItemRefChecker::is_fn_ref(inner_ty)
52-
{
53-
let span = self.nth_arg_span(&args, 0);
54-
self.emit_lint(fn_id, fn_substs, source_info, span);
55-
}
48+
for inner_ty in arg_ty.walk().filter_map(|arg| arg.as_type()) {
49+
if let Some((fn_id, fn_substs)) =
50+
FunctionItemRefChecker::is_fn_ref(inner_ty)
51+
{
52+
let span = self.nth_arg_span(&args, 0);
53+
self.emit_lint(fn_id, fn_substs, source_info, span);
5654
}
5755
}
5856
} else {
@@ -82,24 +80,22 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
8280
let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs();
8381
for (arg_num, arg_def) in arg_defs.iter().enumerate() {
8482
// For all types reachable from the argument type in the fn sig
85-
for generic_inner_ty in arg_def.walk() {
86-
if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() {
87-
// If the inner type matches the type bound by `Pointer`
88-
if inner_ty == bound_ty {
89-
// Do a substitution using the parameters from the callsite
90-
let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref);
91-
if let Some((fn_id, fn_substs)) =
92-
FunctionItemRefChecker::is_fn_ref(subst_ty)
93-
{
94-
let mut span = self.nth_arg_span(args, arg_num);
95-
if span.from_expansion() {
96-
// The operand's ctxt wouldn't display the lint since it's inside a macro so
97-
// we have to use the callsite's ctxt.
98-
let callsite_ctxt = span.source_callsite().ctxt();
99-
span = span.with_ctxt(callsite_ctxt);
100-
}
101-
self.emit_lint(fn_id, fn_substs, source_info, span);
83+
for inner_ty in arg_def.walk().filter_map(|arg| arg.as_type()) {
84+
// If the inner type matches the type bound by `Pointer`
85+
if inner_ty == bound_ty {
86+
// Do a substitution using the parameters from the callsite
87+
let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref);
88+
if let Some((fn_id, fn_substs)) =
89+
FunctionItemRefChecker::is_fn_ref(subst_ty)
90+
{
91+
let mut span = self.nth_arg_span(args, arg_num);
92+
if span.from_expansion() {
93+
// The operand's ctxt wouldn't display the lint since it's inside a macro so
94+
// we have to use the callsite's ctxt.
95+
let callsite_ctxt = span.source_callsite().ctxt();
96+
span = span.with_ctxt(callsite_ctxt);
10297
}
98+
self.emit_lint(fn_id, fn_substs, source_info, span);
10399
}
104100
}
105101
}

compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -814,16 +814,10 @@ fn transform_substs<'tcx>(
814814
substs: SubstsRef<'tcx>,
815815
options: TransformTyOptions,
816816
) -> SubstsRef<'tcx> {
817-
let substs = substs.iter().map(|subst| {
818-
if let GenericArgKind::Type(ty) = subst.unpack() {
819-
if is_c_void_ty(tcx, ty) {
820-
tcx.mk_unit().into()
821-
} else {
822-
transform_ty(tcx, ty, options).into()
823-
}
824-
} else {
825-
subst
826-
}
817+
let substs = substs.iter().map(|subst| match subst.unpack() {
818+
GenericArgKind::Type(ty) if is_c_void_ty(tcx, ty) => tcx.mk_unit().into(),
819+
GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(),
820+
_ => subst,
827821
});
828822
tcx.mk_substs_from_iter(substs)
829823
}

0 commit comments

Comments
 (0)