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