]> git.proxmox.com Git - rustc.git/blob - src/librustc_typeck/astconv.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc_typeck / astconv.rs
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.
4 //
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.
10
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` and a `RegionScope`.
14 //!
15 //! The parameterization of `ast_ty_to_ty()` is because it behaves
16 //! somewhat differently during the collect and check phases,
17 //! particularly with respect to looking up the types of top-level
18 //! items. In the collect phase, the crate context is used as the
19 //! `AstConv` instance; in this phase, the `get_item_type_scheme()`
20 //! function triggers a recursive call to `type_scheme_of_item()`
21 //! (note that `ast_ty_to_ty()` will detect recursive types and report
22 //! an error). In the check phase, when the FnCtxt is used as the
23 //! `AstConv`, `get_item_type_scheme()` just looks up the item type in
24 //! `tcx.tcache` (using `ty::lookup_item_type`).
25 //!
26 //! The `RegionScope` trait controls what happens when the user does
27 //! not specify a region in some location where a region is required
28 //! (e.g., if the user writes `&Foo` as a type rather than `&'a Foo`).
29 //! See the `rscope` module for more details.
30 //!
31 //! Unlike the `AstConv` trait, the region scope can change as we descend
32 //! the type. This is to accommodate the fact that (a) fn types are binding
33 //! scopes and (b) the default region may change. To understand case (a),
34 //! consider something like:
35 //!
36 //! type foo = { x: &a.int, y: |&a.int| }
37 //!
38 //! The type of `x` is an error because there is no region `a` in scope.
39 //! In the type of `y`, however, region `a` is considered a bound region
40 //! as it does not already appear in scope.
41 //!
42 //! Case (b) says that if you have a type:
43 //! type foo<'a> = ...;
44 //! type bar = fn(&foo, &a.foo)
45 //! The fully expanded version of type bar is:
46 //! type bar = fn(&'foo &, &a.foo<'a>)
47 //! Note that the self region for the `foo` defaulted to `&` in the first
48 //! case but `&a` in the second. Basically, defaults that appear inside
49 //! an rptr (`&r.T`) use the region `r` that appears in the rptr.
50
51 use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection};
52 use middle::const_val::ConstVal;
53 use rustc_const_eval::eval_const_expr_partial;
54 use rustc_const_eval::EvalHint::UncheckedExprHint;
55 use hir::def::{self, Def};
56 use hir::def_id::DefId;
57 use middle::resolve_lifetime as rl;
58 use rustc::ty::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs, ParamSpace};
59 use rustc::traits;
60 use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
61 use rustc::ty::wf::object_region_bounds;
62 use require_c_abi_if_variadic;
63 use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
64 ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope,
65 ElisionFailureInfo, ElidedLifetime};
66 use util::common::{ErrorReported, FN_OUTPUT_NAME};
67 use util::nodemap::FnvHashSet;
68
69 use rustc_const_math::ConstInt;
70
71 use syntax::{abi, ast};
72 use syntax::codemap::{Span, Pos};
73 use syntax::errors::DiagnosticBuilder;
74 use syntax::feature_gate::{GateIssue, emit_feature_err};
75 use syntax::parse::token;
76
77 use rustc::hir::print as pprust;
78 use rustc::hir;
79 use rustc_back::slice;
80
81 pub trait AstConv<'tcx> {
82 fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
83
84 /// Identify the type scheme for an item with a type, like a type
85 /// alias, fn, or struct. This allows you to figure out the set of
86 /// type parameters defined on the item.
87 fn get_item_type_scheme(&self, span: Span, id: DefId)
88 -> Result<ty::TypeScheme<'tcx>, ErrorReported>;
89
90 /// Returns the `TraitDef` for a given trait. This allows you to
91 /// figure out the set of type parameters defined on the trait.
92 fn get_trait_def(&self, span: Span, id: DefId)
93 -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>;
94
95 /// Ensure that the super-predicates for the trait with the given
96 /// id are available and also for the transitive set of
97 /// super-predicates.
98 fn ensure_super_predicates(&self, span: Span, id: DefId)
99 -> Result<(), ErrorReported>;
100
101 /// Returns the set of bounds in scope for the type parameter with
102 /// the given id.
103 fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId)
104 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>;
105
106 /// Returns true if the trait with id `trait_def_id` defines an
107 /// associated type with the name `name`.
108 fn trait_defines_associated_type_named(&self, trait_def_id: DefId, name: ast::Name)
109 -> bool;
110
111 /// Return an (optional) substitution to convert bound type parameters that
112 /// are in scope into free ones. This function should only return Some
113 /// within a fn body.
114 /// See ParameterEnvironment::free_substs for more information.
115 fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
116 None
117 }
118
119 /// What type should we use when a type is omitted?
120 fn ty_infer(&self,
121 param_and_substs: Option<ty::TypeParameterDef<'tcx>>,
122 substs: Option<&mut Substs<'tcx>>,
123 space: Option<ParamSpace>,
124 span: Span) -> Ty<'tcx>;
125
126 /// Projecting an associated type from a (potentially)
127 /// higher-ranked trait reference is more complicated, because of
128 /// the possibility of late-bound regions appearing in the
129 /// associated type binding. This is not legal in function
130 /// signatures for that reason. In a function body, we can always
131 /// handle it because we can use inference variables to remove the
132 /// late-bound regions.
133 fn projected_ty_from_poly_trait_ref(&self,
134 span: Span,
135 poly_trait_ref: ty::PolyTraitRef<'tcx>,
136 item_name: ast::Name)
137 -> Ty<'tcx>
138 {
139 if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) {
140 self.projected_ty(span, trait_ref, item_name)
141 } else {
142 // no late-bound regions, we can just ignore the binder
143 span_err!(self.tcx().sess, span, E0212,
144 "cannot extract an associated type from a higher-ranked trait bound \
145 in this context");
146 self.tcx().types.err
147 }
148 }
149
150 /// Project an associated type from a non-higher-ranked trait reference.
151 /// This is fairly straightforward and can be accommodated in any context.
152 fn projected_ty(&self,
153 span: Span,
154 _trait_ref: ty::TraitRef<'tcx>,
155 _item_name: ast::Name)
156 -> Ty<'tcx>;
157 }
158
159 pub fn ast_region_to_region(tcx: &TyCtxt, lifetime: &hir::Lifetime)
160 -> ty::Region {
161 let r = match tcx.named_region_map.get(&lifetime.id) {
162 None => {
163 // should have been recorded by the `resolve_lifetime` pass
164 span_bug!(lifetime.span, "unresolved lifetime");
165 }
166
167 Some(&rl::DefStaticRegion) => {
168 ty::ReStatic
169 }
170
171 Some(&rl::DefLateBoundRegion(debruijn, id)) => {
172 ty::ReLateBound(debruijn, ty::BrNamed(tcx.map.local_def_id(id), lifetime.name))
173 }
174
175 Some(&rl::DefEarlyBoundRegion(space, index, _)) => {
176 ty::ReEarlyBound(ty::EarlyBoundRegion {
177 space: space,
178 index: index,
179 name: lifetime.name
180 })
181 }
182
183 Some(&rl::DefFreeRegion(scope, id)) => {
184 ty::ReFree(ty::FreeRegion {
185 scope: scope.to_code_extent(&tcx.region_maps),
186 bound_region: ty::BrNamed(tcx.map.local_def_id(id),
187 lifetime.name)
188 })
189 }
190 };
191
192 debug!("ast_region_to_region(lifetime={:?} id={}) yields {:?}",
193 lifetime,
194 lifetime.id,
195 r);
196
197 r
198 }
199
200 fn report_elision_failure(
201 db: &mut DiagnosticBuilder,
202 default_span: Span,
203 params: Vec<ElisionFailureInfo>)
204 {
205 let mut m = String::new();
206 let len = params.len();
207 let mut any_lifetimes = false;
208
209 for (i, info) in params.into_iter().enumerate() {
210 let ElisionFailureInfo {
211 name, lifetime_count: n, have_bound_regions
212 } = info;
213
214 any_lifetimes = any_lifetimes || (n > 0);
215
216 let help_name = if name.is_empty() {
217 format!("argument {}", i + 1)
218 } else {
219 format!("`{}`", name)
220 };
221
222 m.push_str(&(if n == 1 {
223 help_name
224 } else {
225 format!("one of {}'s {} elided {}lifetimes", help_name, n,
226 if have_bound_regions { "free " } else { "" } )
227 })[..]);
228
229 if len == 2 && i == 0 {
230 m.push_str(" or ");
231 } else if i + 2 == len {
232 m.push_str(", or ");
233 } else if i + 1 != len {
234 m.push_str(", ");
235 }
236 }
237
238 if len == 0 {
239 fileline_help!(db, default_span,
240 "this function's return type contains a borrowed value, but \
241 there is no value for it to be borrowed from");
242 fileline_help!(db, default_span,
243 "consider giving it a 'static lifetime");
244 } else if !any_lifetimes {
245 fileline_help!(db, default_span,
246 "this function's return type contains a borrowed value with \
247 an elided lifetime, but the lifetime cannot be derived from \
248 the arguments");
249 fileline_help!(db, default_span,
250 "consider giving it an explicit bounded or 'static \
251 lifetime");
252 } else if len == 1 {
253 fileline_help!(db, default_span,
254 "this function's return type contains a borrowed value, but \
255 the signature does not say which {} it is borrowed from",
256 m);
257 } else {
258 fileline_help!(db, default_span,
259 "this function's return type contains a borrowed value, but \
260 the signature does not say whether it is borrowed from {}",
261 m);
262 }
263 }
264
265 pub fn opt_ast_region_to_region<'tcx>(
266 this: &AstConv<'tcx>,
267 rscope: &RegionScope,
268 default_span: Span,
269 opt_lifetime: &Option<hir::Lifetime>) -> ty::Region
270 {
271 let r = match *opt_lifetime {
272 Some(ref lifetime) => {
273 ast_region_to_region(this.tcx(), lifetime)
274 }
275
276 None => match rscope.anon_regions(default_span, 1) {
277 Ok(rs) => rs[0],
278 Err(params) => {
279 let mut err = struct_span_err!(this.tcx().sess, default_span, E0106,
280 "missing lifetime specifier");
281 if let Some(params) = params {
282 report_elision_failure(&mut err, default_span, params);
283 }
284 err.emit();
285 ty::ReStatic
286 }
287 }
288 };
289
290 debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {:?}",
291 opt_lifetime,
292 r);
293
294 r
295 }
296
297 /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
298 /// returns an appropriate set of substitutions for this particular reference to `I`.
299 pub fn ast_path_substs_for_ty<'tcx>(
300 this: &AstConv<'tcx>,
301 rscope: &RegionScope,
302 span: Span,
303 param_mode: PathParamMode,
304 decl_generics: &ty::Generics<'tcx>,
305 item_segment: &hir::PathSegment)
306 -> Substs<'tcx>
307 {
308 let tcx = this.tcx();
309
310 // ast_path_substs() is only called to convert paths that are
311 // known to refer to traits, types, or structs. In these cases,
312 // all type parameters defined for the item being referenced will
313 // be in the TypeSpace or SelfSpace.
314 //
315 // Note: in the case of traits, the self parameter is also
316 // defined, but we don't currently create a `type_param_def` for
317 // `Self` because it is implicit.
318 assert!(decl_generics.regions.all(|d| d.space == TypeSpace));
319 assert!(decl_generics.types.all(|d| d.space != FnSpace));
320
321 let (regions, types, assoc_bindings) = match item_segment.parameters {
322 hir::AngleBracketedParameters(ref data) => {
323 convert_angle_bracketed_parameters(this, rscope, span, decl_generics, data)
324 }
325 hir::ParenthesizedParameters(..) => {
326 span_err!(tcx.sess, span, E0214,
327 "parenthesized parameters may only be used with a trait");
328 let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
329 (Substs::empty(),
330 ty_param_defs.iter().map(|_| tcx.types.err).collect(),
331 vec![])
332 }
333 };
334
335 prohibit_projections(this.tcx(), &assoc_bindings);
336
337 create_substs_for_ast_path(this,
338 span,
339 param_mode,
340 decl_generics,
341 None,
342 types,
343 regions)
344 }
345
346 #[derive(PartialEq, Eq)]
347 pub enum PathParamMode {
348 // Any path in a type context.
349 Explicit,
350 // The `module::Type` in `module::Type::method` in an expression.
351 Optional
352 }
353
354 fn create_region_substs<'tcx>(
355 this: &AstConv<'tcx>,
356 rscope: &RegionScope,
357 span: Span,
358 decl_generics: &ty::Generics<'tcx>,
359 regions_provided: Vec<ty::Region>)
360 -> Substs<'tcx>
361 {
362 let tcx = this.tcx();
363
364 // If the type is parameterized by this region, then replace this
365 // region with the current anon region binding (in other words,
366 // whatever & would get replaced with).
367 let expected_num_region_params = decl_generics.regions.len(TypeSpace);
368 let supplied_num_region_params = regions_provided.len();
369 let regions = if expected_num_region_params == supplied_num_region_params {
370 regions_provided
371 } else {
372 let anon_regions =
373 rscope.anon_regions(span, expected_num_region_params);
374
375 if supplied_num_region_params != 0 || anon_regions.is_err() {
376 report_lifetime_number_error(tcx, span,
377 supplied_num_region_params,
378 expected_num_region_params);
379 }
380
381 match anon_regions {
382 Ok(anon_regions) => anon_regions,
383 Err(_) => (0..expected_num_region_params).map(|_| ty::ReStatic).collect()
384 }
385 };
386 Substs::new_type(vec![], regions)
387 }
388
389 /// Given the type/region arguments provided to some path (along with
390 /// an implicit Self, if this is a trait reference) returns the complete
391 /// set of substitutions. This may involve applying defaulted type parameters.
392 ///
393 /// Note that the type listing given here is *exactly* what the user provided.
394 ///
395 /// The `region_substs` should be the result of `create_region_substs`
396 /// -- that is, a substitution with no types but the correct number of
397 /// regions.
398 fn create_substs_for_ast_path<'tcx>(
399 this: &AstConv<'tcx>,
400 span: Span,
401 param_mode: PathParamMode,
402 decl_generics: &ty::Generics<'tcx>,
403 self_ty: Option<Ty<'tcx>>,
404 types_provided: Vec<Ty<'tcx>>,
405 region_substs: Substs<'tcx>)
406 -> Substs<'tcx>
407 {
408 let tcx = this.tcx();
409
410 debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}, \
411 types_provided={:?}, region_substs={:?})",
412 decl_generics, self_ty, types_provided,
413 region_substs);
414
415 assert_eq!(region_substs.regions.len(TypeSpace), decl_generics.regions.len(TypeSpace));
416 assert!(region_substs.types.is_empty());
417
418 // Convert the type parameters supplied by the user.
419 let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
420 let formal_ty_param_count = ty_param_defs.len();
421 let required_ty_param_count = ty_param_defs.iter()
422 .take_while(|x| x.default.is_none())
423 .count();
424
425 let mut type_substs = get_type_substs_for_defs(this,
426 span,
427 types_provided,
428 param_mode,
429 ty_param_defs,
430 region_substs.clone(),
431 self_ty);
432
433 let supplied_ty_param_count = type_substs.len();
434 check_type_argument_count(this.tcx(), span, supplied_ty_param_count,
435 required_ty_param_count, formal_ty_param_count);
436
437 if supplied_ty_param_count < required_ty_param_count {
438 while type_substs.len() < required_ty_param_count {
439 type_substs.push(tcx.types.err);
440 }
441 } else if supplied_ty_param_count > formal_ty_param_count {
442 type_substs.truncate(formal_ty_param_count);
443 }
444 assert!(type_substs.len() >= required_ty_param_count &&
445 type_substs.len() <= formal_ty_param_count);
446
447 let mut substs = region_substs;
448 substs.types.extend(TypeSpace, type_substs.into_iter());
449
450 match self_ty {
451 None => {
452 // If no self-type is provided, it's still possible that
453 // one was declared, because this could be an object type.
454 }
455 Some(ty) => {
456 // If a self-type is provided, one should have been
457 // "declared" (in other words, this should be a
458 // trait-ref).
459 assert!(decl_generics.types.get_self().is_some());
460 substs.types.push(SelfSpace, ty);
461 }
462 }
463
464 let actual_supplied_ty_param_count = substs.types.len(TypeSpace);
465 for param in &ty_param_defs[actual_supplied_ty_param_count..] {
466 if let Some(default) = param.default {
467 // If we are converting an object type, then the
468 // `Self` parameter is unknown. However, some of the
469 // other type parameters may reference `Self` in their
470 // defaults. This will lead to an ICE if we are not
471 // careful!
472 if self_ty.is_none() && default.has_self_ty() {
473 span_err!(tcx.sess, span, E0393,
474 "the type parameter `{}` must be explicitly specified \
475 in an object type because its default value `{}` references \
476 the type `Self`",
477 param.name,
478 default);
479 substs.types.push(TypeSpace, tcx.types.err);
480 } else {
481 // This is a default type parameter.
482 let default = default.subst_spanned(tcx,
483 &substs,
484 Some(span));
485 substs.types.push(TypeSpace, default);
486 }
487 } else {
488 span_bug!(span, "extra parameter without default");
489 }
490 }
491
492 debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
493 decl_generics, self_ty, substs);
494
495 substs
496 }
497
498 /// Returns types_provided if it is not empty, otherwise populating the
499 /// type parameters with inference variables as appropriate.
500 fn get_type_substs_for_defs<'tcx>(this: &AstConv<'tcx>,
501 span: Span,
502 types_provided: Vec<Ty<'tcx>>,
503 param_mode: PathParamMode,
504 ty_param_defs: &[ty::TypeParameterDef<'tcx>],
505 mut substs: Substs<'tcx>,
506 self_ty: Option<Ty<'tcx>>)
507 -> Vec<Ty<'tcx>>
508 {
509 fn default_type_parameter<'tcx>(p: &ty::TypeParameterDef<'tcx>, self_ty: Option<Ty<'tcx>>)
510 -> Option<ty::TypeParameterDef<'tcx>>
511 {
512 if let Some(ref default) = p.default {
513 if self_ty.is_none() && default.has_self_ty() {
514 // There is no suitable inference default for a type parameter
515 // that references self with no self-type provided.
516 return None;
517 }
518 }
519
520 Some(p.clone())
521 }
522
523 if param_mode == PathParamMode::Optional && types_provided.is_empty() {
524 ty_param_defs
525 .iter()
526 .map(|p| this.ty_infer(default_type_parameter(p, self_ty), Some(&mut substs),
527 Some(TypeSpace), span))
528 .collect()
529 } else {
530 types_provided
531 }
532 }
533
534 struct ConvertedBinding<'tcx> {
535 item_name: ast::Name,
536 ty: Ty<'tcx>,
537 span: Span,
538 }
539
540 fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
541 rscope: &RegionScope,
542 span: Span,
543 decl_generics: &ty::Generics<'tcx>,
544 data: &hir::AngleBracketedParameterData)
545 -> (Substs<'tcx>,
546 Vec<Ty<'tcx>>,
547 Vec<ConvertedBinding<'tcx>>)
548 {
549 let regions: Vec<_> =
550 data.lifetimes.iter()
551 .map(|l| ast_region_to_region(this.tcx(), l))
552 .collect();
553
554 let region_substs =
555 create_region_substs(this, rscope, span, decl_generics, regions);
556
557 let types: Vec<_> =
558 data.types.iter()
559 .enumerate()
560 .map(|(i,t)| ast_ty_arg_to_ty(this, rscope, decl_generics,
561 i, &region_substs, t))
562 .collect();
563
564 let assoc_bindings: Vec<_> =
565 data.bindings.iter()
566 .map(|b| ConvertedBinding { item_name: b.name,
567 ty: ast_ty_to_ty(this, rscope, &b.ty),
568 span: b.span })
569 .collect();
570
571 (region_substs, types, assoc_bindings)
572 }
573
574 /// Returns the appropriate lifetime to use for any output lifetimes
575 /// (if one exists) and a vector of the (pattern, number of lifetimes)
576 /// corresponding to each input type/pattern.
577 fn find_implied_output_region<'tcx>(tcx: &TyCtxt<'tcx>,
578 input_tys: &[Ty<'tcx>],
579 input_pats: Vec<String>) -> ElidedLifetime
580 {
581 let mut lifetimes_for_params = Vec::new();
582 let mut possible_implied_output_region = None;
583
584 for (input_type, input_pat) in input_tys.iter().zip(input_pats) {
585 let mut regions = FnvHashSet();
586 let have_bound_regions = tcx.collect_regions(input_type, &mut regions);
587
588 debug!("find_implied_output_regions: collected {:?} from {:?} \
589 have_bound_regions={:?}", &regions, input_type, have_bound_regions);
590
591 if regions.len() == 1 {
592 // there's a chance that the unique lifetime of this
593 // iteration will be the appropriate lifetime for output
594 // parameters, so lets store it.
595 possible_implied_output_region = regions.iter().cloned().next();
596 }
597
598 lifetimes_for_params.push(ElisionFailureInfo {
599 name: input_pat,
600 lifetime_count: regions.len(),
601 have_bound_regions: have_bound_regions
602 });
603 }
604
605 if lifetimes_for_params.iter().map(|e| e.lifetime_count).sum::<usize>() == 1 {
606 Ok(possible_implied_output_region.unwrap())
607 } else {
608 Err(Some(lifetimes_for_params))
609 }
610 }
611
612 fn convert_ty_with_lifetime_elision<'tcx>(this: &AstConv<'tcx>,
613 elided_lifetime: ElidedLifetime,
614 ty: &hir::Ty)
615 -> Ty<'tcx>
616 {
617 match elided_lifetime {
618 Ok(implied_output_region) => {
619 let rb = ElidableRscope::new(implied_output_region);
620 ast_ty_to_ty(this, &rb, ty)
621 }
622 Err(param_lifetimes) => {
623 // All regions must be explicitly specified in the output
624 // if the lifetime elision rules do not apply. This saves
625 // the user from potentially-confusing errors.
626 let rb = UnelidableRscope::new(param_lifetimes);
627 ast_ty_to_ty(this, &rb, ty)
628 }
629 }
630 }
631
632 fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>,
633 rscope: &RegionScope,
634 span: Span,
635 decl_generics: &ty::Generics<'tcx>,
636 data: &hir::ParenthesizedParameterData)
637 -> (Substs<'tcx>,
638 Vec<Ty<'tcx>>,
639 Vec<ConvertedBinding<'tcx>>)
640 {
641 let region_substs =
642 create_region_substs(this, rscope, span, decl_generics, Vec::new());
643
644 let binding_rscope = BindingRscope::new();
645 let inputs =
646 data.inputs.iter()
647 .map(|a_t| ast_ty_arg_to_ty(this, &binding_rscope, decl_generics,
648 0, &region_substs, a_t))
649 .collect::<Vec<Ty<'tcx>>>();
650
651 let input_params = vec![String::new(); inputs.len()];
652 let implied_output_region = find_implied_output_region(this.tcx(), &inputs, input_params);
653
654 let input_ty = this.tcx().mk_tup(inputs);
655
656 let (output, output_span) = match data.output {
657 Some(ref output_ty) => {
658 (convert_ty_with_lifetime_elision(this,
659 implied_output_region,
660 &output_ty),
661 output_ty.span)
662 }
663 None => {
664 (this.tcx().mk_nil(), data.span)
665 }
666 };
667
668 let output_binding = ConvertedBinding {
669 item_name: token::intern(FN_OUTPUT_NAME),
670 ty: output,
671 span: output_span
672 };
673
674 (region_substs, vec![input_ty], vec![output_binding])
675 }
676
677 pub fn instantiate_poly_trait_ref<'tcx>(
678 this: &AstConv<'tcx>,
679 rscope: &RegionScope,
680 ast_trait_ref: &hir::PolyTraitRef,
681 self_ty: Option<Ty<'tcx>>,
682 poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
683 -> ty::PolyTraitRef<'tcx>
684 {
685 let trait_ref = &ast_trait_ref.trait_ref;
686 let trait_def_id = trait_def_id(this, trait_ref);
687 ast_path_to_poly_trait_ref(this,
688 rscope,
689 trait_ref.path.span,
690 PathParamMode::Explicit,
691 trait_def_id,
692 self_ty,
693 trait_ref.path.segments.last().unwrap(),
694 poly_projections)
695 }
696
697 /// Instantiates the path for the given trait reference, assuming that it's
698 /// bound to a valid trait type. Returns the def_id for the defining trait.
699 /// Fails if the type is a type other than a trait type.
700 ///
701 /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
702 /// are disallowed. Otherwise, they are pushed onto the vector given.
703 pub fn instantiate_mono_trait_ref<'tcx>(
704 this: &AstConv<'tcx>,
705 rscope: &RegionScope,
706 trait_ref: &hir::TraitRef,
707 self_ty: Option<Ty<'tcx>>)
708 -> ty::TraitRef<'tcx>
709 {
710 let trait_def_id = trait_def_id(this, trait_ref);
711 ast_path_to_mono_trait_ref(this,
712 rscope,
713 trait_ref.path.span,
714 PathParamMode::Explicit,
715 trait_def_id,
716 self_ty,
717 trait_ref.path.segments.last().unwrap())
718 }
719
720 fn trait_def_id<'tcx>(this: &AstConv<'tcx>, trait_ref: &hir::TraitRef) -> DefId {
721 let path = &trait_ref.path;
722 match ::lookup_full_def(this.tcx(), path.span, trait_ref.ref_id) {
723 Def::Trait(trait_def_id) => trait_def_id,
724 Def::Err => {
725 this.tcx().sess.fatal("cannot continue compilation due to previous error");
726 }
727 _ => {
728 span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
729 path);
730 }
731 }
732 }
733
734 fn object_path_to_poly_trait_ref<'a,'tcx>(
735 this: &AstConv<'tcx>,
736 rscope: &RegionScope,
737 span: Span,
738 param_mode: PathParamMode,
739 trait_def_id: DefId,
740 trait_segment: &hir::PathSegment,
741 mut projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
742 -> ty::PolyTraitRef<'tcx>
743 {
744 ast_path_to_poly_trait_ref(this,
745 rscope,
746 span,
747 param_mode,
748 trait_def_id,
749 None,
750 trait_segment,
751 projections)
752 }
753
754 fn ast_path_to_poly_trait_ref<'a,'tcx>(
755 this: &AstConv<'tcx>,
756 rscope: &RegionScope,
757 span: Span,
758 param_mode: PathParamMode,
759 trait_def_id: DefId,
760 self_ty: Option<Ty<'tcx>>,
761 trait_segment: &hir::PathSegment,
762 poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
763 -> ty::PolyTraitRef<'tcx>
764 {
765 debug!("ast_path_to_poly_trait_ref(trait_segment={:?})", trait_segment);
766 // The trait reference introduces a binding level here, so
767 // we need to shift the `rscope`. It'd be nice if we could
768 // do away with this rscope stuff and work this knowledge
769 // into resolve_lifetimes, as we do with non-omitted
770 // lifetimes. Oh well, not there yet.
771 let shifted_rscope = &ShiftedRscope::new(rscope);
772
773 let (substs, assoc_bindings) =
774 create_substs_for_ast_trait_ref(this,
775 shifted_rscope,
776 span,
777 param_mode,
778 trait_def_id,
779 self_ty,
780 trait_segment);
781 let poly_trait_ref = ty::Binder(ty::TraitRef::new(trait_def_id, substs));
782
783 {
784 let converted_bindings =
785 assoc_bindings
786 .iter()
787 .filter_map(|binding| {
788 // specify type to assert that error was already reported in Err case:
789 let predicate: Result<_, ErrorReported> =
790 ast_type_binding_to_poly_projection_predicate(this,
791 poly_trait_ref.clone(),
792 self_ty,
793 binding);
794 predicate.ok() // ok to ignore Err() because ErrorReported (see above)
795 });
796 poly_projections.extend(converted_bindings);
797 }
798
799 debug!("ast_path_to_poly_trait_ref(trait_segment={:?}, projections={:?}) -> {:?}",
800 trait_segment, poly_projections, poly_trait_ref);
801 poly_trait_ref
802 }
803
804 fn ast_path_to_mono_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
805 rscope: &RegionScope,
806 span: Span,
807 param_mode: PathParamMode,
808 trait_def_id: DefId,
809 self_ty: Option<Ty<'tcx>>,
810 trait_segment: &hir::PathSegment)
811 -> ty::TraitRef<'tcx>
812 {
813 let (substs, assoc_bindings) =
814 create_substs_for_ast_trait_ref(this,
815 rscope,
816 span,
817 param_mode,
818 trait_def_id,
819 self_ty,
820 trait_segment);
821 prohibit_projections(this.tcx(), &assoc_bindings);
822 ty::TraitRef::new(trait_def_id, substs)
823 }
824
825 fn create_substs_for_ast_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
826 rscope: &RegionScope,
827 span: Span,
828 param_mode: PathParamMode,
829 trait_def_id: DefId,
830 self_ty: Option<Ty<'tcx>>,
831 trait_segment: &hir::PathSegment)
832 -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
833 {
834 debug!("create_substs_for_ast_trait_ref(trait_segment={:?})",
835 trait_segment);
836
837 let trait_def = match this.get_trait_def(span, trait_def_id) {
838 Ok(trait_def) => trait_def,
839 Err(ErrorReported) => {
840 // No convenient way to recover from a cycle here. Just bail. Sorry!
841 this.tcx().sess.abort_if_errors();
842 bug!("ErrorReported returned, but no errors reports?")
843 }
844 };
845
846 let (regions, types, assoc_bindings) = match trait_segment.parameters {
847 hir::AngleBracketedParameters(ref data) => {
848 // For now, require that parenthetical notation be used
849 // only with `Fn()` etc.
850 if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
851 emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
852 "unboxed_closures", span, GateIssue::Language,
853 "\
854 the precise format of `Fn`-family traits' type parameters is \
855 subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
856 }
857
858 convert_angle_bracketed_parameters(this, rscope, span, &trait_def.generics, data)
859 }
860 hir::ParenthesizedParameters(ref data) => {
861 // For now, require that parenthetical notation be used
862 // only with `Fn()` etc.
863 if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
864 emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
865 "unboxed_closures", span, GateIssue::Language,
866 "\
867 parenthetical notation is only stable when used with `Fn`-family traits");
868 }
869
870 convert_parenthesized_parameters(this, rscope, span, &trait_def.generics, data)
871 }
872 };
873
874 let substs = create_substs_for_ast_path(this,
875 span,
876 param_mode,
877 &trait_def.generics,
878 self_ty,
879 types,
880 regions);
881
882 (this.tcx().mk_substs(substs), assoc_bindings)
883 }
884
885 fn ast_type_binding_to_poly_projection_predicate<'tcx>(
886 this: &AstConv<'tcx>,
887 mut trait_ref: ty::PolyTraitRef<'tcx>,
888 self_ty: Option<Ty<'tcx>>,
889 binding: &ConvertedBinding<'tcx>)
890 -> Result<ty::PolyProjectionPredicate<'tcx>, ErrorReported>
891 {
892 let tcx = this.tcx();
893
894 // Given something like `U : SomeTrait<T=X>`, we want to produce a
895 // predicate like `<U as SomeTrait>::T = X`. This is somewhat
896 // subtle in the event that `T` is defined in a supertrait of
897 // `SomeTrait`, because in that case we need to upcast.
898 //
899 // That is, consider this case:
900 //
901 // ```
902 // trait SubTrait : SuperTrait<int> { }
903 // trait SuperTrait<A> { type T; }
904 //
905 // ... B : SubTrait<T=foo> ...
906 // ```
907 //
908 // We want to produce `<B as SuperTrait<int>>::T == foo`.
909
910 // Simple case: X is defined in the current trait.
911 if this.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
912 return Ok(ty::Binder(ty::ProjectionPredicate { // <-------------------+
913 projection_ty: ty::ProjectionTy { // |
914 trait_ref: trait_ref.skip_binder().clone(), // Binder moved here --+
915 item_name: binding.item_name,
916 },
917 ty: binding.ty,
918 }));
919 }
920
921 // Otherwise, we have to walk through the supertraits to find
922 // those that do. This is complicated by the fact that, for an
923 // object type, the `Self` type is not present in the
924 // substitutions (after all, it's being constructed right now),
925 // but the `supertraits` iterator really wants one. To handle
926 // this, we currently insert a dummy type and then remove it
927 // later. Yuck.
928
929 let dummy_self_ty = tcx.mk_infer(ty::FreshTy(0));
930 if self_ty.is_none() { // if converting for an object type
931 let mut dummy_substs = trait_ref.skip_binder().substs.clone(); // binder moved here -+
932 assert!(dummy_substs.self_ty().is_none()); // |
933 dummy_substs.types.push(SelfSpace, dummy_self_ty); // |
934 trait_ref = ty::Binder(ty::TraitRef::new(trait_ref.def_id(), // <------------+
935 tcx.mk_substs(dummy_substs)));
936 }
937
938 this.ensure_super_predicates(binding.span, trait_ref.def_id())?;
939
940 let mut candidates: Vec<ty::PolyTraitRef> =
941 traits::supertraits(tcx, trait_ref.clone())
942 .filter(|r| this.trait_defines_associated_type_named(r.def_id(), binding.item_name))
943 .collect();
944
945 // If converting for an object type, then remove the dummy-ty from `Self` now.
946 // Yuckety yuck.
947 if self_ty.is_none() {
948 for candidate in &mut candidates {
949 let mut dummy_substs = candidate.0.substs.clone();
950 assert!(dummy_substs.self_ty() == Some(dummy_self_ty));
951 dummy_substs.types.pop(SelfSpace);
952 *candidate = ty::Binder(ty::TraitRef::new(candidate.def_id(),
953 tcx.mk_substs(dummy_substs)));
954 }
955 }
956
957 let candidate = one_bound_for_assoc_type(tcx,
958 candidates,
959 &trait_ref.to_string(),
960 &binding.item_name.as_str(),
961 binding.span)?;
962
963 Ok(ty::Binder(ty::ProjectionPredicate { // <-------------------------+
964 projection_ty: ty::ProjectionTy { // |
965 trait_ref: candidate.skip_binder().clone(), // binder is moved up here --+
966 item_name: binding.item_name,
967 },
968 ty: binding.ty,
969 }))
970 }
971
972 fn ast_path_to_ty<'tcx>(
973 this: &AstConv<'tcx>,
974 rscope: &RegionScope,
975 span: Span,
976 param_mode: PathParamMode,
977 did: DefId,
978 item_segment: &hir::PathSegment)
979 -> Ty<'tcx>
980 {
981 let tcx = this.tcx();
982 let (generics, decl_ty) = match this.get_item_type_scheme(span, did) {
983 Ok(ty::TypeScheme { generics, ty: decl_ty }) => {
984 (generics, decl_ty)
985 }
986 Err(ErrorReported) => {
987 return tcx.types.err;
988 }
989 };
990
991 let substs = ast_path_substs_for_ty(this,
992 rscope,
993 span,
994 param_mode,
995 &generics,
996 item_segment);
997
998 // FIXME(#12938): This is a hack until we have full support for DST.
999 if Some(did) == this.tcx().lang_items.owned_box() {
1000 assert_eq!(substs.types.len(TypeSpace), 1);
1001 return this.tcx().mk_box(*substs.types.get(TypeSpace, 0));
1002 }
1003
1004 decl_ty.subst(this.tcx(), &substs)
1005 }
1006
1007 type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec<ty::PolyProjectionPredicate<'tcx>>);
1008
1009 fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
1010 rscope: &RegionScope,
1011 ty: &hir::Ty,
1012 bounds: &[hir::TyParamBound])
1013 -> Result<TraitAndProjections<'tcx>, ErrorReported>
1014 {
1015 /*!
1016 * In a type like `Foo + Send`, we want to wait to collect the
1017 * full set of bounds before we make the object type, because we
1018 * need them to infer a region bound. (For example, if we tried
1019 * made a type from just `Foo`, then it wouldn't be enough to
1020 * infer a 'static bound, and hence the user would get an error.)
1021 * So this function is used when we're dealing with a sum type to
1022 * convert the LHS. It only accepts a type that refers to a trait
1023 * name, and reports an error otherwise.
1024 */
1025
1026 match ty.node {
1027 hir::TyPath(None, ref path) => {
1028 let def = match this.tcx().def_map.borrow().get(&ty.id) {
1029 Some(&def::PathResolution { base_def, depth: 0, .. }) => Some(base_def),
1030 _ => None
1031 };
1032 match def {
1033 Some(Def::Trait(trait_def_id)) => {
1034 let mut projection_bounds = Vec::new();
1035 let trait_ref = object_path_to_poly_trait_ref(this,
1036 rscope,
1037 path.span,
1038 PathParamMode::Explicit,
1039 trait_def_id,
1040 path.segments.last().unwrap(),
1041 &mut projection_bounds);
1042 Ok((trait_ref, projection_bounds))
1043 }
1044 _ => {
1045 span_err!(this.tcx().sess, ty.span, E0172, "expected a reference to a trait");
1046 Err(ErrorReported)
1047 }
1048 }
1049 }
1050 _ => {
1051 let mut err = struct_span_err!(this.tcx().sess, ty.span, E0178,
1052 "expected a path on the left-hand side of `+`, not `{}`",
1053 pprust::ty_to_string(ty));
1054 let hi = bounds.iter().map(|x| match *x {
1055 hir::TraitTyParamBound(ref tr, _) => tr.span.hi,
1056 hir::RegionTyParamBound(ref r) => r.span.hi,
1057 }).max_by_key(|x| x.to_usize());
1058 let full_span = hi.map(|hi| Span {
1059 lo: ty.span.lo,
1060 hi: hi,
1061 expn_id: ty.span.expn_id,
1062 });
1063 match (&ty.node, full_span) {
1064 (&hir::TyRptr(None, ref mut_ty), Some(full_span)) => {
1065 let mutbl_str = if mut_ty.mutbl == hir::MutMutable { "mut " } else { "" };
1066 err.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
1067 format!("&{}({} +{})",
1068 mutbl_str,
1069 pprust::ty_to_string(&mut_ty.ty),
1070 pprust::bounds_to_string(bounds)));
1071 }
1072 (&hir::TyRptr(Some(ref lt), ref mut_ty), Some(full_span)) => {
1073 let mutbl_str = if mut_ty.mutbl == hir::MutMutable { "mut " } else { "" };
1074 err.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
1075 format!("&{} {}({} +{})",
1076 pprust::lifetime_to_string(lt),
1077 mutbl_str,
1078 pprust::ty_to_string(&mut_ty.ty),
1079 pprust::bounds_to_string(bounds)));
1080 }
1081
1082 _ => {
1083 fileline_help!(&mut err, ty.span,
1084 "perhaps you forgot parentheses? (per RFC 438)");
1085 }
1086 }
1087 err.emit();
1088 Err(ErrorReported)
1089 }
1090 }
1091 }
1092
1093 fn trait_ref_to_object_type<'tcx>(this: &AstConv<'tcx>,
1094 rscope: &RegionScope,
1095 span: Span,
1096 trait_ref: ty::PolyTraitRef<'tcx>,
1097 projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
1098 bounds: &[hir::TyParamBound])
1099 -> Ty<'tcx>
1100 {
1101 let existential_bounds = conv_existential_bounds(this,
1102 rscope,
1103 span,
1104 trait_ref.clone(),
1105 projection_bounds,
1106 bounds);
1107
1108 let result = make_object_type(this, span, trait_ref, existential_bounds);
1109 debug!("trait_ref_to_object_type: result={:?}",
1110 result);
1111
1112 result
1113 }
1114
1115 fn make_object_type<'tcx>(this: &AstConv<'tcx>,
1116 span: Span,
1117 principal: ty::PolyTraitRef<'tcx>,
1118 bounds: ty::ExistentialBounds<'tcx>)
1119 -> Ty<'tcx> {
1120 let tcx = this.tcx();
1121 let object = ty::TraitTy {
1122 principal: principal,
1123 bounds: bounds
1124 };
1125 let object_trait_ref =
1126 object.principal_trait_ref_with_self_ty(tcx, tcx.types.err);
1127
1128 // ensure the super predicates and stop if we encountered an error
1129 if this.ensure_super_predicates(span, principal.def_id()).is_err() {
1130 return tcx.types.err;
1131 }
1132
1133 // check that there are no gross object safety violations,
1134 // most importantly, that the supertraits don't contain Self,
1135 // to avoid ICE-s.
1136 let object_safety_violations =
1137 traits::astconv_object_safety_violations(tcx, principal.def_id());
1138 if !object_safety_violations.is_empty() {
1139 traits::report_object_safety_error(
1140 tcx, span, principal.def_id(), object_safety_violations)
1141 .emit();
1142 return tcx.types.err;
1143 }
1144
1145 let mut associated_types: FnvHashSet<(DefId, ast::Name)> =
1146 traits::supertraits(tcx, object_trait_ref)
1147 .flat_map(|tr| {
1148 let trait_def = tcx.lookup_trait_def(tr.def_id());
1149 trait_def.associated_type_names
1150 .clone()
1151 .into_iter()
1152 .map(move |associated_type_name| (tr.def_id(), associated_type_name))
1153 })
1154 .collect();
1155
1156 for projection_bound in &object.bounds.projection_bounds {
1157 let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
1158 projection_bound.0.projection_ty.item_name);
1159 associated_types.remove(&pair);
1160 }
1161
1162 for (trait_def_id, name) in associated_types {
1163 span_err!(tcx.sess, span, E0191,
1164 "the value of the associated type `{}` (from the trait `{}`) must be specified",
1165 name,
1166 tcx.item_path_str(trait_def_id));
1167 }
1168
1169 tcx.mk_trait(object.principal, object.bounds)
1170 }
1171
1172 fn report_ambiguous_associated_type(tcx: &TyCtxt,
1173 span: Span,
1174 type_str: &str,
1175 trait_str: &str,
1176 name: &str) {
1177 span_err!(tcx.sess, span, E0223,
1178 "ambiguous associated type; specify the type using the syntax \
1179 `<{} as {}>::{}`",
1180 type_str, trait_str, name);
1181 }
1182
1183 // Search for a bound on a type parameter which includes the associated item
1184 // given by assoc_name. ty_param_node_id is the node id for the type parameter
1185 // (which might be `Self`, but only if it is the `Self` of a trait, not an
1186 // impl). This function will fail if there are no suitable bounds or there is
1187 // any ambiguity.
1188 fn find_bound_for_assoc_item<'tcx>(this: &AstConv<'tcx>,
1189 ty_param_node_id: ast::NodeId,
1190 ty_param_name: ast::Name,
1191 assoc_name: ast::Name,
1192 span: Span)
1193 -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
1194 {
1195 let tcx = this.tcx();
1196
1197 let bounds = match this.get_type_parameter_bounds(span, ty_param_node_id) {
1198 Ok(v) => v,
1199 Err(ErrorReported) => {
1200 return Err(ErrorReported);
1201 }
1202 };
1203
1204 // Ensure the super predicates and stop if we encountered an error.
1205 if bounds.iter().any(|b| this.ensure_super_predicates(span, b.def_id()).is_err()) {
1206 return Err(ErrorReported);
1207 }
1208
1209 // Check that there is exactly one way to find an associated type with the
1210 // correct name.
1211 let suitable_bounds: Vec<_> =
1212 traits::transitive_bounds(tcx, &bounds)
1213 .filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
1214 .collect();
1215
1216 one_bound_for_assoc_type(tcx,
1217 suitable_bounds,
1218 &ty_param_name.as_str(),
1219 &assoc_name.as_str(),
1220 span)
1221 }
1222
1223
1224 // Checks that bounds contains exactly one element and reports appropriate
1225 // errors otherwise.
1226 fn one_bound_for_assoc_type<'tcx>(tcx: &TyCtxt<'tcx>,
1227 bounds: Vec<ty::PolyTraitRef<'tcx>>,
1228 ty_param_name: &str,
1229 assoc_name: &str,
1230 span: Span)
1231 -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
1232 {
1233 if bounds.is_empty() {
1234 span_err!(tcx.sess, span, E0220,
1235 "associated type `{}` not found for `{}`",
1236 assoc_name,
1237 ty_param_name);
1238 return Err(ErrorReported);
1239 }
1240
1241 if bounds.len() > 1 {
1242 let mut err = struct_span_err!(tcx.sess, span, E0221,
1243 "ambiguous associated type `{}` in bounds of `{}`",
1244 assoc_name,
1245 ty_param_name);
1246
1247 for bound in &bounds {
1248 span_note!(&mut err, span,
1249 "associated type `{}` could derive from `{}`",
1250 ty_param_name,
1251 bound);
1252 }
1253 err.emit();
1254 }
1255
1256 Ok(bounds[0].clone())
1257 }
1258
1259 // Create a type from a path to an associated type.
1260 // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
1261 // and item_segment is the path segment for D. We return a type and a def for
1262 // the whole path.
1263 // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
1264 // parameter or Self.
1265 fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
1266 span: Span,
1267 ty: Ty<'tcx>,
1268 ty_path_def: Def,
1269 item_segment: &hir::PathSegment)
1270 -> (Ty<'tcx>, Def)
1271 {
1272 let tcx = this.tcx();
1273 let assoc_name = item_segment.identifier.name;
1274
1275 debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
1276
1277 prohibit_type_params(tcx, slice::ref_slice(item_segment));
1278
1279 // Find the type of the associated item, and the trait where the associated
1280 // item is declared.
1281 let bound = match (&ty.sty, ty_path_def) {
1282 (_, Def::SelfTy(Some(trait_did), Some((impl_id, _)))) => {
1283 // `Self` in an impl of a trait - we have a concrete self type and a
1284 // trait reference.
1285 let trait_ref = tcx.impl_trait_ref(tcx.map.local_def_id(impl_id)).unwrap();
1286 let trait_ref = if let Some(free_substs) = this.get_free_substs() {
1287 trait_ref.subst(tcx, free_substs)
1288 } else {
1289 trait_ref
1290 };
1291
1292 if this.ensure_super_predicates(span, trait_did).is_err() {
1293 return (tcx.types.err, ty_path_def);
1294 }
1295
1296 let candidates: Vec<ty::PolyTraitRef> =
1297 traits::supertraits(tcx, ty::Binder(trait_ref))
1298 .filter(|r| this.trait_defines_associated_type_named(r.def_id(),
1299 assoc_name))
1300 .collect();
1301
1302 match one_bound_for_assoc_type(tcx,
1303 candidates,
1304 "Self",
1305 &assoc_name.as_str(),
1306 span) {
1307 Ok(bound) => bound,
1308 Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1309 }
1310 }
1311 (&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => {
1312 let trait_node_id = tcx.map.as_local_node_id(trait_did).unwrap();
1313 match find_bound_for_assoc_item(this,
1314 trait_node_id,
1315 token::special_idents::type_self.name,
1316 assoc_name,
1317 span) {
1318 Ok(bound) => bound,
1319 Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1320 }
1321 }
1322 (&ty::TyParam(_), Def::TyParam(_, _, param_did, param_name)) => {
1323 let param_node_id = tcx.map.as_local_node_id(param_did).unwrap();
1324 match find_bound_for_assoc_item(this,
1325 param_node_id,
1326 param_name,
1327 assoc_name,
1328 span) {
1329 Ok(bound) => bound,
1330 Err(ErrorReported) => return (tcx.types.err, ty_path_def),
1331 }
1332 }
1333 _ => {
1334 report_ambiguous_associated_type(tcx,
1335 span,
1336 &ty.to_string(),
1337 "Trait",
1338 &assoc_name.as_str());
1339 return (tcx.types.err, ty_path_def);
1340 }
1341 };
1342
1343 let trait_did = bound.0.def_id;
1344 let ty = this.projected_ty_from_poly_trait_ref(span, bound, assoc_name);
1345
1346 let item_did = if let Some(trait_id) = tcx.map.as_local_node_id(trait_did) {
1347 // `ty::trait_items` used below requires information generated
1348 // by type collection, which may be in progress at this point.
1349 match tcx.map.expect_item(trait_id).node {
1350 hir::ItemTrait(_, _, _, ref trait_items) => {
1351 let item = trait_items.iter()
1352 .find(|i| i.name == assoc_name)
1353 .expect("missing associated type");
1354 tcx.map.local_def_id(item.id)
1355 }
1356 _ => bug!()
1357 }
1358 } else {
1359 let trait_items = tcx.trait_items(trait_did);
1360 let item = trait_items.iter().find(|i| i.name() == assoc_name);
1361 item.expect("missing associated type").def_id()
1362 };
1363
1364 (ty, Def::AssociatedTy(trait_did, item_did))
1365 }
1366
1367 fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
1368 rscope: &RegionScope,
1369 span: Span,
1370 param_mode: PathParamMode,
1371 opt_self_ty: Option<Ty<'tcx>>,
1372 trait_def_id: DefId,
1373 trait_segment: &hir::PathSegment,
1374 item_segment: &hir::PathSegment)
1375 -> Ty<'tcx>
1376 {
1377 let tcx = this.tcx();
1378
1379 prohibit_type_params(tcx, slice::ref_slice(item_segment));
1380
1381 let self_ty = if let Some(ty) = opt_self_ty {
1382 ty
1383 } else {
1384 let path_str = tcx.item_path_str(trait_def_id);
1385 report_ambiguous_associated_type(tcx,
1386 span,
1387 "Type",
1388 &path_str,
1389 &item_segment.identifier.name.as_str());
1390 return tcx.types.err;
1391 };
1392
1393 debug!("qpath_to_ty: self_type={:?}", self_ty);
1394
1395 let trait_ref = ast_path_to_mono_trait_ref(this,
1396 rscope,
1397 span,
1398 param_mode,
1399 trait_def_id,
1400 Some(self_ty),
1401 trait_segment);
1402
1403 debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
1404
1405 this.projected_ty(span, trait_ref, item_segment.identifier.name)
1406 }
1407
1408 /// Convert a type supplied as value for a type argument from AST into our
1409 /// our internal representation. This is the same as `ast_ty_to_ty` but that
1410 /// it applies the object lifetime default.
1411 ///
1412 /// # Parameters
1413 ///
1414 /// * `this`, `rscope`: the surrounding context
1415 /// * `decl_generics`: the generics of the struct/enum/trait declaration being
1416 /// referenced
1417 /// * `index`: the index of the type parameter being instantiated from the list
1418 /// (we assume it is in the `TypeSpace`)
1419 /// * `region_substs`: a partial substitution consisting of
1420 /// only the region type parameters being supplied to this type.
1421 /// * `ast_ty`: the ast representation of the type being supplied
1422 pub fn ast_ty_arg_to_ty<'tcx>(this: &AstConv<'tcx>,
1423 rscope: &RegionScope,
1424 decl_generics: &ty::Generics<'tcx>,
1425 index: usize,
1426 region_substs: &Substs<'tcx>,
1427 ast_ty: &hir::Ty)
1428 -> Ty<'tcx>
1429 {
1430 let tcx = this.tcx();
1431
1432 if let Some(def) = decl_generics.types.opt_get(TypeSpace, index) {
1433 let object_lifetime_default = def.object_lifetime_default.subst(tcx, region_substs);
1434 let rscope1 = &ObjectLifetimeDefaultRscope::new(rscope, object_lifetime_default);
1435 ast_ty_to_ty(this, rscope1, ast_ty)
1436 } else {
1437 ast_ty_to_ty(this, rscope, ast_ty)
1438 }
1439 }
1440
1441 // Check the base def in a PathResolution and convert it to a Ty. If there are
1442 // associated types in the PathResolution, these will need to be separately
1443 // resolved.
1444 fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
1445 rscope: &RegionScope,
1446 span: Span,
1447 param_mode: PathParamMode,
1448 def: &Def,
1449 opt_self_ty: Option<Ty<'tcx>>,
1450 base_segments: &[hir::PathSegment])
1451 -> Ty<'tcx> {
1452 let tcx = this.tcx();
1453
1454 match *def {
1455 Def::Trait(trait_def_id) => {
1456 // N.B. this case overlaps somewhat with
1457 // TyObjectSum, see that fn for details
1458 let mut projection_bounds = Vec::new();
1459
1460 let trait_ref = object_path_to_poly_trait_ref(this,
1461 rscope,
1462 span,
1463 param_mode,
1464 trait_def_id,
1465 base_segments.last().unwrap(),
1466 &mut projection_bounds);
1467
1468 prohibit_type_params(tcx, base_segments.split_last().unwrap().1);
1469 trait_ref_to_object_type(this,
1470 rscope,
1471 span,
1472 trait_ref,
1473 projection_bounds,
1474 &[])
1475 }
1476 Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => {
1477 prohibit_type_params(tcx, base_segments.split_last().unwrap().1);
1478 ast_path_to_ty(this,
1479 rscope,
1480 span,
1481 param_mode,
1482 did,
1483 base_segments.last().unwrap())
1484 }
1485 Def::TyParam(space, index, _, name) => {
1486 prohibit_type_params(tcx, base_segments);
1487 tcx.mk_param(space, index, name)
1488 }
1489 Def::SelfTy(_, Some((_, self_ty_id))) => {
1490 // Self in impl (we know the concrete type).
1491 prohibit_type_params(tcx, base_segments);
1492 if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&self_ty_id) {
1493 if let Some(free_substs) = this.get_free_substs() {
1494 ty.subst(tcx, free_substs)
1495 } else {
1496 ty
1497 }
1498 } else {
1499 span_bug!(span, "self type has not been fully resolved")
1500 }
1501 }
1502 Def::SelfTy(Some(_), None) => {
1503 // Self in trait.
1504 prohibit_type_params(tcx, base_segments);
1505 tcx.mk_self_type()
1506 }
1507 Def::AssociatedTy(trait_did, _) => {
1508 prohibit_type_params(tcx, &base_segments[..base_segments.len()-2]);
1509 qpath_to_ty(this,
1510 rscope,
1511 span,
1512 param_mode,
1513 opt_self_ty,
1514 trait_did,
1515 &base_segments[base_segments.len()-2],
1516 base_segments.last().unwrap())
1517 }
1518 Def::Mod(..) => {
1519 // Used as sentinel by callers to indicate the `<T>::A::B::C` form.
1520 // FIXME(#22519) This part of the resolution logic should be
1521 // avoided entirely for that form, once we stop needed a Def
1522 // for `associated_path_def_to_ty`.
1523 // Fixing this will also let use resolve <Self>::Foo the same way we
1524 // resolve Self::Foo, at the moment we can't resolve the former because
1525 // we don't have the trait information around, which is just sad.
1526
1527 assert!(base_segments.is_empty());
1528
1529 opt_self_ty.expect("missing T in <T>::a::b::c")
1530 }
1531 Def::PrimTy(prim_ty) => {
1532 prim_ty_to_ty(tcx, base_segments, prim_ty)
1533 }
1534 Def::Err => {
1535 return this.tcx().types.err;
1536 }
1537 _ => {
1538 span_err!(tcx.sess, span, E0248,
1539 "found value `{}` used as a type",
1540 tcx.item_path_str(def.def_id()));
1541 return this.tcx().types.err;
1542 }
1543 }
1544 }
1545
1546 // Note that both base_segments and assoc_segments may be empty, although not at
1547 // the same time.
1548 pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
1549 rscope: &RegionScope,
1550 span: Span,
1551 param_mode: PathParamMode,
1552 def: &Def,
1553 opt_self_ty: Option<Ty<'tcx>>,
1554 base_segments: &[hir::PathSegment],
1555 assoc_segments: &[hir::PathSegment])
1556 -> Ty<'tcx> {
1557 let mut ty = base_def_to_ty(this,
1558 rscope,
1559 span,
1560 param_mode,
1561 def,
1562 opt_self_ty,
1563 base_segments);
1564 let mut def = *def;
1565 // If any associated type segments remain, attempt to resolve them.
1566 for segment in assoc_segments {
1567 if ty.sty == ty::TyError {
1568 break;
1569 }
1570 // This is pretty bad (it will fail except for T::A and Self::A).
1571 let (a_ty, a_def) = associated_path_def_to_ty(this,
1572 span,
1573 ty,
1574 def,
1575 segment);
1576 ty = a_ty;
1577 def = a_def;
1578 }
1579 ty
1580 }
1581
1582 /// Parses the programmer's textual representation of a type into our
1583 /// internal notion of a type.
1584 pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
1585 rscope: &RegionScope,
1586 ast_ty: &hir::Ty)
1587 -> Ty<'tcx>
1588 {
1589 debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
1590 ast_ty.id, ast_ty);
1591
1592 let tcx = this.tcx();
1593
1594 if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&ast_ty.id) {
1595 debug!("ast_ty_to_ty: id={:?} ty={:?} (cached)", ast_ty.id, ty);
1596 return ty;
1597 }
1598
1599 let typ = match ast_ty.node {
1600 hir::TyVec(ref ty) => {
1601 tcx.mk_slice(ast_ty_to_ty(this, rscope, &ty))
1602 }
1603 hir::TyObjectSum(ref ty, ref bounds) => {
1604 match ast_ty_to_trait_ref(this, rscope, &ty, bounds) {
1605 Ok((trait_ref, projection_bounds)) => {
1606 trait_ref_to_object_type(this,
1607 rscope,
1608 ast_ty.span,
1609 trait_ref,
1610 projection_bounds,
1611 bounds)
1612 }
1613 Err(ErrorReported) => {
1614 this.tcx().types.err
1615 }
1616 }
1617 }
1618 hir::TyPtr(ref mt) => {
1619 tcx.mk_ptr(ty::TypeAndMut {
1620 ty: ast_ty_to_ty(this, rscope, &mt.ty),
1621 mutbl: mt.mutbl
1622 })
1623 }
1624 hir::TyRptr(ref region, ref mt) => {
1625 let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
1626 debug!("TyRef r={:?}", r);
1627 let rscope1 =
1628 &ObjectLifetimeDefaultRscope::new(
1629 rscope,
1630 ty::ObjectLifetimeDefault::Specific(r));
1631 let t = ast_ty_to_ty(this, rscope1, &mt.ty);
1632 tcx.mk_ref(tcx.mk_region(r), ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
1633 }
1634 hir::TyTup(ref fields) => {
1635 let flds = fields.iter()
1636 .map(|t| ast_ty_to_ty(this, rscope, &t))
1637 .collect();
1638 tcx.mk_tup(flds)
1639 }
1640 hir::TyBareFn(ref bf) => {
1641 require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
1642 tcx.mk_fn_ptr(ty_of_bare_fn(this, bf.unsafety, bf.abi, &bf.decl))
1643 }
1644 hir::TyPolyTraitRef(ref bounds) => {
1645 conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds)
1646 }
1647 hir::TyPath(ref maybe_qself, ref path) => {
1648 let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
1649 d
1650 } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
1651 // Create some fake resolution that can't possibly be a type.
1652 def::PathResolution {
1653 base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
1654 depth: path.segments.len()
1655 }
1656 } else {
1657 span_bug!(ast_ty.span, "unbound path {:?}", ast_ty)
1658 };
1659 let def = path_res.base_def;
1660 let base_ty_end = path.segments.len() - path_res.depth;
1661 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
1662 ast_ty_to_ty(this, rscope, &qself.ty)
1663 });
1664 let ty = finish_resolving_def_to_ty(this,
1665 rscope,
1666 ast_ty.span,
1667 PathParamMode::Explicit,
1668 &def,
1669 opt_self_ty,
1670 &path.segments[..base_ty_end],
1671 &path.segments[base_ty_end..]);
1672
1673 if path_res.depth != 0 && ty.sty != ty::TyError {
1674 // Write back the new resolution.
1675 tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution {
1676 base_def: def,
1677 depth: 0
1678 });
1679 }
1680
1681 ty
1682 }
1683 hir::TyFixedLengthVec(ref ty, ref e) => {
1684 let hint = UncheckedExprHint(tcx.types.usize);
1685 match eval_const_expr_partial(tcx, &e, hint, None) {
1686 Ok(ConstVal::Integral(ConstInt::Usize(i))) => {
1687 let i = i.as_u64(tcx.sess.target.uint_type);
1688 assert_eq!(i as usize as u64, i);
1689 tcx.mk_array(ast_ty_to_ty(this, rscope, &ty), i as usize)
1690 },
1691 Ok(val) => {
1692 span_err!(tcx.sess, ast_ty.span, E0249,
1693 "expected usize value for array length, got {}", val.description());
1694 this.tcx().types.err
1695 },
1696 Err(ref r) => {
1697 let mut err = struct_span_err!(tcx.sess, r.span, E0250,
1698 "array length constant evaluation error: {}",
1699 r.description());
1700 if !ast_ty.span.contains(r.span) {
1701 span_note!(&mut err, ast_ty.span, "for array length here")
1702 }
1703 err.emit();
1704 this.tcx().types.err
1705 }
1706 }
1707 }
1708 hir::TyTypeof(ref _e) => {
1709 span_err!(tcx.sess, ast_ty.span, E0516,
1710 "`typeof` is a reserved keyword but unimplemented");
1711 tcx.types.err
1712 }
1713 hir::TyInfer => {
1714 // TyInfer also appears as the type of arguments or return
1715 // values in a ExprClosure, or as
1716 // the type of local variables. Both of these cases are
1717 // handled specially and will not descend into this routine.
1718 this.ty_infer(None, None, None, ast_ty.span)
1719 }
1720 };
1721
1722 debug!("ast_ty_to_ty: id={:?} ty={:?}", ast_ty.id, typ);
1723 tcx.ast_ty_to_ty_cache.borrow_mut().insert(ast_ty.id, typ);
1724 return typ;
1725 }
1726
1727 pub fn ty_of_arg<'tcx>(this: &AstConv<'tcx>,
1728 rscope: &RegionScope,
1729 a: &hir::Arg,
1730 expected_ty: Option<Ty<'tcx>>)
1731 -> Ty<'tcx>
1732 {
1733 match a.ty.node {
1734 hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
1735 hir::TyInfer => this.ty_infer(None, None, None, a.ty.span),
1736 _ => ast_ty_to_ty(this, rscope, &a.ty),
1737 }
1738 }
1739
1740 struct SelfInfo<'a, 'tcx> {
1741 untransformed_self_ty: Ty<'tcx>,
1742 explicit_self: &'a hir::ExplicitSelf,
1743 }
1744
1745 pub fn ty_of_method<'tcx>(this: &AstConv<'tcx>,
1746 sig: &hir::MethodSig,
1747 untransformed_self_ty: Ty<'tcx>)
1748 -> (ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) {
1749 let self_info = Some(SelfInfo {
1750 untransformed_self_ty: untransformed_self_ty,
1751 explicit_self: &sig.explicit_self,
1752 });
1753 let (bare_fn_ty, optional_explicit_self_category) =
1754 ty_of_method_or_bare_fn(this,
1755 sig.unsafety,
1756 sig.abi,
1757 self_info,
1758 &sig.decl);
1759 (bare_fn_ty, optional_explicit_self_category.unwrap())
1760 }
1761
1762 pub fn ty_of_bare_fn<'tcx>(this: &AstConv<'tcx>, unsafety: hir::Unsafety, abi: abi::Abi,
1763 decl: &hir::FnDecl) -> ty::BareFnTy<'tcx> {
1764 let (bare_fn_ty, _) = ty_of_method_or_bare_fn(this, unsafety, abi, None, decl);
1765 bare_fn_ty
1766 }
1767
1768 fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,
1769 unsafety: hir::Unsafety,
1770 abi: abi::Abi,
1771 opt_self_info: Option<SelfInfo<'a, 'tcx>>,
1772 decl: &hir::FnDecl)
1773 -> (ty::BareFnTy<'tcx>, Option<ty::ExplicitSelfCategory>)
1774 {
1775 debug!("ty_of_method_or_bare_fn");
1776
1777 // New region names that appear inside of the arguments of the function
1778 // declaration are bound to that function type.
1779 let rb = rscope::BindingRscope::new();
1780
1781 // `implied_output_region` is the region that will be assumed for any
1782 // region parameters in the return type. In accordance with the rules for
1783 // lifetime elision, we can determine it in two ways. First (determined
1784 // here), if self is by-reference, then the implied output region is the
1785 // region of the self parameter.
1786 let (self_ty, explicit_self_category) = match opt_self_info {
1787 None => (None, None),
1788 Some(self_info) => determine_self_type(this, &rb, self_info)
1789 };
1790
1791 // HACK(eddyb) replace the fake self type in the AST with the actual type.
1792 let arg_params = if self_ty.is_some() {
1793 &decl.inputs[1..]
1794 } else {
1795 &decl.inputs[..]
1796 };
1797 let arg_tys: Vec<Ty> =
1798 arg_params.iter().map(|a| ty_of_arg(this, &rb, a, None)).collect();
1799 let arg_pats: Vec<String> =
1800 arg_params.iter().map(|a| pprust::pat_to_string(&a.pat)).collect();
1801
1802 // Second, if there was exactly one lifetime (either a substitution or a
1803 // reference) in the arguments, then any anonymous regions in the output
1804 // have that lifetime.
1805 let implied_output_region = match explicit_self_category {
1806 Some(ty::ExplicitSelfCategory::ByReference(region, _)) => Ok(region),
1807 _ => find_implied_output_region(this.tcx(), &arg_tys, arg_pats)
1808 };
1809
1810 let output_ty = match decl.output {
1811 hir::Return(ref output) =>
1812 ty::FnConverging(convert_ty_with_lifetime_elision(this,
1813 implied_output_region,
1814 &output)),
1815 hir::DefaultReturn(..) => ty::FnConverging(this.tcx().mk_nil()),
1816 hir::NoReturn(..) => ty::FnDiverging
1817 };
1818
1819 (ty::BareFnTy {
1820 unsafety: unsafety,
1821 abi: abi,
1822 sig: ty::Binder(ty::FnSig {
1823 inputs: self_ty.into_iter().chain(arg_tys).collect(),
1824 output: output_ty,
1825 variadic: decl.variadic
1826 }),
1827 }, explicit_self_category)
1828 }
1829
1830 fn determine_self_type<'a, 'tcx>(this: &AstConv<'tcx>,
1831 rscope: &RegionScope,
1832 self_info: SelfInfo<'a, 'tcx>)
1833 -> (Option<Ty<'tcx>>, Option<ty::ExplicitSelfCategory>)
1834 {
1835 let self_ty = self_info.untransformed_self_ty;
1836 return match self_info.explicit_self.node {
1837 hir::SelfStatic => (None, Some(ty::ExplicitSelfCategory::Static)),
1838 hir::SelfValue(_) => {
1839 (Some(self_ty), Some(ty::ExplicitSelfCategory::ByValue))
1840 }
1841 hir::SelfRegion(ref lifetime, mutability, _) => {
1842 let region =
1843 opt_ast_region_to_region(this,
1844 rscope,
1845 self_info.explicit_self.span,
1846 lifetime);
1847 (Some(this.tcx().mk_ref(
1848 this.tcx().mk_region(region),
1849 ty::TypeAndMut {
1850 ty: self_ty,
1851 mutbl: mutability
1852 })),
1853 Some(ty::ExplicitSelfCategory::ByReference(region, mutability)))
1854 }
1855 hir::SelfExplicit(ref ast_type, _) => {
1856 let explicit_type = ast_ty_to_ty(this, rscope, &ast_type);
1857
1858 // We wish to (for now) categorize an explicit self
1859 // declaration like `self: SomeType` into either `self`,
1860 // `&self`, `&mut self`, or `Box<self>`. We do this here
1861 // by some simple pattern matching. A more precise check
1862 // is done later in `check_method_self_type()`.
1863 //
1864 // Examples:
1865 //
1866 // ```
1867 // impl Foo for &T {
1868 // // Legal declarations:
1869 // fn method1(self: &&T); // ExplicitSelfCategory::ByReference
1870 // fn method2(self: &T); // ExplicitSelfCategory::ByValue
1871 // fn method3(self: Box<&T>); // ExplicitSelfCategory::ByBox
1872 //
1873 // // Invalid cases will be caught later by `check_method_self_type`:
1874 // fn method_err1(self: &mut T); // ExplicitSelfCategory::ByReference
1875 // }
1876 // ```
1877 //
1878 // To do the check we just count the number of "modifiers"
1879 // on each type and compare them. If they are the same or
1880 // the impl has more, we call it "by value". Otherwise, we
1881 // look at the outermost modifier on the method decl and
1882 // call it by-ref, by-box as appropriate. For method1, for
1883 // example, the impl type has one modifier, but the method
1884 // type has two, so we end up with
1885 // ExplicitSelfCategory::ByReference.
1886
1887 let impl_modifiers = count_modifiers(self_info.untransformed_self_ty);
1888 let method_modifiers = count_modifiers(explicit_type);
1889
1890 debug!("determine_explicit_self_category(self_info.untransformed_self_ty={:?} \
1891 explicit_type={:?} \
1892 modifiers=({},{})",
1893 self_info.untransformed_self_ty,
1894 explicit_type,
1895 impl_modifiers,
1896 method_modifiers);
1897
1898 let category = if impl_modifiers >= method_modifiers {
1899 ty::ExplicitSelfCategory::ByValue
1900 } else {
1901 match explicit_type.sty {
1902 ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(*r, mt.mutbl),
1903 ty::TyBox(_) => ty::ExplicitSelfCategory::ByBox,
1904 _ => ty::ExplicitSelfCategory::ByValue,
1905 }
1906 };
1907
1908 (Some(explicit_type), Some(category))
1909 }
1910 };
1911
1912 fn count_modifiers(ty: Ty) -> usize {
1913 match ty.sty {
1914 ty::TyRef(_, mt) => count_modifiers(mt.ty) + 1,
1915 ty::TyBox(t) => count_modifiers(t) + 1,
1916 _ => 0,
1917 }
1918 }
1919 }
1920
1921 pub fn ty_of_closure<'tcx>(
1922 this: &AstConv<'tcx>,
1923 unsafety: hir::Unsafety,
1924 decl: &hir::FnDecl,
1925 abi: abi::Abi,
1926 expected_sig: Option<ty::FnSig<'tcx>>)
1927 -> ty::ClosureTy<'tcx>
1928 {
1929 debug!("ty_of_closure(expected_sig={:?})",
1930 expected_sig);
1931
1932 // new region names that appear inside of the fn decl are bound to
1933 // that function type
1934 let rb = rscope::BindingRscope::new();
1935
1936 let input_tys: Vec<_> = decl.inputs.iter().enumerate().map(|(i, a)| {
1937 let expected_arg_ty = expected_sig.as_ref().and_then(|e| {
1938 // no guarantee that the correct number of expected args
1939 // were supplied
1940 if i < e.inputs.len() {
1941 Some(e.inputs[i])
1942 } else {
1943 None
1944 }
1945 });
1946 ty_of_arg(this, &rb, a, expected_arg_ty)
1947 }).collect();
1948
1949 let expected_ret_ty = expected_sig.map(|e| e.output);
1950
1951 let is_infer = match decl.output {
1952 hir::Return(ref output) if output.node == hir::TyInfer => true,
1953 hir::DefaultReturn(..) => true,
1954 _ => false
1955 };
1956
1957 let output_ty = match decl.output {
1958 _ if is_infer && expected_ret_ty.is_some() =>
1959 expected_ret_ty.unwrap(),
1960 _ if is_infer =>
1961 ty::FnConverging(this.ty_infer(None, None, None, decl.output.span())),
1962 hir::Return(ref output) =>
1963 ty::FnConverging(ast_ty_to_ty(this, &rb, &output)),
1964 hir::DefaultReturn(..) => bug!(),
1965 hir::NoReturn(..) => ty::FnDiverging
1966 };
1967
1968 debug!("ty_of_closure: input_tys={:?}", input_tys);
1969 debug!("ty_of_closure: output_ty={:?}", output_ty);
1970
1971 ty::ClosureTy {
1972 unsafety: unsafety,
1973 abi: abi,
1974 sig: ty::Binder(ty::FnSig {inputs: input_tys,
1975 output: output_ty,
1976 variadic: decl.variadic}),
1977 }
1978 }
1979
1980 /// Given an existential type like `Foo+'a+Bar`, this routine converts the `'a` and `Bar` intos an
1981 /// `ExistentialBounds` struct. The `main_trait_refs` argument specifies the `Foo` -- it is absent
1982 /// for closures. Eventually this should all be normalized, I think, so that there is no "main
1983 /// trait ref" and instead we just have a flat list of bounds as the existential type.
1984 fn conv_existential_bounds<'tcx>(
1985 this: &AstConv<'tcx>,
1986 rscope: &RegionScope,
1987 span: Span,
1988 principal_trait_ref: ty::PolyTraitRef<'tcx>,
1989 projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
1990 ast_bounds: &[hir::TyParamBound])
1991 -> ty::ExistentialBounds<'tcx>
1992 {
1993 let partitioned_bounds =
1994 partition_bounds(this.tcx(), span, ast_bounds);
1995
1996 conv_existential_bounds_from_partitioned_bounds(
1997 this, rscope, span, principal_trait_ref, projection_bounds, partitioned_bounds)
1998 }
1999
2000 fn conv_ty_poly_trait_ref<'tcx>(
2001 this: &AstConv<'tcx>,
2002 rscope: &RegionScope,
2003 span: Span,
2004 ast_bounds: &[hir::TyParamBound])
2005 -> Ty<'tcx>
2006 {
2007 let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[..]);
2008
2009 let mut projection_bounds = Vec::new();
2010 let main_trait_bound = if !partitioned_bounds.trait_bounds.is_empty() {
2011 let trait_bound = partitioned_bounds.trait_bounds.remove(0);
2012 instantiate_poly_trait_ref(this,
2013 rscope,
2014 trait_bound,
2015 None,
2016 &mut projection_bounds)
2017 } else {
2018 span_err!(this.tcx().sess, span, E0224,
2019 "at least one non-builtin trait is required for an object type");
2020 return this.tcx().types.err;
2021 };
2022
2023 let bounds =
2024 conv_existential_bounds_from_partitioned_bounds(this,
2025 rscope,
2026 span,
2027 main_trait_bound.clone(),
2028 projection_bounds,
2029 partitioned_bounds);
2030
2031 make_object_type(this, span, main_trait_bound, bounds)
2032 }
2033
2034 pub fn conv_existential_bounds_from_partitioned_bounds<'tcx>(
2035 this: &AstConv<'tcx>,
2036 rscope: &RegionScope,
2037 span: Span,
2038 principal_trait_ref: ty::PolyTraitRef<'tcx>,
2039 projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>, // Empty for boxed closures
2040 partitioned_bounds: PartitionedBounds)
2041 -> ty::ExistentialBounds<'tcx>
2042 {
2043 let PartitionedBounds { builtin_bounds,
2044 trait_bounds,
2045 region_bounds } =
2046 partitioned_bounds;
2047
2048 if !trait_bounds.is_empty() {
2049 let b = &trait_bounds[0];
2050 span_err!(this.tcx().sess, b.trait_ref.path.span, E0225,
2051 "only the builtin traits can be used as closure or object bounds");
2052 }
2053
2054 let region_bound =
2055 compute_object_lifetime_bound(this,
2056 span,
2057 &region_bounds,
2058 principal_trait_ref,
2059 builtin_bounds);
2060
2061 let region_bound = match region_bound {
2062 Some(r) => r,
2063 None => {
2064 match rscope.object_lifetime_default(span) {
2065 Some(r) => r,
2066 None => {
2067 span_err!(this.tcx().sess, span, E0228,
2068 "the lifetime bound for this object type cannot be deduced \
2069 from context; please supply an explicit bound");
2070 ty::ReStatic
2071 }
2072 }
2073 }
2074 };
2075
2076 debug!("region_bound: {:?}", region_bound);
2077
2078 ty::ExistentialBounds::new(region_bound, builtin_bounds, projection_bounds)
2079 }
2080
2081 /// Given the bounds on an object, determines what single region bound
2082 /// (if any) we can use to summarize this type. The basic idea is that we will use the bound the
2083 /// user provided, if they provided one, and otherwise search the supertypes of trait bounds for
2084 /// region bounds. It may be that we can derive no bound at all, in which case we return `None`.
2085 fn compute_object_lifetime_bound<'tcx>(
2086 this: &AstConv<'tcx>,
2087 span: Span,
2088 explicit_region_bounds: &[&hir::Lifetime],
2089 principal_trait_ref: ty::PolyTraitRef<'tcx>,
2090 builtin_bounds: ty::BuiltinBounds)
2091 -> Option<ty::Region> // if None, use the default
2092 {
2093 let tcx = this.tcx();
2094
2095 debug!("compute_opt_region_bound(explicit_region_bounds={:?}, \
2096 principal_trait_ref={:?}, builtin_bounds={:?})",
2097 explicit_region_bounds,
2098 principal_trait_ref,
2099 builtin_bounds);
2100
2101 if explicit_region_bounds.len() > 1 {
2102 span_err!(tcx.sess, explicit_region_bounds[1].span, E0226,
2103 "only a single explicit lifetime bound is permitted");
2104 }
2105
2106 if !explicit_region_bounds.is_empty() {
2107 // Explicitly specified region bound. Use that.
2108 let r = explicit_region_bounds[0];
2109 return Some(ast_region_to_region(tcx, r));
2110 }
2111
2112 if let Err(ErrorReported) = this.ensure_super_predicates(span,principal_trait_ref.def_id()) {
2113 return Some(ty::ReStatic);
2114 }
2115
2116 // No explicit region bound specified. Therefore, examine trait
2117 // bounds and see if we can derive region bounds from those.
2118 let derived_region_bounds =
2119 object_region_bounds(tcx, &principal_trait_ref, builtin_bounds);
2120
2121 // If there are no derived region bounds, then report back that we
2122 // can find no region bound. The caller will use the default.
2123 if derived_region_bounds.is_empty() {
2124 return None;
2125 }
2126
2127 // If any of the derived region bounds are 'static, that is always
2128 // the best choice.
2129 if derived_region_bounds.iter().any(|r| ty::ReStatic == *r) {
2130 return Some(ty::ReStatic);
2131 }
2132
2133 // Determine whether there is exactly one unique region in the set
2134 // of derived region bounds. If so, use that. Otherwise, report an
2135 // error.
2136 let r = derived_region_bounds[0];
2137 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2138 span_err!(tcx.sess, span, E0227,
2139 "ambiguous lifetime bound, explicit lifetime bound required");
2140 }
2141 return Some(r);
2142 }
2143
2144 pub struct PartitionedBounds<'a> {
2145 pub builtin_bounds: ty::BuiltinBounds,
2146 pub trait_bounds: Vec<&'a hir::PolyTraitRef>,
2147 pub region_bounds: Vec<&'a hir::Lifetime>,
2148 }
2149
2150 /// Divides a list of bounds from the AST into three groups: builtin bounds (Copy, Sized etc),
2151 /// general trait bounds, and region bounds.
2152 pub fn partition_bounds<'a>(tcx: &TyCtxt,
2153 _span: Span,
2154 ast_bounds: &'a [hir::TyParamBound])
2155 -> PartitionedBounds<'a>
2156 {
2157 let mut builtin_bounds = ty::BuiltinBounds::empty();
2158 let mut region_bounds = Vec::new();
2159 let mut trait_bounds = Vec::new();
2160 for ast_bound in ast_bounds {
2161 match *ast_bound {
2162 hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
2163 match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
2164 Def::Trait(trait_did) => {
2165 if tcx.try_add_builtin_trait(trait_did,
2166 &mut builtin_bounds) {
2167 let segments = &b.trait_ref.path.segments;
2168 let parameters = &segments[segments.len() - 1].parameters;
2169 if !parameters.types().is_empty() {
2170 check_type_argument_count(tcx, b.trait_ref.path.span,
2171 parameters.types().len(), 0, 0);
2172 }
2173 if !parameters.lifetimes().is_empty() {
2174 report_lifetime_number_error(tcx, b.trait_ref.path.span,
2175 parameters.lifetimes().len(), 0);
2176 }
2177 continue; // success
2178 }
2179 }
2180 _ => {
2181 // Not a trait? that's an error, but it'll get
2182 // reported later.
2183 }
2184 }
2185 trait_bounds.push(b);
2186 }
2187 hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
2188 hir::RegionTyParamBound(ref l) => {
2189 region_bounds.push(l);
2190 }
2191 }
2192 }
2193
2194 PartitionedBounds {
2195 builtin_bounds: builtin_bounds,
2196 trait_bounds: trait_bounds,
2197 region_bounds: region_bounds,
2198 }
2199 }
2200
2201 fn prohibit_projections<'tcx>(tcx: &TyCtxt<'tcx>,
2202 bindings: &[ConvertedBinding<'tcx>])
2203 {
2204 for binding in bindings.iter().take(1) {
2205 prohibit_projection(tcx, binding.span);
2206 }
2207 }
2208
2209 fn check_type_argument_count(tcx: &TyCtxt, span: Span, supplied: usize,
2210 required: usize, accepted: usize) {
2211 if supplied < required {
2212 let expected = if required < accepted {
2213 "expected at least"
2214 } else {
2215 "expected"
2216 };
2217 span_err!(tcx.sess, span, E0243,
2218 "wrong number of type arguments: {} {}, found {}",
2219 expected, required, supplied);
2220 } else if supplied > accepted {
2221 let expected = if required < accepted {
2222 "expected at most"
2223 } else {
2224 "expected"
2225 };
2226 span_err!(tcx.sess, span, E0244,
2227 "wrong number of type arguments: {} {}, found {}",
2228 expected,
2229 accepted,
2230 supplied);
2231 }
2232 }
2233
2234 fn report_lifetime_number_error(tcx: &TyCtxt, span: Span, number: usize, expected: usize) {
2235 span_err!(tcx.sess, span, E0107,
2236 "wrong number of lifetime parameters: expected {}, found {}",
2237 expected, number);
2238 }
2239
2240 // A helper struct for conveniently grouping a set of bounds which we pass to
2241 // and return from functions in multiple places.
2242 #[derive(PartialEq, Eq, Clone, Debug)]
2243 pub struct Bounds<'tcx> {
2244 pub region_bounds: Vec<ty::Region>,
2245 pub builtin_bounds: ty::BuiltinBounds,
2246 pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
2247 pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
2248 }
2249
2250 impl<'tcx> Bounds<'tcx> {
2251 pub fn predicates(&self,
2252 tcx: &TyCtxt<'tcx>,
2253 param_ty: Ty<'tcx>)
2254 -> Vec<ty::Predicate<'tcx>>
2255 {
2256 let mut vec = Vec::new();
2257
2258 for builtin_bound in &self.builtin_bounds {
2259 match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) {
2260 Ok(trait_ref) => { vec.push(trait_ref.to_predicate()); }
2261 Err(ErrorReported) => { }
2262 }
2263 }
2264
2265 for &region_bound in &self.region_bounds {
2266 // account for the binder being introduced below; no need to shift `param_ty`
2267 // because, at present at least, it can only refer to early-bound regions
2268 let region_bound = ty::fold::shift_region(region_bound, 1);
2269 vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
2270 }
2271
2272 for bound_trait_ref in &self.trait_bounds {
2273 vec.push(bound_trait_ref.to_predicate());
2274 }
2275
2276 for projection in &self.projection_bounds {
2277 vec.push(projection.to_predicate());
2278 }
2279
2280 vec
2281 }
2282 }