1 //! Miscellaneous type-system utilities that are too small to deserve their own modules.
4 use crate::hir
::def
::DefKind
;
5 use crate::hir
::def_id
::DefId
;
6 use crate::hir
::map
::DefPathData
;
7 use crate::mir
::interpret
::{sign_extend, truncate}
;
8 use crate::ich
::NodeIdHashingMode
;
9 use crate::traits
::{self, ObligationCause}
;
10 use crate::ty
::{self, DefIdTree, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}
;
11 use crate::ty
::subst
::{Subst, InternalSubsts, SubstsRef, GenericArgKind}
;
12 use crate::ty
::query
::TyCtxtAt
;
13 use crate::ty
::TyKind
::*;
14 use crate::ty
::layout
::{Integer, IntegerExt}
;
15 use crate::util
::common
::ErrorReported
;
16 use crate::middle
::lang_items
;
18 use rustc_data_structures
::stable_hasher
::{StableHasher, HashStable}
;
19 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet}
;
20 use rustc_macros
::HashStable
;
23 use syntax
::attr
::{self, SignedInt, UnsignedInt}
;
24 use syntax_pos
::{Span, DUMMY_SP}
;
26 #[derive(Copy, Clone, Debug)]
27 pub struct Discr
<'tcx
> {
28 /// Bit representation of the discriminant (e.g., `-128i8` is `0xFF_u128`).
33 impl<'tcx
> fmt
::Display
for Discr
<'tcx
> {
34 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
37 let size
= ty
::tls
::with(|tcx
| {
38 Integer
::from_attr(&tcx
, SignedInt(ity
)).size()
41 // sign extend the raw representation to be an i128
42 let x
= sign_extend(x
, size
) as i128
;
45 _
=> write
!(fmt
, "{}", self.val
),
50 impl<'tcx
> Discr
<'tcx
> {
51 /// Adds `1` to the value and wraps around if the maximum for the type is reached.
52 pub fn wrap_incr(self, tcx
: TyCtxt
<'tcx
>) -> Self {
53 self.checked_add(tcx
, 1).0
55 pub fn checked_add(self, tcx
: TyCtxt
<'tcx
>, n
: u128
) -> (Self, bool
) {
56 let (int
, signed
) = match self.ty
.kind
{
57 Int(ity
) => (Integer
::from_attr(&tcx
, SignedInt(ity
)), true),
58 Uint(uty
) => (Integer
::from_attr(&tcx
, UnsignedInt(uty
)), false),
59 _
=> bug
!("non integer discriminant"),
62 let size
= int
.size();
63 let bit_size
= int
.size().bits();
64 let shift
= 128 - bit_size
;
67 sign_extend(u
, size
) as i128
69 let min
= sext(1_u128 << (bit_size
- 1));
70 let max
= i128
::max_value() >> shift
;
71 let val
= sext(self.val
);
72 assert
!(n
< (i128
::max_value() as u128
));
74 let oflo
= val
> max
- n
;
76 min
+ (n
- (max
- val
) - 1)
80 // zero the upper bits
81 let val
= val
as u128
;
82 let val
= truncate(val
, size
);
88 let max
= u128
::max_value() >> shift
;
90 let oflo
= val
> max
- n
;
104 pub trait IntTypeExt
{
105 fn to_ty
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Ty
<'tcx
>;
106 fn disr_incr
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>, val
: Option
<Discr
<'tcx
>>) -> Option
<Discr
<'tcx
>>;
107 fn initial_discriminant
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Discr
<'tcx
>;
110 impl IntTypeExt
for attr
::IntType
{
111 fn to_ty
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Ty
<'tcx
> {
113 SignedInt(ast
::IntTy
::I8
) => tcx
.types
.i8,
114 SignedInt(ast
::IntTy
::I16
) => tcx
.types
.i16,
115 SignedInt(ast
::IntTy
::I32
) => tcx
.types
.i32,
116 SignedInt(ast
::IntTy
::I64
) => tcx
.types
.i64,
117 SignedInt(ast
::IntTy
::I128
) => tcx
.types
.i128
,
118 SignedInt(ast
::IntTy
::Isize
) => tcx
.types
.isize,
119 UnsignedInt(ast
::UintTy
::U8
) => tcx
.types
.u8,
120 UnsignedInt(ast
::UintTy
::U16
) => tcx
.types
.u16,
121 UnsignedInt(ast
::UintTy
::U32
) => tcx
.types
.u32,
122 UnsignedInt(ast
::UintTy
::U64
) => tcx
.types
.u64,
123 UnsignedInt(ast
::UintTy
::U128
) => tcx
.types
.u128
,
124 UnsignedInt(ast
::UintTy
::Usize
) => tcx
.types
.usize,
128 fn initial_discriminant
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Discr
<'tcx
> {
135 fn disr_incr
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>, val
: Option
<Discr
<'tcx
>>) -> Option
<Discr
<'tcx
>> {
136 if let Some(val
) = val
{
137 assert_eq
!(self.to_ty(tcx
), val
.ty
);
138 let (new
, oflo
) = val
.checked_add(tcx
, 1);
145 Some(self.initial_discriminant(tcx
))
152 pub enum CopyImplementationError
<'tcx
> {
153 InfrigingFields(Vec
<&'tcx ty
::FieldDef
>),
158 /// Describes whether a type is representable. For types that are not
159 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
160 /// distinguish between types that are recursive with themselves and types that
161 /// contain a different recursive type. These cases can therefore be treated
162 /// differently when reporting errors.
164 /// The ordering of the cases is significant. They are sorted so that cmp::max
165 /// will keep the "more erroneous" of two values.
166 #[derive(Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
167 pub enum Representability
{
170 SelfRecursive(Vec
<Span
>),
173 impl<'tcx
> ty
::ParamEnv
<'tcx
> {
174 pub fn can_type_implement_copy(
178 ) -> Result
<(), CopyImplementationError
<'tcx
>> {
179 // FIXME: (@jroesch) float this code up
180 tcx
.infer_ctxt().enter(|infcx
| {
181 let (adt
, substs
) = match self_type
.kind
{
182 // These types used to have a builtin impl.
183 // Now libcore provides that impl.
184 ty
::Uint(_
) | ty
::Int(_
) | ty
::Bool
| ty
::Float(_
) |
185 ty
::Char
| ty
::RawPtr(..) | ty
::Never
|
186 ty
::Ref(_
, _
, hir
::Mutability
::Immutable
) => return Ok(()),
188 ty
::Adt(adt
, substs
) => (adt
, substs
),
190 _
=> return Err(CopyImplementationError
::NotAnAdt
),
193 let mut infringing
= Vec
::new();
194 for variant
in &adt
.variants
{
195 for field
in &variant
.fields
{
196 let ty
= field
.ty(tcx
, substs
);
197 if ty
.references_error() {
200 let span
= tcx
.def_span(field
.did
);
201 let cause
= ObligationCause { span, ..ObligationCause::dummy() }
;
202 let ctx
= traits
::FulfillmentContext
::new();
203 match traits
::fully_normalize(&infcx
, ctx
, cause
, self, &ty
) {
204 Ok(ty
) => if !infcx
.type_is_copy_modulo_regions(self, ty
, span
) {
205 infringing
.push(field
);
208 infcx
.report_fulfillment_errors(&errors
, None
, false);
213 if !infringing
.is_empty() {
214 return Err(CopyImplementationError
::InfrigingFields(infringing
));
216 if adt
.has_dtor(tcx
) {
217 return Err(CopyImplementationError
::HasDestructor
);
225 impl<'tcx
> TyCtxt
<'tcx
> {
226 /// Creates a hash of the type `Ty` which will be the same no matter what crate
227 /// context it's calculated within. This is used by the `type_id` intrinsic.
228 pub fn type_id_hash(self, ty
: Ty
<'tcx
>) -> u64 {
229 let mut hasher
= StableHasher
::new();
230 let mut hcx
= self.create_stable_hashing_context();
232 // We want the type_id be independent of the types free regions, so we
233 // erase them. The erase_regions() call will also anonymize bound
234 // regions, which is desirable too.
235 let ty
= self.erase_regions(&ty
);
237 hcx
.while_hashing_spans(false, |hcx
| {
238 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
239 ty
.hash_stable(hcx
, &mut hasher
);
246 impl<'tcx
> TyCtxt
<'tcx
> {
247 pub fn has_error_field(self, ty
: Ty
<'tcx
>) -> bool
{
248 if let ty
::Adt(def
, substs
) = ty
.kind
{
249 for field
in def
.all_fields() {
250 let field_ty
= field
.ty(self, substs
);
251 if let Error
= field_ty
.kind
{
259 /// Attempts to returns the deeply last field of nested structures, but
260 /// does not apply any normalization in its search. Returns the same type
261 /// if input `ty` is not a structure at all.
262 pub fn struct_tail_without_normalization(self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
>
265 tcx
.struct_tail_with_normalize(ty
, |ty
| ty
)
268 /// Returns the deeply last field of nested structures, or the same type if
269 /// not a structure at all. Corresponds to the only possible unsized field,
270 /// and its type can be used to determine unsizing strategy.
272 /// Should only be called if `ty` has no inference variables and does not
273 /// need its lifetimes preserved (e.g. as part of codegen); otherwise
274 /// normalization attempt may cause compiler bugs.
275 pub fn struct_tail_erasing_lifetimes(self,
277 param_env
: ty
::ParamEnv
<'tcx
>)
281 tcx
.struct_tail_with_normalize(ty
, |ty
| tcx
.normalize_erasing_regions(param_env
, ty
))
284 /// Returns the deeply last field of nested structures, or the same type if
285 /// not a structure at all. Corresponds to the only possible unsized field,
286 /// and its type can be used to determine unsizing strategy.
288 /// This is parameterized over the normalization strategy (i.e. how to
289 /// handle `<T as Trait>::Assoc` and `impl Trait`); pass the identity
290 /// function to indicate no normalization should take place.
292 /// See also `struct_tail_erasing_lifetimes`, which is suitable for use
294 pub fn struct_tail_with_normalize(self,
296 normalize
: impl Fn(Ty
<'tcx
>) -> Ty
<'tcx
>)
301 ty
::Adt(def
, substs
) => {
302 if !def
.is_struct() {
305 match def
.non_enum_variant().fields
.last() {
306 Some(f
) => ty
= f
.ty(self, substs
),
312 if let Some((&last_ty
, _
)) = tys
.split_last() {
313 ty
= last_ty
.expect_ty();
319 ty
::Projection(_
) | ty
::Opaque(..) => {
320 let normalized
= normalize(ty
);
321 if ty
== normalized
{
336 /// Same as applying `struct_tail` on `source` and `target`, but only
337 /// keeps going as long as the two types are instances of the same
338 /// structure definitions.
339 /// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
340 /// whereas struct_tail produces `T`, and `Trait`, respectively.
342 /// Should only be called if the types have no inference variables and do
343 /// not need their lifetimes preserved (e.g., as part of codegen); otherwise,
344 /// normalization attempt may cause compiler bugs.
345 pub fn struct_lockstep_tails_erasing_lifetimes(self,
348 param_env
: ty
::ParamEnv
<'tcx
>)
349 -> (Ty
<'tcx
>, Ty
<'tcx
>)
352 tcx
.struct_lockstep_tails_with_normalize(
353 source
, target
, |ty
| tcx
.normalize_erasing_regions(param_env
, ty
))
356 /// Same as applying `struct_tail` on `source` and `target`, but only
357 /// keeps going as long as the two types are instances of the same
358 /// structure definitions.
359 /// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
360 /// whereas struct_tail produces `T`, and `Trait`, respectively.
362 /// See also `struct_lockstep_tails_erasing_lifetimes`, which is suitable for use
364 pub fn struct_lockstep_tails_with_normalize(self,
367 normalize
: impl Fn(Ty
<'tcx
>) -> Ty
<'tcx
>)
368 -> (Ty
<'tcx
>, Ty
<'tcx
>)
370 let (mut a
, mut b
) = (source
, target
);
372 match (&a
.kind
, &b
.kind
) {
373 (&Adt(a_def
, a_substs
), &Adt(b_def
, b_substs
))
374 if a_def
== b_def
&& a_def
.is_struct() => {
375 if let Some(f
) = a_def
.non_enum_variant().fields
.last() {
376 a
= f
.ty(self, a_substs
);
377 b
= f
.ty(self, b_substs
);
382 (&Tuple(a_tys
), &Tuple(b_tys
))
383 if a_tys
.len() == b_tys
.len() => {
384 if let Some(a_last
) = a_tys
.last() {
385 a
= a_last
.expect_ty();
386 b
= b_tys
.last().unwrap().expect_ty();
391 (ty
::Projection(_
), _
) | (ty
::Opaque(..), _
) |
392 (_
, ty
::Projection(_
)) | (_
, ty
::Opaque(..)) => {
393 // If either side is a projection, attempt to
394 // progress via normalization. (Should be safe to
395 // apply to both sides as normalization is
397 let a_norm
= normalize(a
);
398 let b_norm
= normalize(b
);
399 if a
== a_norm
&& b
== b_norm
{
413 /// Given a set of predicates that apply to an object type, returns
414 /// the region bounds that the (erased) `Self` type must
415 /// outlive. Precisely *because* the `Self` type is erased, the
416 /// parameter `erased_self_ty` must be supplied to indicate what type
417 /// has been used to represent `Self` in the predicates
418 /// themselves. This should really be a unique type; `FreshTy(0)` is a
421 /// N.B., in some cases, particularly around higher-ranked bounds,
422 /// this function returns a kind of conservative approximation.
423 /// That is, all regions returned by this function are definitely
424 /// required, but there may be other region bounds that are not
425 /// returned, as well as requirements like `for<'a> T: 'a`.
427 /// Requires that trait definitions have been processed so that we can
428 /// elaborate predicates and walk supertraits.
430 // FIXME: callers may only have a `&[Predicate]`, not a `Vec`, so that's
431 // what this code should accept.
432 pub fn required_region_bounds(self,
433 erased_self_ty
: Ty
<'tcx
>,
434 predicates
: Vec
<ty
::Predicate
<'tcx
>>)
435 -> Vec
<ty
::Region
<'tcx
>> {
436 debug
!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
440 assert
!(!erased_self_ty
.has_escaping_bound_vars());
442 traits
::elaborate_predicates(self, predicates
)
443 .filter_map(|predicate
| {
445 ty
::Predicate
::Projection(..) |
446 ty
::Predicate
::Trait(..) |
447 ty
::Predicate
::Subtype(..) |
448 ty
::Predicate
::WellFormed(..) |
449 ty
::Predicate
::ObjectSafe(..) |
450 ty
::Predicate
::ClosureKind(..) |
451 ty
::Predicate
::RegionOutlives(..) |
452 ty
::Predicate
::ConstEvaluatable(..) => {
455 ty
::Predicate
::TypeOutlives(predicate
) => {
456 // Search for a bound of the form `erased_self_ty
457 // : 'a`, but be wary of something like `for<'a>
458 // erased_self_ty : 'a` (we interpret a
459 // higher-ranked bound like that as 'static,
460 // though at present the code in `fulfill.rs`
461 // considers such bounds to be unsatisfiable, so
462 // it's kind of a moot point since you could never
463 // construct such an object, but this seems
464 // correct even if that code changes).
465 let ty
::OutlivesPredicate(ref t
, ref r
) = predicate
.skip_binder();
466 if t
== &erased_self_ty
&& !r
.has_escaping_bound_vars() {
477 /// Calculate the destructor of a given type.
478 pub fn calculate_dtor(
481 validate
: &mut dyn FnMut(Self, DefId
) -> Result
<(), ErrorReported
>
482 ) -> Option
<ty
::Destructor
> {
483 let drop_trait
= if let Some(def_id
) = self.lang_items().drop_trait() {
489 self.ensure().coherent_trait(drop_trait
);
491 let mut dtor_did
= None
;
492 let ty
= self.type_of(adt_did
);
493 self.for_each_relevant_impl(drop_trait
, ty
, |impl_did
| {
494 if let Some(item
) = self.associated_items(impl_did
).next() {
495 if validate(self, impl_did
).is_ok() {
496 dtor_did
= Some(item
.def_id
);
501 Some(ty
::Destructor { did: dtor_did? }
)
504 /// Returns the set of types that are required to be alive in
505 /// order to run the destructor of `def` (see RFCs 769 and
508 /// Note that this returns only the constraints for the
509 /// destructor of `def` itself. For the destructors of the
510 /// contents, you need `adt_dtorck_constraint`.
511 pub fn destructor_constraints(self, def
: &'tcx ty
::AdtDef
)
512 -> Vec
<ty
::subst
::GenericArg
<'tcx
>>
514 let dtor
= match def
.destructor(self) {
516 debug
!("destructor_constraints({:?}) - no dtor", def
.did
);
519 Some(dtor
) => dtor
.did
522 let impl_def_id
= self.associated_item(dtor
).container
.id();
523 let impl_generics
= self.generics_of(impl_def_id
);
525 // We have a destructor - all the parameters that are not
526 // pure_wrt_drop (i.e, don't have a #[may_dangle] attribute)
529 // We need to return the list of parameters from the ADTs
530 // generics/substs that correspond to impure parameters on the
531 // impl's generics. This is a bit ugly, but conceptually simple:
533 // Suppose our ADT looks like the following
535 // struct S<X, Y, Z>(X, Y, Z);
539 // impl<#[may_dangle] P0, P1, P2> Drop for S<P1, P2, P0>
541 // We want to return the parameters (X, Y). For that, we match
542 // up the item-substs <X, Y, Z> with the substs on the impl ADT,
543 // <P1, P2, P0>, and then look up which of the impl substs refer to
544 // parameters marked as pure.
546 let impl_substs
= match self.type_of(impl_def_id
).kind
{
547 ty
::Adt(def_
, substs
) if def_
== def
=> substs
,
551 let item_substs
= match self.type_of(def
.did
).kind
{
552 ty
::Adt(def_
, substs
) if def_
== def
=> substs
,
556 let result
= item_substs
.iter().zip(impl_substs
.iter())
559 GenericArgKind
::Lifetime(&ty
::RegionKind
::ReEarlyBound(ref ebr
)) => {
560 !impl_generics
.region_param(ebr
, self).pure_wrt_drop
562 GenericArgKind
::Type(&ty
::TyS
{
563 kind
: ty
::Param(ref pt
), ..
565 !impl_generics
.type_param(pt
, self).pure_wrt_drop
567 GenericArgKind
::Const(&ty
::Const
{
568 val
: ty
::ConstKind
::Param(ref pc
),
571 !impl_generics
.const_param(pc
, self).pure_wrt_drop
573 GenericArgKind
::Lifetime(_
) |
574 GenericArgKind
::Type(_
) |
575 GenericArgKind
::Const(_
) => {
576 // Not a type, const or region param: this should be reported
582 .map(|(&item_param
, _
)| item_param
)
584 debug
!("destructor_constraint({:?}) = {:?}", def
.did
, result
);
588 /// Returns `true` if `def_id` refers to a closure (e.g., `|x| x * 2`). Note
589 /// that closures have a `DefId`, but the closure *expression* also
590 /// has a `HirId` that is located within the context where the
591 /// closure appears (and, sadly, a corresponding `NodeId`, since
592 /// those are not yet phased out). The parent of the closure's
593 /// `DefId` will also be the context where it appears.
594 pub fn is_closure(self, def_id
: DefId
) -> bool
{
595 self.def_key(def_id
).disambiguated_data
.data
== DefPathData
::ClosureExpr
598 /// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
599 pub fn is_trait(self, def_id
: DefId
) -> bool
{
600 self.def_kind(def_id
) == Some(DefKind
::Trait
)
603 /// Returns `true` if `def_id` refers to a trait alias (i.e., `trait Foo = ...;`),
604 /// and `false` otherwise.
605 pub fn is_trait_alias(self, def_id
: DefId
) -> bool
{
606 self.def_kind(def_id
) == Some(DefKind
::TraitAlias
)
609 /// Returns `true` if this `DefId` refers to the implicit constructor for
610 /// a tuple struct like `struct Foo(u32)`, and `false` otherwise.
611 pub fn is_constructor(self, def_id
: DefId
) -> bool
{
612 self.def_key(def_id
).disambiguated_data
.data
== DefPathData
::Ctor
615 /// Given the def-ID of a fn or closure, returns the def-ID of
616 /// the innermost fn item that the closure is contained within.
617 /// This is a significant `DefId` because, when we do
618 /// type-checking, we type-check this fn item and all of its
619 /// (transitive) closures together. Therefore, when we fetch the
620 /// `typeck_tables_of` the closure, for example, we really wind up
621 /// fetching the `typeck_tables_of` the enclosing fn item.
622 pub fn closure_base_def_id(self, def_id
: DefId
) -> DefId
{
623 let mut def_id
= def_id
;
624 while self.is_closure(def_id
) {
625 def_id
= self.parent(def_id
).unwrap_or_else(|| {
626 bug
!("closure {:?} has no parent", def_id
);
632 /// Given the `DefId` and substs a closure, creates the type of
633 /// `self` argument that the closure expects. For example, for a
634 /// `Fn` closure, this would return a reference type `&T` where
635 /// `T = closure_ty`.
637 /// Returns `None` if this closure's kind has not yet been inferred.
638 /// This should only be possible during type checking.
640 /// Note that the return value is a late-bound region and hence
641 /// wrapped in a binder.
642 pub fn closure_env_ty(self,
643 closure_def_id
: DefId
,
644 closure_substs
: SubstsRef
<'tcx
>)
645 -> Option
<ty
::Binder
<Ty
<'tcx
>>>
647 let closure_ty
= self.mk_closure(closure_def_id
, closure_substs
);
648 let env_region
= ty
::ReLateBound(ty
::INNERMOST
, ty
::BrEnv
);
649 let closure_kind_ty
= closure_substs
.as_closure().kind_ty(closure_def_id
, self);
650 let closure_kind
= closure_kind_ty
.to_opt_closure_kind()?
;
651 let env_ty
= match closure_kind
{
652 ty
::ClosureKind
::Fn
=> self.mk_imm_ref(self.mk_region(env_region
), closure_ty
),
653 ty
::ClosureKind
::FnMut
=> self.mk_mut_ref(self.mk_region(env_region
), closure_ty
),
654 ty
::ClosureKind
::FnOnce
=> closure_ty
,
656 Some(ty
::Binder
::bind(env_ty
))
659 /// Given the `DefId` of some item that has no type or const parameters, make
660 /// a suitable "empty substs" for it.
661 pub fn empty_substs_for_def_id(self, item_def_id
: DefId
) -> SubstsRef
<'tcx
> {
662 InternalSubsts
::for_item(self, item_def_id
, |param
, _
| {
664 GenericParamDefKind
::Lifetime
=> self.lifetimes
.re_erased
.into(),
665 GenericParamDefKind
::Type { .. }
=> {
666 bug
!("empty_substs_for_def_id: {:?} has type parameters", item_def_id
)
668 GenericParamDefKind
::Const { .. }
=> {
669 bug
!("empty_substs_for_def_id: {:?} has const parameters", item_def_id
)
675 /// Returns `true` if the node pointed to by `def_id` is a `static` item.
676 pub fn is_static(&self, def_id
: DefId
) -> bool
{
677 self.static_mutability(def_id
).is_some()
680 /// Returns `true` if the node pointed to by `def_id` is a mutable `static` item.
681 pub fn is_mutable_static(&self, def_id
: DefId
) -> bool
{
682 self.static_mutability(def_id
) == Some(hir
::Mutability
::Mutable
)
685 /// Get the type of the pointer to the static that we use in MIR.
686 pub fn static_ptr_ty(&self, def_id
: DefId
) -> Ty
<'tcx
> {
687 // Make sure that any constants in the static's type are evaluated.
688 let static_ty
= self.normalize_erasing_regions(
689 ty
::ParamEnv
::empty(),
690 self.type_of(def_id
),
693 if self.is_mutable_static(def_id
) {
694 self.mk_mut_ptr(static_ty
)
696 self.mk_imm_ref(self.lifetimes
.re_erased
, static_ty
)
700 /// Expands the given impl trait type, stopping if the type is recursive.
701 pub fn try_expand_impl_trait_type(
704 substs
: SubstsRef
<'tcx
>,
705 ) -> Result
<Ty
<'tcx
>, Ty
<'tcx
>> {
706 use crate::ty
::fold
::TypeFolder
;
708 struct OpaqueTypeExpander
<'tcx
> {
709 // Contains the DefIds of the opaque types that are currently being
710 // expanded. When we expand an opaque type we insert the DefId of
711 // that type, and when we finish expanding that type we remove the
713 seen_opaque_tys
: FxHashSet
<DefId
>,
714 // Cache of all expansions we've seen so far. This is a critical
715 // optimization for some large types produced by async fn trees.
716 expanded_cache
: FxHashMap
<(DefId
, SubstsRef
<'tcx
>), Ty
<'tcx
>>,
717 primary_def_id
: DefId
,
718 found_recursion
: bool
,
722 impl<'tcx
> OpaqueTypeExpander
<'tcx
> {
726 substs
: SubstsRef
<'tcx
>,
727 ) -> Option
<Ty
<'tcx
>> {
728 if self.found_recursion
{
731 let substs
= substs
.fold_with(self);
732 if self.seen_opaque_tys
.insert(def_id
) {
733 let expanded_ty
= match self.expanded_cache
.get(&(def_id
, substs
)) {
734 Some(expanded_ty
) => expanded_ty
,
736 let generic_ty
= self.tcx
.type_of(def_id
);
737 let concrete_ty
= generic_ty
.subst(self.tcx
, substs
);
738 let expanded_ty
= self.fold_ty(concrete_ty
);
739 self.expanded_cache
.insert((def_id
, substs
), expanded_ty
);
743 self.seen_opaque_tys
.remove(&def_id
);
746 // If another opaque type that we contain is recursive, then it
747 // will report the error, so we don't have to.
748 self.found_recursion
= def_id
== self.primary_def_id
;
754 impl<'tcx
> TypeFolder
<'tcx
> for OpaqueTypeExpander
<'tcx
> {
755 fn tcx(&self) -> TyCtxt
<'tcx
> {
759 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
760 if let ty
::Opaque(def_id
, substs
) = t
.kind
{
761 self.expand_opaque_ty(def_id
, substs
).unwrap_or(t
)
762 } else if t
.has_projections() {
763 t
.super_fold_with(self)
770 let mut visitor
= OpaqueTypeExpander
{
771 seen_opaque_tys
: FxHashSet
::default(),
772 expanded_cache
: FxHashMap
::default(),
773 primary_def_id
: def_id
,
774 found_recursion
: false,
777 let expanded_type
= visitor
.expand_opaque_ty(def_id
, substs
).unwrap();
778 if visitor
.found_recursion
{
786 impl<'tcx
> ty
::TyS
<'tcx
> {
787 /// Checks whether values of this type `T` are *moved* or *copied*
788 /// when referenced -- this amounts to a check for whether `T:
789 /// Copy`, but note that we **don't** consider lifetimes when
790 /// doing this check. This means that we may generate MIR which
791 /// does copies even when the type actually doesn't satisfy the
792 /// full requirements for the `Copy` trait (cc #29149) -- this
793 /// winds up being reported as an error during NLL borrow check.
794 pub fn is_copy_modulo_regions(
797 param_env
: ty
::ParamEnv
<'tcx
>,
800 tcx
.at(span
).is_copy_raw(param_env
.and(self))
803 /// Checks whether values of this type `T` have a size known at
804 /// compile time (i.e., whether `T: Sized`). Lifetimes are ignored
805 /// for the purposes of this check, so it can be an
806 /// over-approximation in generic contexts, where one can have
807 /// strange rules like `<T as Foo<'static>>::Bar: Sized` that
808 /// actually carry lifetime requirements.
809 pub fn is_sized(&'tcx
self, tcx_at
: TyCtxtAt
<'tcx
>, param_env
: ty
::ParamEnv
<'tcx
>) -> bool
{
810 tcx_at
.is_sized_raw(param_env
.and(self))
813 /// Checks whether values of this type `T` implement the `Freeze`
814 /// trait -- frozen types are those that do not contain a
815 /// `UnsafeCell` anywhere. This is a language concept used to
816 /// distinguish "true immutability", which is relevant to
817 /// optimization as well as the rules around static values. Note
818 /// that the `Freeze` trait is not exposed to end users and is
819 /// effectively an implementation detail.
823 param_env
: ty
::ParamEnv
<'tcx
>,
826 tcx
.at(span
).is_freeze_raw(param_env
.and(self))
829 /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
830 /// non-copy and *might* have a destructor attached; if it returns
831 /// `false`, then `ty` definitely has no destructor (i.e., no drop glue).
833 /// (Note that this implies that if `ty` has a destructor attached,
834 /// then `needs_drop` will definitely return `true` for `ty`.)
836 /// Note that this method is used to check eligible types in unions.
838 pub fn needs_drop(&'tcx
self, tcx
: TyCtxt
<'tcx
>, param_env
: ty
::ParamEnv
<'tcx
>) -> bool
{
839 tcx
.needs_drop_raw(param_env
.and(self)).0
842 pub fn same_type(a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> bool
{
843 match (&a
.kind
, &b
.kind
) {
844 (&Adt(did_a
, substs_a
), &Adt(did_b
, substs_b
)) => {
849 substs_a
.types().zip(substs_b
.types()).all(|(a
, b
)| Self::same_type(a
, b
))
855 /// Check whether a type is representable. This means it cannot contain unboxed
856 /// structural recursion. This check is needed for structs and enums.
857 pub fn is_representable(&'tcx
self, tcx
: TyCtxt
<'tcx
>, sp
: Span
) -> Representability
{
858 // Iterate until something non-representable is found
859 fn fold_repr
<It
: Iterator
<Item
=Representability
>>(iter
: It
) -> Representability
{
860 iter
.fold(Representability
::Representable
, |r1
, r2
| {
862 (Representability
::SelfRecursive(v1
),
863 Representability
::SelfRecursive(v2
)) => {
864 Representability
::SelfRecursive(v1
.into_iter().chain(v2
).collect())
866 (r1
, r2
) => cmp
::max(r1
, r2
)
871 fn are_inner_types_recursive
<'tcx
>(
874 seen
: &mut Vec
<Ty
<'tcx
>>,
875 representable_cache
: &mut FxHashMap
<Ty
<'tcx
>, Representability
>,
877 ) -> Representability
{
880 // Find non representable
881 fold_repr(ty
.tuple_fields().map(|ty
| {
882 is_type_structurally_recursive(
891 // Fixed-length vectors.
892 // FIXME(#11924) Behavior undecided for zero-length vectors.
894 is_type_structurally_recursive(tcx
, sp
, seen
, representable_cache
, ty
)
896 Adt(def
, substs
) => {
897 // Find non representable fields with their spans
898 fold_repr(def
.all_fields().map(|field
| {
899 let ty
= field
.ty(tcx
, substs
);
900 let span
= tcx
.hir().span_if_local(field
.did
).unwrap_or(sp
);
901 match is_type_structurally_recursive(tcx
, span
, seen
,
902 representable_cache
, ty
)
904 Representability
::SelfRecursive(_
) => {
905 Representability
::SelfRecursive(vec
![span
])
912 // this check is run on type definitions, so we don't expect
913 // to see closure types
914 bug
!("requires check invoked on inapplicable type: {:?}", ty
)
916 _
=> Representability
::Representable
,
920 fn same_struct_or_enum
<'tcx
>(ty
: Ty
<'tcx
>, def
: &'tcx ty
::AdtDef
) -> bool
{
929 // Does the type `ty` directly (without indirection through a pointer)
930 // contain any types on stack `seen`?
931 fn is_type_structurally_recursive
<'tcx
>(
934 seen
: &mut Vec
<Ty
<'tcx
>>,
935 representable_cache
: &mut FxHashMap
<Ty
<'tcx
>, Representability
>,
937 ) -> Representability
{
938 debug
!("is_type_structurally_recursive: {:?} {:?}", ty
, sp
);
939 if let Some(representability
) = representable_cache
.get(ty
) {
940 debug
!("is_type_structurally_recursive: {:?} {:?} - (cached) {:?}",
941 ty
, sp
, representability
);
942 return representability
.clone();
945 let representability
= is_type_structurally_recursive_inner(
946 tcx
, sp
, seen
, representable_cache
, ty
);
948 representable_cache
.insert(ty
, representability
.clone());
952 fn is_type_structurally_recursive_inner
<'tcx
>(
955 seen
: &mut Vec
<Ty
<'tcx
>>,
956 representable_cache
: &mut FxHashMap
<Ty
<'tcx
>, Representability
>,
958 ) -> Representability
{
962 // Iterate through stack of previously seen types.
963 let mut iter
= seen
.iter();
965 // The first item in `seen` is the type we are actually curious about.
966 // We want to return SelfRecursive if this type contains itself.
967 // It is important that we DON'T take generic parameters into account
968 // for this check, so that Bar<T> in this example counts as SelfRecursive:
971 // struct Bar<T> { x: Bar<Foo> }
973 if let Some(&seen_type
) = iter
.next() {
974 if same_struct_or_enum(seen_type
, def
) {
975 debug
!("SelfRecursive: {:?} contains {:?}",
978 return Representability
::SelfRecursive(vec
![sp
]);
982 // We also need to know whether the first item contains other types
983 // that are structurally recursive. If we don't catch this case, we
984 // will recurse infinitely for some inputs.
986 // It is important that we DO take generic parameters into account
987 // here, so that code like this is considered SelfRecursive, not
988 // ContainsRecursive:
990 // struct Foo { Option<Option<Foo>> }
992 for &seen_type
in iter
{
993 if ty
::TyS
::same_type(ty
, seen_type
) {
994 debug
!("ContainsRecursive: {:?} contains {:?}",
997 return Representability
::ContainsRecursive
;
1002 // For structs and enums, track all previously seen types by pushing them
1003 // onto the 'seen' stack.
1005 let out
= are_inner_types_recursive(tcx
, sp
, seen
, representable_cache
, ty
);
1010 // No need to push in other cases.
1011 are_inner_types_recursive(tcx
, sp
, seen
, representable_cache
, ty
)
1016 debug
!("is_type_representable: {:?}", self);
1018 // To avoid a stack overflow when checking an enum variant or struct that
1019 // contains a different, structurally recursive type, maintain a stack
1020 // of seen types and check recursion for each of them (issues #3008, #3779).
1021 let mut seen
: Vec
<Ty
<'_
>> = Vec
::new();
1022 let mut representable_cache
= FxHashMap
::default();
1023 let r
= is_type_structurally_recursive(
1024 tcx
, sp
, &mut seen
, &mut representable_cache
, self);
1025 debug
!("is_type_representable: {:?} is {:?}", self, r
);
1029 /// Peel off all reference types in this type until there are none left.
1031 /// This method is idempotent, i.e. `ty.peel_refs().peel_refs() == ty.peel_refs()`.
1036 /// - `&'a mut u8` -> `u8`
1037 /// - `&'a &'b u8` -> `u8`
1038 /// - `&'a *const &'b u8 -> *const &'b u8`
1039 pub fn peel_refs(&'tcx
self) -> Ty
<'tcx
> {
1041 while let Ref(_
, inner_ty
, _
) = ty
.kind
{
1048 fn is_copy_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> bool
{
1049 is_item_raw(tcx
, query
, lang_items
::CopyTraitLangItem
)
1052 fn is_sized_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> bool
{
1053 is_item_raw(tcx
, query
, lang_items
::SizedTraitLangItem
)
1057 fn is_freeze_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> bool
{
1058 is_item_raw(tcx
, query
, lang_items
::FreezeTraitLangItem
)
1061 fn is_item_raw
<'tcx
>(
1063 query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>,
1064 item
: lang_items
::LangItem
,
1066 let (param_env
, ty
) = query
.into_parts();
1067 let trait_def_id
= tcx
.require_lang_item(item
, None
);
1069 .enter(|infcx
| traits
::type_known_to_meet_bound_modulo_regions(
1078 #[derive(Clone, HashStable)]
1079 pub struct NeedsDrop(pub bool
);
1081 fn needs_drop_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> NeedsDrop
{
1082 let (param_env
, ty
) = query
.into_parts();
1084 let needs_drop
= |ty
: Ty
<'tcx
>| -> bool
{
1085 tcx
.needs_drop_raw(param_env
.and(ty
)).0
1088 assert
!(!ty
.needs_infer());
1090 NeedsDrop(match ty
.kind
{
1091 // Fast-path for primitive types
1092 ty
::Infer(ty
::FreshIntTy(_
)) | ty
::Infer(ty
::FreshFloatTy(_
)) |
1093 ty
::Bool
| ty
::Int(_
) | ty
::Uint(_
) | ty
::Float(_
) | ty
::Never
|
1094 ty
::FnDef(..) | ty
::FnPtr(_
) | ty
::Char
| ty
::GeneratorWitness(..) |
1095 ty
::RawPtr(_
) | ty
::Ref(..) | ty
::Str
=> false,
1097 // Foreign types can never have destructors
1098 ty
::Foreign(..) => false,
1100 // `ManuallyDrop` doesn't have a destructor regardless of field types.
1101 ty
::Adt(def
, _
) if Some(def
.did
) == tcx
.lang_items().manually_drop() => false,
1103 // Issue #22536: We first query `is_copy_modulo_regions`. It sees a
1104 // normalized version of the type, and therefore will definitely
1105 // know whether the type implements Copy (and thus needs no
1106 // cleanup/drop/zeroing) ...
1107 _
if ty
.is_copy_modulo_regions(tcx
, param_env
, DUMMY_SP
) => false,
1109 // ... (issue #22536 continued) but as an optimization, still use
1110 // prior logic of asking for the structural "may drop".
1112 // FIXME(#22815): Note that this is a conservative heuristic;
1113 // it may report that the type "may drop" when actual type does
1114 // not actually have a destructor associated with it. But since
1115 // the type absolutely did not have the `Copy` bound attached
1116 // (see above), it is sound to treat it as having a destructor.
1118 // User destructors are the only way to have concrete drop types.
1119 ty
::Adt(def
, _
) if def
.has_dtor(tcx
) => true,
1121 // Can refer to a type which may drop.
1122 // FIXME(eddyb) check this against a ParamEnv.
1123 ty
::Dynamic(..) | ty
::Projection(..) | ty
::Param(_
) | ty
::Bound(..) |
1124 ty
::Placeholder(..) | ty
::Opaque(..) | ty
::Infer(_
) | ty
::Error
=> true,
1126 ty
::UnnormalizedProjection(..) => bug
!("only used with chalk-engine"),
1128 // Zero-length arrays never contain anything to drop.
1129 ty
::Array(_
, len
) if len
.try_eval_usize(tcx
, param_env
) == Some(0) => false,
1131 // Structural recursion.
1132 ty
::Array(ty
, _
) | ty
::Slice(ty
) => needs_drop(ty
),
1134 ty
::Closure(def_id
, ref substs
) => {
1135 substs
.as_closure().upvar_tys(def_id
, tcx
).any(needs_drop
)
1138 // Pessimistically assume that all generators will require destructors
1139 // as we don't know if a destructor is a noop or not until after the MIR
1140 // state transformation pass
1141 ty
::Generator(..) => true,
1143 ty
::Tuple(..) => ty
.tuple_fields().any(needs_drop
),
1145 // unions don't have destructors because of the child types,
1146 // only if they manually implement `Drop` (handled above).
1147 ty
::Adt(def
, _
) if def
.is_union() => false,
1149 ty
::Adt(def
, substs
) =>
1150 def
.variants
.iter().any(
1151 |variant
| variant
.fields
.iter().any(
1152 |field
| needs_drop(field
.ty(tcx
, substs
)))),
1156 pub enum ExplicitSelf
<'tcx
> {
1158 ByReference(ty
::Region
<'tcx
>, hir
::Mutability
),
1159 ByRawPointer(hir
::Mutability
),
1164 impl<'tcx
> ExplicitSelf
<'tcx
> {
1165 /// Categorizes an explicit self declaration like `self: SomeType`
1166 /// into either `self`, `&self`, `&mut self`, `Box<self>`, or
1168 /// This is mainly used to require the arbitrary_self_types feature
1169 /// in the case of `Other`, to improve error messages in the common cases,
1170 /// and to make `Other` non-object-safe.
1175 /// impl<'a> Foo for &'a T {
1176 /// // Legal declarations:
1177 /// fn method1(self: &&'a T); // ExplicitSelf::ByReference
1178 /// fn method2(self: &'a T); // ExplicitSelf::ByValue
1179 /// fn method3(self: Box<&'a T>); // ExplicitSelf::ByBox
1180 /// fn method4(self: Rc<&'a T>); // ExplicitSelf::Other
1182 /// // Invalid cases will be caught by `check_method_receiver`:
1183 /// fn method_err1(self: &'a mut T); // ExplicitSelf::Other
1184 /// fn method_err2(self: &'static T) // ExplicitSelf::ByValue
1185 /// fn method_err3(self: &&T) // ExplicitSelf::ByReference
1189 pub fn determine
<P
>(
1190 self_arg_ty
: Ty
<'tcx
>,
1192 ) -> ExplicitSelf
<'tcx
>
1194 P
: Fn(Ty
<'tcx
>) -> bool
1196 use self::ExplicitSelf
::*;
1198 match self_arg_ty
.kind
{
1199 _
if is_self_ty(self_arg_ty
) => ByValue
,
1200 ty
::Ref(region
, ty
, mutbl
) if is_self_ty(ty
) => {
1201 ByReference(region
, mutbl
)
1203 ty
::RawPtr(ty
::TypeAndMut { ty, mutbl }
) if is_self_ty(ty
) => {
1206 ty
::Adt(def
, _
) if def
.is_box() && is_self_ty(self_arg_ty
.boxed_ty()) => {
1214 pub fn provide(providers
: &mut ty
::query
::Providers
<'_
>) {
1215 *providers
= ty
::query
::Providers
{