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