Skip to content

Commit

Permalink
Auto merge of #95309 - lcnr:dropck-cleanup, r=nikomatsakis
Browse files Browse the repository at this point in the history
rewrite `ensure_drop_params_and_item_params_correspond`

actually relating types here seems like it's overkill
  • Loading branch information
bors committed May 20, 2022
2 parents cd73afa + 4a82bc9 commit 512a328
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 223 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ pub struct InferCtxtInner<'tcx> {
///
/// Before running `resolve_regions_and_report_errors`, the creator
/// of the inference context is expected to invoke
/// `process_region_obligations` (defined in `self::region_obligations`)
/// [`InferCtxt::process_registered_region_obligations`]
/// for each body-id in this map, which will process the
/// obligations within. This is expected to be done 'late enough'
/// that all type inference variables have been bound and so forth.
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_infer/src/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
///
/// # Parameters
///
/// - `region_bound_pairs`: the set of region bounds implied by
/// - `region_bound_pairs_map`: the set of region bounds implied by
/// the parameters and where-clauses. In particular, each pair
/// `('a, K)` in this list tells us that the bounds in scope
/// indicate that `K: 'a`, where `K` is either a generic
Expand All @@ -147,12 +147,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// - `param_env` is the parameter environment for the enclosing function.
/// - `body_id` is the body-id whose region obligations are being
/// processed.
///
/// # Returns
///
/// This function may have to perform normalizations, and hence it
/// returns an `InferOk` with subobligations that must be
/// processed.
#[instrument(level = "debug", skip(self, region_bound_pairs_map))]
pub fn process_registered_region_obligations(
&self,
Expand Down
124 changes: 92 additions & 32 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFolder};
use crate::ty::layout::IntegerExt;
use crate::ty::query::TyCtxtAt;
use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
use crate::ty::{
self, DebruijnIndex, DefIdTree, EarlyBinder, List, ReEarlyBound, Ty, TyCtxt, TyKind::*,
TypeFoldable,
};
use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
use rustc_apfloat::Float as _;
use rustc_ast as ast;
use rustc_attr::{self as attr, SignedInt, UnsignedInt};
Expand All @@ -18,6 +15,7 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::GrowableBitSet;
use rustc_macros::HashStable;
use rustc_span::{sym, DUMMY_SP};
use rustc_target::abi::{Integer, Size, TargetDataLayout};
Expand All @@ -32,6 +30,19 @@ pub struct Discr<'tcx> {
pub ty: Ty<'tcx>,
}

/// Used as an input to [`TyCtxt::uses_unique_generic_params`].
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum IgnoreRegions {
Yes,
No,
}

