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.
11 //! Conversion from AST representation of types to the ty.rs
12 //! representation. The main routine here is `ast_ty_to_ty()`: each use
13 //! is parameterized by an instance of `AstConv`.
15 use rustc_const_eval
::eval_length
;
16 use rustc_data_structures
::accumulate_vec
::AccumulateVec
;
19 use hir
::def_id
::DefId
;
20 use middle
::resolve_lifetime
as rl
;
21 use rustc
::ty
::subst
::{Kind, Subst, Substs}
;
23 use rustc
::ty
::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}
;
24 use rustc
::ty
::wf
::object_region_bounds
;
25 use rustc_back
::slice
;
26 use require_c_abi_if_variadic
;
27 use util
::common
::{ErrorReported, FN_OUTPUT_NAME}
;
28 use util
::nodemap
::{NodeMap, FxHashSet}
;
30 use std
::cell
::RefCell
;
32 use syntax
::{abi, ast}
;
33 use syntax
::feature_gate
::{GateIssue, emit_feature_err}
;
34 use syntax
::symbol
::Symbol
;
37 pub trait AstConv
<'gcx
, 'tcx
> {
38 fn tcx
<'a
>(&'a
self) -> TyCtxt
<'a
, 'gcx
, 'tcx
>;
40 /// A cache used for the result of `ast_ty_to_ty_cache`
41 fn ast_ty_to_ty_cache(&self) -> &RefCell
<NodeMap
<Ty
<'tcx
>>>;
43 /// Returns the set of bounds in scope for the type parameter with
45 fn get_type_parameter_bounds(&self, span
: Span
, def_id
: DefId
)
46 -> ty
::GenericPredicates
<'tcx
>;
48 /// Return an (optional) substitution to convert bound type parameters that
49 /// are in scope into free ones. This function should only return Some
51 /// See ParameterEnvironment::free_substs for more information.
52 fn get_free_substs(&self) -> Option
<&Substs
<'tcx
>>;
54 /// What lifetime should we use when a lifetime is omitted (and not elided)?
55 fn re_infer(&self, span
: Span
, _def
: Option
<&ty
::RegionParameterDef
>)
56 -> Option
<&'tcx ty
::Region
>;
58 /// What type should we use when a type is omitted?
59 fn ty_infer(&self, span
: Span
) -> Ty
<'tcx
>;
61 /// Same as ty_infer, but with a known type parameter definition.
62 fn ty_infer_for_def(&self,
63 _def
: &ty
::TypeParameterDef
,
64 _substs
: &[Kind
<'tcx
>],
65 span
: Span
) -> Ty
<'tcx
> {
69 /// Projecting an associated type from a (potentially)
70 /// higher-ranked trait reference is more complicated, because of
71 /// the possibility of late-bound regions appearing in the
72 /// associated type binding. This is not legal in function
73 /// signatures for that reason. In a function body, we can always
74 /// handle it because we can use inference variables to remove the
75 /// late-bound regions.
76 fn projected_ty_from_poly_trait_ref(&self,
78 poly_trait_ref
: ty
::PolyTraitRef
<'tcx
>,
82 /// Normalize an associated type coming from the user.
83 fn normalize_ty(&self, span
: Span
, ty
: Ty
<'tcx
>) -> Ty
<'tcx
>;
85 /// Invoked when we encounter an error from some prior pass
86 /// (e.g. resolve) that is translated into a ty-error. This is
87 /// used to help suppress derived errors typeck might otherwise
89 fn set_tainted_by_errors(&self);
92 struct ConvertedBinding
<'tcx
> {
98 /// Dummy type used for the `Self` of a `TraitRef` created for converting
99 /// a trait object, and which gets removed in `ExistentialTraitRef`.
100 /// This type must not appear anywhere in other converted types.
101 const TRAIT_OBJECT_DUMMY_SELF
: ty
::TypeVariants
<'
static> = ty
::TyInfer(ty
::FreshTy(0));
103 impl<'o
, 'gcx
: 'tcx
, 'tcx
> AstConv
<'gcx
, 'tcx
>+'o
{
104 pub fn ast_region_to_region(&self,
105 lifetime
: &hir
::Lifetime
,
106 def
: Option
<&ty
::RegionParameterDef
>)
109 let tcx
= self.tcx();
110 let r
= match tcx
.named_region_map
.defs
.get(&lifetime
.id
) {
111 Some(&rl
::Region
::Static
) => {
112 tcx
.mk_region(ty
::ReStatic
)
115 Some(&rl
::Region
::LateBound(debruijn
, id
)) => {
116 let name
= tcx
.hir
.name(id
);
117 tcx
.mk_region(ty
::ReLateBound(debruijn
,
118 ty
::BrNamed(tcx
.hir
.local_def_id(id
), name
)))
121 Some(&rl
::Region
::LateBoundAnon(debruijn
, index
)) => {
122 tcx
.mk_region(ty
::ReLateBound(debruijn
, ty
::BrAnon(index
)))
125 Some(&rl
::Region
::EarlyBound(index
, id
)) => {
126 let name
= tcx
.hir
.name(id
);
127 tcx
.mk_region(ty
::ReEarlyBound(ty
::EarlyBoundRegion
{
133 Some(&rl
::Region
::Free(scope
, id
)) => {
134 let name
= tcx
.hir
.name(id
);
135 tcx
.mk_region(ty
::ReFree(ty
::FreeRegion
{
136 scope
: scope
.to_code_extent(&tcx
.region_maps
),
137 bound_region
: ty
::BrNamed(tcx
.hir
.local_def_id(id
), name
)
140 // (*) -- not late-bound, won't change
144 self.re_infer(lifetime
.span
, def
).expect("unelided lifetime in signature")
148 debug
!("ast_region_to_region(lifetime={:?}) yields {:?}",
155 /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
156 /// returns an appropriate set of substitutions for this particular reference to `I`.
157 pub fn ast_path_substs_for_ty(&self,
160 item_segment
: &hir
::PathSegment
)
161 -> &'tcx Substs
<'tcx
>
163 let tcx
= self.tcx();
165 match item_segment
.parameters
{
166 hir
::AngleBracketedParameters(_
) => {}
167 hir
::ParenthesizedParameters(..) => {
168 struct_span_err
!(tcx
.sess
, span
, E0214
,
169 "parenthesized parameters may only be used with a trait")
170 .span_label(span
, &format
!("only traits may use parentheses"))
173 return Substs
::for_item(tcx
, def_id
, |_
, _
| {
174 tcx
.mk_region(ty
::ReStatic
)
181 let (substs
, assoc_bindings
) =
182 self.create_substs_for_ast_path(span
,
184 &item_segment
.parameters
,
187 assoc_bindings
.first().map(|b
| self.prohibit_projection(b
.span
));
192 /// Given the type/region arguments provided to some path (along with
193 /// an implicit Self, if this is a trait reference) returns the complete
194 /// set of substitutions. This may involve applying defaulted type parameters.
196 /// Note that the type listing given here is *exactly* what the user provided.
197 fn create_substs_for_ast_path(&self,
200 parameters
: &hir
::PathParameters
,
201 self_ty
: Option
<Ty
<'tcx
>>)
202 -> (&'tcx Substs
<'tcx
>, Vec
<ConvertedBinding
<'tcx
>>)
204 let tcx
= self.tcx();
206 debug
!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
208 def_id
, self_ty
, parameters
);
210 let (lifetimes
, num_types_provided
, infer_types
) = match *parameters
{
211 hir
::AngleBracketedParameters(ref data
) => {
212 (&data
.lifetimes
[..], data
.types
.len(), data
.infer_types
)
214 hir
::ParenthesizedParameters(_
) => (&[][..], 1, false)
217 // If the type is parameterized by this region, then replace this
218 // region with the current anon region binding (in other words,
219 // whatever & would get replaced with).
220 let decl_generics
= tcx
.item_generics(def_id
);
221 let expected_num_region_params
= decl_generics
.regions
.len();
222 let supplied_num_region_params
= lifetimes
.len();
223 if expected_num_region_params
!= supplied_num_region_params
{
224 report_lifetime_number_error(tcx
, span
,
225 supplied_num_region_params
,
226 expected_num_region_params
);
229 // If a self-type was declared, one should be provided.
230 assert_eq
!(decl_generics
.has_self
, self_ty
.is_some());
232 // Check the number of type parameters supplied by the user.
233 let ty_param_defs
= &decl_generics
.types
[self_ty
.is_some() as usize..];
234 if !infer_types
|| num_types_provided
> ty_param_defs
.len() {
235 check_type_argument_count(tcx
, span
, num_types_provided
, ty_param_defs
);
238 let is_object
= self_ty
.map_or(false, |ty
| ty
.sty
== TRAIT_OBJECT_DUMMY_SELF
);
239 let default_needs_object_self
= |p
: &ty
::TypeParameterDef
| {
240 if is_object
&& p
.has_default
{
241 if ty
::queries
::ty
::get(tcx
, span
, p
.def_id
).has_self_ty() {
242 // There is no suitable inference default for a type parameter
243 // that references self, in an object type.
251 let mut output_assoc_binding
= None
;
252 let substs
= Substs
::for_item(tcx
, def_id
, |def
, _
| {
253 let i
= def
.index
as usize - self_ty
.is_some() as usize;
254 if let Some(lifetime
) = lifetimes
.get(i
) {
255 self.ast_region_to_region(lifetime
, Some(def
))
257 tcx
.mk_region(ty
::ReStatic
)
260 let i
= def
.index
as usize;
262 // Handle Self first, so we can adjust the index to match the AST.
263 if let (0, Some(ty
)) = (i
, self_ty
) {
267 let i
= i
- self_ty
.is_some() as usize - decl_generics
.regions
.len();
268 if i
< num_types_provided
{
269 // A provided type parameter.
271 hir
::AngleBracketedParameters(ref data
) => {
272 self.ast_ty_to_ty(&data
.types
[i
])
274 hir
::ParenthesizedParameters(ref data
) => {
276 let (ty
, assoc
) = self.convert_parenthesized_parameters(data
);
277 output_assoc_binding
= Some(assoc
);
281 } else if infer_types
{
282 // No type parameters were provided, we can infer all.
283 let ty_var
= if !default_needs_object_self(def
) {
284 self.ty_infer_for_def(def
, substs
, span
)
289 } else if def
.has_default
{
290 // No type parameter provided, but a default exists.
292 // If we are converting an object type, then the
293 // `Self` parameter is unknown. However, some of the
294 // other type parameters may reference `Self` in their
295 // defaults. This will lead to an ICE if we are not
297 if default_needs_object_self(def
) {
298 struct_span_err
!(tcx
.sess
, span
, E0393
,
299 "the type parameter `{}` must be explicitly specified",
301 .span_label(span
, &format
!("missing reference to `{}`", def
.name
))
302 .note(&format
!("because of the default `Self` reference, \
303 type parameters must be specified on object types"))
307 // This is a default type parameter.
310 ty
::queries
::ty
::get(tcx
, span
, def
.def_id
)
311 .subst_spanned(tcx
, substs
, Some(span
))
315 // We've already errored above about the mismatch.
320 let assoc_bindings
= match *parameters
{
321 hir
::AngleBracketedParameters(ref data
) => {
322 data
.bindings
.iter().map(|b
| {
325 ty
: self.ast_ty_to_ty(&b
.ty
),
330 hir
::ParenthesizedParameters(ref data
) => {
331 vec
![output_assoc_binding
.unwrap_or_else(|| {
332 // This is an error condition, but we should
333 // get the associated type binding anyway.
334 self.convert_parenthesized_parameters(data
).1
339 debug
!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
340 decl_generics
, self_ty
, substs
);
342 (substs
, assoc_bindings
)
345 fn convert_parenthesized_parameters(&self,
346 data
: &hir
::ParenthesizedParameterData
)
347 -> (Ty
<'tcx
>, ConvertedBinding
<'tcx
>)
349 let inputs
= self.tcx().mk_type_list(data
.inputs
.iter().map(|a_t
| {
350 self.ast_ty_to_ty(a_t
)
353 let (output
, output_span
) = match data
.output
{
354 Some(ref output_ty
) => {
355 (self.ast_ty_to_ty(output_ty
), output_ty
.span
)
358 (self.tcx().mk_nil(), data
.span
)
362 let output_binding
= ConvertedBinding
{
363 item_name
: Symbol
::intern(FN_OUTPUT_NAME
),
368 (self.tcx().mk_ty(ty
::TyTuple(inputs
, false)), output_binding
)
371 /// Instantiates the path for the given trait reference, assuming that it's
372 /// bound to a valid trait type. Returns the def_id for the defining trait.
373 /// Fails if the type is a type other than a trait type.
375 /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
376 /// are disallowed. Otherwise, they are pushed onto the vector given.
377 pub fn instantiate_mono_trait_ref(&self,
378 trait_ref
: &hir
::TraitRef
,
380 -> ty
::TraitRef
<'tcx
>
382 let trait_def_id
= self.trait_def_id(trait_ref
);
383 self.ast_path_to_mono_trait_ref(trait_ref
.path
.span
,
386 trait_ref
.path
.segments
.last().unwrap())
389 fn trait_def_id(&self, trait_ref
: &hir
::TraitRef
) -> DefId
{
390 let path
= &trait_ref
.path
;
392 Def
::Trait(trait_def_id
) => trait_def_id
,
394 self.tcx().sess
.fatal("cannot continue compilation due to previous error");
397 span_fatal
!(self.tcx().sess
, path
.span
, E0245
, "`{}` is not a trait",
398 self.tcx().hir
.node_to_pretty_string(trait_ref
.ref_id
));
403 pub fn instantiate_poly_trait_ref(&self,
404 ast_trait_ref
: &hir
::PolyTraitRef
,
406 poly_projections
: &mut Vec
<ty
::PolyProjectionPredicate
<'tcx
>>)
407 -> ty
::PolyTraitRef
<'tcx
>
409 let trait_ref
= &ast_trait_ref
.trait_ref
;
410 let trait_def_id
= self.trait_def_id(trait_ref
);
412 debug
!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref
, trait_def_id
);
414 let (substs
, assoc_bindings
) =
415 self.create_substs_for_ast_trait_ref(trait_ref
.path
.span
,
418 trait_ref
.path
.segments
.last().unwrap());
419 let poly_trait_ref
= ty
::Binder(ty
::TraitRef
::new(trait_def_id
, substs
));
421 poly_projections
.extend(assoc_bindings
.iter().filter_map(|binding
| {
422 // specify type to assert that error was already reported in Err case:
423 let predicate
: Result
<_
, ErrorReported
> =
424 self.ast_type_binding_to_poly_projection_predicate(trait_ref
.ref_id
,
427 predicate
.ok() // ok to ignore Err() because ErrorReported (see above)
430 debug
!("ast_path_to_poly_trait_ref({:?}, projections={:?}) -> {:?}",
431 trait_ref
, poly_projections
, poly_trait_ref
);
435 fn ast_path_to_mono_trait_ref(&self,
439 trait_segment
: &hir
::PathSegment
)
440 -> ty
::TraitRef
<'tcx
>
442 let (substs
, assoc_bindings
) =
443 self.create_substs_for_ast_trait_ref(span
,
447 assoc_bindings
.first().map(|b
| self.prohibit_projection(b
.span
));
448 ty
::TraitRef
::new(trait_def_id
, substs
)
451 fn create_substs_for_ast_trait_ref(&self,
455 trait_segment
: &hir
::PathSegment
)
456 -> (&'tcx Substs
<'tcx
>, Vec
<ConvertedBinding
<'tcx
>>)
458 debug
!("create_substs_for_ast_trait_ref(trait_segment={:?})",
461 let trait_def
= self.tcx().lookup_trait_def(trait_def_id
);
463 match trait_segment
.parameters
{
464 hir
::AngleBracketedParameters(_
) => {
465 // For now, require that parenthetical notation be used
466 // only with `Fn()` etc.
467 if !self.tcx().sess
.features
.borrow().unboxed_closures
&& trait_def
.paren_sugar
{
468 emit_feature_err(&self.tcx().sess
.parse_sess
,
469 "unboxed_closures", span
, GateIssue
::Language
,
471 the precise format of `Fn`-family traits' \
472 type parameters is subject to change. \
473 Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
476 hir
::ParenthesizedParameters(_
) => {
477 // For now, require that parenthetical notation be used
478 // only with `Fn()` etc.
479 if !self.tcx().sess
.features
.borrow().unboxed_closures
&& !trait_def
.paren_sugar
{
480 emit_feature_err(&self.tcx().sess
.parse_sess
,
481 "unboxed_closures", span
, GateIssue
::Language
,
483 parenthetical notation is only stable when used with `Fn`-family traits");
488 self.create_substs_for_ast_path(span
,
490 &trait_segment
.parameters
,
494 fn trait_defines_associated_type_named(&self,
496 assoc_name
: ast
::Name
)
499 self.tcx().associated_items(trait_def_id
).any(|item
| {
500 item
.kind
== ty
::AssociatedKind
::Type
&& item
.name
== assoc_name
504 fn ast_type_binding_to_poly_projection_predicate(
506 _path_id
: ast
::NodeId
,
507 trait_ref
: ty
::PolyTraitRef
<'tcx
>,
508 binding
: &ConvertedBinding
<'tcx
>)
509 -> Result
<ty
::PolyProjectionPredicate
<'tcx
>, ErrorReported
>
511 let tcx
= self.tcx();
513 // Given something like `U : SomeTrait<T=X>`, we want to produce a
514 // predicate like `<U as SomeTrait>::T = X`. This is somewhat
515 // subtle in the event that `T` is defined in a supertrait of
516 // `SomeTrait`, because in that case we need to upcast.
518 // That is, consider this case:
521 // trait SubTrait : SuperTrait<int> { }
522 // trait SuperTrait<A> { type T; }
524 // ... B : SubTrait<T=foo> ...
527 // We want to produce `<B as SuperTrait<int>>::T == foo`.
529 // Find any late-bound regions declared in `ty` that are not
530 // declared in the trait-ref. These are not wellformed.
534 // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
535 // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
536 let late_bound_in_trait_ref
= tcx
.collect_constrained_late_bound_regions(&trait_ref
);
537 let late_bound_in_ty
= tcx
.collect_referenced_late_bound_regions(&ty
::Binder(binding
.ty
));
538 debug
!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref
);
539 debug
!("late_bound_in_ty = {:?}", late_bound_in_ty
);
540 for br
in late_bound_in_ty
.difference(&late_bound_in_trait_ref
) {
541 let br_name
= match *br
{
542 ty
::BrNamed(_
, name
) => name
,
546 "anonymous bound region {:?} in binding but not trait ref",
550 struct_span_err
!(tcx
.sess
,
553 "binding for associated type `{}` references lifetime `{}`, \
554 which does not appear in the trait input types",
555 binding
.item_name
, br_name
)
559 // Simple case: X is defined in the current trait.
560 if self.trait_defines_associated_type_named(trait_ref
.def_id(), binding
.item_name
) {
561 return Ok(trait_ref
.map_bound(|trait_ref
| {
562 ty
::ProjectionPredicate
{
563 projection_ty
: ty
::ProjectionTy
{
564 trait_ref
: trait_ref
,
565 item_name
: binding
.item_name
,
572 // Otherwise, we have to walk through the supertraits to find
575 traits
::supertraits(tcx
, trait_ref
.clone())
576 .filter(|r
| self.trait_defines_associated_type_named(r
.def_id(), binding
.item_name
));
578 let candidate
= self.one_bound_for_assoc_type(candidates
,
579 &trait_ref
.to_string(),
580 &binding
.item_name
.as_str(),
583 Ok(candidate
.map_bound(|trait_ref
| {
584 ty
::ProjectionPredicate
{
585 projection_ty
: ty
::ProjectionTy
{
586 trait_ref
: trait_ref
,
587 item_name
: binding
.item_name
,
594 fn ast_path_to_ty(&self,
597 item_segment
: &hir
::PathSegment
)
600 let substs
= self.ast_path_substs_for_ty(span
, did
, item_segment
);
603 ty
::queries
::ty
::get(self.tcx(), span
, did
).subst(self.tcx(), substs
)
607 /// Transform a PolyTraitRef into a PolyExistentialTraitRef by
608 /// removing the dummy Self type (TRAIT_OBJECT_DUMMY_SELF).
609 fn trait_ref_to_existential(&self, trait_ref
: ty
::TraitRef
<'tcx
>)
610 -> ty
::ExistentialTraitRef
<'tcx
> {
611 assert_eq
!(trait_ref
.self_ty().sty
, TRAIT_OBJECT_DUMMY_SELF
);
612 ty
::ExistentialTraitRef
::erase_self_ty(self.tcx(), trait_ref
)
615 fn conv_object_ty_poly_trait_ref(&self,
617 trait_bounds
: &[hir
::PolyTraitRef
],
618 lifetime
: &hir
::Lifetime
)
621 let tcx
= self.tcx();
623 if trait_bounds
.is_empty() {
624 span_err
!(tcx
.sess
, span
, E0224
,
625 "at least one non-builtin trait is required for an object type");
626 return tcx
.types
.err
;
629 let mut projection_bounds
= vec
![];
630 let dummy_self
= tcx
.mk_ty(TRAIT_OBJECT_DUMMY_SELF
);
631 let principal
= self.instantiate_poly_trait_ref(&trait_bounds
[0],
633 &mut projection_bounds
);
635 let (auto_traits
, trait_bounds
) = split_auto_traits(tcx
, &trait_bounds
[1..]);
637 if !trait_bounds
.is_empty() {
638 let b
= &trait_bounds
[0];
639 let span
= b
.trait_ref
.path
.span
;
640 struct_span_err
!(self.tcx().sess
, span
, E0225
,
641 "only Send/Sync traits can be used as additional traits in a trait object")
642 .span_label(span
, &format
!("non-Send/Sync additional trait"))
646 // Erase the dummy_self (TRAIT_OBJECT_DUMMY_SELF) used above.
647 let existential_principal
= principal
.map_bound(|trait_ref
| {
648 self.trait_ref_to_existential(trait_ref
)
650 let existential_projections
= projection_bounds
.iter().map(|bound
| {
651 bound
.map_bound(|b
| {
652 let p
= b
.projection_ty
;
653 ty
::ExistentialProjection
{
654 trait_ref
: self.trait_ref_to_existential(p
.trait_ref
),
655 item_name
: p
.item_name
,
661 // check that there are no gross object safety violations,
662 // most importantly, that the supertraits don't contain Self,
664 let object_safety_violations
=
665 tcx
.astconv_object_safety_violations(principal
.def_id());
666 if !object_safety_violations
.is_empty() {
667 tcx
.report_object_safety_error(
668 span
, principal
.def_id(), object_safety_violations
)
670 return tcx
.types
.err
;
673 let mut associated_types
= FxHashSet
::default();
674 for tr
in traits
::supertraits(tcx
, principal
) {
675 associated_types
.extend(tcx
.associated_items(tr
.def_id())
676 .filter(|item
| item
.kind
== ty
::AssociatedKind
::Type
)
677 .map(|item
| (tr
.def_id(), item
.name
)));
680 for projection_bound
in &projection_bounds
{
681 let pair
= (projection_bound
.0.projection_ty
.trait_ref
.def_id
,
682 projection_bound
.0.projection_ty
.item_name
);
683 associated_types
.remove(&pair
);
686 for (trait_def_id
, name
) in associated_types
{
687 struct_span_err
!(tcx
.sess
, span
, E0191
,
688 "the value of the associated type `{}` (from the trait `{}`) must be specified",
690 tcx
.item_path_str(trait_def_id
))
691 .span_label(span
, &format
!(
692 "missing associated type `{}` value", name
))
697 iter
::once(ty
::ExistentialPredicate
::Trait(*existential_principal
.skip_binder()))
698 .chain(auto_traits
.into_iter().map(ty
::ExistentialPredicate
::AutoTrait
))
699 .chain(existential_projections
700 .map(|x
| ty
::ExistentialPredicate
::Projection(*x
.skip_binder())))
701 .collect
::<AccumulateVec
<[_
; 8]>>();
702 v
.sort_by(|a
, b
| a
.cmp(tcx
, b
));
703 let existential_predicates
= ty
::Binder(tcx
.mk_existential_predicates(v
.into_iter()));
706 // Explicitly specified region bound. Use that.
707 let region_bound
= if !lifetime
.is_elided() {
708 self.ast_region_to_region(lifetime
, None
)
710 self.compute_object_lifetime_bound(span
, existential_predicates
).unwrap_or_else(|| {
711 if tcx
.named_region_map
.defs
.contains_key(&lifetime
.id
) {
712 self.ast_region_to_region(lifetime
, None
)
714 self.re_infer(span
, None
).unwrap_or_else(|| {
715 span_err
!(tcx
.sess
, span
, E0228
,
716 "the lifetime bound for this object type cannot be deduced \
717 from context; please supply an explicit bound");
718 tcx
.mk_region(ty
::ReStatic
)
724 debug
!("region_bound: {:?}", region_bound
);
726 let ty
= tcx
.mk_dynamic(existential_predicates
, region_bound
);
727 debug
!("trait_object_type: {:?}", ty
);
731 fn report_ambiguous_associated_type(&self,
736 struct_span_err
!(self.tcx().sess
, span
, E0223
, "ambiguous associated type")
737 .span_label(span
, &format
!("ambiguous associated type"))
738 .note(&format
!("specify the type using the syntax `<{} as {}>::{}`",
739 type_str
, trait_str
, name
))
744 // Search for a bound on a type parameter which includes the associated item
745 // given by `assoc_name`. `ty_param_def_id` is the `DefId` for the type parameter
746 // This function will fail if there are no suitable bounds or there is
748 fn find_bound_for_assoc_item(&self,
749 ty_param_def_id
: DefId
,
750 assoc_name
: ast
::Name
,
752 -> Result
<ty
::PolyTraitRef
<'tcx
>, ErrorReported
>
754 let tcx
= self.tcx();
756 let bounds
: Vec
<_
> = self.get_type_parameter_bounds(span
, ty_param_def_id
)
757 .predicates
.into_iter().filter_map(|p
| p
.to_opt_poly_trait_ref()).collect();
759 // Check that there is exactly one way to find an associated type with the
761 let suitable_bounds
=
762 traits
::transitive_bounds(tcx
, &bounds
)
763 .filter(|b
| self.trait_defines_associated_type_named(b
.def_id(), assoc_name
));
765 let param_node_id
= tcx
.hir
.as_local_node_id(ty_param_def_id
).unwrap();
766 let param_name
= tcx
.hir
.ty_param_name(param_node_id
);
767 self.one_bound_for_assoc_type(suitable_bounds
,
768 ¶m_name
.as_str(),
769 &assoc_name
.as_str(),
774 // Checks that bounds contains exactly one element and reports appropriate
776 fn one_bound_for_assoc_type
<I
>(&self,
781 -> Result
<ty
::PolyTraitRef
<'tcx
>, ErrorReported
>
782 where I
: Iterator
<Item
=ty
::PolyTraitRef
<'tcx
>>
784 let bound
= match bounds
.next() {
785 Some(bound
) => bound
,
787 struct_span_err
!(self.tcx().sess
, span
, E0220
,
788 "associated type `{}` not found for `{}`",
791 .span_label(span
, &format
!("associated type `{}` not found", assoc_name
))
793 return Err(ErrorReported
);
797 if let Some(bound2
) = bounds
.next() {
798 let bounds
= iter
::once(bound
).chain(iter
::once(bound2
)).chain(bounds
);
799 let mut err
= struct_span_err
!(
800 self.tcx().sess
, span
, E0221
,
801 "ambiguous associated type `{}` in bounds of `{}`",
804 err
.span_label(span
, &format
!("ambiguous associated type `{}`", assoc_name
));
806 for bound
in bounds
{
807 let bound_span
= self.tcx().associated_items(bound
.def_id()).find(|item
| {
808 item
.kind
== ty
::AssociatedKind
::Type
&& item
.name
== assoc_name
810 .and_then(|item
| self.tcx().hir
.span_if_local(item
.def_id
));
812 if let Some(span
) = bound_span
{
813 err
.span_label(span
, &format
!("ambiguous `{}` from `{}`",
817 span_note
!(&mut err
, span
,
818 "associated type `{}` could derive from `{}`",
829 // Create a type from a path to an associated type.
830 // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
831 // and item_segment is the path segment for D. We return a type and a def for
833 // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
834 // parameter or Self.
835 pub fn associated_path_def_to_ty(&self,
840 item_segment
: &hir
::PathSegment
)
843 let tcx
= self.tcx();
844 let assoc_name
= item_segment
.name
;
846 debug
!("associated_path_def_to_ty: {:?}::{}", ty
, assoc_name
);
848 self.prohibit_type_params(slice
::ref_slice(item_segment
));
850 // Find the type of the associated item, and the trait where the associated
852 let bound
= match (&ty
.sty
, ty_path_def
) {
853 (_
, Def
::SelfTy(Some(_
), Some(impl_def_id
))) => {
854 // `Self` in an impl of a trait - we have a concrete self type and a
856 let trait_ref
= match tcx
.impl_trait_ref(impl_def_id
) {
857 Some(trait_ref
) => trait_ref
,
859 // A cycle error occurred, most likely.
860 return (tcx
.types
.err
, Def
::Err
);
864 let trait_ref
= if let Some(free_substs
) = self.get_free_substs() {
865 trait_ref
.subst(tcx
, free_substs
)
871 traits
::supertraits(tcx
, ty
::Binder(trait_ref
))
872 .filter(|r
| self.trait_defines_associated_type_named(r
.def_id(),
875 match self.one_bound_for_assoc_type(candidates
,
877 &assoc_name
.as_str(),
880 Err(ErrorReported
) => return (tcx
.types
.err
, Def
::Err
),
883 (&ty
::TyParam(_
), Def
::SelfTy(Some(param_did
), None
)) |
884 (&ty
::TyParam(_
), Def
::TyParam(param_did
)) => {
885 match self.find_bound_for_assoc_item(param_did
, assoc_name
, span
) {
887 Err(ErrorReported
) => return (tcx
.types
.err
, Def
::Err
),
891 // Don't print TyErr to the user.
892 if !ty
.references_error() {
893 self.report_ambiguous_associated_type(span
,
896 &assoc_name
.as_str());
898 return (tcx
.types
.err
, Def
::Err
);
902 let trait_did
= bound
.0.def_id
;
903 let ty
= self.projected_ty_from_poly_trait_ref(span
, bound
, assoc_name
);
904 let ty
= self.normalize_ty(span
, ty
);
906 let item
= tcx
.associated_items(trait_did
).find(|i
| i
.name
== assoc_name
);
907 let def_id
= item
.expect("missing associated type").def_id
;
908 tcx
.check_stability(def_id
, ref_id
, span
);
909 (ty
, Def
::AssociatedTy(def_id
))
912 fn qpath_to_ty(&self,
914 opt_self_ty
: Option
<Ty
<'tcx
>>,
916 trait_segment
: &hir
::PathSegment
,
917 item_segment
: &hir
::PathSegment
)
920 let tcx
= self.tcx();
922 self.prohibit_type_params(slice
::ref_slice(item_segment
));
924 let self_ty
= if let Some(ty
) = opt_self_ty
{
927 let path_str
= tcx
.item_path_str(trait_def_id
);
928 self.report_ambiguous_associated_type(span
,
931 &item_segment
.name
.as_str());
932 return tcx
.types
.err
;
935 debug
!("qpath_to_ty: self_type={:?}", self_ty
);
937 let trait_ref
= self.ast_path_to_mono_trait_ref(span
,
942 debug
!("qpath_to_ty: trait_ref={:?}", trait_ref
);
944 self.normalize_ty(span
, tcx
.mk_projection(trait_ref
, item_segment
.name
))
947 pub fn prohibit_type_params(&self, segments
: &[hir
::PathSegment
]) {
948 for segment
in segments
{
949 for typ
in segment
.parameters
.types() {
950 struct_span_err
!(self.tcx().sess
, typ
.span
, E0109
,
951 "type parameters are not allowed on this type")
952 .span_label(typ
.span
, &format
!("type parameter not allowed"))
956 for lifetime
in segment
.parameters
.lifetimes() {
957 struct_span_err
!(self.tcx().sess
, lifetime
.span
, E0110
,
958 "lifetime parameters are not allowed on this type")
959 .span_label(lifetime
.span
,
960 &format
!("lifetime parameter not allowed on this type"))
964 for binding
in segment
.parameters
.bindings() {
965 self.prohibit_projection(binding
.span
);
971 pub fn prohibit_projection(&self, span
: Span
) {
972 let mut err
= struct_span_err
!(self.tcx().sess
, span
, E0229
,
973 "associated type bindings are not allowed here");
974 err
.span_label(span
, &format
!("associate type not allowed here")).emit();
977 // Check a type Path and convert it to a Ty.
978 pub fn def_to_ty(&self,
979 opt_self_ty
: Option
<Ty
<'tcx
>>,
981 permit_variants
: bool
)
983 let tcx
= self.tcx();
985 debug
!("base_def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})",
986 path
.def
, opt_self_ty
, path
.segments
);
988 let span
= path
.span
;
990 Def
::Enum(did
) | Def
::TyAlias(did
) | Def
::Struct(did
) | Def
::Union(did
) => {
991 assert_eq
!(opt_self_ty
, None
);
992 self.prohibit_type_params(path
.segments
.split_last().unwrap().1);
993 self.ast_path_to_ty(span
, did
, path
.segments
.last().unwrap())
995 Def
::Variant(did
) if permit_variants
=> {
996 // Convert "variant type" as if it were a real type.
997 // The resulting `Ty` is type of the variant's enum for now.
998 assert_eq
!(opt_self_ty
, None
);
999 self.prohibit_type_params(path
.segments
.split_last().unwrap().1);
1000 self.ast_path_to_ty(span
,
1001 tcx
.parent_def_id(did
).unwrap(),
1002 path
.segments
.last().unwrap())
1004 Def
::TyParam(did
) => {
1005 assert_eq
!(opt_self_ty
, None
);
1006 self.prohibit_type_params(&path
.segments
);
1008 let node_id
= tcx
.hir
.as_local_node_id(did
).unwrap();
1009 let item_id
= tcx
.hir
.get_parent_node(node_id
);
1010 let item_def_id
= tcx
.hir
.local_def_id(item_id
);
1011 let generics
= tcx
.item_generics(item_def_id
);
1012 let index
= generics
.type_param_to_index
[&tcx
.hir
.local_def_id(node_id
).index
];
1013 tcx
.mk_param(index
, tcx
.hir
.name(node_id
))
1015 Def
::SelfTy(_
, Some(def_id
)) => {
1016 // Self in impl (we know the concrete type).
1018 assert_eq
!(opt_self_ty
, None
);
1019 self.prohibit_type_params(&path
.segments
);
1021 let ty
= ty
::queries
::ty
::get(tcx
, span
, def_id
);
1022 if let Some(free_substs
) = self.get_free_substs() {
1023 ty
.subst(tcx
, free_substs
)
1028 Def
::SelfTy(Some(_
), None
) => {
1030 assert_eq
!(opt_self_ty
, None
);
1031 self.prohibit_type_params(&path
.segments
);
1034 Def
::AssociatedTy(def_id
) => {
1035 self.prohibit_type_params(&path
.segments
[..path
.segments
.len()-2]);
1036 let trait_did
= tcx
.parent_def_id(def_id
).unwrap();
1037 self.qpath_to_ty(span
,
1040 &path
.segments
[path
.segments
.len()-2],
1041 path
.segments
.last().unwrap())
1043 Def
::PrimTy(prim_ty
) => {
1044 assert_eq
!(opt_self_ty
, None
);
1045 self.prohibit_type_params(&path
.segments
);
1047 hir
::TyBool
=> tcx
.types
.bool
,
1048 hir
::TyChar
=> tcx
.types
.char,
1049 hir
::TyInt(it
) => tcx
.mk_mach_int(it
),
1050 hir
::TyUint(uit
) => tcx
.mk_mach_uint(uit
),
1051 hir
::TyFloat(ft
) => tcx
.mk_mach_float(ft
),
1052 hir
::TyStr
=> tcx
.mk_str()
1056 self.set_tainted_by_errors();
1057 return self.tcx().types
.err
;
1059 _
=> span_bug
!(span
, "unexpected definition: {:?}", path
.def
)
1063 /// Parses the programmer's textual representation of a type into our
1064 /// internal notion of a type.
1065 pub fn ast_ty_to_ty(&self, ast_ty
: &hir
::Ty
) -> Ty
<'tcx
> {
1066 debug
!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
1069 let tcx
= self.tcx();
1071 let cache
= self.ast_ty_to_ty_cache();
1072 if let Some(ty
) = cache
.borrow().get(&ast_ty
.id
) {
1076 let result_ty
= match ast_ty
.node
{
1077 hir
::TySlice(ref ty
) => {
1078 tcx
.mk_slice(self.ast_ty_to_ty(&ty
))
1080 hir
::TyPtr(ref mt
) => {
1081 tcx
.mk_ptr(ty
::TypeAndMut
{
1082 ty
: self.ast_ty_to_ty(&mt
.ty
),
1086 hir
::TyRptr(ref region
, ref mt
) => {
1087 let r
= self.ast_region_to_region(region
, None
);
1088 debug
!("TyRef r={:?}", r
);
1089 let t
= self.ast_ty_to_ty(&mt
.ty
);
1090 tcx
.mk_ref(r
, ty
::TypeAndMut {ty: t, mutbl: mt.mutbl}
)
1095 hir
::TyTup(ref fields
) => {
1096 tcx
.mk_tup(fields
.iter().map(|t
| self.ast_ty_to_ty(&t
)), false)
1098 hir
::TyBareFn(ref bf
) => {
1099 require_c_abi_if_variadic(tcx
, &bf
.decl
, bf
.abi
, ast_ty
.span
);
1100 let bare_fn_ty
= self.ty_of_fn(bf
.unsafety
, bf
.abi
, &bf
.decl
);
1102 // Find any late-bound regions declared in return type that do
1103 // not appear in the arguments. These are not wellformed.
1107 // for<'a> fn() -> &'a str <-- 'a is bad
1108 // for<'a> fn(&'a String) -> &'a str <-- 'a is ok
1110 // Note that we do this check **here** and not in
1111 // `ty_of_bare_fn` because the latter is also used to make
1112 // the types for fn items, and we do not want to issue a
1113 // warning then. (Once we fix #32330, the regions we are
1114 // checking for here would be considered early bound
1116 let inputs
= bare_fn_ty
.inputs();
1117 let late_bound_in_args
= tcx
.collect_constrained_late_bound_regions(
1118 &inputs
.map_bound(|i
| i
.to_owned()));
1119 let output
= bare_fn_ty
.output();
1120 let late_bound_in_ret
= tcx
.collect_referenced_late_bound_regions(&output
);
1121 for br
in late_bound_in_ret
.difference(&late_bound_in_args
) {
1122 let br_name
= match *br
{
1123 ty
::BrNamed(_
, name
) => name
,
1126 bf
.decl
.output
.span(),
1127 "anonymous bound region {:?} in return but not args",
1131 struct_span_err
!(tcx
.sess
,
1134 "return type references lifetime `{}`, \
1135 which does not appear in the fn input types",
1139 tcx
.mk_fn_ptr(bare_fn_ty
)
1141 hir
::TyTraitObject(ref bounds
, ref lifetime
) => {
1142 self.conv_object_ty_poly_trait_ref(ast_ty
.span
, bounds
, lifetime
)
1144 hir
::TyImplTrait(_
) => {
1145 // Figure out if we can allow an `impl Trait` here, by walking up
1146 // to a `fn` or inherent `impl` method, going only through `Ty`
1147 // or `TraitRef` nodes (as nothing else should be in types) and
1148 // ensuring that we reach the `fn`/method signature's return type.
1149 let mut node_id
= ast_ty
.id
;
1150 let fn_decl
= loop {
1151 let parent
= tcx
.hir
.get_parent_node(node_id
);
1152 match tcx
.hir
.get(parent
) {
1153 hir
::map
::NodeItem(&hir
::Item
{
1154 node
: hir
::ItemFn(ref fn_decl
, ..), ..
1155 }) => break Some(fn_decl
),
1157 hir
::map
::NodeImplItem(&hir
::ImplItem
{
1158 node
: hir
::ImplItemKind
::Method(ref sig
, _
), ..
1160 match tcx
.hir
.expect_item(tcx
.hir
.get_parent(parent
)).node
{
1161 hir
::ItemImpl(.., None
, _
, _
) => {
1162 break Some(&sig
.decl
)
1168 hir
::map
::NodeTy(_
) | hir
::map
::NodeTraitRef(_
) => {}
1174 let allow
= fn_decl
.map_or(false, |fd
| {
1176 hir
::DefaultReturn(_
) => false,
1177 hir
::Return(ref ty
) => ty
.id
== node_id
1181 // Create the anonymized type.
1183 let def_id
= tcx
.hir
.local_def_id(ast_ty
.id
);
1184 tcx
.mk_anon(def_id
, Substs
::identity_for_item(tcx
, def_id
))
1186 span_err
!(tcx
.sess
, ast_ty
.span
, E0562
,
1187 "`impl Trait` not allowed outside of function \
1188 and inherent method return types");
1192 hir
::TyPath(hir
::QPath
::Resolved(ref maybe_qself
, ref path
)) => {
1193 debug
!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself
, path
);
1194 let opt_self_ty
= maybe_qself
.as_ref().map(|qself
| {
1195 self.ast_ty_to_ty(qself
)
1197 self.def_to_ty(opt_self_ty
, path
, false)
1199 hir
::TyPath(hir
::QPath
::TypeRelative(ref qself
, ref segment
)) => {
1200 debug
!("ast_ty_to_ty: qself={:?} segment={:?}", qself
, segment
);
1201 let ty
= self.ast_ty_to_ty(qself
);
1203 let def
= if let hir
::TyPath(hir
::QPath
::Resolved(_
, ref path
)) = qself
.node
{
1208 self.associated_path_def_to_ty(ast_ty
.id
, ast_ty
.span
, ty
, def
, segment
).0
1210 hir
::TyArray(ref ty
, length
) => {
1211 if let Ok(length
) = eval_length(tcx
.global_tcx(), length
, "array length") {
1212 tcx
.mk_array(self.ast_ty_to_ty(&ty
), length
)
1214 self.tcx().types
.err
1217 hir
::TyTypeof(ref _e
) => {
1218 struct_span_err
!(tcx
.sess
, ast_ty
.span
, E0516
,
1219 "`typeof` is a reserved keyword but unimplemented")
1220 .span_label(ast_ty
.span
, &format
!("reserved keyword"))
1226 // TyInfer also appears as the type of arguments or return
1227 // values in a ExprClosure, or as
1228 // the type of local variables. Both of these cases are
1229 // handled specially and will not descend into this routine.
1230 self.ty_infer(ast_ty
.span
)
1234 cache
.borrow_mut().insert(ast_ty
.id
, result_ty
);
1239 pub fn ty_of_arg(&self,
1241 expected_ty
: Option
<Ty
<'tcx
>>)
1245 hir
::TyInfer
if expected_ty
.is_some() => expected_ty
.unwrap(),
1246 hir
::TyInfer
=> self.ty_infer(ty
.span
),
1247 _
=> self.ast_ty_to_ty(ty
),
1251 pub fn ty_of_fn(&self,
1252 unsafety
: hir
::Unsafety
,
1255 -> ty
::PolyFnSig
<'tcx
> {
1258 let input_tys
: Vec
<Ty
> =
1259 decl
.inputs
.iter().map(|a
| self.ty_of_arg(a
, None
)).collect();
1261 let output_ty
= match decl
.output
{
1262 hir
::Return(ref output
) => self.ast_ty_to_ty(output
),
1263 hir
::DefaultReturn(..) => self.tcx().mk_nil(),
1266 debug
!("ty_of_fn: output_ty={:?}", output_ty
);
1268 ty
::Binder(self.tcx().mk_fn_sig(
1269 input_tys
.into_iter(),
1277 pub fn ty_of_closure(&self,
1278 unsafety
: hir
::Unsafety
,
1281 expected_sig
: Option
<ty
::FnSig
<'tcx
>>)
1282 -> ty
::PolyFnSig
<'tcx
>
1284 debug
!("ty_of_closure(expected_sig={:?})",
1287 let input_tys
= decl
.inputs
.iter().enumerate().map(|(i
, a
)| {
1288 let expected_arg_ty
= expected_sig
.as_ref().and_then(|e
| {
1289 // no guarantee that the correct number of expected args
1291 if i
< e
.inputs().len() {
1297 self.ty_of_arg(a
, expected_arg_ty
)
1300 let expected_ret_ty
= expected_sig
.as_ref().map(|e
| e
.output());
1302 let is_infer
= match decl
.output
{
1303 hir
::Return(ref output
) if output
.node
== hir
::TyInfer
=> true,
1304 hir
::DefaultReturn(..) => true,
1308 let output_ty
= match decl
.output
{
1309 _
if is_infer
&& expected_ret_ty
.is_some() =>
1310 expected_ret_ty
.unwrap(),
1311 _
if is_infer
=> self.ty_infer(decl
.output
.span()),
1312 hir
::Return(ref output
) =>
1313 self.ast_ty_to_ty(&output
),
1314 hir
::DefaultReturn(..) => bug
!(),
1317 debug
!("ty_of_closure: output_ty={:?}", output_ty
);
1319 ty
::Binder(self.tcx().mk_fn_sig(
1328 /// Given the bounds on an object, determines what single region bound (if any) we can
1329 /// use to summarize this type. The basic idea is that we will use the bound the user
1330 /// provided, if they provided one, and otherwise search the supertypes of trait bounds
1331 /// for region bounds. It may be that we can derive no bound at all, in which case
1332 /// we return `None`.
1333 fn compute_object_lifetime_bound(&self,
1335 existential_predicates
: ty
::Binder
<&'tcx ty
::Slice
<ty
::ExistentialPredicate
<'tcx
>>>)
1336 -> Option
<&'tcx ty
::Region
> // if None, use the default
1338 let tcx
= self.tcx();
1340 debug
!("compute_opt_region_bound(existential_predicates={:?})",
1341 existential_predicates
);
1343 // No explicit region bound specified. Therefore, examine trait
1344 // bounds and see if we can derive region bounds from those.
1345 let derived_region_bounds
=
1346 object_region_bounds(tcx
, existential_predicates
);
1348 // If there are no derived region bounds, then report back that we
1349 // can find no region bound. The caller will use the default.
1350 if derived_region_bounds
.is_empty() {
1354 // If any of the derived region bounds are 'static, that is always
1356 if derived_region_bounds
.iter().any(|&r
| ty
::ReStatic
== *r
) {
1357 return Some(tcx
.mk_region(ty
::ReStatic
));
1360 // Determine whether there is exactly one unique region in the set
1361 // of derived region bounds. If so, use that. Otherwise, report an
1363 let r
= derived_region_bounds
[0];
1364 if derived_region_bounds
[1..].iter().any(|r1
| r
!= *r1
) {
1365 span_err
!(tcx
.sess
, span
, E0227
,
1366 "ambiguous lifetime bound, explicit lifetime bound required");
1372 /// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
1373 /// remaining general trait bounds.
1374 fn split_auto_traits
<'a
, 'b
, 'gcx
, 'tcx
>(tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
1375 trait_bounds
: &'b
[hir
::PolyTraitRef
])
1376 -> (Vec
<DefId
>, Vec
<&'b hir
::PolyTraitRef
>)
1378 let (auto_traits
, trait_bounds
): (Vec
<_
>, _
) = trait_bounds
.iter().partition(|bound
| {
1379 match bound
.trait_ref
.path
.def
{
1380 Def
::Trait(trait_did
) => {
1381 // Checks whether `trait_did` refers to one of the builtin
1382 // traits, like `Send`, and adds it to `auto_traits` if so.
1383 if Some(trait_did
) == tcx
.lang_items
.send_trait() ||
1384 Some(trait_did
) == tcx
.lang_items
.sync_trait() {
1385 let segments
= &bound
.trait_ref
.path
.segments
;
1386 let parameters
= &segments
[segments
.len() - 1].parameters
;
1387 if !parameters
.types().is_empty() {
1388 check_type_argument_count(tcx
, bound
.trait_ref
.path
.span
,
1389 parameters
.types().len(), &[]);
1391 if !parameters
.lifetimes().is_empty() {
1392 report_lifetime_number_error(tcx
, bound
.trait_ref
.path
.span
,
1393 parameters
.lifetimes().len(), 0);
1404 let auto_traits
= auto_traits
.into_iter().map(|tr
| {
1405 if let Def
::Trait(trait_did
) = tr
.trait_ref
.path
.def
{
1410 }).collect
::<Vec
<_
>>();
1412 (auto_traits
, trait_bounds
)
1415 fn check_type_argument_count(tcx
: TyCtxt
, span
: Span
, supplied
: usize,
1416 ty_param_defs
: &[ty
::TypeParameterDef
]) {
1417 let accepted
= ty_param_defs
.len();
1418 let required
= ty_param_defs
.iter().take_while(|x
| !x
.has_default
).count();
1419 if supplied
< required
{
1420 let expected
= if required
< accepted
{
1425 let arguments_plural
= if required
== 1 { "" }
else { "s" }
;
1427 struct_span_err
!(tcx
.sess
, span
, E0243
,
1428 "wrong number of type arguments: {} {}, found {}",
1429 expected
, required
, supplied
)
1431 &format
!("{} {} type argument{}",
1436 } else if supplied
> accepted
{
1437 let expected
= if required
< accepted
{
1438 format
!("expected at most {}", accepted
)
1440 format
!("expected {}", accepted
)
1442 let arguments_plural
= if accepted
== 1 { "" }
else { "s" }
;
1444 struct_span_err
!(tcx
.sess
, span
, E0244
,
1445 "wrong number of type arguments: {}, found {}",
1449 &format
!("{} type argument{}",
1450 if accepted
== 0 { "expected no" }
else { &expected }
,
1457 fn report_lifetime_number_error(tcx
: TyCtxt
, span
: Span
, number
: usize, expected
: usize) {
1458 let label
= if number
< expected
{
1460 format
!("expected {} lifetime parameter", expected
)
1462 format
!("expected {} lifetime parameters", expected
)
1465 let additional
= number
- expected
;
1466 if additional
== 1 {
1467 "unexpected lifetime parameter".to_string()
1469 format
!("{} unexpected lifetime parameters", additional
)
1472 struct_span_err
!(tcx
.sess
, span
, E0107
,
1473 "wrong number of lifetime parameters: expected {}, found {}",
1475 .span_label(span
, &label
)
1479 // A helper struct for conveniently grouping a set of bounds which we pass to
1480 // and return from functions in multiple places.
1481 #[derive(PartialEq, Eq, Clone, Debug)]
1482 pub struct Bounds
<'tcx
> {
1483 pub region_bounds
: Vec
<&'tcx ty
::Region
>,
1484 pub implicitly_sized
: bool
,
1485 pub trait_bounds
: Vec
<ty
::PolyTraitRef
<'tcx
>>,
1486 pub projection_bounds
: Vec
<ty
::PolyProjectionPredicate
<'tcx
>>,
1489 impl<'a
, 'gcx
, 'tcx
> Bounds
<'tcx
> {
1490 pub fn predicates(&self, tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>, param_ty
: Ty
<'tcx
>)
1491 -> Vec
<ty
::Predicate
<'tcx
>>
1493 let mut vec
= Vec
::new();
1495 // If it could be sized, and is, add the sized predicate
1496 if self.implicitly_sized
{
1497 if let Some(sized
) = tcx
.lang_items
.sized_trait() {
1498 let trait_ref
= ty
::TraitRef
{
1500 substs
: tcx
.mk_substs_trait(param_ty
, &[])
1502 vec
.push(trait_ref
.to_predicate());
1506 for ®ion_bound
in &self.region_bounds
{
1507 // account for the binder being introduced below; no need to shift `param_ty`
1508 // because, at present at least, it can only refer to early-bound regions
1509 let region_bound
= tcx
.mk_region(ty
::fold
::shift_region(*region_bound
, 1));
1510 vec
.push(ty
::Binder(ty
::OutlivesPredicate(param_ty
, region_bound
)).to_predicate());
1513 for bound_trait_ref
in &self.trait_bounds
{
1514 vec
.push(bound_trait_ref
.to_predicate());
1517 for projection
in &self.projection_bounds
{
1518 vec
.push(projection
.to_predicate());
1525 pub enum ExplicitSelf
<'tcx
> {
1527 ByReference(&'tcx ty
::Region
, hir
::Mutability
),
1531 impl<'tcx
> ExplicitSelf
<'tcx
> {
1532 /// We wish to (for now) categorize an explicit self
1533 /// declaration like `self: SomeType` into either `self`,
1534 /// `&self`, `&mut self`, or `Box<self>`. We do this here
1535 /// by some simple pattern matching. A more precise check
1536 /// is done later in `check_method_self_type()`.
1541 /// impl Foo for &T {
1542 /// // Legal declarations:
1543 /// fn method1(self: &&T); // ExplicitSelf::ByReference
1544 /// fn method2(self: &T); // ExplicitSelf::ByValue
1545 /// fn method3(self: Box<&T>); // ExplicitSelf::ByBox
1547 /// // Invalid cases will be caught later by `check_method_self_type`:
1548 /// fn method_err1(self: &mut T); // ExplicitSelf::ByReference
1552 /// To do the check we just count the number of "modifiers"
1553 /// on each type and compare them. If they are the same or
1554 /// the impl has more, we call it "by value". Otherwise, we
1555 /// look at the outermost modifier on the method decl and
1556 /// call it by-ref, by-box as appropriate. For method1, for
1557 /// example, the impl type has one modifier, but the method
1558 /// type has two, so we end up with
1559 /// ExplicitSelf::ByReference.
1560 pub fn determine(untransformed_self_ty
: Ty
<'tcx
>,
1561 self_arg_ty
: Ty
<'tcx
>)
1562 -> ExplicitSelf
<'tcx
> {
1563 fn count_modifiers(ty
: Ty
) -> usize {
1565 ty
::TyRef(_
, mt
) => count_modifiers(mt
.ty
) + 1,
1566 ty
::TyAdt(def
, _
) if def
.is_box() => count_modifiers(ty
.boxed_ty()) + 1,
1571 let impl_modifiers
= count_modifiers(untransformed_self_ty
);
1572 let method_modifiers
= count_modifiers(self_arg_ty
);
1574 if impl_modifiers
>= method_modifiers
{
1575 ExplicitSelf
::ByValue
1577 match self_arg_ty
.sty
{
1578 ty
::TyRef(r
, mt
) => ExplicitSelf
::ByReference(r
, mt
.mutbl
),
1579 ty
::TyAdt(def
, _
) if def
.is_box() => ExplicitSelf
::ByBox
,
1580 _
=> ExplicitSelf
::ByValue
,