]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/wfcheck.rs
support `default impl` for specialization
[rust.git] / src / librustc_typeck / check / wfcheck.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use check::{Inherited, FnCtxt};
12 use constrained_type_params::{identify_constrained_type_params, Parameter};
13
14 use hir::def_id::DefId;
15 use rustc::traits::{self, ObligationCauseCode};
16 use rustc::ty::{self, Lift, Ty, TyCtxt};
17 use rustc::ty::util::ExplicitSelf;
18 use rustc::util::nodemap::{FxHashSet, FxHashMap};
19 use rustc::middle::lang_items;
20
21 use syntax::ast;
22 use syntax::feature_gate::{self, GateIssue};
23 use syntax_pos::Span;
24 use errors::{DiagnosticBuilder, DiagnosticId};
25
26 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
27 use rustc::hir;
28 use rustc::ty::TypeFoldable;
29
30 pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> {
31     tcx: TyCtxt<'a, 'tcx, 'tcx>,
32     code: ObligationCauseCode<'tcx>,
33 }
34
35 /// Helper type of a temporary returned by .for_item(...).
36 /// Necessary because we can't write the following bound:
37 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
38 struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
39     inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
40     code: ObligationCauseCode<'gcx>,
41     id: ast::NodeId,
42     span: Span,
43     param_env: ty::ParamEnv<'tcx>,
44 }
45
46 impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
47     fn with_fcx<F>(&'tcx mut self, f: F) where
48         F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>,
49                           &mut CheckTypeWellFormedVisitor<'b, 'gcx>) -> Vec<Ty<'tcx>>
50     {
51         let code = self.code.clone();
52         let id = self.id;
53         let span = self.span;
54         let param_env = self.param_env;
55         self.inherited.enter(|inh| {
56             let fcx = FnCtxt::new(&inh, param_env, id);
57             let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor {
58                 tcx: fcx.tcx.global_tcx(),
59                 code,
60             });
61             fcx.select_all_obligations_or_error();
62             fcx.regionck_item(id, span, &wf_tys);
63         });
64     }
65 }
66
67 impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
68     pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>)
69                -> CheckTypeWellFormedVisitor<'a, 'gcx> {
70         CheckTypeWellFormedVisitor {
71             tcx,
72             code: ObligationCauseCode::MiscObligation
73         }
74     }
75
76     /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
77     /// well-formed, meaning that they do not require any constraints not declared in the struct
78     /// definition itself. For example, this definition would be illegal:
79     ///
80     ///     struct Ref<'a, T> { x: &'a T }
81     ///
82     /// because the type did not declare that `T:'a`.
83     ///
84     /// We do this check as a pre-pass before checking fn bodies because if these constraints are
85     /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
86     /// the types first.
87     fn check_item_well_formed(&mut self, item: &hir::Item) {
88         let tcx = self.tcx;
89         debug!("check_item_well_formed(it.id={}, it.name={})",
90                item.id,
91                tcx.item_path_str(tcx.hir.local_def_id(item.id)));
92
93         match item.node {
94             // Right now we check that every default trait implementation
95             // has an implementation of itself. Basically, a case like:
96             //
97             // `impl Trait for T {}`
98             //
99             // has a requirement of `T: Trait` which was required for default
100             // method implementations. Although this could be improved now that
101             // there's a better infrastructure in place for this, it's being left
102             // for a follow-up work.
103             //
104             // Since there's such a requirement, we need to check *just* positive
105             // implementations, otherwise things like:
106             //
107             // impl !Send for T {}
108             //
109             // won't be allowed unless there's an *explicit* implementation of `Send`
110             // for `T`
111             hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => {
112                 let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id))
113                                  .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
114                 if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
115                     tcx.sess.span_err(item.span, "impls of auto traits cannot be default");
116                 }
117                 if polarity == hir::ImplPolarity::Positive {
118                     self.check_impl(item, self_ty, trait_ref);
119                 } else {
120                     // FIXME(#27579) what amount of WF checking do we need for neg impls?
121                     if trait_ref.is_some() && !is_auto {
122                         span_err!(tcx.sess, item.span, E0192,
123                                   "negative impls are only allowed for \
124                                    auto traits (e.g., `Send` and `Sync`)")
125                     }
126                 }
127             }
128             hir::ItemFn(..) => {
129                 self.check_item_fn(item);
130             }
131             hir::ItemStatic(..) => {
132                 self.check_item_type(item);
133             }
134             hir::ItemConst(..) => {
135                 self.check_item_type(item);
136             }
137             hir::ItemStruct(ref struct_def, ref ast_generics) => {
138                 self.check_type_defn(item, false, |fcx| {
139                     vec![fcx.non_enum_variant(struct_def)]
140                 });
141
142                 self.check_variances_for_type_defn(item, ast_generics);
143             }
144             hir::ItemUnion(ref struct_def, ref ast_generics) => {
145                 self.check_type_defn(item, true, |fcx| {
146                     vec![fcx.non_enum_variant(struct_def)]
147                 });
148
149                 self.check_variances_for_type_defn(item, ast_generics);
150             }
151             hir::ItemEnum(ref enum_def, ref ast_generics) => {
152                 self.check_type_defn(item, true, |fcx| {
153                     fcx.enum_variants(enum_def)
154                 });
155
156                 self.check_variances_for_type_defn(item, ast_generics);
157             }
158             hir::ItemTrait(..) => {
159                 self.check_trait(item);
160             }
161             _ => {}
162         }
163     }
164
165     fn check_associated_item(&mut self,
166                              item_id: ast::NodeId,
167                              span: Span,
168                              sig_if_method: Option<&hir::MethodSig>) {
169         let code = self.code.clone();
170         self.for_id(item_id, span).with_fcx(|fcx, this| {
171             let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
172
173             let (mut implied_bounds, self_ty) = match item.container {
174                 ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
175                 ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span),
176                                               fcx.tcx.type_of(def_id))
177             };
178
179             match item.kind {
180                 ty::AssociatedKind::Const => {
181                     let ty = fcx.tcx.type_of(item.def_id);
182                     let ty = fcx.normalize_associated_types_in(span, &ty);
183                     fcx.register_wf_obligation(ty, span, code.clone());
184                 }
185                 ty::AssociatedKind::Method => {
186                     reject_shadowing_type_parameters(fcx.tcx, item.def_id);
187                     let sig = fcx.tcx.fn_sig(item.def_id);
188                     let sig = fcx.normalize_associated_types_in(span, &sig);
189                     let predicates = fcx.tcx.predicates_of(item.def_id)
190                         .instantiate_identity(fcx.tcx);
191                     let predicates = fcx.normalize_associated_types_in(span, &predicates);
192                     this.check_fn_or_method(fcx, span, sig, &predicates,
193                                             item.def_id, &mut implied_bounds);
194                     let sig_if_method = sig_if_method.expect("bad signature for method");
195                     this.check_method_receiver(fcx, sig_if_method, &item, self_ty);
196                 }
197                 ty::AssociatedKind::Type => {
198                     if item.defaultness.has_value() {
199                         let ty = fcx.tcx.type_of(item.def_id);
200                         let ty = fcx.normalize_associated_types_in(span, &ty);
201                         fcx.register_wf_obligation(ty, span, code.clone());
202                     }
203                 }
204             }
205
206             implied_bounds
207         })
208     }
209
210     fn for_item<'tcx>(&self, item: &hir::Item)
211                       -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
212         self.for_id(item.id, item.span)
213     }
214
215     fn for_id<'tcx>(&self, id: ast::NodeId, span: Span)
216                     -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
217         let def_id = self.tcx.hir.local_def_id(id);
218         CheckWfFcxBuilder {
219             inherited: Inherited::build(self.tcx, def_id),
220             code: self.code.clone(),
221             id,
222             span,
223             param_env: self.tcx.param_env(def_id),
224         }
225     }
226
227     /// In a type definition, we check that to ensure that the types of the fields are well-formed.
228     fn check_type_defn<F>(&mut self, item: &hir::Item, all_sized: bool, mut lookup_fields: F)
229         where F: for<'fcx, 'tcx> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx>) -> Vec<AdtVariant<'tcx>>
230     {
231         self.for_item(item).with_fcx(|fcx, this| {
232             let variants = lookup_fields(fcx);
233             let def_id = fcx.tcx.hir.local_def_id(item.id);
234             let packed = fcx.tcx.adt_def(def_id).repr.packed();
235
236             for variant in &variants {
237                 // For DST, or when drop needs to copy things around, all
238                 // intermediate types must be sized.
239                 let needs_drop_copy = || {
240                     packed && {
241                         let ty = variant.fields.last().unwrap().ty;
242                         let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(this.tcx)
243                             .unwrap_or_else(|| {
244                                 span_bug!(item.span, "inference variables in {:?}", ty)
245                             });
246                         ty.needs_drop(this.tcx, this.tcx.param_env(def_id))
247                     }
248                 };
249                 let unsized_len = if
250                     all_sized ||
251                     variant.fields.is_empty() ||
252                     needs_drop_copy()
253                 {
254                     0
255                 } else {
256                     1
257                 };
258                 for field in &variant.fields[..variant.fields.len() - unsized_len] {
259                     fcx.register_bound(
260                         field.ty,
261                         fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
262                         traits::ObligationCause::new(field.span,
263                                                      fcx.body_id,
264                                                      traits::FieldSized(match item.node.adt_kind() {
265                                                         Some(i) => i,
266                                                         None => bug!(),
267                                                      })));
268                 }
269
270                 // All field types must be well-formed.
271                 for field in &variant.fields {
272                     fcx.register_wf_obligation(field.ty, field.span, this.code.clone())
273                 }
274             }
275
276             let predicates = fcx.tcx.predicates_of(def_id).instantiate_identity(fcx.tcx);
277             let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
278             this.check_where_clauses(fcx, item.span, &predicates);
279
280             vec![] // no implied bounds in a struct def'n
281         });
282     }
283
284     fn check_trait(&mut self, item: &hir::Item) {
285         let trait_def_id = self.tcx.hir.local_def_id(item.id);
286         self.for_item(item).with_fcx(|fcx, this| {
287             let predicates = fcx.tcx.predicates_of(trait_def_id).instantiate_identity(fcx.tcx);
288             let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
289             this.check_where_clauses(fcx, item.span, &predicates);
290             vec![]
291         });
292     }
293
294     fn check_item_fn(&mut self, item: &hir::Item) {
295         self.for_item(item).with_fcx(|fcx, this| {
296             let def_id = fcx.tcx.hir.local_def_id(item.id);
297             let sig = fcx.tcx.fn_sig(def_id);
298             let sig = fcx.normalize_associated_types_in(item.span, &sig);
299
300             let predicates = fcx.tcx.predicates_of(def_id).instantiate_identity(fcx.tcx);
301             let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
302
303             let mut implied_bounds = vec![];
304             this.check_fn_or_method(fcx, item.span, sig, &predicates,
305                                     def_id, &mut implied_bounds);
306             implied_bounds
307         })
308     }
309
310     fn check_item_type(&mut self,
311                        item: &hir::Item)
312     {
313         debug!("check_item_type: {:?}", item);
314
315         self.for_item(item).with_fcx(|fcx, this| {
316             let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id));
317             let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
318
319             fcx.register_wf_obligation(item_ty, item.span, this.code.clone());
320
321             vec![] // no implied bounds in a const etc
322         });
323     }
324
325     fn check_impl(&mut self,
326                   item: &hir::Item,
327                   ast_self_ty: &hir::Ty,
328                   ast_trait_ref: &Option<hir::TraitRef>)
329     {
330         debug!("check_impl: {:?}", item);
331
332         self.for_item(item).with_fcx(|fcx, this| {
333             let item_def_id = fcx.tcx.hir.local_def_id(item.id);
334
335             match *ast_trait_ref {
336                 Some(ref ast_trait_ref) => {
337                     let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap();
338                     let trait_ref =
339                         fcx.normalize_associated_types_in(
340                             ast_trait_ref.path.span, &trait_ref);
341                     let obligations =
342                         ty::wf::trait_obligations(fcx,
343                                                   fcx.param_env,
344                                                   fcx.body_id,
345                                                   &trait_ref,
346                                                   ast_trait_ref.path.span);
347
348                     // not registering predicates associcated with a `default impl`
349                     // that doesn't implement all the trait items.
350                     // it's left to the trait selection to select those trait predicates
351                     // and trigger an `Unimplemented` error in case the defaul_impl_check
352                     // is applicable
353                     let impl_not_implement_trait =
354                         if fcx.tcx.impl_is_default(item_def_id) &&
355                            !fcx.tcx.default_impl_implement_all_methods(item_def_id) {
356                             true
357                         } else {
358                             false
359                         };
360
361                     for obligation in obligations {
362                         let register = match obligation.predicate {
363                             ty::Predicate::Trait(..)  => {
364                                 if impl_not_implement_trait &&
365                                    !obligation.predicate.has_param_types() {
366                                     false
367                                 } else {
368                                     true
369                                 }
370                             }
371                             _ => true
372                         };
373
374                         if register {
375                             fcx.register_predicate(obligation);
376                         }
377                     }
378                 }
379                 None => {
380                     let self_ty = fcx.tcx.type_of(item_def_id);
381                     let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty);
382                     fcx.register_wf_obligation(self_ty, ast_self_ty.span, this.code.clone());
383                 }
384             }
385
386             let predicates = fcx.tcx.predicates_of(item_def_id).instantiate_identity(fcx.tcx);
387             let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
388             this.check_where_clauses(fcx, item.span, &predicates);
389
390             fcx.impl_implied_bounds(item_def_id, item.span)
391         });
392     }
393
394     fn check_where_clauses<'fcx, 'tcx>(&mut self,
395                                        fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
396                                        span: Span,
397                                        predicates: &ty::InstantiatedPredicates<'tcx>)
398     {
399         let obligations =
400             predicates.predicates
401                       .iter()
402                       .flat_map(|p| ty::wf::predicate_obligations(fcx,
403                                                                   fcx.param_env,
404                                                                   fcx.body_id,
405                                                                   p,
406                                                                   span));
407
408         for obligation in obligations {
409             fcx.register_predicate(obligation);
410         }
411     }
412
413     fn check_fn_or_method<'fcx, 'tcx>(&mut self,
414                                       fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
415                                       span: Span,
416                                       sig: ty::PolyFnSig<'tcx>,
417                                       predicates: &ty::InstantiatedPredicates<'tcx>,
418                                       def_id: DefId,
419                                       implied_bounds: &mut Vec<Ty<'tcx>>)
420     {
421         let sig = fcx.normalize_associated_types_in(span, &sig);
422         let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig);
423
424         for input_ty in sig.inputs() {
425             fcx.register_wf_obligation(&input_ty, span, self.code.clone());
426         }
427         implied_bounds.extend(sig.inputs());
428
429         fcx.register_wf_obligation(sig.output(), span, self.code.clone());
430
431         // FIXME(#25759) return types should not be implied bounds
432         implied_bounds.push(sig.output());
433
434         self.check_where_clauses(fcx, span, predicates);
435     }
436
437     fn check_method_receiver<'fcx, 'tcx>(&mut self,
438                                          fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
439                                          method_sig: &hir::MethodSig,
440                                          method: &ty::AssociatedItem,
441                                          self_ty: Ty<'tcx>)
442     {
443         // check that the method has a valid receiver type, given the type `Self`
444         debug!("check_method_receiver({:?}, self_ty={:?})",
445                method, self_ty);
446
447         if !method.method_has_self_argument {
448             return;
449         }
450
451         let span = method_sig.decl.inputs[0].span;
452
453         let sig = fcx.tcx.fn_sig(method.def_id);
454         let sig = fcx.normalize_associated_types_in(span, &sig);
455         let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig);
456
457         debug!("check_method_receiver: sig={:?}", sig);
458
459         let self_ty = fcx.normalize_associated_types_in(span, &self_ty);
460         let self_ty = fcx.tcx.liberate_late_bound_regions(
461             method.def_id,
462             &ty::Binder(self_ty)
463         );
464
465         let self_arg_ty = sig.inputs()[0];
466
467         let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
468         let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty);
469         let self_arg_ty = fcx.tcx.liberate_late_bound_regions(
470             method.def_id,
471             &ty::Binder(self_arg_ty)
472         );
473
474         let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers();
475
476         loop {
477             if let Some((potential_self_ty, _)) = autoderef.next() {
478                 debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`",
479                     potential_self_ty, self_ty);
480
481                 if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() {
482                     autoderef.finalize();
483                     if let Some(mut err) = fcx.demand_eqtype_with_origin(
484                         &cause, self_ty, potential_self_ty) {
485                         err.emit();
486                     }
487                     break
488                 }
489             } else {
490                 fcx.tcx.sess.diagnostic().mut_span_err(
491                     span, &format!("invalid `self` type: {:?}", self_arg_ty))
492                 .note(&format!("type must be `{:?}` or a type that dereferences to it`", self_ty))
493                 .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
494                 .code(DiagnosticId::Error("E0307".into()))
495                 .emit();
496                 return
497             }
498         }
499
500         let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok();
501         let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty);
502
503         if !fcx.tcx.sess.features.borrow().arbitrary_self_types {
504             match self_kind {
505                 ExplicitSelf::ByValue |
506                 ExplicitSelf::ByReference(_, _) |
507                 ExplicitSelf::ByBox => (),
508
509                 ExplicitSelf::ByRawPointer(_) => {
510                     feature_gate::feature_err(
511                         &fcx.tcx.sess.parse_sess,
512                         "arbitrary_self_types",
513                         span,
514                         GateIssue::Language,
515                         "raw pointer `self` is unstable")
516                     .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
517                     .emit();
518                 }
519
520                 ExplicitSelf::Other => {
521                     feature_gate::feature_err(
522                         &fcx.tcx.sess.parse_sess,
523                         "arbitrary_self_types",
524                         span,
525                         GateIssue::Language,"arbitrary `self` types are unstable")
526                     .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
527                     .emit();
528                 }
529             }
530         }
531     }
532
533     fn check_variances_for_type_defn(&self,
534                                      item: &hir::Item,
535                                      ast_generics: &hir::Generics)
536     {
537         let item_def_id = self.tcx.hir.local_def_id(item.id);
538         let ty = self.tcx.type_of(item_def_id);
539         if self.tcx.has_error_field(ty) {
540             return;
541         }
542
543         let ty_predicates = self.tcx.predicates_of(item_def_id);
544         assert_eq!(ty_predicates.parent, None);
545         let variances = self.tcx.variances_of(item_def_id);
546
547         let mut constrained_parameters: FxHashSet<_> =
548             variances.iter().enumerate()
549                      .filter(|&(_, &variance)| variance != ty::Bivariant)
550                      .map(|(index, _)| Parameter(index as u32))
551                      .collect();
552
553         identify_constrained_type_params(self.tcx,
554                                          ty_predicates.predicates.as_slice(),
555                                          None,
556                                          &mut constrained_parameters);
557
558         for (index, _) in variances.iter().enumerate() {
559             if constrained_parameters.contains(&Parameter(index as u32)) {
560                 continue;
561             }
562
563             let (span, name) = match ast_generics.params[index] {
564                 hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()),
565                 hir::GenericParam::Type(ref tp) => (tp.span, tp.name),
566             };
567             self.report_bivariance(span, name);
568         }
569     }
570
571     fn report_bivariance(&self,
572                          span: Span,
573                          param_name: ast::Name)
574     {
575         let mut err = error_392(self.tcx, span, param_name);
576
577         let suggested_marker_id = self.tcx.lang_items().phantom_data();
578         match suggested_marker_id {
579             Some(def_id) => {
580                 err.help(
581                     &format!("consider removing `{}` or using a marker such as `{}`",
582                              param_name,
583                              self.tcx.item_path_str(def_id)));
584             }
585             None => {
586                 // no lang items, no help!
587             }
588         }
589         err.emit();
590     }
591 }
592
593 fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
594     let generics = tcx.generics_of(def_id);
595     let parent = tcx.generics_of(generics.parent.unwrap());
596     let impl_params: FxHashMap<_, _> = parent.types
597                                        .iter()
598                                        .map(|tp| (tp.name, tp.def_id))
599                                        .collect();
600
601     for method_param in &generics.types {
602         if impl_params.contains_key(&method_param.name) {
603             // Tighten up the span to focus on only the shadowing type
604             let type_span = tcx.def_span(method_param.def_id);
605
606             // The expectation here is that the original trait declaration is
607             // local so it should be okay to just unwrap everything.
608             let trait_def_id = impl_params[&method_param.name];
609             let trait_decl_span = tcx.def_span(trait_def_id);
610             error_194(tcx, type_span, trait_decl_span, method_param.name);
611         }
612     }
613 }
614
615 impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
616     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
617         NestedVisitorMap::None
618     }
619
620     fn visit_item(&mut self, i: &hir::Item) {
621         debug!("visit_item: {:?}", i);
622         self.check_item_well_formed(i);
623         intravisit::walk_item(self, i);
624     }
625
626     fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
627         debug!("visit_trait_item: {:?}", trait_item);
628         let method_sig = match trait_item.node {
629             hir::TraitItemKind::Method(ref sig, _) => Some(sig),
630             _ => None
631         };
632         self.check_associated_item(trait_item.id, trait_item.span, method_sig);
633         intravisit::walk_trait_item(self, trait_item)
634     }
635
636     fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
637         debug!("visit_impl_item: {:?}", impl_item);
638         let method_sig = match impl_item.node {
639             hir::ImplItemKind::Method(ref sig, _) => Some(sig),
640             _ => None
641         };
642         self.check_associated_item(impl_item.id, impl_item.span, method_sig);
643         intravisit::walk_impl_item(self, impl_item)
644     }
645 }
646
647 ///////////////////////////////////////////////////////////////////////////
648 // ADT
649
650 struct AdtVariant<'tcx> {
651     fields: Vec<AdtField<'tcx>>,
652 }
653
654 struct AdtField<'tcx> {
655     ty: Ty<'tcx>,
656     span: Span,
657 }
658
659 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
660     fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
661         let fields =
662             struct_def.fields().iter()
663             .map(|field| {
664                 let field_ty = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
665                 let field_ty = self.normalize_associated_types_in(field.span,
666                                                                   &field_ty);
667                 AdtField { ty: field_ty, span: field.span }
668             })
669             .collect();
670         AdtVariant { fields: fields }
671     }
672
673     fn enum_variants(&self, enum_def: &hir::EnumDef) -> Vec<AdtVariant<'tcx>> {
674         enum_def.variants.iter()
675             .map(|variant| self.non_enum_variant(&variant.node.data))
676             .collect()
677     }
678
679     fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
680         match self.tcx.impl_trait_ref(impl_def_id) {
681             Some(ref trait_ref) => {
682                 // Trait impl: take implied bounds from all types that
683                 // appear in the trait reference.
684                 let trait_ref = self.normalize_associated_types_in(span, trait_ref);
685                 trait_ref.substs.types().collect()
686             }
687
688             None => {
689                 // Inherent impl: take implied bounds from the self type.
690                 let self_ty = self.tcx.type_of(impl_def_id);
691                 let self_ty = self.normalize_associated_types_in(span, &self_ty);
692                 vec![self_ty]
693             }
694         }
695     }
696 }
697
698 fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name)
699                        -> DiagnosticBuilder<'tcx> {
700     let mut err = struct_span_err!(tcx.sess, span, E0392,
701                   "parameter `{}` is never used", param_name);
702     err.span_label(span, "unused type parameter");
703     err
704 }
705
706 fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) {
707     struct_span_err!(tcx.sess, span, E0194,
708               "type parameter `{}` shadows another type parameter of the same name",
709               name)
710         .span_label(span, "shadows another type parameter")
711         .span_label(trait_decl_span, format!("first `{}` declared here", name))
712         .emit();
713 }