#[derive(Copy, Clone, Debug)]
pub enum NotUniqueParam<'tcx> {
DuplicateParam(ty::GenericArg<'tcx>),
NotParam(ty::GenericArg<'tcx>),
}

impl<'tcx> fmt::Display for Discr<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self.ty.kind() {
Expand All @@ -49,8 +60,8 @@ impl<'tcx> fmt::Display for Discr<'tcx> {

fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
let (int, signed) = match *ty.kind() {
Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false),
ty::Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
ty::Uint(uty) => (Integer::from_uint_ty(&tcx, uty), false),
_ => bug!("non integer discriminant"),
};
(int.size(), signed)
Expand Down Expand Up @@ -176,7 +187,7 @@ impl<'tcx> TyCtxt<'tcx> {
if let ty::Adt(def, substs) = *ty.kind() {
for field in def.all_fields() {
let field_ty = field.ty(self, substs);
if let Error(_) = field_ty.kind() {
if let ty::Error(_) = field_ty.kind() {
return true;
}
}
Expand Down Expand Up @@ -311,7 +322,7 @@ impl<'tcx> TyCtxt<'tcx> {
let (mut a, mut b) = (source, target);
loop {
match (&a.kind(), &b.kind()) {
(&Adt(a_def, a_substs), &Adt(b_def, b_substs))
(&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
if a_def == b_def && a_def.is_struct() =>
{
if let Some(f) = a_def.non_enum_variant().fields.last() {
Expand All @@ -321,7 +332,7 @@ impl<'tcx> TyCtxt<'tcx> {
break;
}
}
(&Tuple(a_tys), &Tuple(b_tys)) if a_tys.len() == b_tys.len() => {
(&ty::Tuple(a_tys), &ty::Tuple(b_tys)) if a_tys.len() == b_tys.len() => {
if let Some(&a_last) = a_tys.last() {
a = a_last;
b = *b_tys.last().unwrap();
Expand Down Expand Up @@ -427,7 +438,7 @@ impl<'tcx> TyCtxt<'tcx> {
.filter(|&(_, k)| {
match k.unpack() {
GenericArgKind::Lifetime(region) => match region.kind() {
ReEarlyBound(ref ebr) => {
ty::ReEarlyBound(ref ebr) => {
!impl_generics.region_param(ebr, self).pure_wrt_drop
}
// Error: not a region param
Expand All @@ -453,6 +464,47 @@ impl<'tcx> TyCtxt<'tcx> {
result
}

/// Checks whether each generic argument is simply a unique generic parameter.
pub fn uses_unique_generic_params(
self,
substs: SubstsRef<'tcx>,
ignore_regions: IgnoreRegions,
) -> Result<(), NotUniqueParam<'tcx>> {
let mut seen = GrowableBitSet::default();
for arg in substs {
match arg.unpack() {
GenericArgKind::Lifetime(lt) => {
if ignore_regions == IgnoreRegions::No {
let ty::ReEarlyBound(p) = lt.kind() else {
return Err(NotUniqueParam::NotParam(lt.into()))
};
if !seen.insert(p.index) {
return Err(NotUniqueParam::DuplicateParam(lt.into()));
}
}
}
GenericArgKind::Type(t) => match t.kind() {
ty::Param(p) => {
if !seen.insert(p.index) {
return Err(NotUniqueParam::DuplicateParam(t.into()));
}
}
_ => return Err(NotUniqueParam::NotParam(t.into())),
},
GenericArgKind::Const(c) => match c.val() {
ty::ConstKind::Param(p) => {
if !seen.insert(p.index) {
return Err(NotUniqueParam::DuplicateParam(c.into()));
}
}
_ => return Err(NotUniqueParam::NotParam(c.into())),
},
}
}

Ok(())
}

/// Returns `true` if `def_id` refers to a closure (e.g., `|x| x * 2`). Note
/// that closures have a `DefId`, but the closure *expression* also
/// has a `HirId` that is located within the context where the
Expand Down Expand Up @@ -594,30 +646,33 @@ impl<'tcx> TyCtxt<'tcx> {
if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
}

pub fn bound_type_of(self, def_id: DefId) -> EarlyBinder<Ty<'tcx>> {
EarlyBinder(self.type_of(def_id))
pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}

pub fn bound_fn_sig(self, def_id: DefId) -> EarlyBinder<ty::PolyFnSig<'tcx>> {
EarlyBinder(self.fn_sig(def_id))
pub fn bound_fn_sig(self, def_id: DefId) -> ty::EarlyBinder<ty::PolyFnSig<'tcx>> {
ty::EarlyBinder(self.fn_sig(def_id))
}

pub fn bound_impl_trait_ref(self, def_id: DefId) -> Option<EarlyBinder<ty::TraitRef<'tcx>>> {
self.impl_trait_ref(def_id).map(|i| EarlyBinder(i))
pub fn bound_impl_trait_ref(
self,
def_id: DefId,
) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> {
self.impl_trait_ref(def_id).map(|i| ty::EarlyBinder(i))
}

pub fn bound_explicit_item_bounds(
self,
def_id: DefId,
) -> EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> {
EarlyBinder(self.explicit_item_bounds(def_id))
) -> ty::EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> {
ty::EarlyBinder(self.explicit_item_bounds(def_id))
}

pub fn bound_item_bounds(
self,
def_id: DefId,
) -> EarlyBinder<&'tcx ty::List<ty::Predicate<'tcx>>> {
EarlyBinder(self.item_bounds(def_id))
) -> ty::EarlyBinder<&'tcx ty::List<ty::Predicate<'tcx>>> {
ty::EarlyBinder(self.item_bounds(def_id))
}
}

Expand Down Expand Up @@ -930,35 +985,40 @@ impl<'tcx> Ty<'tcx> {
pub fn is_structural_eq_shallow(self, tcx: TyCtxt<'tcx>) -> bool {
match self.kind() {
// Look for an impl of both `PartialStructuralEq` and `StructuralEq`.
Adt(..) => tcx.has_structural_eq_impls(self),
ty::Adt(..) => tcx.has_structural_eq_impls(self),

// Primitive types that satisfy `Eq`.
Bool | Char | Int(_) | Uint(_) | Str | Never => true,
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Str | ty::Never => true,

// Composite types that satisfy `Eq` when all of their fields do.
//
// Because this function is "shallow", we return `true` for these composites regardless
// of the type(s) contained within.
Ref(..) | Array(..) | Slice(_) | Tuple(..) => true,
ty::Ref(..) | ty::Array(..) | ty::Slice(_) | ty::Tuple(..) => true,

// Raw pointers use bitwise comparison.
RawPtr(_) | FnPtr(_) => true,
ty::RawPtr(_) | ty::FnPtr(_) => true,

// Floating point numbers are not `Eq`.
Float(_) => false,
ty::Float(_) => false,

// Conservatively return `false` for all others...

// Anonymous function types
FnDef(..) | Closure(..) | Dynamic(..) | Generator(..) => false,
ty::FnDef(..) | ty::Closure(..) | ty::Dynamic(..) | ty::Generator(..) => false,

// Generic or inferred types
//
// FIXME(ecstaticmorse): Maybe we should `bug` here? This should probably only be
// called for known, fully-monomorphized types.
Projection(_) | Opaque(..) | Param(_) | Bound(..) | Placeholder(_) | Infer(_) => false,
ty::Projection(_)
| ty::Opaque(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(_) => false,

Foreign(_) | GeneratorWitness(..) | Error(_) => false,
ty::Foreign(_) | ty::GeneratorWitness(..) | ty::Error(_) => false,
}
}

Expand All @@ -974,13 +1034,13 @@ impl<'tcx> Ty<'tcx> {
/// - `&'a *const &'b u8 -> *const &'b u8`
pub fn peel_refs(self) -> Ty<'tcx> {
let mut ty = self;
while let Ref(_, inner_ty, _) = ty.kind() {
while let ty::Ref(_, inner_ty, _) = ty.kind() {
ty = *inner_ty;
}
ty
}

pub fn outer_exclusive_binder(self) -> DebruijnIndex {
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
self.0.outer_exclusive_binder
}
}
Expand Down Expand Up @@ -1177,8 +1237,8 @@ pub struct AlwaysRequiresDrop;
/// with their underlying types.
pub fn normalize_opaque_types<'tcx>(
tcx: TyCtxt<'tcx>,
val: &'tcx List<ty::Predicate<'tcx>>,
) -> &'tcx List<ty::Predicate<'tcx>> {
val: &'tcx ty::List<ty::Predicate<'tcx>>,
) -> &'tcx ty::List<ty::Predicate<'tcx>> {
let mut visitor = OpaqueTypeExpander {
seen_opaque_tys: FxHashSet::default(),
expanded_cache: FxHashMap::default(),
Expand Down
Loading

0 comments on commit 512a328

Please sign in to comment.