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, UnpackedKind}
;
12 use crate::ty
::query
::TyCtxtAt
;
13 use crate::ty
::TyKind
::*;
14 use crate::ty
::layout
::{Integer, IntegerExt}
;
15 use crate::mir
::interpret
::ConstValue
;
16 use crate::util
::common
::ErrorReported
;
17 use crate::middle
::lang_items
;
19 use rustc_data_structures
::stable_hasher
::{StableHasher, HashStable}
;
20 use rustc_data_structures
::fx
::{FxHashMap, FxHashSet}
;
21 use rustc_macros
::HashStable
;
24 use syntax
::attr
::{self, SignedInt, UnsignedInt}
;
25 use syntax
::symbol
::sym
;
26 use syntax_pos
::{Span, DUMMY_SP}
;
28 #[derive(Copy, Clone, Debug)]
29 pub struct Discr
<'tcx
> {
30 /// Bit representation of the discriminant (e.g., `-128i8` is `0xFF_u128`).
35 impl<'tcx
> fmt
::Display
for Discr
<'tcx
> {
36 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
39 let size
= ty
::tls
::with(|tcx
| {
40 Integer
::from_attr(&tcx
, SignedInt(ity
)).size()
43 // sign extend the raw representation to be an i128
44 let x
= sign_extend(x
, size
) as i128
;
47 _
=> write
!(fmt
, "{}", self.val
),
52 impl<'tcx
> Discr
<'tcx
> {
53 /// Adds `1` to the value and wraps around if the maximum for the type is reached.
54 pub fn wrap_incr(self, tcx
: TyCtxt
<'tcx
>) -> Self {
55 self.checked_add(tcx
, 1).0
57 pub fn checked_add(self, tcx
: TyCtxt
<'tcx
>, n
: u128
) -> (Self, bool
) {
58 let (int
, signed
) = match self.ty
.sty
{
59 Int(ity
) => (Integer
::from_attr(&tcx
, SignedInt(ity
)), true),
60 Uint(uty
) => (Integer
::from_attr(&tcx
, UnsignedInt(uty
)), false),
61 _
=> bug
!("non integer discriminant"),
64 let size
= int
.size();
65 let bit_size
= int
.size().bits();
66 let shift
= 128 - bit_size
;
69 sign_extend(u
, size
) as i128
71 let min
= sext(1_u128 << (bit_size
- 1));
72 let max
= i128
::max_value() >> shift
;
73 let val
= sext(self.val
);
74 assert
!(n
< (i128
::max_value() as u128
));
76 let oflo
= val
> max
- n
;
78 min
+ (n
- (max
- val
) - 1)
82 // zero the upper bits
83 let val
= val
as u128
;
84 let val
= truncate(val
, size
);
90 let max
= u128
::max_value() >> shift
;
92 let oflo
= val
> max
- n
;
106 pub trait IntTypeExt
{
107 fn to_ty
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Ty
<'tcx
>;
108 fn disr_incr
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>, val
: Option
<Discr
<'tcx
>>) -> Option
<Discr
<'tcx
>>;
109 fn initial_discriminant
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Discr
<'tcx
>;
112 impl IntTypeExt
for attr
::IntType
{
113 fn to_ty
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Ty
<'tcx
> {
115 SignedInt(ast
::IntTy
::I8
) => tcx
.types
.i8,
116 SignedInt(ast
::IntTy
::I16
) => tcx
.types
.i16,
117 SignedInt(ast
::IntTy
::I32
) => tcx
.types
.i32,
118 SignedInt(ast
::IntTy
::I64
) => tcx
.types
.i64,
119 SignedInt(ast
::IntTy
::I128
) => tcx
.types
.i128
,
120 SignedInt(ast
::IntTy
::Isize
) => tcx
.types
.isize,
121 UnsignedInt(ast
::UintTy
::U8
) => tcx
.types
.u8,
122 UnsignedInt(ast
::UintTy
::U16
) => tcx
.types
.u16,
123 UnsignedInt(ast
::UintTy
::U32
) => tcx
.types
.u32,
124 UnsignedInt(ast
::UintTy
::U64
) => tcx
.types
.u64,
125 UnsignedInt(ast
::UintTy
::U128
) => tcx
.types
.u128
,
126 UnsignedInt(ast
::UintTy
::Usize
) => tcx
.types
.usize,
130 fn initial_discriminant
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Discr
<'tcx
> {
137 fn disr_incr
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>, val
: Option
<Discr
<'tcx
>>) -> Option
<Discr
<'tcx
>> {
138 if let Some(val
) = val
{
139 assert_eq
!(self.to_ty(tcx
), val
.ty
);
140 let (new
, oflo
) = val
.checked_add(tcx
, 1);
147 Some(self.initial_discriminant(tcx
))
154 pub enum CopyImplementationError
<'tcx
> {
155 InfrigingFields(Vec
<&'tcx ty
::FieldDef
>),
160 /// Describes whether a type is representable. For types that are not
161 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
162 /// distinguish between types that are recursive with themselves and types that
163 /// contain a different recursive type. These cases can therefore be treated
164 /// differently when reporting errors.
166 /// The ordering of the cases is significant. They are sorted so that cmp::max
167 /// will keep the "more erroneous" of two values.
168 #[derive(Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
169 pub enum Representability
{
172 SelfRecursive(Vec
<Span
>),
175 impl<'tcx
> ty
::ParamEnv
<'tcx
> {
176 pub fn can_type_implement_copy(
180 ) -> Result
<(), CopyImplementationError
<'tcx
>> {
181 // FIXME: (@jroesch) float this code up
182 tcx
.infer_ctxt().enter(|infcx
| {
183 let (adt
, substs
) = match self_type
.sty
{
184 // These types used to have a builtin impl.
185 // Now libcore provides that impl.
186 ty
::Uint(_
) | ty
::Int(_
) | ty
::Bool
| ty
::Float(_
) |
187 ty
::Char
| ty
::RawPtr(..) | ty
::Never
|
188 ty
::Ref(_
, _
, hir
::MutImmutable
) => return Ok(()),
190 ty
::Adt(adt
, substs
) => (adt
, substs
),
192 _
=> return Err(CopyImplementationError
::NotAnAdt
),
195 let mut infringing
= Vec
::new();
196 for variant
in &adt
.variants
{
197 for field
in &variant
.fields
{
198 let ty
= field
.ty(tcx
, substs
);
199 if ty
.references_error() {
202 let span
= tcx
.def_span(field
.did
);
203 let cause
= ObligationCause { span, ..ObligationCause::dummy() }
;
204 let ctx
= traits
::FulfillmentContext
::new();
205 match traits
::fully_normalize(&infcx
, ctx
, cause
, self, &ty
) {
206 Ok(ty
) => if !infcx
.type_is_copy_modulo_regions(self, ty
, span
) {
207 infringing
.push(field
);
210 infcx
.report_fulfillment_errors(&errors
, None
, false);
215 if !infringing
.is_empty() {
216 return Err(CopyImplementationError
::InfrigingFields(infringing
));
218 if adt
.has_dtor(tcx
) {
219 return Err(CopyImplementationError
::HasDestructor
);
227 impl<'tcx
> TyCtxt
<'tcx
> {
228 /// Creates a hash of the type `Ty` which will be the same no matter what crate
229 /// context it's calculated within. This is used by the `type_id` intrinsic.
230 pub fn type_id_hash(self, ty
: Ty
<'tcx
>) -> u64 {
231 let mut hasher
= StableHasher
::new();
232 let mut hcx
= self.create_stable_hashing_context();
234 // We want the type_id be independent of the types free regions, so we
235 // erase them. The erase_regions() call will also anonymize bound
236 // regions, which is desirable too.
237 let ty
= self.erase_regions(&ty
);
239 hcx
.while_hashing_spans(false, |hcx
| {
240 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
241 ty
.hash_stable(hcx
, &mut hasher
);
248 impl<'tcx
> TyCtxt
<'tcx
> {
249 pub fn has_error_field(self, ty
: Ty
<'tcx
>) -> bool
{
250 if let ty
::Adt(def
, substs
) = ty
.sty
{
251 for field
in def
.all_fields() {
252 let field_ty
= field
.ty(self, substs
);
253 if let Error
= field_ty
.sty
{
261 /// Returns the deeply last field of nested structures, or the same type,
262 /// if not a structure at all. Corresponds to the only possible unsized
263 /// field, and its type can be used to determine unsizing strategy.
264 pub fn struct_tail(self, mut ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
267 ty
::Adt(def
, substs
) => {
268 if !def
.is_struct() {
271 match def
.non_enum_variant().fields
.last() {
272 Some(f
) => ty
= f
.ty(self, substs
),
278 if let Some((&last_ty
, _
)) = tys
.split_last() {
279 ty
= last_ty
.expect_ty();
293 /// Same as applying struct_tail on `source` and `target`, but only
294 /// keeps going as long as the two types are instances of the same
295 /// structure definitions.
296 /// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
297 /// whereas struct_tail produces `T`, and `Trait`, respectively.
298 pub fn struct_lockstep_tails(self,
301 -> (Ty
<'tcx
>, Ty
<'tcx
>) {
302 let (mut a
, mut b
) = (source
, target
);
304 match (&a
.sty
, &b
.sty
) {
305 (&Adt(a_def
, a_substs
), &Adt(b_def
, b_substs
))
306 if a_def
== b_def
&& a_def
.is_struct() => {
307 if let Some(f
) = a_def
.non_enum_variant().fields
.last() {
308 a
= f
.ty(self, a_substs
);
309 b
= f
.ty(self, b_substs
);
314 (&Tuple(a_tys
), &Tuple(b_tys
))
315 if a_tys
.len() == b_tys
.len() => {
316 if let Some(a_last
) = a_tys
.last() {
317 a
= a_last
.expect_ty();
318 b
= b_tys
.last().unwrap().expect_ty();
329 /// Given a set of predicates that apply to an object type, returns
330 /// the region bounds that the (erased) `Self` type must
331 /// outlive. Precisely *because* the `Self` type is erased, the
332 /// parameter `erased_self_ty` must be supplied to indicate what type
333 /// has been used to represent `Self` in the predicates
334 /// themselves. This should really be a unique type; `FreshTy(0)` is a
337 /// N.B., in some cases, particularly around higher-ranked bounds,
338 /// this function returns a kind of conservative approximation.
339 /// That is, all regions returned by this function are definitely
340 /// required, but there may be other region bounds that are not
341 /// returned, as well as requirements like `for<'a> T: 'a`.
343 /// Requires that trait definitions have been processed so that we can
344 /// elaborate predicates and walk supertraits.
346 // FIXME: callers may only have a `&[Predicate]`, not a `Vec`, so that's
347 // what this code should accept.
348 pub fn required_region_bounds(self,
349 erased_self_ty
: Ty
<'tcx
>,
350 predicates
: Vec
<ty
::Predicate
<'tcx
>>)
351 -> Vec
<ty
::Region
<'tcx
>> {
352 debug
!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
356 assert
!(!erased_self_ty
.has_escaping_bound_vars());
358 traits
::elaborate_predicates(self, predicates
)
359 .filter_map(|predicate
| {
361 ty
::Predicate
::Projection(..) |
362 ty
::Predicate
::Trait(..) |
363 ty
::Predicate
::Subtype(..) |
364 ty
::Predicate
::WellFormed(..) |
365 ty
::Predicate
::ObjectSafe(..) |
366 ty
::Predicate
::ClosureKind(..) |
367 ty
::Predicate
::RegionOutlives(..) |
368 ty
::Predicate
::ConstEvaluatable(..) => {
371 ty
::Predicate
::TypeOutlives(predicate
) => {
372 // Search for a bound of the form `erased_self_ty
373 // : 'a`, but be wary of something like `for<'a>
374 // erased_self_ty : 'a` (we interpret a
375 // higher-ranked bound like that as 'static,
376 // though at present the code in `fulfill.rs`
377 // considers such bounds to be unsatisfiable, so
378 // it's kind of a moot point since you could never
379 // construct such an object, but this seems
380 // correct even if that code changes).
381 let ty
::OutlivesPredicate(ref t
, ref r
) = predicate
.skip_binder();
382 if t
== &erased_self_ty
&& !r
.has_escaping_bound_vars() {
393 /// Calculate the destructor of a given type.
394 pub fn calculate_dtor(
397 validate
: &mut dyn FnMut(Self, DefId
) -> Result
<(), ErrorReported
>
398 ) -> Option
<ty
::Destructor
> {
399 let drop_trait
= if let Some(def_id
) = self.lang_items().drop_trait() {
405 self.ensure().coherent_trait(drop_trait
);
407 let mut dtor_did
= None
;
408 let ty
= self.type_of(adt_did
);
409 self.for_each_relevant_impl(drop_trait
, ty
, |impl_did
| {
410 if let Some(item
) = self.associated_items(impl_did
).next() {
411 if validate(self, impl_did
).is_ok() {
412 dtor_did
= Some(item
.def_id
);
417 Some(ty
::Destructor { did: dtor_did? }
)
420 /// Returns the set of types that are required to be alive in
421 /// order to run the destructor of `def` (see RFCs 769 and
424 /// Note that this returns only the constraints for the
425 /// destructor of `def` itself. For the destructors of the
426 /// contents, you need `adt_dtorck_constraint`.
427 pub fn destructor_constraints(self, def
: &'tcx ty
::AdtDef
)
428 -> Vec
<ty
::subst
::Kind
<'tcx
>>
430 let dtor
= match def
.destructor(self) {
432 debug
!("destructor_constraints({:?}) - no dtor", def
.did
);
435 Some(dtor
) => dtor
.did
438 // RFC 1238: if the destructor method is tagged with the
439 // attribute `unsafe_destructor_blind_to_params`, then the
440 // compiler is being instructed to *assume* that the
441 // destructor will not access borrowed data,
442 // even if such data is otherwise reachable.
444 // Such access can be in plain sight (e.g., dereferencing
445 // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden
446 // (e.g., calling `foo.0.clone()` of `Foo<T:Clone>`).
447 if self.has_attr(dtor
, sym
::unsafe_destructor_blind_to_params
) {
448 debug
!("destructor_constraint({:?}) - blind", def
.did
);
452 let impl_def_id
= self.associated_item(dtor
).container
.id();
453 let impl_generics
= self.generics_of(impl_def_id
);
455 // We have a destructor - all the parameters that are not
456 // pure_wrt_drop (i.e, don't have a #[may_dangle] attribute)
459 // We need to return the list of parameters from the ADTs
460 // generics/substs that correspond to impure parameters on the
461 // impl's generics. This is a bit ugly, but conceptually simple:
463 // Suppose our ADT looks like the following
465 // struct S<X, Y, Z>(X, Y, Z);
469 // impl<#[may_dangle] P0, P1, P2> Drop for S<P1, P2, P0>
471 // We want to return the parameters (X, Y). For that, we match
472 // up the item-substs <X, Y, Z> with the substs on the impl ADT,
473 // <P1, P2, P0>, and then look up which of the impl substs refer to
474 // parameters marked as pure.
476 let impl_substs
= match self.type_of(impl_def_id
).sty
{
477 ty
::Adt(def_
, substs
) if def_
== def
=> substs
,
481 let item_substs
= match self.type_of(def
.did
).sty
{
482 ty
::Adt(def_
, substs
) if def_
== def
=> substs
,
486 let result
= item_substs
.iter().zip(impl_substs
.iter())
489 UnpackedKind
::Lifetime(&ty
::RegionKind
::ReEarlyBound(ref ebr
)) => {
490 !impl_generics
.region_param(ebr
, self).pure_wrt_drop
492 UnpackedKind
::Type(&ty
::TyS
{
493 sty
: ty
::Param(ref pt
), ..
495 !impl_generics
.type_param(pt
, self).pure_wrt_drop
497 UnpackedKind
::Const(&ty
::Const
{
498 val
: ConstValue
::Param(ref pc
),
501 !impl_generics
.const_param(pc
, self).pure_wrt_drop
503 UnpackedKind
::Lifetime(_
) |
504 UnpackedKind
::Type(_
) |
505 UnpackedKind
::Const(_
) => {
506 // Not a type, const or region param: this should be reported
512 .map(|(&item_param
, _
)| item_param
)
514 debug
!("destructor_constraint({:?}) = {:?}", def
.did
, result
);
518 /// Returns `true` if `def_id` refers to a closure (e.g., `|x| x * 2`). Note
519 /// that closures have a `DefId`, but the closure *expression* also
520 /// has a `HirId` that is located within the context where the
521 /// closure appears (and, sadly, a corresponding `NodeId`, since
522 /// those are not yet phased out). The parent of the closure's
523 /// `DefId` will also be the context where it appears.
524 pub fn is_closure(self, def_id
: DefId
) -> bool
{
525 self.def_key(def_id
).disambiguated_data
.data
== DefPathData
::ClosureExpr
528 /// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
529 pub fn is_trait(self, def_id
: DefId
) -> bool
{
530 self.def_kind(def_id
) == Some(DefKind
::Trait
)
533 /// Returns `true` if `def_id` refers to a trait alias (i.e., `trait Foo = ...;`),
534 /// and `false` otherwise.
535 pub fn is_trait_alias(self, def_id
: DefId
) -> bool
{
536 self.def_kind(def_id
) == Some(DefKind
::TraitAlias
)
539 /// Returns `true` if this `DefId` refers to the implicit constructor for
540 /// a tuple struct like `struct Foo(u32)`, and `false` otherwise.
541 pub fn is_constructor(self, def_id
: DefId
) -> bool
{
542 self.def_key(def_id
).disambiguated_data
.data
== DefPathData
::Ctor
545 /// Given the def-ID of a fn or closure, returns the def-ID of
546 /// the innermost fn item that the closure is contained within.
547 /// This is a significant `DefId` because, when we do
548 /// type-checking, we type-check this fn item and all of its
549 /// (transitive) closures together. Therefore, when we fetch the
550 /// `typeck_tables_of` the closure, for example, we really wind up
551 /// fetching the `typeck_tables_of` the enclosing fn item.
552 pub fn closure_base_def_id(self, def_id
: DefId
) -> DefId
{
553 let mut def_id
= def_id
;
554 while self.is_closure(def_id
) {
555 def_id
= self.parent(def_id
).unwrap_or_else(|| {
556 bug
!("closure {:?} has no parent", def_id
);
562 /// Given the `DefId` and substs a closure, creates the type of
563 /// `self` argument that the closure expects. For example, for a
564 /// `Fn` closure, this would return a reference type `&T` where
565 /// `T = closure_ty`.
567 /// Returns `None` if this closure's kind has not yet been inferred.
568 /// This should only be possible during type checking.
570 /// Note that the return value is a late-bound region and hence
571 /// wrapped in a binder.
572 pub fn closure_env_ty(self,
573 closure_def_id
: DefId
,
574 closure_substs
: ty
::ClosureSubsts
<'tcx
>)
575 -> Option
<ty
::Binder
<Ty
<'tcx
>>>
577 let closure_ty
= self.mk_closure(closure_def_id
, closure_substs
);
578 let env_region
= ty
::ReLateBound(ty
::INNERMOST
, ty
::BrEnv
);
579 let closure_kind_ty
= closure_substs
.closure_kind_ty(closure_def_id
, self);
580 let closure_kind
= closure_kind_ty
.to_opt_closure_kind()?
;
581 let env_ty
= match closure_kind
{
582 ty
::ClosureKind
::Fn
=> self.mk_imm_ref(self.mk_region(env_region
), closure_ty
),
583 ty
::ClosureKind
::FnMut
=> self.mk_mut_ref(self.mk_region(env_region
), closure_ty
),
584 ty
::ClosureKind
::FnOnce
=> closure_ty
,
586 Some(ty
::Binder
::bind(env_ty
))
589 /// Given the `DefId` of some item that has no type or const parameters, make
590 /// a suitable "empty substs" for it.
591 pub fn empty_substs_for_def_id(self, item_def_id
: DefId
) -> SubstsRef
<'tcx
> {
592 InternalSubsts
::for_item(self, item_def_id
, |param
, _
| {
594 GenericParamDefKind
::Lifetime
=> self.lifetimes
.re_erased
.into(),
595 GenericParamDefKind
::Type { .. }
=> {
596 bug
!("empty_substs_for_def_id: {:?} has type parameters", item_def_id
)
598 GenericParamDefKind
::Const { .. }
=> {
599 bug
!("empty_substs_for_def_id: {:?} has const parameters", item_def_id
)
605 /// Returns `true` if the node pointed to by `def_id` is a `static` item.
606 pub fn is_static(&self, def_id
: DefId
) -> bool
{
607 self.static_mutability(def_id
).is_some()
610 /// Returns `true` if the node pointed to by `def_id` is a mutable `static` item.
611 pub fn is_mutable_static(&self, def_id
: DefId
) -> bool
{
612 self.static_mutability(def_id
) == Some(hir
::MutMutable
)
615 /// Expands the given impl trait type, stopping if the type is recursive.
616 pub fn try_expand_impl_trait_type(
619 substs
: SubstsRef
<'tcx
>,
620 ) -> Result
<Ty
<'tcx
>, Ty
<'tcx
>> {
621 use crate::ty
::fold
::TypeFolder
;
623 struct OpaqueTypeExpander
<'tcx
> {
624 // Contains the DefIds of the opaque types that are currently being
625 // expanded. When we expand an opaque type we insert the DefId of
626 // that type, and when we finish expanding that type we remove the
628 seen_opaque_tys
: FxHashSet
<DefId
>,
629 primary_def_id
: DefId
,
630 found_recursion
: bool
,
634 impl<'tcx
> OpaqueTypeExpander
<'tcx
> {
638 substs
: SubstsRef
<'tcx
>,
639 ) -> Option
<Ty
<'tcx
>> {
640 if self.found_recursion
{
642 } else if self.seen_opaque_tys
.insert(def_id
) {
643 let generic_ty
= self.tcx
.type_of(def_id
);
644 let concrete_ty
= generic_ty
.subst(self.tcx
, substs
);
645 let expanded_ty
= self.fold_ty(concrete_ty
);
646 self.seen_opaque_tys
.remove(&def_id
);
649 // If another opaque type that we contain is recursive, then it
650 // will report the error, so we don't have to.
651 self.found_recursion
= def_id
== self.primary_def_id
;
657 impl<'tcx
> TypeFolder
<'tcx
> for OpaqueTypeExpander
<'tcx
> {
658 fn tcx(&self) -> TyCtxt
<'tcx
> {
662 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
663 if let ty
::Opaque(def_id
, substs
) = t
.sty
{
664 self.expand_opaque_ty(def_id
, substs
).unwrap_or(t
)
666 t
.super_fold_with(self)
671 let mut visitor
= OpaqueTypeExpander
{
672 seen_opaque_tys
: FxHashSet
::default(),
673 primary_def_id
: def_id
,
674 found_recursion
: false,
677 let expanded_type
= visitor
.expand_opaque_ty(def_id
, substs
).unwrap();
678 if visitor
.found_recursion
{
686 impl<'tcx
> ty
::TyS
<'tcx
> {
687 /// Checks whether values of this type `T` are *moved* or *copied*
688 /// when referenced -- this amounts to a check for whether `T:
689 /// Copy`, but note that we **don't** consider lifetimes when
690 /// doing this check. This means that we may generate MIR which
691 /// does copies even when the type actually doesn't satisfy the
692 /// full requirements for the `Copy` trait (cc #29149) -- this
693 /// winds up being reported as an error during NLL borrow check.
694 pub fn is_copy_modulo_regions(
697 param_env
: ty
::ParamEnv
<'tcx
>,
700 tcx
.at(span
).is_copy_raw(param_env
.and(self))
703 /// Checks whether values of this type `T` have a size known at
704 /// compile time (i.e., whether `T: Sized`). Lifetimes are ignored
705 /// for the purposes of this check, so it can be an
706 /// over-approximation in generic contexts, where one can have
707 /// strange rules like `<T as Foo<'static>>::Bar: Sized` that
708 /// actually carry lifetime requirements.
709 pub fn is_sized(&'tcx
self, tcx_at
: TyCtxtAt
<'tcx
>, param_env
: ty
::ParamEnv
<'tcx
>) -> bool
{
710 tcx_at
.is_sized_raw(param_env
.and(self))
713 /// Checks whether values of this type `T` implement the `Freeze`
714 /// trait -- frozen types are those that do not contain a
715 /// `UnsafeCell` anywhere. This is a language concept used to
716 /// distinguish "true immutability", which is relevant to
717 /// optimization as well as the rules around static values. Note
718 /// that the `Freeze` trait is not exposed to end users and is
719 /// effectively an implementation detail.
723 param_env
: ty
::ParamEnv
<'tcx
>,
726 tcx
.at(span
).is_freeze_raw(param_env
.and(self))
729 /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
730 /// non-copy and *might* have a destructor attached; if it returns
731 /// `false`, then `ty` definitely has no destructor (i.e., no drop glue).
733 /// (Note that this implies that if `ty` has a destructor attached,
734 /// then `needs_drop` will definitely return `true` for `ty`.)
736 pub fn needs_drop(&'tcx
self, tcx
: TyCtxt
<'tcx
>, param_env
: ty
::ParamEnv
<'tcx
>) -> bool
{
737 tcx
.needs_drop_raw(param_env
.and(self)).0
740 pub fn same_type(a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> bool
{
741 match (&a
.sty
, &b
.sty
) {
742 (&Adt(did_a
, substs_a
), &Adt(did_b
, substs_b
)) => {
747 substs_a
.types().zip(substs_b
.types()).all(|(a
, b
)| Self::same_type(a
, b
))
753 /// Check whether a type is representable. This means it cannot contain unboxed
754 /// structural recursion. This check is needed for structs and enums.
755 pub fn is_representable(&'tcx
self, tcx
: TyCtxt
<'tcx
>, sp
: Span
) -> Representability
{
756 // Iterate until something non-representable is found
757 fn fold_repr
<It
: Iterator
<Item
=Representability
>>(iter
: It
) -> Representability
{
758 iter
.fold(Representability
::Representable
, |r1
, r2
| {
760 (Representability
::SelfRecursive(v1
),
761 Representability
::SelfRecursive(v2
)) => {
762 Representability
::SelfRecursive(v1
.into_iter().chain(v2
).collect())
764 (r1
, r2
) => cmp
::max(r1
, r2
)
769 fn are_inner_types_recursive
<'tcx
>(
772 seen
: &mut Vec
<Ty
<'tcx
>>,
773 representable_cache
: &mut FxHashMap
<Ty
<'tcx
>, Representability
>,
775 ) -> Representability
{
778 // Find non representable
779 fold_repr(ts
.iter().map(|ty
| {
780 is_type_structurally_recursive(
789 // Fixed-length vectors.
790 // FIXME(#11924) Behavior undecided for zero-length vectors.
792 is_type_structurally_recursive(tcx
, sp
, seen
, representable_cache
, ty
)
794 Adt(def
, substs
) => {
795 // Find non representable fields with their spans
796 fold_repr(def
.all_fields().map(|field
| {
797 let ty
= field
.ty(tcx
, substs
);
798 let span
= tcx
.hir().span_if_local(field
.did
).unwrap_or(sp
);
799 match is_type_structurally_recursive(tcx
, span
, seen
,
800 representable_cache
, ty
)
802 Representability
::SelfRecursive(_
) => {
803 Representability
::SelfRecursive(vec
![span
])
810 // this check is run on type definitions, so we don't expect
811 // to see closure types
812 bug
!("requires check invoked on inapplicable type: {:?}", ty
)
814 _
=> Representability
::Representable
,
818 fn same_struct_or_enum
<'tcx
>(ty
: Ty
<'tcx
>, def
: &'tcx ty
::AdtDef
) -> bool
{
827 // Does the type `ty` directly (without indirection through a pointer)
828 // contain any types on stack `seen`?
829 fn is_type_structurally_recursive
<'tcx
>(
832 seen
: &mut Vec
<Ty
<'tcx
>>,
833 representable_cache
: &mut FxHashMap
<Ty
<'tcx
>, Representability
>,
835 ) -> Representability
{
836 debug
!("is_type_structurally_recursive: {:?} {:?}", ty
, sp
);
837 if let Some(representability
) = representable_cache
.get(ty
) {
838 debug
!("is_type_structurally_recursive: {:?} {:?} - (cached) {:?}",
839 ty
, sp
, representability
);
840 return representability
.clone();
843 let representability
= is_type_structurally_recursive_inner(
844 tcx
, sp
, seen
, representable_cache
, ty
);
846 representable_cache
.insert(ty
, representability
.clone());
850 fn is_type_structurally_recursive_inner
<'tcx
>(
853 seen
: &mut Vec
<Ty
<'tcx
>>,
854 representable_cache
: &mut FxHashMap
<Ty
<'tcx
>, Representability
>,
856 ) -> Representability
{
860 // Iterate through stack of previously seen types.
861 let mut iter
= seen
.iter();
863 // The first item in `seen` is the type we are actually curious about.
864 // We want to return SelfRecursive if this type contains itself.
865 // It is important that we DON'T take generic parameters into account
866 // for this check, so that Bar<T> in this example counts as SelfRecursive:
869 // struct Bar<T> { x: Bar<Foo> }
871 if let Some(&seen_type
) = iter
.next() {
872 if same_struct_or_enum(seen_type
, def
) {
873 debug
!("SelfRecursive: {:?} contains {:?}",
876 return Representability
::SelfRecursive(vec
![sp
]);
880 // We also need to know whether the first item contains other types
881 // that are structurally recursive. If we don't catch this case, we
882 // will recurse infinitely for some inputs.
884 // It is important that we DO take generic parameters into account
885 // here, so that code like this is considered SelfRecursive, not
886 // ContainsRecursive:
888 // struct Foo { Option<Option<Foo>> }
890 for &seen_type
in iter
{
891 if ty
::TyS
::same_type(ty
, seen_type
) {
892 debug
!("ContainsRecursive: {:?} contains {:?}",
895 return Representability
::ContainsRecursive
;
900 // For structs and enums, track all previously seen types by pushing them
901 // onto the 'seen' stack.
903 let out
= are_inner_types_recursive(tcx
, sp
, seen
, representable_cache
, ty
);
908 // No need to push in other cases.
909 are_inner_types_recursive(tcx
, sp
, seen
, representable_cache
, ty
)
914 debug
!("is_type_representable: {:?}", self);
916 // To avoid a stack overflow when checking an enum variant or struct that
917 // contains a different, structurally recursive type, maintain a stack
918 // of seen types and check recursion for each of them (issues #3008, #3779).
919 let mut seen
: Vec
<Ty
<'_
>> = Vec
::new();
920 let mut representable_cache
= FxHashMap
::default();
921 let r
= is_type_structurally_recursive(
922 tcx
, sp
, &mut seen
, &mut representable_cache
, self);
923 debug
!("is_type_representable: {:?} is {:?}", self, r
);
928 fn is_copy_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> bool
{
929 let (param_env
, ty
) = query
.into_parts();
930 let trait_def_id
= tcx
.require_lang_item(lang_items
::CopyTraitLangItem
);
932 .enter(|infcx
| traits
::type_known_to_meet_bound_modulo_regions(
941 fn is_sized_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> bool
{
942 let (param_env
, ty
) = query
.into_parts();
943 let trait_def_id
= tcx
.require_lang_item(lang_items
::SizedTraitLangItem
);
945 .enter(|infcx
| traits
::type_known_to_meet_bound_modulo_regions(
954 fn is_freeze_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> bool
{
955 let (param_env
, ty
) = query
.into_parts();
956 let trait_def_id
= tcx
.require_lang_item(lang_items
::FreezeTraitLangItem
);
958 .enter(|infcx
| traits
::type_known_to_meet_bound_modulo_regions(
967 #[derive(Clone, HashStable)]
968 pub struct NeedsDrop(pub bool
);
970 fn needs_drop_raw
<'tcx
>(tcx
: TyCtxt
<'tcx
>, query
: ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>) -> NeedsDrop
{
971 let (param_env
, ty
) = query
.into_parts();
973 let needs_drop
= |ty
: Ty
<'tcx
>| -> bool
{
974 tcx
.needs_drop_raw(param_env
.and(ty
)).0
977 assert
!(!ty
.needs_infer());
979 NeedsDrop(match ty
.sty
{
980 // Fast-path for primitive types
981 ty
::Infer(ty
::FreshIntTy(_
)) | ty
::Infer(ty
::FreshFloatTy(_
)) |
982 ty
::Bool
| ty
::Int(_
) | ty
::Uint(_
) | ty
::Float(_
) | ty
::Never
|
983 ty
::FnDef(..) | ty
::FnPtr(_
) | ty
::Char
| ty
::GeneratorWitness(..) |
984 ty
::RawPtr(_
) | ty
::Ref(..) | ty
::Str
=> false,
986 // Foreign types can never have destructors
987 ty
::Foreign(..) => false,
989 // `ManuallyDrop` doesn't have a destructor regardless of field types.
990 ty
::Adt(def
, _
) if Some(def
.did
) == tcx
.lang_items().manually_drop() => false,
992 // Issue #22536: We first query `is_copy_modulo_regions`. It sees a
993 // normalized version of the type, and therefore will definitely
994 // know whether the type implements Copy (and thus needs no
995 // cleanup/drop/zeroing) ...
996 _
if ty
.is_copy_modulo_regions(tcx
, param_env
, DUMMY_SP
) => false,
998 // ... (issue #22536 continued) but as an optimization, still use
999 // prior logic of asking for the structural "may drop".
1001 // FIXME(#22815): Note that this is a conservative heuristic;
1002 // it may report that the type "may drop" when actual type does
1003 // not actually have a destructor associated with it. But since
1004 // the type absolutely did not have the `Copy` bound attached
1005 // (see above), it is sound to treat it as having a destructor.
1007 // User destructors are the only way to have concrete drop types.
1008 ty
::Adt(def
, _
) if def
.has_dtor(tcx
) => true,
1010 // Can refer to a type which may drop.
1011 // FIXME(eddyb) check this against a ParamEnv.
1012 ty
::Dynamic(..) | ty
::Projection(..) | ty
::Param(_
) | ty
::Bound(..) |
1013 ty
::Placeholder(..) | ty
::Opaque(..) | ty
::Infer(_
) | ty
::Error
=> true,
1015 ty
::UnnormalizedProjection(..) => bug
!("only used with chalk-engine"),
1017 // Structural recursion.
1018 ty
::Array(ty
, _
) | ty
::Slice(ty
) => needs_drop(ty
),
1020 ty
::Closure(def_id
, ref substs
) => substs
.upvar_tys(def_id
, tcx
).any(needs_drop
),
1022 // Pessimistically assume that all generators will require destructors
1023 // as we don't know if a destructor is a noop or not until after the MIR
1024 // state transformation pass
1025 ty
::Generator(..) => true,
1027 ty
::Tuple(ref tys
) => tys
.iter().map(|k
| k
.expect_ty()).any(needs_drop
),
1029 // unions don't have destructors because of the child types,
1030 // only if they manually implement `Drop` (handled above).
1031 ty
::Adt(def
, _
) if def
.is_union() => false,
1033 ty
::Adt(def
, substs
) =>
1034 def
.variants
.iter().any(
1035 |variant
| variant
.fields
.iter().any(
1036 |field
| needs_drop(field
.ty(tcx
, substs
)))),
1040 pub enum ExplicitSelf
<'tcx
> {
1042 ByReference(ty
::Region
<'tcx
>, hir
::Mutability
),
1043 ByRawPointer(hir
::Mutability
),
1048 impl<'tcx
> ExplicitSelf
<'tcx
> {
1049 /// Categorizes an explicit self declaration like `self: SomeType`
1050 /// into either `self`, `&self`, `&mut self`, `Box<self>`, or
1052 /// This is mainly used to require the arbitrary_self_types feature
1053 /// in the case of `Other`, to improve error messages in the common cases,
1054 /// and to make `Other` non-object-safe.
1059 /// impl<'a> Foo for &'a T {
1060 /// // Legal declarations:
1061 /// fn method1(self: &&'a T); // ExplicitSelf::ByReference
1062 /// fn method2(self: &'a T); // ExplicitSelf::ByValue
1063 /// fn method3(self: Box<&'a T>); // ExplicitSelf::ByBox
1064 /// fn method4(self: Rc<&'a T>); // ExplicitSelf::Other
1066 /// // Invalid cases will be caught by `check_method_receiver`:
1067 /// fn method_err1(self: &'a mut T); // ExplicitSelf::Other
1068 /// fn method_err2(self: &'static T) // ExplicitSelf::ByValue
1069 /// fn method_err3(self: &&T) // ExplicitSelf::ByReference
1073 pub fn determine
<P
>(
1074 self_arg_ty
: Ty
<'tcx
>,
1076 ) -> ExplicitSelf
<'tcx
>
1078 P
: Fn(Ty
<'tcx
>) -> bool
1080 use self::ExplicitSelf
::*;
1082 match self_arg_ty
.sty
{
1083 _
if is_self_ty(self_arg_ty
) => ByValue
,
1084 ty
::Ref(region
, ty
, mutbl
) if is_self_ty(ty
) => {
1085 ByReference(region
, mutbl
)
1087 ty
::RawPtr(ty
::TypeAndMut { ty, mutbl }
) if is_self_ty(ty
) => {
1090 ty
::Adt(def
, _
) if def
.is_box() && is_self_ty(self_arg_ty
.boxed_ty()) => {
1098 pub fn provide(providers
: &mut ty
::query
::Providers
<'_
>) {
1099 *providers
= ty
::query
::Providers
{