astconv.rs 62.2 KB
Newer Older
V
Virgile Andreani 已提交
1
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

S
Steve Klabnik 已提交
11 12
//! Conversion from AST representation of types to the ty.rs
//! representation.  The main routine here is `ast_ty_to_ty()`: each use
13
//! is parameterized by an instance of `AstConv`.
14

15
use rustc_const_eval::eval_length;
16
use rustc_data_structures::accumulate_vec::AccumulateVec;
17
use hir;
18
use hir::def::Def;
19
use hir::def_id::DefId;
20
use middle::resolve_lifetime as rl;
21
use rustc::ty::subst::{Kind, Subst, Substs};
22 23 24
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
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};
29

30
use std::cell::RefCell;
31
use std::iter;
N
Niko Matsakis 已提交
32
use syntax::{abi, ast};
33
use syntax::feature_gate::{GateIssue, emit_feature_err};
34
use syntax::symbol::Symbol;
35
use syntax_pos::Span;
36

37 38
pub trait AstConv<'gcx, 'tcx> {
    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
39

40 41 42
    /// A cache used for the result of `ast_ty_to_ty_cache`
    fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>>;

43 44
    /// Returns the set of bounds in scope for the type parameter with
    /// the given id.
45
    fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
46
                                 -> ty::GenericPredicates<'tcx>;
47

N
Nick Cameron 已提交
48 49 50 51
    /// Return an (optional) substitution to convert bound type parameters that
    /// are in scope into free ones. This function should only return Some
    /// within a fn body.
    /// See ParameterEnvironment::free_substs for more information.
52
    fn get_free_substs(&self) -> Option<&Substs<'tcx>>;
53

54 55
    /// What lifetime should we use when a lifetime is omitted (and not elided)?
    fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>)
56
                -> Option<&'tcx ty::Region>;
57

58
    /// What type should we use when a type is omitted?
59 60 61 62
    fn ty_infer(&self, span: Span) -> Ty<'tcx>;

    /// Same as ty_infer, but with a known type parameter definition.
    fn ty_infer_for_def(&self,
63
                        _def: &ty::TypeParameterDef,
64
                        _substs: &[Kind<'tcx>],
65 66 67
                        span: Span) -> Ty<'tcx> {
        self.ty_infer(span)
    }
68

69 70 71 72 73 74 75 76 77 78 79
    /// Projecting an associated type from a (potentially)
    /// higher-ranked trait reference is more complicated, because of
    /// the possibility of late-bound regions appearing in the
    /// associated type binding. This is not legal in function
    /// signatures for that reason. In a function body, we can always
    /// handle it because we can use inference variables to remove the
    /// late-bound regions.
    fn projected_ty_from_poly_trait_ref(&self,
                                        span: Span,
                                        poly_trait_ref: ty::PolyTraitRef<'tcx>,
                                        item_name: ast::Name)
80
                                        -> Ty<'tcx>;
81 82 83 84 85

    /// Project an associated type from a non-higher-ranked trait reference.
    /// This is fairly straightforward and can be accommodated in any context.
    fn projected_ty(&self,
                    span: Span,
86
                    _trait_ref: ty::TraitRef<'tcx>,
87
                    _item_name: ast::Name)
N
Nick Cameron 已提交
88
                    -> Ty<'tcx>;
89 90 91 92 93 94

    /// Invoked when we encounter an error from some prior pass
    /// (e.g. resolve) that is translated into a ty-error. This is
    /// used to help suppress derived errors typeck might otherwise
    /// report.
    fn set_tainted_by_errors(&self);
95 96
}

97 98 99 100 101 102
struct ConvertedBinding<'tcx> {
    item_name: ast::Name,
    ty: Ty<'tcx>,
    span: Span,
}

103 104 105 106 107
/// Dummy type used for the `Self` of a `TraitRef` created for converting
/// a trait object, and which gets removed in `ExistentialTraitRef`.
/// This type must not appear anywhere in other converted types.
const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0));

108
impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
109 110
    pub fn ast_region_to_region(&self,
        lifetime: &hir::Lifetime,
111
        def: Option<&ty::RegionParameterDef>)
112
        -> &'tcx ty::Region
113
    {
114
        let tcx = self.tcx();
115
        let r = match tcx.named_region_map.defs.get(&lifetime.id) {
116
            Some(&rl::Region::Static) => {
117
                tcx.mk_region(ty::ReStatic)
118
            }
119

120
            Some(&rl::Region::LateBound(debruijn, id)) => {
121 122
                let name = tcx.hir.name(id);
                tcx.mk_region(ty::ReLateBound(debruijn,
123
                    ty::BrNamed(tcx.hir.local_def_id(id), name)))
124 125 126 127
            }

            Some(&rl::Region::LateBoundAnon(debruijn, index)) => {
                tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index)))
128
            }
129

130 131 132
            Some(&rl::Region::EarlyBound(index, id)) => {
                let name = tcx.hir.name(id);
                tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
133
                    index: index,
134 135
                    name: name
                }))
136
            }
137

138
            Some(&rl::Region::Free(scope, id)) => {
139 140 141
                let name = tcx.hir.name(id);
                tcx.mk_region(ty::ReFree(ty::FreeRegion {
                    scope: scope.to_code_extent(&tcx.region_maps),
142
                    bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name)
143
                }))
144 145

                    // (*) -- not late-bound, won't change
146
            }
147

148 149 150
            None => {
                self.re_infer(lifetime.span, def).expect("unelided lifetime in signature")
            }
151
        };
152

153 154
        debug!("ast_region_to_region(lifetime={:?}) yields {:?}",
                lifetime,
155
                r);
156

157
        r
158
    }
159

160 161 162 163
    /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
    /// returns an appropriate set of substitutions for this particular reference to `I`.
    pub fn ast_path_substs_for_ty(&self,
        span: Span,
164
        def_id: DefId,
165
        item_segment: &hir::PathSegment)
166
        -> &'tcx Substs<'tcx>
167 168 169
    {
        let tcx = self.tcx();

170 171
        match item_segment.parameters {
            hir::AngleBracketedParameters(_) => {}
172
            hir::ParenthesizedParameters(..) => {
173 174 175 176 177
                struct_span_err!(tcx.sess, span, E0214,
                          "parenthesized parameters may only be used with a trait")
                    .span_label(span, &format!("only traits may use parentheses"))
                    .emit();

178
                return Substs::for_item(tcx, def_id, |_, _| {
179
                    tcx.mk_region(ty::ReStatic)
180 181
                }, |_, _| {
                    tcx.types.err
182
                });
183
            }
184 185 186
        }

        let (substs, assoc_bindings) =
187
            self.create_substs_for_ast_path(span,
188
                                            def_id,
189 190
                                            &item_segment.parameters,
                                            None);
191

192
        assoc_bindings.first().map(|b| self.tcx().prohibit_projection(b.span));
193

194
        substs
195
    }
196

197 198 199 200 201 202
    /// Given the type/region arguments provided to some path (along with
    /// an implicit Self, if this is a trait reference) returns the complete
    /// set of substitutions. This may involve applying defaulted type parameters.
    ///
    /// Note that the type listing given here is *exactly* what the user provided.
    fn create_substs_for_ast_path(&self,
203
        span: Span,
204
        def_id: DefId,
205 206 207
        parameters: &hir::PathParameters,
        self_ty: Option<Ty<'tcx>>)
        -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
208 209 210
    {
        let tcx = self.tcx();

211
        debug!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
212
               parameters={:?})",
213
               def_id, self_ty, parameters);
