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 ty::queries::ty::get(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 314
                    ty::queries::ty::get(tcx, span, def.def_id)
                        .subst_spanned(tcx, substs, Some(span))
315
                }
316
            } else {
317 318
                // We've already errored above about the mismatch.
                tcx.types.err
S
Sean Bowe 已提交
319
            }
320
        });
S
Sean Bowe 已提交
321

322 323 324 325 326
        let assoc_bindings = match *parameters {
            hir::AngleBracketedParameters(ref data) => {
                data.bindings.iter().map(|b| {
                    ConvertedBinding {
                        item_name: b.name,
327
                        ty: self.ast_ty_to_ty(&b.ty),
328 329 330 331 332 333 334 335
                        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.
336
                    self.convert_parenthesized_parameters(data).1
337 338
                })]
            }
339
        };
S
Sean Bowe 已提交
340

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

344
        (substs, assoc_bindings)
345
    }
346

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

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

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

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

373 374 375 376 377 378 379 380
    /// 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,
381
        self_ty: Ty<'tcx>)
382 383 384
        -> ty::TraitRef<'tcx>
    {
        let trait_def_id = self.trait_def_id(trait_ref);
385
        self.ast_path_to_mono_trait_ref(trait_ref.path.span,
386 387 388 389
                                        trait_def_id,
                                        self_ty,
                                        trait_ref.path.segments.last().unwrap())
    }
390

391 392
    fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
        let path = &trait_ref.path;
393
        match path.def {
394 395 396 397 398 399
            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",
400
                            self.tcx().hir.node_to_pretty_string(trait_ref.ref_id));
401
            }
N
Niko Matsakis 已提交
402 403 404
        }
    }

405 406
    pub fn instantiate_poly_trait_ref(&self,
        ast_trait_ref: &hir::PolyTraitRef,
407
        self_ty: Ty<'tcx>,
408 409
        poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
        -> ty::PolyTraitRef<'tcx>
410
    {
411 412 413 414
        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);
415 416

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

423 424 425
        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> =
426
                self.ast_type_binding_to_poly_projection_predicate(trait_ref.ref_id,
427 428 429 430
                                                                   poly_trait_ref,
                                                                   binding);
            predicate.ok() // ok to ignore Err() because ErrorReported (see above)
        }));
431

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

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

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

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

465 466
        match trait_segment.parameters {
            hir::AngleBracketedParameters(_) => {
467 468 469
                // For now, require that parenthetical notation be used
                // only with `Fn()` etc.
                if !self.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
470
                    emit_feature_err(&self.tcx().sess.parse_sess,
471 472 473 474 475 476
                                     "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");
                }
477
            }
478
            hir::ParenthesizedParameters(_) => {
479 480 481
                // For now, require that parenthetical notation be used
                // only with `Fn()` etc.
                if !self.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
482
                    emit_feature_err(&self.tcx().sess.parse_sess,
483 484 485 486
                                     "unboxed_closures", span, GateIssue::Language,
                                     "\
                        parenthetical notation is only stable when used with `Fn`-family traits");
                }
487
            }
488
        }
489

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

496 497 498 499 500 501 502 503 504 505
    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
        })
    }

