1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 The collect phase of type check has the job of visiting all items,
16 determining their type, and writing that type into the `tcx.tcache`
17 table. Despite its name, this table does not really operate as a
18 *cache*, at least not for the types of items defined within the
19 current crate: we assume that after the collect phase, the types of
20 all local items will be present in the table.
22 Unlike most of the types that are present in Rust, the types computed
23 for each item are in fact type schemes. This means that they are
24 generic types that may have type parameters. TypeSchemes are
25 represented by an instance of `ty::TypeScheme`. This combines the
26 core type along with a list of the bounds for each parameter. Type
27 parameters themselves are represented as `ty_param()` instances.
29 The phasing of type conversion is somewhat complicated. There is no
30 clear set of phases we can enforce (e.g., converting traits first,
31 then types, or something like that) because the user can introduce
32 arbitrary interdependencies. So instead we generally convert things
33 lazilly and on demand, and include logic that checks for cycles.
34 Demand is driven by calls to `AstConv::get_item_type_scheme` or
35 `AstConv::lookup_trait_def`.
37 Currently, we "convert" types and traits in two phases (note that
38 conversion only affects the types of items / enum variants / methods;
39 it does not e.g. compute the types of individual expressions):
42 1. Trait/Type definitions
44 Conversion itself is done by simply walking each of the items in turn
45 and invoking an appropriate function (e.g., `trait_def_of_item` or
46 `convert_item`). However, it is possible that while converting an
47 item, we may need to compute the *type scheme* or *trait definition*
50 There are some shortcomings in this design:
52 - Before walking the set of supertraits for a given trait, you must
53 call `ensure_super_predicates` on that trait def-id. Otherwise,
54 `lookup_super_predicates` will result in ICEs.
55 - Because the type scheme includes defaults, cycles through type
56 parameter defaults are illegal even if those defaults are never
57 employed. This is not necessarily a bug.
61 use astconv
::{AstConv, ast_region_to_region, Bounds, PartitionedBounds, partition_bounds}
;
63 use constrained_type_params
as ctp
;
64 use middle
::lang_items
::SizedTraitLangItem
;
65 use middle
::const_val
::ConstVal
;
66 use rustc_const_eval
::EvalHint
::UncheckedExprHint
;
67 use rustc_const_eval
::{eval_const_expr_partial, report_const_eval_err}
;
68 use rustc
::ty
::subst
::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace}
;
69 use rustc
::ty
::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer}
;
70 use rustc
::ty
::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme}
;
71 use rustc
::ty
::{VariantKind}
;
72 use rustc
::ty
::util
::IntTypeExt
;
74 use rustc
::dep_graph
::DepNode
;
75 use util
::common
::{ErrorReported, MemoizationMap}
;
76 use util
::nodemap
::{NodeMap, FnvHashMap}
;
77 use {CrateCtxt, write_ty_to_tcx}
;
79 use rustc_const_math
::ConstInt
;
81 use std
::cell
::RefCell
;
82 use std
::collections
::HashSet
;
83 use std
::collections
::hash_map
::Entry
::{Occupied, Vacant}
;
86 use syntax
::{abi, ast, attr}
;
87 use syntax
::parse
::token
::keywords
;
91 use rustc
::hir
::{self, intravisit, map as hir_map, print as pprust}
;
92 use rustc
::hir
::def
::Def
;
93 use rustc
::hir
::def_id
::DefId
;
95 ///////////////////////////////////////////////////////////////////////////
98 pub fn collect_item_types(ccx
: &CrateCtxt
) {
99 let mut visitor
= CollectItemTypesVisitor { ccx: ccx }
;
100 ccx
.tcx
.visit_all_items_in_krate(DepNode
::CollectItem
, &mut visitor
);
103 ///////////////////////////////////////////////////////////////////////////
105 /// Context specific to some particular item. This is what implements
106 /// AstConv. It has information about the predicates that are defined
107 /// on the trait. Unfortunately, this predicate information is
108 /// available in various different forms at various points in the
109 /// process. So we can't just store a pointer to e.g. the AST or the
110 /// parsed ty form, we have to be more flexible. To this end, the
111 /// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
112 /// that it uses to satisfy `get_type_parameter_bounds` requests.
113 /// This object might draw the information from the AST
114 /// (`hir::Generics`) or it might draw from a `ty::GenericPredicates`
115 /// or both (a tuple).
116 struct ItemCtxt
<'a
,'tcx
:'a
> {
117 ccx
: &'a CrateCtxt
<'a
,'tcx
>,
118 param_bounds
: &'
a (GetTypeParameterBounds
<'tcx
>+'a
),
121 #[derive(Copy, Clone, PartialEq, Eq)]
122 pub enum AstConvRequest
{
123 GetItemTypeScheme(DefId
),
125 EnsureSuperPredicates(DefId
),
126 GetTypeParameterBounds(ast
::NodeId
),
129 ///////////////////////////////////////////////////////////////////////////
131 struct CollectItemTypesVisitor
<'a
, 'tcx
: 'a
> {
132 ccx
: &'a CrateCtxt
<'a
, 'tcx
>
135 impl<'a
, 'tcx
, 'v
> intravisit
::Visitor
<'v
> for CollectItemTypesVisitor
<'a
, 'tcx
> {
136 fn visit_item(&mut self, item
: &hir
::Item
) {
137 convert_item(self.ccx
, item
);
141 ///////////////////////////////////////////////////////////////////////////
142 // Utility types and common code for the above passes.
144 impl<'a
,'tcx
> CrateCtxt
<'a
,'tcx
> {
145 fn icx(&'a
self, param_bounds
: &'a GetTypeParameterBounds
<'tcx
>) -> ItemCtxt
<'a
,'tcx
> {
148 param_bounds
: param_bounds
,
152 fn cycle_check
<F
,R
>(&self,
154 request
: AstConvRequest
,
156 -> Result
<R
,ErrorReported
>
157 where F
: FnOnce() -> Result
<R
,ErrorReported
>
160 let mut stack
= self.stack
.borrow_mut();
161 match stack
.iter().enumerate().rev().find(|&(_
, r
)| *r
== request
) {
164 let cycle
= &stack
[i
..];
165 self.report_cycle(span
, cycle
);
166 return Err(ErrorReported
);
174 self.stack
.borrow_mut().pop();
178 fn report_cycle(&self,
180 cycle
: &[AstConvRequest
])
182 assert
!(!cycle
.is_empty());
185 let mut err
= struct_span_err
!(tcx
.sess
, span
, E0391
,
186 "unsupported cyclic reference between types/traits detected");
187 err
.span_label(span
, &format
!("cyclic reference"));
190 AstConvRequest
::GetItemTypeScheme(def_id
) |
191 AstConvRequest
::GetTraitDef(def_id
) => {
193 &format
!("the cycle begins when processing `{}`...",
194 tcx
.item_path_str(def_id
)));
196 AstConvRequest
::EnsureSuperPredicates(def_id
) => {
198 &format
!("the cycle begins when computing the supertraits of `{}`...",
199 tcx
.item_path_str(def_id
)));
201 AstConvRequest
::GetTypeParameterBounds(id
) => {
202 let def
= tcx
.type_parameter_def(id
);
204 &format
!("the cycle begins when computing the bounds \
205 for type parameter `{}`...",
210 for request
in &cycle
[1..] {
212 AstConvRequest
::GetItemTypeScheme(def_id
) |
213 AstConvRequest
::GetTraitDef(def_id
) => {
215 &format
!("...which then requires processing `{}`...",
216 tcx
.item_path_str(def_id
)));
218 AstConvRequest
::EnsureSuperPredicates(def_id
) => {
220 &format
!("...which then requires computing the supertraits of `{}`...",
221 tcx
.item_path_str(def_id
)));
223 AstConvRequest
::GetTypeParameterBounds(id
) => {
224 let def
= tcx
.type_parameter_def(id
);
226 &format
!("...which then requires computing the bounds \
227 for type parameter `{}`...",
234 AstConvRequest
::GetItemTypeScheme(def_id
) |
235 AstConvRequest
::GetTraitDef(def_id
) => {
237 &format
!("...which then again requires processing `{}`, completing the cycle.",
238 tcx
.item_path_str(def_id
)));
240 AstConvRequest
::EnsureSuperPredicates(def_id
) => {
242 &format
!("...which then again requires computing the supertraits of `{}`, \
243 completing the cycle.",
244 tcx
.item_path_str(def_id
)));
246 AstConvRequest
::GetTypeParameterBounds(id
) => {
247 let def
= tcx
.type_parameter_def(id
);
249 &format
!("...which then again requires computing the bounds \
250 for type parameter `{}`, completing the cycle.",
257 /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
258 fn get_trait_def(&self, trait_id
: DefId
)
259 -> &'tcx ty
::TraitDef
<'tcx
>
263 if let Some(trait_id
) = tcx
.map
.as_local_node_id(trait_id
) {
264 let item
= match tcx
.map
.get(trait_id
) {
265 hir_map
::NodeItem(item
) => item
,
266 _
=> bug
!("get_trait_def({:?}): not an item", trait_id
)
269 trait_def_of_item(self, &item
)
271 tcx
.lookup_trait_def(trait_id
)
275 /// Ensure that the (transitive) super predicates for
276 /// `trait_def_id` are available. This will report a cycle error
277 /// if a trait `X` (transitively) extends itself in some form.
278 fn ensure_super_predicates(&self, span
: Span
, trait_def_id
: DefId
)
279 -> Result
<(), ErrorReported
>
281 self.cycle_check(span
, AstConvRequest
::EnsureSuperPredicates(trait_def_id
), || {
282 let def_ids
= ensure_super_predicates_step(self, trait_def_id
);
284 for def_id
in def_ids
{
285 self.ensure_super_predicates(span
, def_id
)?
;
293 impl<'a
,'tcx
> ItemCtxt
<'a
,'tcx
> {
294 fn to_ty
<RS
:RegionScope
>(&self, rs
: &RS
, ast_ty
: &hir
::Ty
) -> Ty
<'tcx
> {
295 AstConv
::ast_ty_to_ty(self, rs
, ast_ty
)
299 impl<'a
, 'tcx
> AstConv
<'tcx
, 'tcx
> for ItemCtxt
<'a
, 'tcx
> {
300 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'b
, 'tcx
, 'tcx
> { self.ccx.tcx }
302 fn ast_ty_to_ty_cache(&self) -> &RefCell
<NodeMap
<Ty
<'tcx
>>> {
303 &self.ccx
.ast_ty_to_ty_cache
306 fn get_item_type_scheme(&self, span
: Span
, id
: DefId
)
307 -> Result
<ty
::TypeScheme
<'tcx
>, ErrorReported
>
309 self.ccx
.cycle_check(span
, AstConvRequest
::GetItemTypeScheme(id
), || {
310 Ok(type_scheme_of_def_id(self.ccx
, id
))
314 fn get_trait_def(&self, span
: Span
, id
: DefId
)
315 -> Result
<&'tcx ty
::TraitDef
<'tcx
>, ErrorReported
>
317 self.ccx
.cycle_check(span
, AstConvRequest
::GetTraitDef(id
), || {
318 Ok(self.ccx
.get_trait_def(id
))
322 fn ensure_super_predicates(&self,
325 -> Result
<(), ErrorReported
>
327 debug
!("ensure_super_predicates(trait_def_id={:?})",
330 self.ccx
.ensure_super_predicates(span
, trait_def_id
)
334 fn get_type_parameter_bounds(&self,
336 node_id
: ast
::NodeId
)
337 -> Result
<Vec
<ty
::PolyTraitRef
<'tcx
>>, ErrorReported
>
339 self.ccx
.cycle_check(span
, AstConvRequest
::GetTypeParameterBounds(node_id
), || {
340 let v
= self.param_bounds
.get_type_parameter_bounds(self, span
, node_id
)
342 .filter_map(|p
| p
.to_opt_poly_trait_ref())
348 fn trait_defines_associated_type_named(&self,
350 assoc_name
: ast
::Name
)
353 if let Some(trait_id
) = self.tcx().map
.as_local_node_id(trait_def_id
) {
354 trait_defines_associated_type_named(self.ccx
, trait_id
, assoc_name
)
356 let trait_def
= self.tcx().lookup_trait_def(trait_def_id
);
357 trait_def
.associated_type_names
.contains(&assoc_name
)
361 fn get_free_substs(&self) -> Option
<&Substs
<'tcx
>> {
366 _ty_param_def
: Option
<ty
::TypeParameterDef
<'tcx
>>,
367 _substs
: Option
<&mut Substs
<'tcx
>>,
368 _space
: Option
<ParamSpace
>,
369 span
: Span
) -> Ty
<'tcx
> {
374 "the type placeholder `_` is not allowed within types on item signatures"
375 ).span_label(span
, &format
!("not allowed in type signatures"))
380 fn projected_ty_from_poly_trait_ref(&self,
382 poly_trait_ref
: ty
::PolyTraitRef
<'tcx
>,
383 item_name
: ast
::Name
)
386 if let Some(trait_ref
) = self.tcx().no_late_bound_regions(&poly_trait_ref
) {
387 self.projected_ty(span
, trait_ref
, item_name
)
389 // no late-bound regions, we can just ignore the binder
390 span_err
!(self.tcx().sess
, span
, E0212
,
391 "cannot extract an associated type from a higher-ranked trait bound \
397 fn projected_ty(&self,
399 trait_ref
: ty
::TraitRef
<'tcx
>,
400 item_name
: ast
::Name
)
403 self.tcx().mk_projection(trait_ref
, item_name
)
406 fn set_tainted_by_errors(&self) {
407 // no obvious place to track this, just let it go
411 /// Interface used to find the bounds on a type parameter from within
412 /// an `ItemCtxt`. This allows us to use multiple kinds of sources.
413 trait GetTypeParameterBounds
<'tcx
> {
414 fn get_type_parameter_bounds(&self,
415 astconv
: &AstConv
<'tcx
, 'tcx
>,
417 node_id
: ast
::NodeId
)
418 -> Vec
<ty
::Predicate
<'tcx
>>;
421 /// Find bounds from both elements of the tuple.
422 impl<'a
,'b
,'tcx
,A
,B
> GetTypeParameterBounds
<'tcx
> for (&'a A
,&'b B
)
423 where A
: GetTypeParameterBounds
<'tcx
>, B
: GetTypeParameterBounds
<'tcx
>
425 fn get_type_parameter_bounds(&self,
426 astconv
: &AstConv
<'tcx
, 'tcx
>,
428 node_id
: ast
::NodeId
)
429 -> Vec
<ty
::Predicate
<'tcx
>>
431 let mut v
= self.0.get_type_parameter_bounds(astconv
, span
, node_id
);
432 v
.extend(self.1.get_type_parameter_bounds(astconv
, span
, node_id
));
437 /// Empty set of bounds.
438 impl<'tcx
> GetTypeParameterBounds
<'tcx
> for () {
439 fn get_type_parameter_bounds(&self,
440 _astconv
: &AstConv
<'tcx
, 'tcx
>,
442 _node_id
: ast
::NodeId
)
443 -> Vec
<ty
::Predicate
<'tcx
>>
449 /// Find bounds from the parsed and converted predicates. This is
450 /// used when converting methods, because by that time the predicates
451 /// from the trait/impl have been fully converted.
452 impl<'tcx
> GetTypeParameterBounds
<'tcx
> for ty
::GenericPredicates
<'tcx
> {
453 fn get_type_parameter_bounds(&self,
454 astconv
: &AstConv
<'tcx
, 'tcx
>,
456 node_id
: ast
::NodeId
)
457 -> Vec
<ty
::Predicate
<'tcx
>>
459 let def
= astconv
.tcx().type_parameter_def(node_id
);
463 .filter(|predicate
| {
465 ty
::Predicate
::Trait(ref data
) => {
466 data
.skip_binder().self_ty().is_param(def
.space
, def
.index
)
468 ty
::Predicate
::TypeOutlives(ref data
) => {
469 data
.skip_binder().0.is_param
(def
.space
, def
.index
)
471 ty
::Predicate
::Rfc1592(..) |
472 ty
::Predicate
::Equate(..) |
473 ty
::Predicate
::RegionOutlives(..) |
474 ty
::Predicate
::WellFormed(..) |
475 ty
::Predicate
::ObjectSafe(..) |
476 ty
::Predicate
::ClosureKind(..) |
477 ty
::Predicate
::Projection(..) => {
487 /// Find bounds from hir::Generics. This requires scanning through the
488 /// AST. We do this to avoid having to convert *all* the bounds, which
489 /// would create artificial cycles. Instead we can only convert the
490 /// bounds for a type parameter `X` if `X::Foo` is used.
491 impl<'tcx
> GetTypeParameterBounds
<'tcx
> for hir
::Generics
{
492 fn get_type_parameter_bounds(&self,
493 astconv
: &AstConv
<'tcx
, 'tcx
>,
495 node_id
: ast
::NodeId
)
496 -> Vec
<ty
::Predicate
<'tcx
>>
498 // In the AST, bounds can derive from two places. Either
499 // written inline like `<T:Foo>` or in a where clause like
502 let def
= astconv
.tcx().type_parameter_def(node_id
);
503 let ty
= astconv
.tcx().mk_param_from_def(&def
);
508 .filter(|p
| p
.id
== node_id
)
509 .flat_map(|p
| p
.bounds
.iter())
510 .flat_map(|b
| predicates_from_bound(astconv
, ty
, b
));
512 let from_where_clauses
=
516 .filter_map(|wp
| match *wp
{
517 hir
::WherePredicate
::BoundPredicate(ref bp
) => Some(bp
),
520 .filter(|bp
| is_param(astconv
.tcx(), &bp
.bounded_ty
, node_id
))
521 .flat_map(|bp
| bp
.bounds
.iter())
522 .flat_map(|b
| predicates_from_bound(astconv
, ty
, b
));
524 from_ty_params
.chain(from_where_clauses
).collect()
528 /// Tests whether this is the AST for a reference to the type
529 /// parameter with id `param_id`. We use this so as to avoid running
530 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
531 /// conversion of the type to avoid inducing unnecessary cycles.
532 fn is_param
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
534 param_id
: ast
::NodeId
)
537 if let hir
::TyPath(None
, _
) = ast_ty
.node
{
538 let path_res
= tcx
.expect_resolution(ast_ty
.id
);
539 match path_res
.base_def
{
540 Def
::SelfTy(Some(def_id
), None
) |
541 Def
::TyParam(_
, _
, def_id
, _
) if path_res
.depth
== 0 => {
542 def_id
== tcx
.map
.local_def_id(param_id
)
552 fn convert_method
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
553 container
: ImplOrTraitItemContainer
,
556 vis
: &hir
::Visibility
,
557 sig
: &hir
::MethodSig
,
558 defaultness
: hir
::Defaultness
,
559 untransformed_rcvr_ty
: Ty
<'tcx
>,
560 rcvr_ty_generics
: &ty
::Generics
<'tcx
>,
561 rcvr_ty_predicates
: &ty
::GenericPredicates
<'tcx
>) {
562 let ty_generics
= ty_generics_for_fn(ccx
, &sig
.generics
, rcvr_ty_generics
);
564 let ty_generic_predicates
=
565 ty_generic_predicates_for_fn(ccx
, &sig
.generics
, rcvr_ty_predicates
);
567 let (fty
, explicit_self_category
) = {
568 let anon_scope
= match container
{
569 ImplContainer(_
) => Some(AnonTypeScope
::new(&ty_generics
)),
570 TraitContainer(_
) => None
572 AstConv
::ty_of_method(&ccx
.icx(&(rcvr_ty_predicates
, &sig
.generics
)),
573 sig
, untransformed_rcvr_ty
, anon_scope
)
576 let def_id
= ccx
.tcx
.map
.local_def_id(id
);
577 let substs
= mk_item_substs(ccx
.tcx
, &ty_generics
);
579 let ty_method
= ty
::Method
::new(name
,
581 ty_generic_predicates
,
583 explicit_self_category
,
584 ty
::Visibility
::from_hir(vis
, id
, ccx
.tcx
),
589 let fty
= ccx
.tcx
.mk_fn_def(def_id
, substs
, ty_method
.fty
);
590 debug
!("method {} (id {}) has type {:?}",
592 ccx
.tcx
.register_item_type(def_id
, TypeScheme
{
593 generics
: ty_method
.generics
.clone(),
596 ccx
.tcx
.predicates
.borrow_mut().insert(def_id
, ty_method
.predicates
.clone());
598 write_ty_to_tcx(ccx
, id
, fty
);
600 debug
!("writing method type: def_id={:?} mty={:?}",
603 ccx
.tcx
.impl_or_trait_items
.borrow_mut().insert(def_id
,
604 ty
::MethodTraitItem(Rc
::new(ty_method
)));
607 fn convert_field
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
608 struct_generics
: &ty
::Generics
<'tcx
>,
609 struct_predicates
: &ty
::GenericPredicates
<'tcx
>,
610 field
: &hir
::StructField
,
611 ty_f
: ty
::FieldDefMaster
<'tcx
>)
613 let tt
= ccx
.icx(struct_predicates
).to_ty(&ExplicitRscope
, &field
.ty
);
615 write_ty_to_tcx(ccx
, field
.id
, tt
);
617 /* add the field to the tcache */
618 ccx
.tcx
.register_item_type(ccx
.tcx
.map
.local_def_id(field
.id
),
620 generics
: struct_generics
.clone(),
623 ccx
.tcx
.predicates
.borrow_mut().insert(ccx
.tcx
.map
.local_def_id(field
.id
),
624 struct_predicates
.clone());
627 fn convert_associated_const
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
628 container
: ImplOrTraitItemContainer
,
631 vis
: &hir
::Visibility
,
632 defaultness
: hir
::Defaultness
,
636 ccx
.tcx
.predicates
.borrow_mut().insert(ccx
.tcx
.map
.local_def_id(id
),
637 ty
::GenericPredicates
::empty());
639 write_ty_to_tcx(ccx
, id
, ty
);
641 let associated_const
= Rc
::new(ty
::AssociatedConst
{
643 vis
: ty
::Visibility
::from_hir(vis
, id
, ccx
.tcx
),
644 defaultness
: defaultness
,
645 def_id
: ccx
.tcx
.map
.local_def_id(id
),
646 container
: container
,
650 ccx
.tcx
.impl_or_trait_items
.borrow_mut()
651 .insert(ccx
.tcx
.map
.local_def_id(id
), ty
::ConstTraitItem(associated_const
));
654 fn convert_associated_type
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
655 container
: ImplOrTraitItemContainer
,
658 vis
: &hir
::Visibility
,
659 defaultness
: hir
::Defaultness
,
660 ty
: Option
<Ty
<'tcx
>>)
662 let associated_type
= Rc
::new(ty
::AssociatedType
{
664 vis
: ty
::Visibility
::from_hir(vis
, id
, ccx
.tcx
),
665 defaultness
: defaultness
,
667 def_id
: ccx
.tcx
.map
.local_def_id(id
),
670 ccx
.tcx
.impl_or_trait_items
.borrow_mut()
671 .insert(ccx
.tcx
.map
.local_def_id(id
), ty
::TypeTraitItem(associated_type
));
674 fn ensure_no_ty_param_bounds(ccx
: &CrateCtxt
,
676 generics
: &hir
::Generics
,
677 thing
: &'
static str) {
678 let mut warn
= false;
680 for ty_param
in generics
.ty_params
.iter() {
681 for bound
in ty_param
.bounds
.iter() {
683 hir
::TraitTyParamBound(..) => {
686 hir
::RegionTyParamBound(..) => { }
692 // According to accepted RFC #XXX, we should
693 // eventually accept these, but it will not be
694 // part of this PR. Still, convert to warning to
695 // make bootstrapping easier.
696 span_warn
!(ccx
.tcx
.sess
, span
, E0122
,
697 "trait bounds are not (yet) enforced \
703 fn convert_item(ccx
: &CrateCtxt
, it
: &hir
::Item
) {
705 debug
!("convert: item {} with id {}", it
.name
, it
.id
);
707 // These don't define types.
708 hir
::ItemExternCrate(_
) | hir
::ItemUse(_
) | hir
::ItemMod(_
) => {
710 hir
::ItemForeignMod(ref foreign_mod
) => {
711 for item
in &foreign_mod
.items
{
712 convert_foreign_item(ccx
, item
);
715 hir
::ItemEnum(ref enum_definition
, _
) => {
716 let (scheme
, predicates
) = convert_typed_item(ccx
, it
);
717 write_ty_to_tcx(ccx
, it
.id
, scheme
.ty
);
718 convert_enum_variant_types(ccx
,
719 tcx
.lookup_adt_def_master(ccx
.tcx
.map
.local_def_id(it
.id
)),
722 &enum_definition
.variants
);
724 hir
::ItemDefaultImpl(_
, ref ast_trait_ref
) => {
726 AstConv
::instantiate_mono_trait_ref(&ccx
.icx(&()),
731 tcx
.record_trait_has_default_impl(trait_ref
.def_id
);
733 tcx
.impl_trait_refs
.borrow_mut().insert(ccx
.tcx
.map
.local_def_id(it
.id
),
741 // Create generics from the generics specified in the impl head.
742 debug
!("convert: ast_generics={:?}", generics
);
743 let def_id
= ccx
.tcx
.map
.local_def_id(it
.id
);
744 let ty_generics
= ty_generics_for_impl(ccx
, generics
);
745 let mut ty_predicates
= ty_generic_predicates_for_type_or_impl(ccx
, generics
);
747 debug
!("convert: impl_bounds={:?}", ty_predicates
);
749 let selfty
= ccx
.icx(&ty_predicates
).to_ty(&ExplicitRscope
, &selfty
);
750 write_ty_to_tcx(ccx
, it
.id
, selfty
);
752 tcx
.register_item_type(def_id
,
753 TypeScheme
{ generics
: ty_generics
.clone(),
755 let trait_ref
= opt_trait_ref
.as_ref().map(|ast_trait_ref
| {
756 AstConv
::instantiate_mono_trait_ref(&ccx
.icx(&ty_predicates
),
761 tcx
.impl_trait_refs
.borrow_mut().insert(def_id
, trait_ref
);
763 enforce_impl_params_are_constrained(ccx
, generics
, &mut ty_predicates
, def_id
);
764 tcx
.predicates
.borrow_mut().insert(def_id
, ty_predicates
.clone());
767 // Convert all the associated consts.
768 // Also, check if there are any duplicate associated items
769 let mut seen_type_items
= FnvHashMap();
770 let mut seen_value_items
= FnvHashMap();
772 for impl_item
in impl_items
{
773 let seen_items
= match impl_item
.node
{
774 hir
::ImplItemKind
::Type(_
) => &mut seen_type_items
,
775 _
=> &mut seen_value_items
,
777 match seen_items
.entry(impl_item
.name
) {
779 let mut err
= struct_span_err
!(tcx
.sess
, impl_item
.span
, E0201
,
780 "duplicate definitions with name `{}`:",
782 err
.span_label(*entry
.get(),
783 &format
!("previous definition of `{}` here",
785 err
.span_label(impl_item
.span
, &format
!("duplicate definition"));
789 entry
.insert(impl_item
.span
);
793 if let hir
::ImplItemKind
::Const(ref ty
, _
) = impl_item
.node
{
794 let ty
= ccx
.icx(&ty_predicates
)
795 .to_ty(&ExplicitRscope
, &ty
);
796 tcx
.register_item_type(ccx
.tcx
.map
.local_def_id(impl_item
.id
),
798 generics
: ty_generics
.clone(),
801 // Trait-associated constants are always public.
802 let public
= &hir
::Public
;
803 let visibility
= if opt_trait_ref
.is_some() { public }
else { &impl_item.vis }
;
804 convert_associated_const(ccx
, ImplContainer(def_id
),
805 impl_item
.name
, impl_item
.id
,
807 impl_item
.defaultness
,
808 ty
, true /* has_value */);
812 // Convert all the associated types.
813 for impl_item
in impl_items
{
814 if let hir
::ImplItemKind
::Type(ref ty
) = impl_item
.node
{
815 if opt_trait_ref
.is_none() {
816 span_err
!(tcx
.sess
, impl_item
.span
, E0202
,
817 "associated types are not allowed in inherent impls");
820 let typ
= ccx
.icx(&ty_predicates
).to_ty(&ExplicitRscope
, ty
);
822 convert_associated_type(ccx
, ImplContainer(def_id
),
823 impl_item
.name
, impl_item
.id
, &impl_item
.vis
,
824 impl_item
.defaultness
, Some(typ
));
828 for impl_item
in impl_items
{
829 if let hir
::ImplItemKind
::Method(ref sig
, _
) = impl_item
.node
{
830 // Trait methods are always public.
831 let public
= &hir
::Public
;
832 let method_vis
= if opt_trait_ref
.is_some() { public }
else { &impl_item.vis }
;
834 convert_method(ccx
, ImplContainer(def_id
),
835 impl_item
.name
, impl_item
.id
, method_vis
,
836 sig
, impl_item
.defaultness
, selfty
, &ty_generics
,
841 enforce_impl_lifetimes_are_constrained(ccx
, generics
, def_id
, impl_items
);
843 hir
::ItemTrait(_
, _
, _
, ref trait_items
) => {
844 let trait_def
= trait_def_of_item(ccx
, it
);
845 let def_id
= trait_def
.trait_ref
.def_id
;
846 let _
: Result
<(), ErrorReported
> = // any error is already reported, can ignore
847 ccx
.ensure_super_predicates(it
.span
, def_id
);
848 convert_trait_predicates(ccx
, it
);
849 let trait_predicates
= tcx
.lookup_predicates(def_id
);
851 debug
!("convert: trait_bounds={:?}", trait_predicates
);
853 // FIXME: is the ordering here important? I think it is.
854 let container
= TraitContainer(def_id
);
856 // Convert all the associated constants.
857 for trait_item
in trait_items
{
858 if let hir
::ConstTraitItem(ref ty
, ref default) = trait_item
.node
{
859 let ty
= ccx
.icx(&trait_predicates
)
860 .to_ty(&ExplicitRscope
, ty
);
861 tcx
.register_item_type(ccx
.tcx
.map
.local_def_id(trait_item
.id
),
863 generics
: trait_def
.generics
.clone(),
866 convert_associated_const(ccx
,
871 hir
::Defaultness
::Default
,
877 // Convert all the associated types.
878 for trait_item
in trait_items
{
879 if let hir
::TypeTraitItem(_
, ref opt_ty
) = trait_item
.node
{
880 let typ
= opt_ty
.as_ref().map({
881 |ty
| ccx
.icx(&trait_predicates
).to_ty(&ExplicitRscope
, &ty
)
884 convert_associated_type(ccx
,
889 hir
::Defaultness
::Default
,
894 // Convert all the methods
895 for trait_item
in trait_items
{
896 if let hir
::MethodTraitItem(ref sig
, _
) = trait_item
.node
{
903 hir
::Defaultness
::Default
,
911 // Add an entry mapping
912 let trait_item_def_ids
= Rc
::new(trait_items
.iter().map(|trait_item
| {
913 let def_id
= ccx
.tcx
.map
.local_def_id(trait_item
.id
);
914 match trait_item
.node
{
915 hir
::ConstTraitItem(..) => ty
::ConstTraitItemId(def_id
),
916 hir
::MethodTraitItem(..) => ty
::MethodTraitItemId(def_id
),
917 hir
::TypeTraitItem(..) => ty
::TypeTraitItemId(def_id
)
920 tcx
.trait_item_def_ids
.borrow_mut().insert(ccx
.tcx
.map
.local_def_id(it
.id
),
923 hir
::ItemStruct(ref struct_def
, _
) => {
924 let (scheme
, predicates
) = convert_typed_item(ccx
, it
);
925 write_ty_to_tcx(ccx
, it
.id
, scheme
.ty
);
927 let it_def_id
= ccx
.tcx
.map
.local_def_id(it
.id
);
928 let variant
= tcx
.lookup_adt_def_master(it_def_id
).struct_variant();
930 for (f
, ty_f
) in struct_def
.fields().iter().zip(variant
.fields
.iter()) {
931 convert_field(ccx
, &scheme
.generics
, &predicates
, f
, ty_f
)
934 if !struct_def
.is_struct() {
935 convert_variant_ctor(ccx
, struct_def
.id(), variant
, scheme
, predicates
);
938 hir
::ItemTy(_
, ref generics
) => {
939 ensure_no_ty_param_bounds(ccx
, it
.span
, generics
, "type");
940 let (scheme
, _
) = convert_typed_item(ccx
, it
);
941 write_ty_to_tcx(ccx
, it
.id
, scheme
.ty
);
944 // This call populates the type cache with the converted type
945 // of the item in passing. All we have to do here is to write
946 // it into the node type table.
947 let (scheme
, _
) = convert_typed_item(ccx
, it
);
948 write_ty_to_tcx(ccx
, it
.id
, scheme
.ty
);
953 fn convert_variant_ctor
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
954 ctor_id
: ast
::NodeId
,
955 variant
: ty
::VariantDef
<'tcx
>,
956 scheme
: ty
::TypeScheme
<'tcx
>,
957 predicates
: ty
::GenericPredicates
<'tcx
>) {
959 let ctor_ty
= match variant
.kind
{
960 VariantKind
::Unit
| VariantKind
::Struct
=> scheme
.ty
,
961 VariantKind
::Tuple
=> {
965 .map(|field
| field
.unsubst_ty())
967 let def_id
= tcx
.map
.local_def_id(ctor_id
);
968 let substs
= mk_item_substs(tcx
, &scheme
.generics
);
969 tcx
.mk_fn_def(def_id
, substs
, tcx
.mk_bare_fn(ty
::BareFnTy
{
970 unsafety
: hir
::Unsafety
::Normal
,
972 sig
: ty
::Binder(ty
::FnSig
{
980 write_ty_to_tcx(ccx
, ctor_id
, ctor_ty
);
981 tcx
.predicates
.borrow_mut().insert(tcx
.map
.local_def_id(ctor_id
), predicates
);
982 tcx
.register_item_type(tcx
.map
.local_def_id(ctor_id
),
984 generics
: scheme
.generics
,
989 fn convert_enum_variant_types
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
990 def
: ty
::AdtDefMaster
<'tcx
>,
991 scheme
: ty
::TypeScheme
<'tcx
>,
992 predicates
: ty
::GenericPredicates
<'tcx
>,
993 variants
: &[hir
::Variant
]) {
994 // fill the field types
995 for (variant
, ty_variant
) in variants
.iter().zip(def
.variants
.iter()) {
996 for (f
, ty_f
) in variant
.node
.data
.fields().iter().zip(ty_variant
.fields
.iter()) {
997 convert_field(ccx
, &scheme
.generics
, &predicates
, f
, ty_f
)
1000 // Convert the ctor, if any. This also registers the variant as
1002 convert_variant_ctor(
1004 variant
.node
.data
.id(),
1012 fn convert_struct_variant
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1016 def
: &hir
::VariantData
)
1017 -> ty
::VariantDefData
<'tcx
, 'tcx
> {
1018 let mut seen_fields
: FnvHashMap
<ast
::Name
, Span
> = FnvHashMap();
1019 let node_id
= ccx
.tcx
.map
.as_local_node_id(did
).unwrap();
1020 let fields
= def
.fields().iter().map(|f
| {
1021 let fid
= ccx
.tcx
.map
.local_def_id(f
.id
);
1022 let dup_span
= seen_fields
.get(&f
.name
).cloned();
1023 if let Some(prev_span
) = dup_span
{
1024 struct_span_err
!(ccx
.tcx
.sess
, f
.span
, E0124
,
1025 "field `{}` is already declared",
1027 .span_label(f
.span
, &"field already declared")
1028 .span_label(prev_span
, &format
!("`{}` first declared here", f
.name
))
1031 seen_fields
.insert(f
.name
, f
.span
);
1034 ty
::FieldDefData
::new(fid
, f
.name
,
1035 ty
::Visibility
::from_hir(&f
.vis
, node_id
, ccx
.tcx
))
1037 ty
::VariantDefData
{
1042 kind
: VariantKind
::from_variant_data(def
),
1046 fn convert_struct_def
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1048 def
: &hir
::VariantData
)
1049 -> ty
::AdtDefMaster
<'tcx
>
1051 let did
= ccx
.tcx
.map
.local_def_id(it
.id
);
1052 // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
1053 let ctor_id
= if !def
.is_struct() { Some(ccx.tcx.map.local_def_id(def.id())) }
else { None }
;
1054 let variants
= vec
![convert_struct_variant(ccx
, ctor_id
.unwrap_or(did
), it
.name
,
1055 ConstInt
::Infer(0), def
)];
1056 let adt
= ccx
.tcx
.intern_adt_def(did
, ty
::AdtKind
::Struct
, variants
);
1057 if let Some(ctor_id
) = ctor_id
{
1058 // Make adt definition available through constructor id as well.
1059 ccx
.tcx
.insert_adt_def(ctor_id
, adt
);
1064 fn evaluate_disr_expr(ccx
: &CrateCtxt
, repr_ty
: attr
::IntType
, e
: &hir
::Expr
)
1065 -> Option
<ty
::Disr
> {
1066 debug
!("disr expr, checking {}", pprust
::expr_to_string(e
));
1068 let ty_hint
= repr_ty
.to_ty(ccx
.tcx
);
1069 let print_err
= |cv
: ConstVal
| {
1070 struct_span_err
!(ccx
.tcx
.sess
, e
.span
, E0079
, "mismatched types")
1071 .note_expected_found(&"type", &ty_hint
, &format
!("{}", cv
.description()))
1072 .span_label(e
.span
, &format
!("expected '{}' type", ty_hint
))
1076 let hint
= UncheckedExprHint(ty_hint
);
1077 match eval_const_expr_partial(ccx
.tcx
, e
, hint
, None
) {
1078 Ok(ConstVal
::Integral(i
)) => {
1079 // FIXME: eval_const_expr_partial should return an error if the hint is wrong
1080 match (repr_ty
, i
) {
1081 (attr
::SignedInt(ast
::IntTy
::I8
), ConstInt
::I8(_
)) |
1082 (attr
::SignedInt(ast
::IntTy
::I16
), ConstInt
::I16(_
)) |
1083 (attr
::SignedInt(ast
::IntTy
::I32
), ConstInt
::I32(_
)) |
1084 (attr
::SignedInt(ast
::IntTy
::I64
), ConstInt
::I64(_
)) |
1085 (attr
::SignedInt(ast
::IntTy
::Is
), ConstInt
::Isize(_
)) |
1086 (attr
::UnsignedInt(ast
::UintTy
::U8
), ConstInt
::U8(_
)) |
1087 (attr
::UnsignedInt(ast
::UintTy
::U16
), ConstInt
::U16(_
)) |
1088 (attr
::UnsignedInt(ast
::UintTy
::U32
), ConstInt
::U32(_
)) |
1089 (attr
::UnsignedInt(ast
::UintTy
::U64
), ConstInt
::U64(_
)) |
1090 (attr
::UnsignedInt(ast
::UintTy
::Us
), ConstInt
::Usize(_
)) => Some(i
),
1092 print_err(ConstVal
::Integral(i
));
1101 // enum variant evaluation happens before the global constant check
1102 // so we need to report the real error
1104 let mut diag
= report_const_eval_err(
1105 ccx
.tcx
, &err
, e
.span
, "enum discriminant");
1112 fn convert_enum_def
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1115 -> ty
::AdtDefMaster
<'tcx
>
1118 let did
= tcx
.map
.local_def_id(it
.id
);
1119 let repr_hints
= tcx
.lookup_repr_hints(did
);
1120 let repr_type
= tcx
.enum_repr_type(repr_hints
.get(0));
1121 let initial
= repr_type
.initial_discriminant(tcx
);
1122 let mut prev_disr
= None
::<ty
::Disr
>;
1123 let variants
= def
.variants
.iter().map(|v
| {
1124 let wrapped_disr
= prev_disr
.map_or(initial
, |d
| d
.wrap_incr());
1125 let disr
= if let Some(ref e
) = v
.node
.disr_expr
{
1126 evaluate_disr_expr(ccx
, repr_type
, e
)
1127 } else if let Some(disr
) = repr_type
.disr_incr(tcx
, prev_disr
) {
1130 span_err
!(tcx
.sess
, v
.span
, E0370
,
1131 "enum discriminant overflowed on value after {}; \
1132 set explicitly via {} = {} if that is desired outcome",
1133 prev_disr
.unwrap(), v
.node
.name
, wrapped_disr
);
1135 }.unwrap_or(wrapped_disr
);
1136 prev_disr
= Some(disr
);
1138 let did
= tcx
.map
.local_def_id(v
.node
.data
.id());
1139 convert_struct_variant(ccx
, did
, v
.node
.name
, disr
, &v
.node
.data
)
1141 tcx
.intern_adt_def(tcx
.map
.local_def_id(it
.id
), ty
::AdtKind
::Enum
, variants
)
1144 /// Ensures that the super-predicates of the trait with def-id
1145 /// trait_def_id are converted and stored. This does NOT ensure that
1146 /// the transitive super-predicates are converted; that is the job of
1147 /// the `ensure_super_predicates()` method in the `AstConv` impl
1148 /// above. Returns a list of trait def-ids that must be ensured as
1149 /// well to guarantee that the transitive superpredicates are
1151 fn ensure_super_predicates_step(ccx
: &CrateCtxt
,
1152 trait_def_id
: DefId
)
1157 debug
!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id
);
1159 let trait_node_id
= if let Some(n
) = tcx
.map
.as_local_node_id(trait_def_id
) {
1162 // If this trait comes from an external crate, then all of the
1163 // supertraits it may depend on also must come from external
1164 // crates, and hence all of them already have their
1165 // super-predicates "converted" (and available from crate
1166 // meta-data), so there is no need to transitively test them.
1170 let superpredicates
= tcx
.super_predicates
.borrow().get(&trait_def_id
).cloned();
1171 let superpredicates
= superpredicates
.unwrap_or_else(|| {
1172 let item
= match ccx
.tcx
.map
.get(trait_node_id
) {
1173 hir_map
::NodeItem(item
) => item
,
1174 _
=> bug
!("trait_node_id {} is not an item", trait_node_id
)
1177 let (generics
, bounds
) = match item
.node
{
1178 hir
::ItemTrait(_
, ref generics
, ref supertraits
, _
) => (generics
, supertraits
),
1179 _
=> span_bug
!(item
.span
,
1180 "ensure_super_predicates_step invoked on non-trait"),
1183 // In-scope when converting the superbounds for `Trait` are
1184 // that `Self:Trait` as well as any bounds that appear on the
1186 let trait_def
= trait_def_of_item(ccx
, item
);
1187 let self_predicate
= ty
::GenericPredicates
{
1188 predicates
: VecPerParamSpace
::new(vec
![],
1189 vec
![trait_def
.trait_ref
.to_predicate()],
1192 let scope
= &(generics
, &self_predicate
);
1194 // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
1195 let self_param_ty
= tcx
.mk_self_type();
1196 let superbounds1
= compute_bounds(&ccx
.icx(scope
),
1203 let superbounds1
= superbounds1
.predicates(tcx
, self_param_ty
);
1205 // Convert any explicit superbounds in the where clause,
1206 // e.g. `trait Foo where Self : Bar`:
1207 let superbounds2
= generics
.get_type_parameter_bounds(&ccx
.icx(scope
), item
.span
, item
.id
);
1209 // Combine the two lists to form the complete set of superbounds:
1210 let superbounds
= superbounds1
.into_iter().chain(superbounds2
).collect();
1211 let superpredicates
= ty
::GenericPredicates
{
1212 predicates
: VecPerParamSpace
::new(superbounds
, vec
![], vec
![])
1214 debug
!("superpredicates for trait {:?} = {:?}",
1215 tcx
.map
.local_def_id(item
.id
),
1218 tcx
.super_predicates
.borrow_mut().insert(trait_def_id
, superpredicates
.clone());
1223 let def_ids
: Vec
<_
> = superpredicates
.predicates
1225 .filter_map(|p
| p
.to_opt_poly_trait_ref())
1226 .map(|tr
| tr
.def_id())
1229 debug
!("ensure_super_predicates_step: def_ids={:?}", def_ids
);
1234 fn trait_def_of_item
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1236 -> &'tcx ty
::TraitDef
<'tcx
>
1238 let def_id
= ccx
.tcx
.map
.local_def_id(it
.id
);
1241 if let Some(def
) = tcx
.trait_defs
.borrow().get(&def_id
) {
1245 let (unsafety
, generics
, items
) = match it
.node
{
1246 hir
::ItemTrait(unsafety
, ref generics
, _
, ref items
) => (unsafety
, generics
, items
),
1247 _
=> span_bug
!(it
.span
, "trait_def_of_item invoked on non-trait"),
1250 let paren_sugar
= tcx
.has_attr(def_id
, "rustc_paren_sugar");
1251 if paren_sugar
&& !ccx
.tcx
.sess
.features
.borrow().unboxed_closures
{
1252 let mut err
= ccx
.tcx
.sess
.struct_span_err(
1254 "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
1255 which traits can use parenthetical notation");
1257 "add `#![feature(unboxed_closures)]` to \
1258 the crate attributes to use it");
1262 let substs
= ccx
.tcx
.mk_substs(mk_trait_substs(ccx
, generics
));
1264 let ty_generics
= ty_generics_for_trait(ccx
, it
.id
, substs
, generics
);
1266 let associated_type_names
: Vec
<_
> = items
.iter().filter_map(|trait_item
| {
1267 match trait_item
.node
{
1268 hir
::TypeTraitItem(..) => Some(trait_item
.name
),
1273 let trait_ref
= ty
::TraitRef
{
1278 let trait_def
= ty
::TraitDef
::new(unsafety
,
1282 associated_type_names
);
1284 return tcx
.intern_trait_def(trait_def
);
1286 fn mk_trait_substs
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1287 generics
: &hir
::Generics
)
1292 // Creates a no-op substitution for the trait's type parameters.
1297 .map(|(i
, def
)| ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
1300 name
: def
.lifetime
.name
1304 // Start with the generics in the type parameters...
1309 .map(|(i
, def
)| tcx
.mk_param(TypeSpace
,
1310 i
as u32, def
.name
))
1313 // ...and also create the `Self` parameter.
1314 let self_ty
= tcx
.mk_self_type();
1316 Substs
::new_trait(types
, regions
, self_ty
)
1320 fn trait_defines_associated_type_named(ccx
: &CrateCtxt
,
1321 trait_node_id
: ast
::NodeId
,
1322 assoc_name
: ast
::Name
)
1325 let item
= match ccx
.tcx
.map
.get(trait_node_id
) {
1326 hir_map
::NodeItem(item
) => item
,
1327 _
=> bug
!("trait_node_id {} is not an item", trait_node_id
)
1330 let trait_items
= match item
.node
{
1331 hir
::ItemTrait(_
, _
, _
, ref trait_items
) => trait_items
,
1332 _
=> bug
!("trait_node_id {} is not a trait", trait_node_id
)
1335 trait_items
.iter().any(|trait_item
| {
1336 match trait_item
.node
{
1337 hir
::TypeTraitItem(..) => trait_item
.name
== assoc_name
,
1343 fn convert_trait_predicates
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>, it
: &hir
::Item
) {
1345 let trait_def
= trait_def_of_item(ccx
, it
);
1347 let def_id
= ccx
.tcx
.map
.local_def_id(it
.id
);
1349 let (generics
, items
) = match it
.node
{
1350 hir
::ItemTrait(_
, ref generics
, _
, ref items
) => (generics
, items
),
1354 "trait_def_of_item invoked on {:?}",
1359 let super_predicates
= ccx
.tcx
.lookup_super_predicates(def_id
);
1361 // `ty_generic_predicates` below will consider the bounds on the type
1362 // parameters (including `Self`) and the explicit where-clauses,
1363 // but to get the full set of predicates on a trait we need to add
1364 // in the supertrait bounds and anything declared on the
1365 // associated types.
1366 let mut base_predicates
= super_predicates
;
1368 // Add in a predicate that `Self:Trait` (where `Trait` is the
1369 // current trait). This is needed for builtin bounds.
1370 let self_predicate
= trait_def
.trait_ref
.to_poly_trait_ref().to_predicate();
1371 base_predicates
.predicates
.push(SelfSpace
, self_predicate
);
1373 // add in the explicit where-clauses
1374 let mut trait_predicates
=
1375 ty_generic_predicates(ccx
, TypeSpace
, generics
, &base_predicates
);
1377 let assoc_predicates
= predicates_for_associated_types(ccx
,
1380 trait_def
.trait_ref
,
1382 trait_predicates
.predicates
.extend(TypeSpace
, assoc_predicates
.into_iter());
1384 let prev_predicates
= tcx
.predicates
.borrow_mut().insert(def_id
, trait_predicates
);
1385 assert
!(prev_predicates
.is_none());
1389 fn predicates_for_associated_types
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1390 ast_generics
: &hir
::Generics
,
1391 trait_predicates
: &ty
::GenericPredicates
<'tcx
>,
1392 self_trait_ref
: ty
::TraitRef
<'tcx
>,
1393 trait_items
: &[hir
::TraitItem
])
1394 -> Vec
<ty
::Predicate
<'tcx
>>
1396 trait_items
.iter().flat_map(|trait_item
| {
1397 let bounds
= match trait_item
.node
{
1398 hir
::TypeTraitItem(ref bounds
, _
) => bounds
,
1400 return vec
!().into_iter();
1404 let assoc_ty
= ccx
.tcx
.mk_projection(self_trait_ref
,
1407 let bounds
= compute_bounds(&ccx
.icx(&(ast_generics
, trait_predicates
)),
1410 SizedByDefault
::Yes
,
1414 bounds
.predicates(ccx
.tcx
, assoc_ty
).into_iter()
1419 fn type_scheme_of_def_id
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1421 -> ty
::TypeScheme
<'tcx
>
1423 if let Some(node_id
) = ccx
.tcx
.map
.as_local_node_id(def_id
) {
1424 match ccx
.tcx
.map
.find(node_id
) {
1425 Some(hir_map
::NodeItem(item
)) => {
1426 type_scheme_of_item(ccx
, &item
)
1428 Some(hir_map
::NodeForeignItem(foreign_item
)) => {
1429 let abi
= ccx
.tcx
.map
.get_foreign_abi(node_id
);
1430 type_scheme_of_foreign_item(ccx
, &foreign_item
, abi
)
1433 bug
!("unexpected sort of node in get_item_type_scheme(): {:?}",
1438 ccx
.tcx
.lookup_item_type(def_id
)
1442 fn type_scheme_of_item
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1444 -> ty
::TypeScheme
<'tcx
>
1446 let item_def_id
= ccx
.tcx
.map
.local_def_id(item
.id
);
1447 ccx
.tcx
.tcache
.memoize(item_def_id
, || {
1448 // NB. Since the `memoized` function enters a new task, and we
1449 // are giving this task access to the item `item`, we must
1451 assert
!(!ccx
.tcx
.map
.is_inlined_def_id(item_def_id
));
1452 ccx
.tcx
.dep_graph
.read(DepNode
::Hir(item_def_id
));
1453 compute_type_scheme_of_item(ccx
, item
)
1457 fn compute_type_scheme_of_item
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1459 -> ty
::TypeScheme
<'tcx
>
1463 hir
::ItemStatic(ref t
, _
, _
) | hir
::ItemConst(ref t
, _
) => {
1464 let ty
= ccx
.icx(&()).to_ty(&ExplicitRscope
, &t
);
1465 ty
::TypeScheme { ty: ty, generics: ty::Generics::empty() }
1467 hir
::ItemFn(ref decl
, unsafety
, _
, abi
, ref generics
, _
) => {
1468 let ty_generics
= ty_generics_for_fn(ccx
, generics
, &ty
::Generics
::empty());
1469 let tofd
= AstConv
::ty_of_bare_fn(&ccx
.icx(generics
), unsafety
, abi
, &decl
,
1470 Some(AnonTypeScope
::new(&ty_generics
)));
1471 let def_id
= ccx
.tcx
.map
.local_def_id(it
.id
);
1472 let substs
= mk_item_substs(tcx
, &ty_generics
);
1473 let ty
= tcx
.mk_fn_def(def_id
, substs
, tofd
);
1474 ty
::TypeScheme { ty: ty, generics: ty_generics }
1476 hir
::ItemTy(ref t
, ref generics
) => {
1477 let ty_generics
= ty_generics_for_type(ccx
, generics
);
1478 let ty
= ccx
.icx(generics
).to_ty(&ExplicitRscope
, &t
);
1479 ty
::TypeScheme { ty: ty, generics: ty_generics }
1481 hir
::ItemEnum(ref ei
, ref generics
) => {
1482 let def
= convert_enum_def(ccx
, it
, ei
);
1483 let ty_generics
= ty_generics_for_type(ccx
, generics
);
1484 let substs
= mk_item_substs(tcx
, &ty_generics
);
1485 let t
= tcx
.mk_enum(def
, substs
);
1486 ty
::TypeScheme { ty: t, generics: ty_generics }
1488 hir
::ItemStruct(ref si
, ref generics
) => {
1489 let def
= convert_struct_def(ccx
, it
, si
);
1490 let ty_generics
= ty_generics_for_type(ccx
, generics
);
1491 let substs
= mk_item_substs(tcx
, &ty_generics
);
1492 let t
= tcx
.mk_struct(def
, substs
);
1493 ty
::TypeScheme { ty: t, generics: ty_generics }
1495 hir
::ItemDefaultImpl(..) |
1496 hir
::ItemTrait(..) |
1499 hir
::ItemForeignMod(..) |
1500 hir
::ItemExternCrate(..) |
1501 hir
::ItemUse(..) => {
1504 "compute_type_scheme_of_item: unexpected item type: {:?}",
1510 fn convert_typed_item
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1512 -> (ty
::TypeScheme
<'tcx
>, ty
::GenericPredicates
<'tcx
>)
1516 let tag
= type_scheme_of_item(ccx
, it
);
1517 let scheme
= TypeScheme { generics: tag.generics, ty: tag.ty }
;
1518 let predicates
= match it
.node
{
1519 hir
::ItemStatic(..) | hir
::ItemConst(..) => {
1520 ty
::GenericPredicates
::empty()
1522 hir
::ItemFn(_
, _
, _
, _
, ref ast_generics
, _
) => {
1523 ty_generic_predicates_for_fn(ccx
, ast_generics
, &ty
::GenericPredicates
::empty())
1525 hir
::ItemTy(_
, ref generics
) => {
1526 ty_generic_predicates_for_type_or_impl(ccx
, generics
)
1528 hir
::ItemEnum(_
, ref generics
) => {
1529 ty_generic_predicates_for_type_or_impl(ccx
, generics
)
1531 hir
::ItemStruct(_
, ref generics
) => {
1532 ty_generic_predicates_for_type_or_impl(ccx
, generics
)
1534 hir
::ItemDefaultImpl(..) |
1535 hir
::ItemTrait(..) |
1536 hir
::ItemExternCrate(..) |
1540 hir
::ItemForeignMod(..) => {
1543 "compute_type_scheme_of_item: unexpected item type: {:?}",
1548 let prev_predicates
= tcx
.predicates
.borrow_mut().insert(ccx
.tcx
.map
.local_def_id(it
.id
),
1549 predicates
.clone());
1550 assert
!(prev_predicates
.is_none());
1553 if tcx
.has_attr(ccx
.tcx
.map
.local_def_id(it
.id
), "rustc_object_lifetime_default") {
1554 let object_lifetime_default_reprs
: String
=
1555 scheme
.generics
.types
.iter()
1556 .map(|t
| match t
.object_lifetime_default
{
1557 ty
::ObjectLifetimeDefault
::Specific(r
) => r
.to_string(),
1558 d
=> format
!("{:?}", d
),
1560 .collect
::<Vec
<String
>>()
1563 tcx
.sess
.span_err(it
.span
, &object_lifetime_default_reprs
);
1566 return (scheme
, predicates
);
1569 fn type_scheme_of_foreign_item
<'a
, 'tcx
>(
1570 ccx
: &CrateCtxt
<'a
, 'tcx
>,
1571 item
: &hir
::ForeignItem
,
1573 -> ty
::TypeScheme
<'tcx
>
1575 let item_def_id
= ccx
.tcx
.map
.local_def_id(item
.id
);
1576 ccx
.tcx
.tcache
.memoize(item_def_id
, || {
1577 // NB. Since the `memoized` function enters a new task, and we
1578 // are giving this task access to the item `item`, we must
1580 assert
!(!ccx
.tcx
.map
.is_inlined_def_id(item_def_id
));
1581 ccx
.tcx
.dep_graph
.read(DepNode
::Hir(item_def_id
));
1582 compute_type_scheme_of_foreign_item(ccx
, item
, abi
)
1586 fn compute_type_scheme_of_foreign_item
<'a
, 'tcx
>(
1587 ccx
: &CrateCtxt
<'a
, 'tcx
>,
1588 it
: &hir
::ForeignItem
,
1590 -> ty
::TypeScheme
<'tcx
>
1593 hir
::ForeignItemFn(ref fn_decl
, ref generics
) => {
1594 compute_type_scheme_of_foreign_fn_decl(
1595 ccx
, ccx
.tcx
.map
.local_def_id(it
.id
),
1596 fn_decl
, generics
, abi
)
1598 hir
::ForeignItemStatic(ref t
, _
) => {
1600 generics
: ty
::Generics
::empty(),
1601 ty
: AstConv
::ast_ty_to_ty(&ccx
.icx(&()), &ExplicitRscope
, t
)
1607 fn convert_foreign_item
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1608 it
: &hir
::ForeignItem
)
1610 // For reasons I cannot fully articulate, I do so hate the AST
1611 // map, and I regard each time that I use it as a personal and
1612 // moral failing, but at the moment it seems like the only
1613 // convenient way to extract the ABI. - ndm
1615 let abi
= tcx
.map
.get_foreign_abi(it
.id
);
1617 let scheme
= type_scheme_of_foreign_item(ccx
, it
, abi
);
1618 write_ty_to_tcx(ccx
, it
.id
, scheme
.ty
);
1620 let predicates
= match it
.node
{
1621 hir
::ForeignItemFn(_
, ref generics
) => {
1622 ty_generic_predicates_for_fn(ccx
, generics
, &ty
::GenericPredicates
::empty())
1624 hir
::ForeignItemStatic(..) => {
1625 ty
::GenericPredicates
::empty()
1629 let prev_predicates
= tcx
.predicates
.borrow_mut().insert(ccx
.tcx
.map
.local_def_id(it
.id
),
1631 assert
!(prev_predicates
.is_none());
1634 fn ty_generics_for_type
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>, generics
: &hir
::Generics
)
1635 -> ty
::Generics
<'tcx
> {
1636 ty_generics(ccx
, TypeSpace
, generics
, &ty
::Generics
::empty(), true)
1639 fn ty_generics_for_impl
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>, generics
: &hir
::Generics
)
1640 -> ty
::Generics
<'tcx
> {
1641 ty_generics(ccx
, TypeSpace
, generics
, &ty
::Generics
::empty(), false)
1644 fn ty_generic_predicates_for_type_or_impl
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1645 generics
: &hir
::Generics
)
1646 -> ty
::GenericPredicates
<'tcx
>
1648 ty_generic_predicates(ccx
, TypeSpace
, generics
, &ty
::GenericPredicates
::empty())
1651 fn ty_generics_for_trait
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1652 trait_id
: ast
::NodeId
,
1653 substs
: &'tcx Substs
<'tcx
>,
1654 ast_generics
: &hir
::Generics
)
1655 -> ty
::Generics
<'tcx
>
1657 debug
!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
1658 ccx
.tcx
.map
.local_def_id(trait_id
), substs
);
1660 let mut generics
= ty_generics_for_type(ccx
, ast_generics
);
1662 // Add in the self type parameter.
1664 // Something of a hack: use the node id for the trait, also as
1665 // the node id for the Self type parameter.
1666 let param_id
= trait_id
;
1668 let parent
= ccx
.tcx
.map
.get_parent(param_id
);
1670 let def
= ty
::TypeParameterDef
{
1673 name
: keywords
::SelfType
.name(),
1674 def_id
: ccx
.tcx
.map
.local_def_id(param_id
),
1675 default_def_id
: ccx
.tcx
.map
.local_def_id(parent
),
1677 object_lifetime_default
: ty
::ObjectLifetimeDefault
::BaseDefault
,
1680 ccx
.tcx
.ty_param_defs
.borrow_mut().insert(param_id
, def
.clone());
1682 generics
.types
.push(SelfSpace
, def
);
1687 fn ty_generics_for_fn
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1688 generics
: &hir
::Generics
,
1689 base_generics
: &ty
::Generics
<'tcx
>)
1690 -> ty
::Generics
<'tcx
>
1692 ty_generics(ccx
, FnSpace
, generics
, base_generics
, false)
1695 fn ty_generic_predicates_for_fn
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1696 generics
: &hir
::Generics
,
1697 base_predicates
: &ty
::GenericPredicates
<'tcx
>)
1698 -> ty
::GenericPredicates
<'tcx
>
1700 ty_generic_predicates(ccx
, FnSpace
, generics
, base_predicates
)
1703 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
1704 fn add_unsized_bound
<'gcx
: 'tcx
, 'tcx
>(astconv
: &AstConv
<'gcx
, 'tcx
>,
1705 bounds
: &mut ty
::BuiltinBounds
,
1706 ast_bounds
: &[hir
::TyParamBound
],
1709 let tcx
= astconv
.tcx();
1711 // Try to find an unbound in bounds.
1712 let mut unbound
= None
;
1713 for ab
in ast_bounds
{
1714 if let &hir
::TraitTyParamBound(ref ptr
, hir
::TraitBoundModifier
::Maybe
) = ab
{
1715 if unbound
.is_none() {
1716 assert
!(ptr
.bound_lifetimes
.is_empty());
1717 unbound
= Some(ptr
.trait_ref
.clone());
1719 span_err
!(tcx
.sess
, span
, E0203
,
1720 "type parameter has more than one relaxed default \
1721 bound, only one is supported");
1726 let kind_id
= tcx
.lang_items
.require(SizedTraitLangItem
);
1729 // FIXME(#8559) currently requires the unbound to be built-in.
1730 let trait_def_id
= tcx
.expect_def(tpb
.ref_id
).def_id();
1732 Ok(kind_id
) if trait_def_id
!= kind_id
=> {
1733 tcx
.sess
.span_warn(span
,
1734 "default bound relaxed for a type parameter, but \
1735 this does nothing because the given bound is not \
1736 a default. Only `?Sized` is supported");
1737 tcx
.try_add_builtin_trait(kind_id
, bounds
);
1742 _
if kind_id
.is_ok() => {
1743 tcx
.try_add_builtin_trait(kind_id
.unwrap(), bounds
);
1745 // No lang item for Sized, so we can't add it as a bound.
1750 /// Returns the early-bound lifetimes declared in this generics
1751 /// listing. For anything other than fns/methods, this is just all
1752 /// the lifetimes that are declared. For fns or methods, we have to
1753 /// screen out those that do not appear in any where-clauses etc using
1754 /// `resolve_lifetime::early_bound_lifetimes`.
1755 fn early_bound_lifetimes_from_generics
<'a
, 'tcx
, 'hir
>(
1756 ccx
: &CrateCtxt
<'a
, 'tcx
>,
1757 ast_generics
: &'hir hir
::Generics
)
1758 -> Vec
<&'hir hir
::LifetimeDef
>
1763 .filter(|l
| !ccx
.tcx
.named_region_map
.late_bound
.contains_key(&l
.lifetime
.id
))
1767 fn ty_generic_predicates
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1769 ast_generics
: &hir
::Generics
,
1770 base_predicates
: &ty
::GenericPredicates
<'tcx
>)
1771 -> ty
::GenericPredicates
<'tcx
>
1774 let mut result
= base_predicates
.clone();
1776 // Collect the predicates that were written inline by the user on each
1777 // type parameter (e.g., `<T:Foo>`).
1778 for (index
, param
) in ast_generics
.ty_params
.iter().enumerate() {
1779 let index
= index
as u32;
1780 let param_ty
= ty
::ParamTy
::new(space
, index
, param
.name
).to_ty(ccx
.tcx
);
1781 let bounds
= compute_bounds(&ccx
.icx(&(base_predicates
, ast_generics
)),
1784 SizedByDefault
::Yes
,
1787 let predicates
= bounds
.predicates(ccx
.tcx
, param_ty
);
1788 result
.predicates
.extend(space
, predicates
.into_iter());
1791 // Collect the region predicates that were declared inline as
1792 // well. In the case of parameters declared on a fn or method, we
1793 // have to be careful to only iterate over early-bound regions.
1794 let early_lifetimes
= early_bound_lifetimes_from_generics(ccx
, ast_generics
);
1795 for (index
, param
) in early_lifetimes
.iter().enumerate() {
1796 let index
= index
as u32;
1798 ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
1801 name
: param
.lifetime
.name
1803 for bound
in ¶m
.bounds
{
1804 let bound_region
= ast_region_to_region(ccx
.tcx
, bound
);
1805 let outlives
= ty
::Binder(ty
::OutlivesPredicate(region
, bound_region
));
1806 result
.predicates
.push(space
, outlives
.to_predicate());
1810 // Add in the bounds that appear in the where-clause
1811 let where_clause
= &ast_generics
.where_clause
;
1812 for predicate
in &where_clause
.predicates
{
1814 &hir
::WherePredicate
::BoundPredicate(ref bound_pred
) => {
1815 let ty
= AstConv
::ast_ty_to_ty(&ccx
.icx(&(base_predicates
, ast_generics
)),
1817 &bound_pred
.bounded_ty
);
1819 for bound
in bound_pred
.bounds
.iter() {
1821 &hir
::TyParamBound
::TraitTyParamBound(ref poly_trait_ref
, _
) => {
1822 let mut projections
= Vec
::new();
1825 conv_poly_trait_ref(&ccx
.icx(&(base_predicates
, ast_generics
)),
1830 result
.predicates
.push(space
, trait_ref
.to_predicate());
1832 for projection
in &projections
{
1833 result
.predicates
.push(space
, projection
.to_predicate());
1837 &hir
::TyParamBound
::RegionTyParamBound(ref lifetime
) => {
1838 let region
= ast_region_to_region(tcx
, lifetime
);
1839 let pred
= ty
::Binder(ty
::OutlivesPredicate(ty
, region
));
1840 result
.predicates
.push(space
, ty
::Predicate
::TypeOutlives(pred
))
1846 &hir
::WherePredicate
::RegionPredicate(ref region_pred
) => {
1847 let r1
= ast_region_to_region(tcx
, ®ion_pred
.lifetime
);
1848 for bound
in ®ion_pred
.bounds
{
1849 let r2
= ast_region_to_region(tcx
, bound
);
1850 let pred
= ty
::Binder(ty
::OutlivesPredicate(r1
, r2
));
1851 result
.predicates
.push(space
, ty
::Predicate
::RegionOutlives(pred
))
1855 &hir
::WherePredicate
::EqPredicate(ref eq_pred
) => {
1857 span_bug
!(eq_pred
.span
,
1858 "Equality constraints are not yet \
1859 implemented (#20041)")
1867 fn ty_generics
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1869 ast_generics
: &hir
::Generics
,
1870 base_generics
: &ty
::Generics
<'tcx
>,
1871 allow_defaults
: bool
)
1872 -> ty
::Generics
<'tcx
>
1875 let mut result
= base_generics
.clone();
1877 let early_lifetimes
= early_bound_lifetimes_from_generics(ccx
, ast_generics
);
1878 for (i
, l
) in early_lifetimes
.iter().enumerate() {
1879 let bounds
= l
.bounds
.iter()
1880 .map(|l
| ast_region_to_region(tcx
, l
))
1882 let def
= ty
::RegionParameterDef
{ name
: l
.lifetime
.name
,
1885 def_id
: ccx
.tcx
.map
.local_def_id(l
.lifetime
.id
),
1887 result
.regions
.push(space
, def
);
1890 assert
!(result
.types
.is_empty_in(space
));
1892 // Now create the real type parameters.
1893 for i
in 0..ast_generics
.ty_params
.len() {
1895 get_or_create_type_parameter_def(ccx
, ast_generics
, space
, i
as u32, allow_defaults
);
1896 debug
!("ty_generics: def for type param: {:?}, {:?}", def
, space
);
1897 result
.types
.push(space
, def
);
1903 fn convert_default_type_parameter
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
1909 let ty
= AstConv
::ast_ty_to_ty(&ccx
.icx(&()), &ExplicitRscope
, &path
);
1911 for leaf_ty
in ty
.walk() {
1912 if let ty
::TyParam(p
) = leaf_ty
.sty
{
1913 if p
.space
== space
&& p
.idx
>= index
{
1914 struct_span_err
!(ccx
.tcx
.sess
, path
.span
, E0128
,
1915 "type parameters with a default cannot use \
1916 forward declared identifiers")
1917 .span_label(path
.span
, &format
!("defaulted type parameters \
1918 cannot be forward declared"))
1921 return ccx
.tcx
.types
.err
1929 fn get_or_create_type_parameter_def
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1930 ast_generics
: &hir
::Generics
,
1933 allow_defaults
: bool
)
1934 -> ty
::TypeParameterDef
<'tcx
>
1936 let param
= &ast_generics
.ty_params
[index
as usize];
1939 match tcx
.ty_param_defs
.borrow().get(¶m
.id
) {
1940 Some(d
) => { return d.clone(); }
1944 let default = param
.default.as_ref().map(
1945 |def
| convert_default_type_parameter(ccx
, def
, space
, index
)
1948 let object_lifetime_default
=
1949 compute_object_lifetime_default(ccx
, param
.id
,
1950 ¶m
.bounds
, &ast_generics
.where_clause
);
1952 let parent
= tcx
.map
.get_parent(param
.id
);
1954 if !allow_defaults
&& default.is_some() {
1955 if !tcx
.sess
.features
.borrow().default_type_parameter_fallback
{
1957 lint
::builtin
::INVALID_TYPE_PARAM_DEFAULT
,
1960 format
!("defaults for type parameters are only allowed in `struct`, \
1961 `enum`, `type`, or `trait` definitions."));
1965 let def
= ty
::TypeParameterDef
{
1969 def_id
: ccx
.tcx
.map
.local_def_id(param
.id
),
1970 default_def_id
: ccx
.tcx
.map
.local_def_id(parent
),
1972 object_lifetime_default
: object_lifetime_default
,
1975 tcx
.ty_param_defs
.borrow_mut().insert(param
.id
, def
.clone());
1980 /// Scan the bounds and where-clauses on a parameter to extract bounds
1981 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`.
1982 /// This runs as part of computing the minimal type scheme, so we
1983 /// intentionally avoid just asking astconv to convert all the where
1984 /// clauses into a `ty::Predicate`. This is because that could induce
1985 /// artificial cycles.
1986 fn compute_object_lifetime_default
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
1987 param_id
: ast
::NodeId
,
1988 param_bounds
: &[hir
::TyParamBound
],
1989 where_clause
: &hir
::WhereClause
)
1990 -> ty
::ObjectLifetimeDefault
1992 let inline_bounds
= from_bounds(ccx
, param_bounds
);
1993 let where_bounds
= from_predicates(ccx
, param_id
, &where_clause
.predicates
);
1994 let all_bounds
: HashSet
<_
> = inline_bounds
.into_iter()
1995 .chain(where_bounds
)
1997 return if all_bounds
.len() > 1 {
1998 ty
::ObjectLifetimeDefault
::Ambiguous
1999 } else if all_bounds
.len() == 0 {
2000 ty
::ObjectLifetimeDefault
::BaseDefault
2002 ty
::ObjectLifetimeDefault
::Specific(
2003 all_bounds
.into_iter().next().unwrap())
2006 fn from_bounds
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
2007 bounds
: &[hir
::TyParamBound
])
2011 .filter_map(|bound
| {
2013 hir
::TraitTyParamBound(..) =>
2015 hir
::RegionTyParamBound(ref lifetime
) =>
2016 Some(ast_region_to_region(ccx
.tcx
, lifetime
)),
2022 fn from_predicates
<'a
,'tcx
>(ccx
: &CrateCtxt
<'a
,'tcx
>,
2023 param_id
: ast
::NodeId
,
2024 predicates
: &[hir
::WherePredicate
])
2028 .flat_map(|predicate
| {
2030 hir
::WherePredicate
::BoundPredicate(ref data
) => {
2031 if data
.bound_lifetimes
.is_empty() &&
2032 is_param(ccx
.tcx
, &data
.bounded_ty
, param_id
)
2034 from_bounds(ccx
, &data
.bounds
).into_iter()
2036 Vec
::new().into_iter()
2039 hir
::WherePredicate
::RegionPredicate(..) |
2040 hir
::WherePredicate
::EqPredicate(..) => {
2041 Vec
::new().into_iter()
2049 pub enum SizedByDefault { Yes, No, }
2051 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
2052 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
2053 /// built-in trait (formerly known as kind): Send.
2054 pub fn compute_bounds
<'gcx
: 'tcx
, 'tcx
>(astconv
: &AstConv
<'gcx
, 'tcx
>,
2055 param_ty
: ty
::Ty
<'tcx
>,
2056 ast_bounds
: &[hir
::TyParamBound
],
2057 sized_by_default
: SizedByDefault
,
2058 anon_scope
: Option
<AnonTypeScope
>,
2062 let tcx
= astconv
.tcx();
2063 let PartitionedBounds
{
2067 } = partition_bounds(tcx
, span
, &ast_bounds
);
2069 if let SizedByDefault
::Yes
= sized_by_default
{
2070 add_unsized_bound(astconv
, &mut builtin_bounds
, ast_bounds
, span
);
2073 let mut projection_bounds
= vec
![];
2075 let rscope
= MaybeWithAnonTypes
::new(ExplicitRscope
, anon_scope
);
2076 let mut trait_bounds
: Vec
<_
> = trait_bounds
.iter().map(|&bound
| {
2077 astconv
.instantiate_poly_trait_ref(&rscope
,
2080 &mut projection_bounds
)
2083 let region_bounds
= region_bounds
.into_iter().map(|r
| {
2084 ast_region_to_region(tcx
, r
)
2087 trait_bounds
.sort_by(|a
,b
| a
.def_id().cmp(&b
.def_id()));
2090 region_bounds
: region_bounds
,
2091 builtin_bounds
: builtin_bounds
,
2092 trait_bounds
: trait_bounds
,
2093 projection_bounds
: projection_bounds
,
2097 /// Converts a specific TyParamBound from the AST into a set of
2098 /// predicates that apply to the self-type. A vector is returned
2099 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2100 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2101 /// and `<T as Bar>::X == i32`).
2102 fn predicates_from_bound
<'tcx
>(astconv
: &AstConv
<'tcx
, 'tcx
>,
2104 bound
: &hir
::TyParamBound
)
2105 -> Vec
<ty
::Predicate
<'tcx
>>
2108 hir
::TraitTyParamBound(ref tr
, hir
::TraitBoundModifier
::None
) => {
2109 let mut projections
= Vec
::new();
2110 let pred
= conv_poly_trait_ref(astconv
, param_ty
, tr
, &mut projections
);
2111 projections
.into_iter()
2112 .map(|p
| p
.to_predicate())
2113 .chain(Some(pred
.to_predicate()))
2116 hir
::RegionTyParamBound(ref lifetime
) => {
2117 let region
= ast_region_to_region(astconv
.tcx(), lifetime
);
2118 let pred
= ty
::Binder(ty
::OutlivesPredicate(param_ty
, region
));
2119 vec
![ty
::Predicate
::TypeOutlives(pred
)]
2121 hir
::TraitTyParamBound(_
, hir
::TraitBoundModifier
::Maybe
) => {
2127 fn conv_poly_trait_ref
<'gcx
: 'tcx
, 'tcx
>(astconv
: &AstConv
<'gcx
, 'tcx
>,
2129 trait_ref
: &hir
::PolyTraitRef
,
2130 projections
: &mut Vec
<ty
::PolyProjectionPredicate
<'tcx
>>)
2131 -> ty
::PolyTraitRef
<'tcx
>
2133 AstConv
::instantiate_poly_trait_ref(astconv
,
2140 fn compute_type_scheme_of_foreign_fn_decl
<'a
, 'tcx
>(
2141 ccx
: &CrateCtxt
<'a
, 'tcx
>,
2144 ast_generics
: &hir
::Generics
,
2146 -> ty
::TypeScheme
<'tcx
>
2148 let ty_generics
= ty_generics_for_fn(ccx
, ast_generics
, &ty
::Generics
::empty());
2150 let rb
= BindingRscope
::new();
2151 let input_tys
= decl
.inputs
2153 .map(|a
| AstConv
::ty_of_arg(&ccx
.icx(ast_generics
), &rb
, a
, None
))
2154 .collect
::<Vec
<_
>>();
2156 let output
= match decl
.output
{
2157 hir
::Return(ref ty
) =>
2158 AstConv
::ast_ty_to_ty(&ccx
.icx(ast_generics
), &rb
, &ty
),
2159 hir
::DefaultReturn(..) =>
2163 // feature gate SIMD types in FFI, since I (huonw) am not sure the
2164 // ABIs are handled at all correctly.
2165 if abi
!= abi
::Abi
::RustIntrinsic
&& abi
!= abi
::Abi
::PlatformIntrinsic
2166 && !ccx
.tcx
.sess
.features
.borrow().simd_ffi
{
2167 let check
= |ast_ty
: &hir
::Ty
, ty
: ty
::Ty
| {
2169 ccx
.tcx
.sess
.struct_span_err(ast_ty
.span
,
2170 &format
!("use of SIMD type `{}` in FFI is highly experimental and \
2171 may result in invalid code",
2172 pprust
::ty_to_string(ast_ty
)))
2173 .help("add #![feature(simd_ffi)] to the crate attributes to enable")
2177 for (input
, ty
) in decl
.inputs
.iter().zip(&input_tys
) {
2178 check(&input
.ty
, ty
)
2180 if let hir
::Return(ref ty
) = decl
.output
{
2185 let substs
= mk_item_substs(ccx
.tcx
, &ty_generics
);
2186 let t_fn
= ccx
.tcx
.mk_fn_def(id
, substs
, ccx
.tcx
.mk_bare_fn(ty
::BareFnTy
{
2188 unsafety
: hir
::Unsafety
::Unsafe
,
2189 sig
: ty
::Binder(ty
::FnSig
{inputs
: input_tys
,
2191 variadic
: decl
.variadic
}),
2195 generics
: ty_generics
,
2200 pub fn mk_item_substs
<'a
, 'gcx
, 'tcx
>(tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
2201 ty_generics
: &ty
::Generics
)
2202 -> &'tcx Substs
<'tcx
>
2205 ty_generics
.types
.map(
2206 |def
| tcx
.mk_param_from_def(def
));
2209 ty_generics
.regions
.map(
2210 |def
| def
.to_early_bound_region());
2212 tcx
.mk_substs(Substs
::new(types
, regions
))
2215 /// Checks that all the type parameters on an impl
2216 fn enforce_impl_params_are_constrained
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
2217 ast_generics
: &hir
::Generics
,
2218 impl_predicates
: &mut ty
::GenericPredicates
<'tcx
>,
2221 let impl_scheme
= ccx
.tcx
.lookup_item_type(impl_def_id
);
2222 let impl_trait_ref
= ccx
.tcx
.impl_trait_ref(impl_def_id
);
2224 assert
!(impl_predicates
.predicates
.is_empty_in(FnSpace
));
2225 assert
!(impl_predicates
.predicates
.is_empty_in(SelfSpace
));
2227 // The trait reference is an input, so find all type parameters
2228 // reachable from there, to start (if this is an inherent impl,
2229 // then just examine the self type).
2230 let mut input_parameters
: HashSet
<_
> =
2231 ctp
::parameters_for(&impl_scheme
.ty
, false).into_iter().collect();
2232 if let Some(ref trait_ref
) = impl_trait_ref
{
2233 input_parameters
.extend(ctp
::parameters_for(trait_ref
, false));
2236 ctp
::setup_constraining_predicates(impl_predicates
.predicates
.get_mut_slice(TypeSpace
),
2238 &mut input_parameters
);
2240 for (index
, ty_param
) in ast_generics
.ty_params
.iter().enumerate() {
2241 let param_ty
= ty
::ParamTy
{ space
: TypeSpace
,
2243 name
: ty_param
.name
};
2244 if !input_parameters
.contains(&ctp
::Parameter
::Type(param_ty
)) {
2245 report_unused_parameter(ccx
, ty_param
.span
, "type", ¶m_ty
.to_string());
2250 fn enforce_impl_lifetimes_are_constrained
<'a
, 'tcx
>(ccx
: &CrateCtxt
<'a
, 'tcx
>,
2251 ast_generics
: &hir
::Generics
,
2253 impl_items
: &[hir
::ImplItem
])
2255 // Every lifetime used in an associated type must be constrained.
2256 let impl_scheme
= ccx
.tcx
.lookup_item_type(impl_def_id
);
2257 let impl_predicates
= ccx
.tcx
.lookup_predicates(impl_def_id
);
2258 let impl_trait_ref
= ccx
.tcx
.impl_trait_ref(impl_def_id
);
2260 let mut input_parameters
: HashSet
<_
> =
2261 ctp
::parameters_for(&impl_scheme
.ty
, false).into_iter().collect();
2262 if let Some(ref trait_ref
) = impl_trait_ref
{
2263 input_parameters
.extend(ctp
::parameters_for(trait_ref
, false));
2265 ctp
::identify_constrained_type_params(
2266 &impl_predicates
.predicates
.as_slice(), impl_trait_ref
, &mut input_parameters
);
2268 let lifetimes_in_associated_types
: HashSet
<_
> = impl_items
.iter()
2269 .map(|item
| ccx
.tcx
.impl_or_trait_item(ccx
.tcx
.map
.local_def_id(item
.id
)))
2270 .filter_map(|item
| match item
{
2271 ty
::TypeTraitItem(ref assoc_ty
) => assoc_ty
.ty
,
2272 ty
::ConstTraitItem(..) | ty
::MethodTraitItem(..) => None
2274 .flat_map(|ty
| ctp
::parameters_for(&ty
, true))
2275 .filter_map(|p
| match p
{
2276 ctp
::Parameter
::Type(_
) => None
,
2277 ctp
::Parameter
::Region(r
) => Some(r
),
2281 for (index
, lifetime_def
) in ast_generics
.lifetimes
.iter().enumerate() {
2282 let region
= ty
::EarlyBoundRegion
{ space
: TypeSpace
,
2283 index
: index
as u32,
2284 name
: lifetime_def
.lifetime
.name
};
2286 lifetimes_in_associated_types
.contains(®ion
) && // (*)
2287 !input_parameters
.contains(&ctp
::Parameter
::Region(region
))
2289 report_unused_parameter(ccx
, lifetime_def
.lifetime
.span
,
2290 "lifetime", ®ion
.name
.to_string());
2294 // (*) This is a horrible concession to reality. I think it'd be
2295 // better to just ban unconstrianed lifetimes outright, but in
2296 // practice people do non-hygenic macros like:
2299 // macro_rules! __impl_slice_eq1 {
2300 // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
2301 // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
2308 // In a concession to backwards compatbility, we continue to
2309 // permit those, so long as the lifetimes aren't used in
2310 // associated types. I believe this is sound, because lifetimes
2311 // used elsewhere are not projected back out.
2314 fn report_unused_parameter(ccx
: &CrateCtxt
,
2320 ccx
.tcx
.sess
, span
, E0207
,
2321 "the {} parameter `{}` is not constrained by the \
2322 impl trait, self type, or predicates",
2324 .span_label(span
, &format
!("unconstrained lifetime parameter"))