214

215
        let (lifetimes, num_types_provided, infer_types) = match *parameters {
216
            hir::AngleBracketedParameters(ref data) => {
217
                (&data.lifetimes[..], data.types.len(), data.infer_types)
218
            }
219
            hir::ParenthesizedParameters(_) => (&[][..], 1, false)
220 221
        };

222 223 224
        // If the type is parameterized by this region, then replace this
        // region with the current anon region binding (in other words,
        // whatever & would get replaced with).
225
        let decl_generics = tcx.item_generics(def_id);
226
        let expected_num_region_params = decl_generics.regions.len();
227
        let supplied_num_region_params = lifetimes.len();
228
        if expected_num_region_params != supplied_num_region_params {
229 230 231
            report_lifetime_number_error(tcx, span,
                                         supplied_num_region_params,
                                         expected_num_region_params);
232 233
        }

234
        // If a self-type was declared, one should be provided.
235
        assert_eq!(decl_generics.has_self, self_ty.is_some());
236

237
        // Check the number of type parameters supplied by the user.
238 239 240
        let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..];
        if !infer_types || num_types_provided > ty_param_defs.len() {
            check_type_argument_count(tcx, span, num_types_provided, ty_param_defs);
241
        }
242

243
        let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
244 245
        let default_needs_object_self = |p: &ty::TypeParameterDef| {
            if is_object && p.has_default {
246
                if tcx.maps.ty(tcx, span, p.def_id).has_self_ty() {
247 248 249 250 251
                    // There is no suitable inference default for a type parameter
                    // that references self, in an object type.
                    return true;
                }
            }
252

253 254 255 256
            false
        };

        let mut output_assoc_binding = None;
257
        let substs = Substs::for_item(tcx, def_id, |def, _| {
258
            let i = def.index as usize - self_ty.is_some() as usize;
259 260 261
            if let Some(lifetime) = lifetimes.get(i) {
                self.ast_region_to_region(lifetime, Some(def))
            } else {
262
                tcx.mk_region(ty::ReStatic)
263
            }
264 265
        }, |def, substs| {
            let i = def.index as usize;
266 267 268 269 270 271

            // Handle Self first, so we can adjust the index to match the AST.
            if let (0, Some(ty)) = (i, self_ty) {
                return ty;
            }

272
            let i = i - self_ty.is_some() as usize - decl_generics.regions.len();
273
            if i < num_types_provided {
274 275 276
                // A provided type parameter.
                match *parameters {
                    hir::AngleBracketedParameters(ref data) => {
277
                        self.ast_ty_to_ty(&data.types[i])
278 279 280
                    }
                    hir::ParenthesizedParameters(ref data) => {
                        assert_eq!(i, 0);
281
                        let (ty, assoc) = self.convert_parenthesized_parameters(data);
282 283 284 285
                        output_assoc_binding = Some(assoc);
                        ty
                    }
                }
286
            } else if infer_types {
287 288 289 290 291 292 293
                // No type parameters were provided, we can infer all.
                let ty_var = if !default_needs_object_self(def) {
                    self.ty_infer_for_def(def, substs, span)
                } else {
                    self.ty_infer(span)
                };
                ty_var
294
            } else if def.has_default {
295
                // No type parameter provided, but a default exists.
296

297 298 299 300 301
                // If we are converting an object type, then the
                // `Self` parameter is unknown. However, some of the
                // other type parameters may reference `Self` in their
                // defaults. This will lead to an ICE if we are not
                // careful!
302
                if default_needs_object_self(def) {
Z
zjhmale 已提交
303 304 305 306 307 308 309
                    struct_span_err!(tcx.sess, span, E0393,
                                     "the type parameter `{}` must be explicitly specified",
                                     def.name)
                        .span_label(span, &format!("missing reference to `{}`", def.name))
                        .note(&format!("because of the default `Self` reference, \
                                        type parameters must be specified on object types"))
                        .emit();
310
                    tcx.types.err
311 312
                } else {
                    // This is a default type parameter.
313
                    tcx.maps.ty(tcx, span, def.def_id).subst_spanned(tcx, substs, Some(span))
314
                }
315
            } else {
316 317
                // We've already errored above about the mismatch.
                tcx.types.err
S
Sean Bowe 已提交
318
            }
319
        });
S
Sean Bowe 已提交
320

321 322 323 324 325
        let assoc_bindings = match *parameters {
            hir::AngleBracketedParameters(ref data) => {
                data.bindings.iter().map(|b| {
                    ConvertedBinding {
                        item_name: b.name,
326
                        ty: self.ast_ty_to_ty(&b.ty),
327 328 329 330 331 332 333 334
                        span: b.span
                    }
                }).collect()
            }
            hir::ParenthesizedParameters(ref data) => {
                vec![output_assoc_binding.unwrap_or_else(|| {
                    // This is an error condition, but we should
                    // get the associated type binding anyway.
335
                    self.convert_parenthesized_parameters(data).1
336 337
                })]
            }
338
        };
S
Sean Bowe 已提交
339

340 341
        debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
               decl_generics, self_ty, substs);
S
Sean Bowe 已提交
342

343
        (substs, assoc_bindings)
344
    }
345

346 347
    fn convert_parenthesized_parameters(&self,
                                        data: &hir::ParenthesizedParameterData)
348
                                        -> (Ty<'tcx>, ConvertedBinding<'tcx>)
349
    {
350
        let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| {
351
            self.ast_ty_to_ty(a_t)
352
        }));
353

354 355
        let (output, output_span) = match data.output {
            Some(ref output_ty) => {
356
                (self.ast_ty_to_ty(output_ty), output_ty.span)
357 358 359 360 361
            }
            None => {
                (self.tcx().mk_nil(), data.span)
            }
        };
362

363
        let output_binding = ConvertedBinding {
364
            item_name: Symbol::intern(FN_OUTPUT_NAME),
365 366 367
            ty: output,
            span: output_span
        };
368

A
Andrew Cann 已提交
369
        (self.tcx().mk_ty(ty::TyTuple(inputs, false)), output_binding)
370
    }
371

372 373 374 375 376 377 378 379
    /// Instantiates the path for the given trait reference, assuming that it's
    /// bound to a valid trait type. Returns the def_id for the defining trait.
    /// Fails if the type is a type other than a trait type.
    ///
    /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
    /// are disallowed. Otherwise, they are pushed onto the vector given.
    pub fn instantiate_mono_trait_ref(&self,
        trait_ref: &hir::TraitRef,
380
        self_ty: Ty<'tcx>)
381 382 383
        -> ty::TraitRef<'tcx>
    {
        let trait_def_id = self.trait_def_id(trait_ref);
384
        self.ast_path_to_mono_trait_ref(trait_ref.path.span,
385 386 387 388
                                        trait_def_id,
                                        self_ty,
                                        trait_ref.path.segments.last().unwrap())
    }
389

390 391
    fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
        let path = &trait_ref.path;
392
        match path.def {
393 394 395 396 397 398
            Def::Trait(trait_def_id) => trait_def_id,
            Def::Err => {
                self.tcx().sess.fatal("cannot continue compilation due to previous error");
            }
            _ => {
                span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait",
399
                            self.tcx().hir.node_to_pretty_string(trait_ref.ref_id));
400
            }
N
Niko Matsakis 已提交
401 402 403
        }
    }