506 507
    fn ast_type_binding_to_poly_projection_predicate(
        &self,
508
        _path_id: ast::NodeId,
509
        trait_ref: ty::PolyTraitRef<'tcx>,
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
        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`.

531 532 533 534 535 536 537 538 539 540 541 542 543
        // 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 {
544
                ty::BrNamed(_, name) => name,
545 546 547 548 549 550 551
                _ => {
                    span_bug!(
                        binding.span,
                        "anonymous bound region {:?} in binding but not trait ref",
                        br);
                }
            };
552 553 554 555 556 557 558
            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();
559 560
        }

561 562
        // Simple case: X is defined in the current trait.
        if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
563 564 565 566 567 568 569 570
            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,
                }
571 572 573 574
            }));
        }

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

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

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

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

606 607 608 609 610 611
    /// 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)
612
    }
613

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

622 623 624 625 626 627
        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;
        }

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

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

636 637 638 639
        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,
640 641
                "only Send/Sync traits can be used as additional traits in a trait object")
                .span_label(span, &format!("non-Send/Sync additional trait"))
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
                .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
                }
            })
658
        });
659

660 661 662 663 664 665 666
        // 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(
667 668
                span, principal.def_id(), object_safety_violations)
                .emit();
669 670
            return tcx.types.err;
        }
671

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

679
        for projection_bound in &projection_bounds {
680 681 682 683 684 685
            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 {
686
            struct_span_err!(tcx.sess, span, E0191,
687 688
                "the value of the associated type `{}` (from the trait `{}`) must be specified",
                        name,
689 690 691 692
                        tcx.item_path_str(trait_def_id))
                        .span_label(span, &format!(
                            "missing associated type `{}` value", name))
                        .emit();
693
        }
694

695 696 697 698 699 700 701 702 703 704
        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()));


705 706 707 708 709
        // 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(|| {
710 711 712 713 714
                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,
715 716
                                  "the lifetime bound for this object type cannot be deduced \
                                   from context; please supply an explicit bound");
717 718 719
                        tcx.mk_region(ty::ReStatic)
                    })
                }
720
            })
721 722 723 724 725
        };

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

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

730 731 732 733 734
    fn report_ambiguous_associated_type(&self,
                                        span: Span,
                                        type_str: &str,
                                        trait_str: &str,
                                        name: &str) {
K
Keith Yeung 已提交
735 736 737 738 739 740
        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();

741
    }
742

743
    // Search for a bound on a type parameter which includes the associated item
744 745
    // 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
746 747
    // any ambiguity.
    fn find_bound_for_assoc_item(&self,
748
                                 ty_param_def_id: DefId,
749 750 751 752 753
                                 assoc_name: ast::Name,
                                 span: Span)
                                 -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
    {
        let tcx = self.tcx();
754

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

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

764 765
        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);
766
        self.one_bound_for_assoc_type(suitable_bounds,
767
                                      &param_name.as_str(),
768 769
                                      &assoc_name.as_str(),
                                      span)
770
    }
771

772

773 774
    // Checks that bounds contains exactly one element and reports appropriate
    // errors otherwise.
775 776
    fn one_bound_for_assoc_type<I>(&self,
                                mut bounds: I,
777 778 779 780
                                ty_param_name: &str,
                                assoc_name: &str,
                                span: Span)
        -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
781
        where I: Iterator<Item=ty::PolyTraitRef<'tcx>>
782
    {
783 784 785 786 787 788 789 790 791 792 793 794
        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 已提交
795

796 797
        if let Some(bound2) = bounds.next() {
            let bounds = iter::once(bound).chain(iter::once(bound2)).chain(bounds);
798 799 800 801 802 803
            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));
804

805 806 807 808
            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
                })
809
                .and_then(|item| self.tcx().hir.span_if_local(item.def_id));
810 811

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

825
        return Ok(bound);
826
    }
827

828 829 830 831 832 833
    // 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.
834
    pub fn associated_path_def_to_ty(&self,
835
                                     ref_id: ast::NodeId,
836 837 838 839 840
                                     span: Span,
                                     ty: Ty<'tcx>,
                                     ty_path_def: Def,
                                     item_segment: &hir::PathSegment)
                                     -> (Ty<'tcx>, Def)
841 842
    {
        let tcx = self.tcx();
V
Vadim Petrochenkov 已提交
843
        let assoc_name = item_segment.name;
844 845 846 847 848 849 850 851

        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) {
852
            (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
853 854
                // `Self` in an impl of a trait - we have a concrete self type and a
                // trait reference.
855 856 857 858 859 860
                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);
                    }
861
                };
862

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

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

                match self.one_bound_for_assoc_type(candidates,
                                                    "Self",
                                                    &assoc_name.as_str(),
                                                    span) {
                    Ok(bound) => bound,
879
                    Err(ErrorReported) => return (tcx.types.err, Def::Err),
880
                }
881
            }
882
            (&ty::TyParam(_), Def::SelfTy(Some(param_did), None)) |
883
            (&ty::TyParam(_), Def::TyParam(param_did)) => {
884
                match self.find_bound_for_assoc_item(param_did, assoc_name, span) {
885
                    Ok(bound) => bound,
886
                    Err(ErrorReported) => return (tcx.types.err, Def::Err),
887
                }
888
            }
889
            _ => {
890 891 892 893 894 895 896
                // 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());
                }
897
                return (tcx.types.err, Def::Err);
898
            }
899
        };
900

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

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

910 911 912 913 914 915 916 917 918
    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();
919

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

922 923 924 925 926 927 928
        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 已提交
929
                                                  &item_segment.name.as_str());
930 931
            return tcx.types.err;
        };
932

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

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

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

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

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

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

956 957
        let span = path.span;
        match path.def {
958
            Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
959
                assert_eq!(opt_self_ty, None);
960
                tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
961
                self.ast_path_to_ty(span, did, path.segments.last().unwrap())
962
            }
V
Vadim Petrochenkov 已提交
963 964 965
            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.
966
                assert_eq!(opt_self_ty, None);
967
                tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
968
                self.ast_path_to_ty(span,
V
Vadim Petrochenkov 已提交
969
                                    tcx.parent_def_id(did).unwrap(),
970
                                    path.segments.last().unwrap())
V
Vadim Petrochenkov 已提交
971
            }
972
            Def::TyParam(did) => {
973
                assert_eq!(opt_self_ty, None);
974
                tcx.prohibit_type_params(&path.segments);
975

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

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

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

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

1029
        let tcx = self.tcx();
1030

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

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

                // 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.)
1076
                let inputs = bare_fn_ty.inputs();
1077 1078
                let late_bound_in_args = tcx.collect_constrained_late_bound_regions(
                    &inputs.map_bound(|i| i.to_owned()));
1079
                let output = bare_fn_ty.output();
1080 1081 1082
                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 {
1083
                        ty::BrNamed(_, name) => name,
1084 1085 1086 1087 1088 1089 1090
                        _ => {
                            span_bug!(
                                bf.decl.output.span(),
                                "anonymous bound region {:?} in return but not args",
                                br);
                        }
                    };
1091 1092 1093 1094 1095 1096 1097
                    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();
1098 1099
                }
                tcx.mk_fn_ptr(bare_fn_ty)
1100
            }
1101
            hir::TyTraitObject(ref bounds, ref lifetime) => {
1102
                self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
1103
            }
1104
            hir::TyImplTrait(_) => {
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 1140
                // 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
                    }
                });

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

1163 1164 1165 1166 1167
                let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node {
                    path.def
                } else {
                    Def::Err
                };
1168
                self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0
1169
            }
1170
            hir::TyArray(ref ty, length) => {
1171
                if let Ok(length) = eval_length(tcx.global_tcx(), length, "array length") {
1172
                    tcx.mk_array(self.ast_ty_to_ty(&ty), length)
1173 1174
                } else {
                    self.tcx().types.err
1175 1176
                }
            }
1177
            hir::TyTypeof(ref _e) => {
G
Gavin Baker 已提交
1178 1179 1180 1181 1182
                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();

1183 1184 1185 1186 1187 1188 1189
                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.
1190
                self.ty_infer(ast_ty.span)
1191
            }
1192 1193 1194 1195 1196
        };

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

        result_ty
1197
    }
1198

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

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

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

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

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

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

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

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

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

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

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

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

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

1288 1289 1290 1291 1292 1293 1294
    /// 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,
1295
        existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
1296
        -> Option<&'tcx ty::Region> // if None, use the default
1297 1298
    {
        let tcx = self.tcx();
1299

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

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

1308 1309 1310 1311 1312
        // 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;
        }
1313

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

1320 1321 1322 1323 1324 1325 1326 1327 1328
        // 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);
1329
    }
1330
}
1331

1332 1333 1334
/// 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>,
1335
                                         trait_bounds: &'b [hir::PolyTraitRef])
1336 1337
    -> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
{
1338
    let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
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 1374
        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)
}

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

        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))
1395
            .emit();
1396
    } else if supplied > accepted {
1397
        let expected = if required < accepted {
1398
            format!("expected at most {}", accepted)
1399
        } else {
1400
            format!("expected {}", accepted)
1401
        };
1402
        let arguments_plural = if accepted == 1 { "" } else { "s" };
1403

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

1417
fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
O
Omer Sheikh 已提交
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436
    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();
1437
}
1438 1439 1440 1441 1442

// 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> {
1443
    pub region_bounds: Vec<&'tcx ty::Region>,
1444
    pub implicitly_sized: bool,
1445 1446 1447 1448
    pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
    pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
}

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

1455 1456 1457 1458 1459 1460 1461 1462 1463
        // 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());
            }
1464 1465 1466 1467 1468
        }

        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
1469
            let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
1470
            vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
1471 1472 1473
        }

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

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

        vec
    }
}
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 1525

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,
1526
                ty::TyAdt(def, _) if def.is_box() => count_modifiers(ty.boxed_ty()) + 1,
1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
                _ => 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),
1539
                ty::TyAdt(def, _) if def.is_box() => ExplicitSelf::ByBox,
1540 1541 1542 1543 1544
                _ => ExplicitSelf::ByValue,
            }
        }
    }
}