404 405
    pub fn instantiate_poly_trait_ref(&self,
        ast_trait_ref: &hir::PolyTraitRef,
406
        self_ty: Ty<'tcx>,
407 408
        poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
        -> ty::PolyTraitRef<'tcx>
409
    {
410 411 412 413
        let trait_ref = &ast_trait_ref.trait_ref;
        let trait_def_id = self.trait_def_id(trait_ref);

        debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
414 415

        let (substs, assoc_bindings) =
416
            self.create_substs_for_ast_trait_ref(trait_ref.path.span,
417 418
                                                 trait_def_id,
                                                 self_ty,
419
                                                 trait_ref.path.segments.last().unwrap());
420 421
        let poly_trait_ref = ty::Binder(ty::TraitRef::new(trait_def_id, substs));

422 423 424
        poly_projections.extend(assoc_bindings.iter().filter_map(|binding| {
            // specify type to assert that error was already reported in Err case:
            let predicate: Result<_, ErrorReported> =
425
                self.ast_type_binding_to_poly_projection_predicate(trait_ref.ref_id,
426 427 428 429
                                                                   poly_trait_ref,
                                                                   binding);
            predicate.ok() // ok to ignore Err() because ErrorReported (see above)
        }));
430

431 432
        debug!("ast_path_to_poly_trait_ref({:?}, projections={:?}) -> {:?}",
               trait_ref, poly_projections, poly_trait_ref);
433
        poly_trait_ref
434 435
    }

436 437 438
    fn ast_path_to_mono_trait_ref(&self,
                                  span: Span,
                                  trait_def_id: DefId,
439
                                  self_ty: Ty<'tcx>,
440 441 442 443
                                  trait_segment: &hir::PathSegment)
                                  -> ty::TraitRef<'tcx>
    {
        let (substs, assoc_bindings) =
444
            self.create_substs_for_ast_trait_ref(span,
445 446 447 448 449 450
                                                 trait_def_id,
                                                 self_ty,
                                                 trait_segment);
        assoc_bindings.first().map(|b| self.tcx().prohibit_projection(b.span));
        ty::TraitRef::new(trait_def_id, substs)
    }
451

452 453 454
    fn create_substs_for_ast_trait_ref(&self,
                                       span: Span,
                                       trait_def_id: DefId,
455
                                       self_ty: Ty<'tcx>,
456 457 458 459 460 461
                                       trait_segment: &hir::PathSegment)
                                       -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
    {
        debug!("create_substs_for_ast_trait_ref(trait_segment={:?})",
               trait_segment);

462
        let trait_def = self.tcx().lookup_trait_def(trait_def_id);
463

464 465
        match trait_segment.parameters {
            hir::AngleBracketedParameters(_) => {
466 467 468
                // For now, require that parenthetical notation be used
                // only with `Fn()` etc.
                if !self.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
469
                    emit_feature_err(&self.tcx().sess.parse_sess,
470 471 472 473 474 475
                                     "unboxed_closures", span, GateIssue::Language,
                                     "\
                        the precise format of `Fn`-family traits' \
                        type parameters is subject to change. \
                        Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
                }
476
            }
477
            hir::ParenthesizedParameters(_) => {
478 479 480
                // For now, require that parenthetical notation be used
                // only with `Fn()` etc.
                if !self.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
481
                    emit_feature_err(&self.tcx().sess.parse_sess,
482 483 484 485
                                     "unboxed_closures", span, GateIssue::Language,
                                     "\
                        parenthetical notation is only stable when used with `Fn`-family traits");
                }
486
            }
487
        }
488

489
        self.create_substs_for_ast_path(span,
490
                                        trait_def_id,
491 492
                                        &trait_segment.parameters,
                                        Some(self_ty))
493
    }
494

495 496 497 498 499 500 501 502 503 504
    fn trait_defines_associated_type_named(&self,
                                           trait_def_id: DefId,
                                           assoc_name: ast::Name)
                                           -> bool
    {
        self.tcx().associated_items(trait_def_id).any(|item| {
            item.kind == ty::AssociatedKind::Type && item.name == assoc_name
        })
    }

505 506
    fn ast_type_binding_to_poly_projection_predicate(
        &self,
507
        _path_id: ast::NodeId,
508
        trait_ref: ty::PolyTraitRef<'tcx>,
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
        binding: &ConvertedBinding<'tcx>)
        -> Result<ty::PolyProjectionPredicate<'tcx>, ErrorReported>
    {
        let tcx = self.tcx();

        // Given something like `U : SomeTrait<T=X>`, we want to produce a
        // predicate like `<U as SomeTrait>::T = X`. This is somewhat
        // subtle in the event that `T` is defined in a supertrait of
        // `SomeTrait`, because in that case we need to upcast.
        //
        // That is, consider this case:
        //
        // ```
        // trait SubTrait : SuperTrait<int> { }
        // trait SuperTrait<A> { type T; }
        //
        // ... B : SubTrait<T=foo> ...
        // ```
        //
        // We want to produce `<B as SuperTrait<int>>::T == foo`.

530 531 532 533 534 535 536 537 538 539 540 541 542
        // Find any late-bound regions declared in `ty` that are not
        // declared in the trait-ref. These are not wellformed.
        //
        // Example:
        //
        //     for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
        //     for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
        let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&trait_ref);
        let late_bound_in_ty = tcx.collect_referenced_late_bound_regions(&ty::Binder(binding.ty));
        debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
        debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
        for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) {
            let br_name = match *br {
543
                ty::BrNamed(_, name) => name,
544 545 546 547 548 549 550
                _ => {
                    span_bug!(
                        binding.span,
                        "anonymous bound region {:?} in binding but not trait ref",
                        br);
                }
            };
551 552 553 554 555 556 557
            struct_span_err!(tcx.sess,
                             binding.span,
                             E0582,
                             "binding for associated type `{}` references lifetime `{}`, \
                              which does not appear in the trait input types",
                             binding.item_name, br_name)
                .emit();
558 559
        }

560 561
        // Simple case: X is defined in the current trait.
        if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
562 563 564 565 566 567 568 569
            return Ok(trait_ref.map_bound(|trait_ref| {
                ty::ProjectionPredicate {
                    projection_ty: ty::ProjectionTy {
                        trait_ref: trait_ref,
                        item_name: binding.item_name,
                    },
                    ty: binding.ty,
                }
570 571 572 573
            }));
        }

        // Otherwise, we have to walk through the supertraits to find
574
        // those that do.
575
        let candidates =
576
            traits::supertraits(tcx, trait_ref.clone())
577
            .filter(|r| self.trait_defines_associated_type_named(r.def_id(), binding.item_name));
578 579 580 581 582 583

        let candidate = self.one_bound_for_assoc_type(candidates,
                                                      &trait_ref.to_string(),
                                                      &binding.item_name.as_str(),
                                                      binding.span)?;

584 585 586 587 588 589 590 591
        Ok(candidate.map_bound(|trait_ref| {
            ty::ProjectionPredicate {
                projection_ty: ty::ProjectionTy {
                    trait_ref: trait_ref,
                    item_name: binding.item_name,
                },
                ty: binding.ty,
            }
592
        }))
593 594
    }

595 596 597 598 599 600
    fn ast_path_to_ty(&self,
        span: Span,
        did: DefId,
        item_segment: &hir::PathSegment)
        -> Ty<'tcx>
    {
601
        let substs = self.ast_path_substs_for_ty(span, did, item_segment);
602
        self.tcx().maps.ty(self.tcx(), span, did).subst(self.tcx(), substs)
603 604
    }

605 606 607 608 609 610
    /// Transform a PolyTraitRef into a PolyExistentialTraitRef by
    /// removing the dummy Self type (TRAIT_OBJECT_DUMMY_SELF).
    fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
                                -> ty::ExistentialTraitRef<'tcx> {
        assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF);
        ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
611
    }
612

613 614 615 616 617 618
    fn conv_object_ty_poly_trait_ref(&self,
        span: Span,
        trait_bounds: &[hir::PolyTraitRef],
        lifetime: &hir::Lifetime)
        -> Ty<'tcx>
    {
619
        let tcx = self.tcx();
620

621 622 623 624 625 626
        if trait_bounds.is_empty() {
            span_err!(tcx.sess, span, E0224,
                      "at least one non-builtin trait is required for an object type");
            return tcx.types.err;
        }

627 628
        let mut projection_bounds = vec![];
        let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF);
629
        let principal = self.instantiate_poly_trait_ref(&trait_bounds[0],
630 631 632
                                                        dummy_self,
                                                        &mut projection_bounds);

633
        let (auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]);
634

635 636 637 638
        if !trait_bounds.is_empty() {
            let b = &trait_bounds[0];
            let span = b.trait_ref.path.span;
            struct_span_err!(self.tcx().sess, span, E0225,
639 640
                "only Send/Sync traits can be used as additional traits in a trait object")
                .span_label(span, &format!("non-Send/Sync additional trait"))
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
                .emit();
        }

        // Erase the dummy_self (TRAIT_OBJECT_DUMMY_SELF) used above.
        let existential_principal = principal.map_bound(|trait_ref| {
            self.trait_ref_to_existential(trait_ref)
        });
        let existential_projections = projection_bounds.iter().map(|bound| {
            bound.map_bound(|b| {
                let p = b.projection_ty;
                ty::ExistentialProjection {
                    trait_ref: self.trait_ref_to_existential(p.trait_ref),
                    item_name: p.item_name,
                    ty: b.ty
                }
            })
657
        });
658

659 660 661 662 663 664 665
        // check that there are no gross object safety violations,
        // most importantly, that the supertraits don't contain Self,
        // to avoid ICE-s.
        let object_safety_violations =
            tcx.astconv_object_safety_violations(principal.def_id());
        if !object_safety_violations.is_empty() {
            tcx.report_object_safety_error(
666 667
                span, principal.def_id(), object_safety_violations)
                .emit();
668 669
            return tcx.types.err;
        }
670

671
        let mut associated_types = FxHashSet::default();
672
        for tr in traits::supertraits(tcx, principal) {
673 674 675
            associated_types.extend(tcx.associated_items(tr.def_id())
                .filter(|item| item.kind == ty::AssociatedKind::Type)
                .map(|item| (tr.def_id(), item.name)));
676
        }
677

678
        for projection_bound in &projection_bounds {
679 680 681 682 683 684
            let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
                        projection_bound.0.projection_ty.item_name);
            associated_types.remove(&pair);
        }

        for (trait_def_id, name) in associated_types {
685
            struct_span_err!(tcx.sess, span, E0191,
686 687
                "the value of the associated type `{}` (from the trait `{}`) must be specified",
                        name,
688 689 690 691
                        tcx.item_path_str(trait_def_id))
                        .span_label(span, &format!(
                            "missing associated type `{}` value", name))
                        .emit();
692
        }
693

694 695 696 697 698 699 700 701 702 703
        let mut v =
            iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder()))
            .chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait))
            .chain(existential_projections
                   .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder())))
            .collect::<AccumulateVec<[_; 8]>>();
        v.sort_by(|a, b| a.cmp(tcx, b));
        let existential_predicates = ty::Binder(tcx.mk_existential_predicates(v.into_iter()));


704 705 706 707 708
        // Explicitly specified region bound. Use that.
        let region_bound = if !lifetime.is_elided() {
            self.ast_region_to_region(lifetime, None)
        } else {
            self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
709 710 711 712 713
                if tcx.named_region_map.defs.contains_key(&lifetime.id) {
                    self.ast_region_to_region(lifetime, None)
                } else {
                    self.re_infer(span, None).unwrap_or_else(|| {
                        span_err!(tcx.sess, span, E0228,
714 715
                                  "the lifetime bound for this object type cannot be deduced \
                                   from context; please supply an explicit bound");
716 717 718
                        tcx.mk_region(ty::ReStatic)
                    })
                }
719
            })
720 721 722 723 724
        };

        debug!("region_bound: {:?}", region_bound);

        let ty = tcx.mk_dynamic(existential_predicates, region_bound);
725 726
        debug!("trait_object_type: {:?}", ty);
        ty
727 728
    }

729 730 731 732 733
    fn report_ambiguous_associated_type(&self,
                                        span: Span,
                                        type_str: &str,
                                        trait_str: &str,
                                        name: &str) {
K
Keith Yeung 已提交
734 735 736 737 738 739
        struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type")
            .span_label(span, &format!("ambiguous associated type"))
            .note(&format!("specify the type using the syntax `<{} as {}>::{}`",
                  type_str, trait_str, name))
            .emit();

740
    }
741

742
    // Search for a bound on a type parameter which includes the associated item
743 744
    // given by `assoc_name`. `ty_param_def_id` is the `DefId` for the type parameter
    // This function will fail if there are no suitable bounds or there is
745 746
    // any ambiguity.
    fn find_bound_for_assoc_item(&self,
747
                                 ty_param_def_id: DefId,
748 749 750 751 752
                                 assoc_name: ast::Name,
                                 span: Span)
                                 -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
    {
        let tcx = self.tcx();
753

754
        let bounds: Vec<_> = self.get_type_parameter_bounds(span, ty_param_def_id)
755
            .predicates.into_iter().filter_map(|p| p.to_opt_poly_trait_ref()).collect();
756

757 758
        // Check that there is exactly one way to find an associated type with the
        // correct name.
759
        let suitable_bounds =
760
            traits::transitive_bounds(tcx, &bounds)
761
            .filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
762

763 764
        let param_node_id = tcx.hir.as_local_node_id(ty_param_def_id).unwrap();
        let param_name = tcx.hir.ty_param_name(param_node_id);
765
        self.one_bound_for_assoc_type(suitable_bounds,
766
                                      &param_name.as_str(),
767 768
                                      &assoc_name.as_str(),
                                      span)
769
    }
770

771

772 773
    // Checks that bounds contains exactly one element and reports appropriate
    // errors otherwise.
774 775
    fn one_bound_for_assoc_type<I>(&self,
                                mut bounds: I,
776 777 778 779
                                ty_param_name: &str,
                                assoc_name: &str,
                                span: Span)
        -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
780
        where I: Iterator<Item=ty::PolyTraitRef<'tcx>>
781
    {
782 783 784 785 786 787 788 789 790 791 792 793
        let bound = match bounds.next() {
            Some(bound) => bound,
            None => {
                struct_span_err!(self.tcx().sess, span, E0220,
                          "associated type `{}` not found for `{}`",
                          assoc_name,
                          ty_param_name)
                  .span_label(span, &format!("associated type `{}` not found", assoc_name))
                  .emit();
                return Err(ErrorReported);
            }
        };
M
Mikhail Modin 已提交
794

795 796
        if let Some(bound2) = bounds.next() {
            let bounds = iter::once(bound).chain(iter::once(bound2)).chain(bounds);
797 798 799 800 801 802
            let mut err = struct_span_err!(
                self.tcx().sess, span, E0221,
                "ambiguous associated type `{}` in bounds of `{}`",
                assoc_name,
                ty_param_name);
            err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
803

804 805 806 807
            for bound in bounds {
                let bound_span = self.tcx().associated_items(bound.def_id()).find(|item| {
                    item.kind == ty::AssociatedKind::Type && item.name == assoc_name
                })
808
                .and_then(|item| self.tcx().hir.span_if_local(item.def_id));
809 810

                if let Some(span) = bound_span {
M
Mikhail Modin 已提交
811 812
                    err.span_label(span, &format!("ambiguous `{}` from `{}`",
                                                  assoc_name,
813
                                                  bound));
M
Mikhail Modin 已提交
814 815 816 817
                } else {
                    span_note!(&mut err, span,
                               "associated type `{}` could derive from `{}`",
                               ty_param_name,
818
                               bound);
M
Mikhail Modin 已提交
819
                }
820 821
            }
            err.emit();
822 823
        }

824
        return Ok(bound);
825
    }
826

827 828 829 830 831 832
    // Create a type from a path to an associated type.
    // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
    // and item_segment is the path segment for D. We return a type and a def for
    // the whole path.
    // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
    // parameter or Self.
833
    pub fn associated_path_def_to_ty(&self,
834
                                     ref_id: ast::NodeId,
835 836 837 838 839
                                     span: Span,
                                     ty: Ty<'tcx>,
                                     ty_path_def: Def,
                                     item_segment: &hir::PathSegment)
                                     -> (Ty<'tcx>, Def)
840 841
    {
        let tcx = self.tcx();
V
Vadim Petrochenkov 已提交
842
        let assoc_name = item_segment.name;
843 844 845 846 847 848 849 850

        debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);

        tcx.prohibit_type_params(slice::ref_slice(item_segment));

        // Find the type of the associated item, and the trait where the associated
        // item is declared.
        let bound = match (&ty.sty, ty_path_def) {
851
            (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
852 853
                // `Self` in an impl of a trait - we have a concrete self type and a
                // trait reference.
854 855 856 857 858 859
                let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
                    Some(trait_ref) => trait_ref,
                    None => {
                        // A cycle error occurred, most likely.
                        return (tcx.types.err, Def::Err);
                    }
860
                };
861

862 863 864 865 866 867
                let trait_ref = if let Some(free_substs) = self.get_free_substs() {
                    trait_ref.subst(tcx, free_substs)
                } else {
                    trait_ref
                };

868
                let candidates =
869 870
                    traits::supertraits(tcx, ty::Binder(trait_ref))
                    .filter(|r| self.trait_defines_associated_type_named(r.def_id(),
871
                                                                         assoc_name));
872 873 874 875 876 877

                match self.one_bound_for_assoc_type(candidates,
                                                    "Self",
                                                    &assoc_name.as_str(),
                                                    span) {
                    Ok(bound) => bound,
878
                    Err(ErrorReported) => return (tcx.types.err, Def::Err),
879
                }
880
            }
881
            (&ty::TyParam(_), Def::SelfTy(Some(param_did), None)) |
882
            (&ty::TyParam(_), Def::TyParam(param_did)) => {
883
                match self.find_bound_for_assoc_item(param_did, assoc_name, span) {
884
                    Ok(bound) => bound,
885
                    Err(ErrorReported) => return (tcx.types.err, Def::Err),
886
                }
887
            }
888
            _ => {
889 890 891 892 893 894 895
                // Don't print TyErr to the user.
                if !ty.references_error() {
                    self.report_ambiguous_associated_type(span,
                                                          &ty.to_string(),
                                                          "Trait",
                                                          &assoc_name.as_str());
                }
896
                return (tcx.types.err, Def::Err);
897
            }
898
        };
899

900 901 902
        let trait_did = bound.0.def_id;
        let ty = self.projected_ty_from_poly_trait_ref(span, bound, assoc_name);

903
        let item = tcx.associated_items(trait_did).find(|i| i.name == assoc_name);
904 905 906
        let def_id = item.expect("missing associated type").def_id;
        tcx.check_stability(def_id, ref_id, span);
        (ty, Def::AssociatedTy(def_id))
907
    }
908

909 910 911 912 913 914 915 916 917
    fn qpath_to_ty(&self,
                   span: Span,
                   opt_self_ty: Option<Ty<'tcx>>,
                   trait_def_id: DefId,
                   trait_segment: &hir::PathSegment,
                   item_segment: &hir::PathSegment)
                   -> Ty<'tcx>
    {
        let tcx = self.tcx();
918

919
        tcx.prohibit_type_params(slice::ref_slice(item_segment));
920

921 922 923 924 925 926 927
        let self_ty = if let Some(ty) = opt_self_ty {
            ty
        } else {
            let path_str = tcx.item_path_str(trait_def_id);
            self.report_ambiguous_associated_type(span,
                                                  "Type",
                                                  &path_str,
V
Vadim Petrochenkov 已提交
928
                                                  &item_segment.name.as_str());
929 930
            return tcx.types.err;
        };
931

932
        debug!("qpath_to_ty: self_type={:?}", self_ty);
933

934
        let trait_ref = self.ast_path_to_mono_trait_ref(span,
935
                                                        trait_def_id,
936
                                                        self_ty,
937
                                                        trait_segment);
938

939
        debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
940

V
Vadim Petrochenkov 已提交
941
        self.projected_ty(span, trait_ref, item_segment.name)
942
    }
943

944
    // Check a type Path and convert it to a Ty.
945 946
    pub fn def_to_ty(&self,
                     opt_self_ty: Option<Ty<'tcx>>,
947
                     path: &hir::Path,
948 949
                     permit_variants: bool)
                     -> Ty<'tcx> {
950 951
        let tcx = self.tcx();

952
        debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})",
953
               path.def, opt_self_ty, path.segments);
954

955 956
        let span = path.span;
        match path.def {
957
            Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
958
                assert_eq!(opt_self_ty, None);
959
                tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
960
                self.ast_path_to_ty(span, did, path.segments.last().unwrap())
961
            }
V
Vadim Petrochenkov 已提交
962 963 964
            Def::Variant(did) if permit_variants => {
                // Convert "variant type" as if it were a real type.
                // The resulting `Ty` is type of the variant's enum for now.
965
                assert_eq!(opt_self_ty, None);
966
                tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
967
                self.ast_path_to_ty(span,
V
Vadim Petrochenkov 已提交
968
                                    tcx.parent_def_id(did).unwrap(),
969
                                    path.segments.last().unwrap())
V
Vadim Petrochenkov 已提交
970
            }
971
            Def::TyParam(did) => {
972
                assert_eq!(opt_self_ty, None);
973
                tcx.prohibit_type_params(&path.segments);
974

975
                let node_id = tcx.hir.as_local_node_id(did).unwrap();
976 977
                let item_id = tcx.hir.get_parent_node(node_id);
                let item_def_id = tcx.hir.local_def_id(item_id);
978
                let generics = tcx.item_generics(item_def_id);
979 980
                let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index];
                tcx.mk_param(index, tcx.hir.name(node_id))
981
            }
982
            Def::SelfTy(_, Some(def_id)) => {
983
                // Self in impl (we know the concrete type).
984

985
                assert_eq!(opt_self_ty, None);
986
                tcx.prohibit_type_params(&path.segments);
987

988
                let ty = tcx.maps.ty(tcx, span, def_id);
989 990
                if let Some(free_substs) = self.get_free_substs() {
                    ty.subst(tcx, free_substs)
991
                } else {
992
                    ty
993 994 995 996
                }
            }
            Def::SelfTy(Some(_), None) => {
                // Self in trait.
997
                assert_eq!(opt_self_ty, None);
998
                tcx.prohibit_type_params(&path.segments);
999 1000
                tcx.mk_self_type()
            }
1001
            Def::AssociatedTy(def_id) => {
1002
                tcx.prohibit_type_params(&path.segments[..path.segments.len()-2]);
1003
                let trait_did = tcx.parent_def_id(def_id).unwrap();
1004
                self.qpath_to_ty(span,
1005 1006
                                 opt_self_ty,
                                 trait_did,
1007 1008
                                 &path.segments[path.segments.len()-2],
                                 path.segments.last().unwrap())
1009 1010
            }
            Def::PrimTy(prim_ty) => {
1011
                assert_eq!(opt_self_ty, None);
1012
                tcx.prim_ty_to_ty(&path.segments, prim_ty)
1013 1014 1015 1016 1017
            }
            Def::Err => {
                self.set_tainted_by_errors();
                return self.tcx().types.err;
            }
1018
            _ => span_bug!(span, "unexpected definition: {:?}", path.def)
1019
        }
1020
    }
1021

1022 1023
    /// Parses the programmer's textual representation of a type into our
    /// internal notion of a type.
1024
    pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
1025 1026
        debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
               ast_ty.id, ast_ty);
1027

1028
        let tcx = self.tcx();
1029

1030
        let cache = self.ast_ty_to_ty_cache();
1031 1032
        if let Some(ty) = cache.borrow().get(&ast_ty.id) {
            return ty;
1033 1034 1035
        }

        let result_ty = match ast_ty.node {
1036
            hir::TySlice(ref ty) => {
1037
                tcx.mk_slice(self.ast_ty_to_ty(&ty))
1038
            }
1039 1040
            hir::TyPtr(ref mt) => {
                tcx.mk_ptr(ty::TypeAndMut {
1041
                    ty: self.ast_ty_to_ty(&mt.ty),
1042 1043 1044 1045
                    mutbl: mt.mutbl
                })
            }
            hir::TyRptr(ref region, ref mt) => {
1046
                let r = self.ast_region_to_region(region, None);
1047
                debug!("TyRef r={:?}", r);
1048
                let t = self.ast_ty_to_ty(&mt.ty);
1049
                tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
1050
            }
A
Andrew Cann 已提交
1051 1052
            hir::TyNever => {
                tcx.types.never
1053
            },
1054
            hir::TyTup(ref fields) => {
A
Andrew Cann 已提交
1055
                tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)), false)
1056 1057 1058
            }
            hir::TyBareFn(ref bf) => {
                require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
1059
                let bare_fn_ty = self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl);
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074

                // Find any late-bound regions declared in return type that do
                // not appear in the arguments. These are not wellformed.
                //
                // Example:
                //
                //     for<'a> fn() -> &'a str <-- 'a is bad
                //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
                //
                // Note that we do this check **here** and not in
                // `ty_of_bare_fn` because the latter is also used to make
                // the types for fn items, and we do not want to issue a
                // warning then. (Once we fix #32330, the regions we are
                // checking for here would be considered early bound
                // anyway.)
1075
                let inputs = bare_fn_ty.inputs();
1076 1077
                let late_bound_in_args = tcx.collect_constrained_late_bound_regions(
                    &inputs.map_bound(|i| i.to_owned()));
1078
                let output = bare_fn_ty.output();
1079 1080 1081
                let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
                for br in late_bound_in_ret.difference(&late_bound_in_args) {
                    let br_name = match *br {
1082
                        ty::BrNamed(_, name) => name,
1083 1084 1085 1086 1087 1088 1089
                        _ => {
                            span_bug!(
                                bf.decl.output.span(),
                                "anonymous bound region {:?} in return but not args",
                                br);
                        }
                    };
1090 1091 1092 1093 1094 1095 1096
                    struct_span_err!(tcx.sess,
                                     ast_ty.span,
                                     E0581,
                                     "return type references lifetime `{}`, \
                                      which does not appear in the fn input types",
                                     br_name)
                        .emit();
1097 1098
                }
                tcx.mk_fn_ptr(bare_fn_ty)
1099
            }
1100
            hir::TyTraitObject(ref bounds, ref lifetime) => {
1101
                self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
1102
            }
1103
            hir::TyImplTrait(_) => {
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
                // Figure out if we can allow an `impl Trait` here, by walking up
                // to a `fn` or inherent `impl` method, going only through `Ty`
                // or `TraitRef` nodes (as nothing else should be in types) and
                // ensuring that we reach the `fn`/method signature's return type.
                let mut node_id = ast_ty.id;
                let fn_decl = loop {
                    let parent = tcx.hir.get_parent_node(node_id);
                    match tcx.hir.get(parent) {
                        hir::map::NodeItem(&hir::Item {
                            node: hir::ItemFn(ref fn_decl, ..), ..
                        }) => break Some(fn_decl),

                        hir::map::NodeImplItem(&hir::ImplItem {
                            node: hir::ImplItemKind::Method(ref sig, _), ..
                        }) => {
                            match tcx.hir.expect_item(tcx.hir.get_parent(parent)).node {
                                hir::ItemImpl(.., None, _, _) => {
                                    break Some(&sig.decl)
                                }
                                _ => break None
                            }
                        }

                        hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => {}

                        _ => break None
                    }
                    node_id = parent;
                };
                let allow = fn_decl.map_or(false, |fd| {
                    match fd.output {
                        hir::DefaultReturn(_) => false,
                        hir::Return(ref ty) => ty.id == node_id
                    }
                });

1140
                // Create the anonymized type.
1141 1142
                if allow {
                    let def_id = tcx.hir.local_def_id(ast_ty.id);
1143
                    tcx.mk_anon(def_id, Substs::identity_for_item(tcx, def_id))
1144 1145 1146 1147
                } else {
                    span_err!(tcx.sess, ast_ty.span, E0562,
                              "`impl Trait` not allowed outside of function \
                               and inherent method return types");
1148 1149
                    tcx.types.err
                }
1150
            }
1151
            hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
1152
                debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
1153
                let opt_self_ty = maybe_qself.as_ref().map(|qself| {
1154
                    self.ast_ty_to_ty(qself)
1155
                });
1156
                self.def_to_ty(opt_self_ty, path, false)
1157 1158 1159
            }
            hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => {
                debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
1160
                let ty = self.ast_ty_to_ty(qself);
1161

1162 1163 1164 1165 1166
                let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
                    path.def
                } else {
                    Def::Err
                };
1167
                self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
1168
            }
1169
            hir::TyArray(ref ty, length) => {
1170
                if let Ok(length) = eval_length(tcx.global_tcx(), length, "array length") {
1171
                    tcx.mk_array(self.ast_ty_to_ty(&ty), length)
1172 1173
                } else {
                    self.tcx().types.err
1174 1175
                }
            }
1176
            hir::TyTypeof(ref _e) => {
G
Gavin Baker 已提交
1177 1178 1179 1180 1181
                struct_span_err!(tcx.sess, ast_ty.span, E0516,
                                 "`typeof` is a reserved keyword but unimplemented")
                    .span_label(ast_ty.span, &format!("reserved keyword"))
                    .emit();

1182 1183 1184 1185 1186 1187 1188
                tcx.types.err
            }
            hir::TyInfer => {
                // TyInfer also appears as the type of arguments or return
                // values in a ExprClosure, or as
                // the type of local variables. Both of these cases are
                // handled specially and will not descend into this routine.
1189
                self.ty_infer(ast_ty.span)
1190
            }
1191 1192 1193 1194 1195
        };

        cache.borrow_mut().insert(ast_ty.id, result_ty);

        result_ty
1196
    }
1197

1198
    pub fn ty_of_arg(&self,
1199
                     ty: &hir::Ty,
1200 1201 1202
                     expected_ty: Option<Ty<'tcx>>)
                     -> Ty<'tcx>
    {
1203
        match ty.node {
1204
            hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
1205
            hir::TyInfer => self.ty_infer(ty.span),
1206
            _ => self.ast_ty_to_ty(ty),
1207
        }
1208
    }
1209

1210 1211 1212
    pub fn ty_of_fn(&self,
                    unsafety: hir::Unsafety,
                    abi: abi::Abi,
1213
                    decl: &hir::FnDecl)
1214
                    -> ty::PolyFnSig<'tcx> {
1215
        debug!("ty_of_fn");
1216

1217
        let input_tys: Vec<Ty> =
1218
            decl.inputs.iter().map(|a| self.ty_of_arg(a, None)).collect();
1219

1220
        let output_ty = match decl.output {
1221
            hir::Return(ref output) => self.ast_ty_to_ty(output),
1222
            hir::DefaultReturn(..) => self.tcx().mk_nil(),
1223
        };
1224

1225
        debug!("ty_of_fn: output_ty={:?}", output_ty);
1226

1227 1228 1229 1230 1231 1232 1233
        ty::Binder(self.tcx().mk_fn_sig(
            input_tys.into_iter(),
            output_ty,
            decl.variadic,
            unsafety,
            abi
        ))
1234
    }
1235

1236 1237 1238 1239 1240
    pub fn ty_of_closure(&self,
        unsafety: hir::Unsafety,
        decl: &hir::FnDecl,
        abi: abi::Abi,
        expected_sig: Option<ty::FnSig<'tcx>>)
1241
        -> ty::PolyFnSig<'tcx>
1242 1243 1244 1245
    {
        debug!("ty_of_closure(expected_sig={:?})",
               expected_sig);

1246
        let input_tys = decl.inputs.iter().enumerate().map(|(i, a)| {
1247 1248 1249
            let expected_arg_ty = expected_sig.as_ref().and_then(|e| {
                // no guarantee that the correct number of expected args
                // were supplied
1250 1251
                if i < e.inputs().len() {
                    Some(e.inputs()[i])
1252 1253 1254 1255
                } else {
                    None
                }
            });
1256
            self.ty_of_arg(a, expected_arg_ty)
1257
        });
1258

1259
        let expected_ret_ty = expected_sig.as_ref().map(|e| e.output());
J
Jakub Bukaj 已提交
1260

1261 1262 1263 1264 1265
        let is_infer = match decl.output {
            hir::Return(ref output) if output.node == hir::TyInfer => true,
            hir::DefaultReturn(..) => true,
            _ => false
        };
1266

1267 1268 1269
        let output_ty = match decl.output {
            _ if is_infer && expected_ret_ty.is_some() =>
                expected_ret_ty.unwrap(),
1270
            _ if is_infer => self.ty_infer(decl.output.span()),
1271
            hir::Return(ref output) =>
1272
                self.ast_ty_to_ty(&output),
1273 1274
            hir::DefaultReturn(..) => bug!(),
        };
1275

1276
        debug!("ty_of_closure: output_ty={:?}", output_ty);
1277

1278 1279 1280 1281 1282 1283 1284
        ty::Binder(self.tcx().mk_fn_sig(
            input_tys,
            output_ty,
            decl.variadic,
            unsafety,
            abi
        ))
1285
    }
1286

1287 1288 1289 1290 1291 1292 1293
    /// Given the bounds on an object, determines what single region bound (if any) we can
    /// use to summarize this type. The basic idea is that we will use the bound the user
    /// provided, if they provided one, and otherwise search the supertypes of trait bounds
    /// for region bounds. It may be that we can derive no bound at all, in which case
    /// we return `None`.
    fn compute_object_lifetime_bound(&self,
        span: Span,
1294
        existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
1295
        -> Option<&'tcx ty::Region> // if None, use the default
1296 1297
    {
        let tcx = self.tcx();
1298

1299
        debug!("compute_opt_region_bound(existential_predicates={:?})",
1300
               existential_predicates);
1301

1302 1303 1304
        // No explicit region bound specified. Therefore, examine trait
        // bounds and see if we can derive region bounds from those.
        let derived_region_bounds =
1305
            object_region_bounds(tcx, existential_predicates);
1306

1307 1308 1309 1310 1311
        // If there are no derived region bounds, then report back that we
        // can find no region bound. The caller will use the default.
        if derived_region_bounds.is_empty() {
            return None;
        }
1312

1313 1314
        // If any of the derived region bounds are 'static, that is always
        // the best choice.
1315 1316
        if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
            return Some(tcx.mk_region(ty::ReStatic));
1317
        }
1318

1319 1320 1321 1322 1323 1324 1325 1326 1327
        // Determine whether there is exactly one unique region in the set
        // of derived region bounds. If so, use that. Otherwise, report an
        // error.
        let r = derived_region_bounds[0];
        if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
            span_err!(tcx.sess, span, E0227,
                      "ambiguous lifetime bound, explicit lifetime bound required");
        }
        return Some(r);
1328
    }
1329
}
1330

1331 1332 1333
/// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
/// remaining general trait bounds.
fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1334
                                         trait_bounds: &'b [hir::PolyTraitRef])
1335 1336
    -> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
{
1337
    let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373
        match bound.trait_ref.path.def {
            Def::Trait(trait_did) => {
                // Checks whether `trait_did` refers to one of the builtin
                // traits, like `Send`, and adds it to `auto_traits` if so.
                if Some(trait_did) == tcx.lang_items.send_trait() ||
                    Some(trait_did) == tcx.lang_items.sync_trait() {
                    let segments = &bound.trait_ref.path.segments;
                    let parameters = &segments[segments.len() - 1].parameters;
                    if !parameters.types().is_empty() {
                        check_type_argument_count(tcx, bound.trait_ref.path.span,
                                                  parameters.types().len(), &[]);
                    }
                    if !parameters.lifetimes().is_empty() {
                        report_lifetime_number_error(tcx, bound.trait_ref.path.span,
                                                     parameters.lifetimes().len(), 0);
                    }
                    true
                } else {
                    false
                }
            }
            _ => false
        }
    });

    let auto_traits = auto_traits.into_iter().map(|tr| {
        if let Def::Trait(trait_did) = tr.trait_ref.path.def {
            trait_did
        } else {
            unreachable!()
        }
    }).collect::<Vec<_>>();

    (auto_traits, trait_bounds)
}

1374
fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
1375 1376
                             ty_param_defs: &[ty::TypeParameterDef]) {
    let accepted = ty_param_defs.len();
1377
    let required = ty_param_defs.iter().take_while(|x| !x.has_default).count();
1378 1379 1380 1381 1382 1383
    if supplied < required {
        let expected = if required < accepted {
            "expected at least"
        } else {
            "expected"
        };
1384
        let arguments_plural = if required == 1 { "" } else { "s" };
1385 1386 1387 1388 1389 1390 1391 1392 1393

        struct_span_err!(tcx.sess, span, E0243,
                "wrong number of type arguments: {} {}, found {}",
                expected, required, supplied)
            .span_label(span,
                &format!("{} {} type argument{}",
                    expected,
                    required,
                    arguments_plural))
1394
            .emit();
1395
    } else if supplied > accepted {
1396
        let expected = if required < accepted {
1397
            format!("expected at most {}", accepted)
1398
        } else {
1399
            format!("expected {}", accepted)
1400
        };
1401
        let arguments_plural = if accepted == 1 { "" } else { "s" };
1402

1403 1404 1405
        struct_span_err!(tcx.sess, span, E0244,
                "wrong number of type arguments: {}, found {}",
                expected, supplied)
1406 1407
            .span_label(
                span,
1408 1409 1410
                &format!("{} type argument{}",
                    if accepted == 0 { "expected no" } else { &expected },
                    arguments_plural)
1411 1412
            )
            .emit();
1413 1414 1415
    }
}

1416
fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
O
Omer Sheikh 已提交
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
    let label = if number < expected {
        if expected == 1 {
            format!("expected {} lifetime parameter", expected)
        } else {
            format!("expected {} lifetime parameters", expected)
        }
    } else {
        let additional = number - expected;
        if additional == 1 {
            "unexpected lifetime parameter".to_string()
        } else {
            format!("{} unexpected lifetime parameters", additional)
        }
    };
    struct_span_err!(tcx.sess, span, E0107,
                     "wrong number of lifetime parameters: expected {}, found {}",
                     expected, number)
        .span_label(span, &label)
        .emit();
1436
}
1437 1438 1439 1440 1441

// A helper struct for conveniently grouping a set of bounds which we pass to
// and return from functions in multiple places.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Bounds<'tcx> {
1442
    pub region_bounds: Vec<&'tcx ty::Region>,
1443
    pub implicitly_sized: bool,
1444 1445 1446 1447
    pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
    pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
}

1448 1449
impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
1450
                      -> Vec<ty::Predicate<'tcx>>
1451 1452 1453
    {
        let mut vec = Vec::new();

1454 1455 1456 1457 1458 1459 1460 1461 1462
        // If it could be sized, and is, add the sized predicate
        if self.implicitly_sized {
            if let Some(sized) = tcx.lang_items.sized_trait() {
                let trait_ref = ty::TraitRef {
                    def_id: sized,
                    substs: tcx.mk_substs_trait(param_ty, &[])
                };
                vec.push(trait_ref.to_predicate());
            }
1463 1464 1465 1466 1467
        }

        for &region_bound in &self.region_bounds {
            // account for the binder being introduced below; no need to shift `param_ty`
            // because, at present at least, it can only refer to early-bound regions
1468
            let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
1469
            vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
1470 1471 1472
        }

        for bound_trait_ref in &self.trait_bounds {
1473
            vec.push(bound_trait_ref.to_predicate());
1474 1475 1476
        }

        for projection in &self.projection_bounds {
1477
            vec.push(projection.to_predicate());
1478 1479 1480 1481 1482
        }

        vec
    }
}
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524

pub enum ExplicitSelf<'tcx> {
    ByValue,
    ByReference(&'tcx ty::Region, hir::Mutability),
    ByBox
}

impl<'tcx> ExplicitSelf<'tcx> {
    /// We wish to (for now) categorize an explicit self
    /// declaration like `self: SomeType` into either `self`,
    /// `&self`, `&mut self`, or `Box<self>`. We do this here
    /// by some simple pattern matching. A more precise check
    /// is done later in `check_method_self_type()`.
    ///
    /// Examples:
    ///
    /// ```
    /// impl Foo for &T {
    ///     // Legal declarations:
    ///     fn method1(self: &&T); // ExplicitSelf::ByReference
    ///     fn method2(self: &T); // ExplicitSelf::ByValue
    ///     fn method3(self: Box<&T>); // ExplicitSelf::ByBox
    ///
    ///     // Invalid cases will be caught later by `check_method_self_type`:
    ///     fn method_err1(self: &mut T); // ExplicitSelf::ByReference
    /// }
    /// ```
    ///
    /// To do the check we just count the number of "modifiers"
    /// on each type and compare them. If they are the same or
    /// the impl has more, we call it "by value". Otherwise, we
    /// look at the outermost modifier on the method decl and
    /// call it by-ref, by-box as appropriate. For method1, for
    /// example, the impl type has one modifier, but the method
    /// type has two, so we end up with
    /// ExplicitSelf::ByReference.
    pub fn determine(untransformed_self_ty: Ty<'tcx>,
                     self_arg_ty: Ty<'tcx>)
                     -> ExplicitSelf<'tcx> {
        fn count_modifiers(ty: Ty) -> usize {
            match ty.sty {
                ty::TyRef(_, mt) => count_modifiers(mt.ty) + 1,
1525
                ty::TyAdt(def, _) if def.is_box() => count_modifiers(ty.boxed_ty()) + 1,
1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537
                _ => 0,
            }
        }

        let impl_modifiers = count_modifiers(untransformed_self_ty);
        let method_modifiers = count_modifiers(self_arg_ty);

        if impl_modifiers >= method_modifiers {
            ExplicitSelf::ByValue
        } else {
            match self_arg_ty.sty {
                ty::TyRef(r, mt) => ExplicitSelf::ByReference(r, mt.mutbl),
1538
                ty::TyAdt(def, _) if def.is_box() => ExplicitSelf::ByBox,
1539 1540 1541 1542 1543
                _ => ExplicitSelf::ByValue,
            }
        }
    }
}