]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/check/wfcheck.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / librustc_typeck / check / wfcheck.rs
CommitLineData
e9174d1e
SL
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
476ff2be 11use astconv::ExplicitSelf;
8bb4bdeb 12use check::{Inherited, FnCtxt};
e9174d1e 13use constrained_type_params::{identify_constrained_type_params, Parameter};
476ff2be 14
54a0048b 15use hir::def_id::DefId;
9cc50fc6 16use middle::region::{CodeExtent};
476ff2be 17use rustc::traits::{self, ObligationCauseCode};
54a0048b 18use rustc::ty::{self, Ty, TyCtxt};
476ff2be
SL
19use rustc::util::nodemap::{FxHashSet, FxHashMap};
20use rustc::middle::lang_items;
e9174d1e 21
e9174d1e 22use syntax::ast;
3157f602
XL
23use syntax_pos::Span;
24use errors::DiagnosticBuilder;
25
476ff2be 26use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
54a0048b 27use rustc::hir;
e9174d1e 28
8bb4bdeb
XL
29pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> {
30 tcx: TyCtxt<'a, 'tcx, 'tcx>,
476ff2be 31 code: ObligationCauseCode<'tcx>,
e9174d1e
SL
32}
33
a7813a04
XL
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>).
37struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
38 inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
476ff2be 39 code: ObligationCauseCode<'gcx>,
a7813a04
XL
40 id: ast::NodeId,
41 span: Span
42}
43
44impl<'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| {
8bb4bdeb 53 let fcx = FnCtxt::new(&inh, None, id);
a7813a04 54 let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor {
8bb4bdeb 55 tcx: fcx.tcx.global_tcx(),
a7813a04
XL
56 code: code
57 });
58 fcx.select_all_obligations_or_error();
59 fcx.regionck_item(id, span, &wf_tys);
60 });
61 }
62}
63
8bb4bdeb
XL
64impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
65 pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>)
66 -> CheckTypeWellFormedVisitor<'a, 'gcx> {
e9174d1e 67 CheckTypeWellFormedVisitor {
8bb4bdeb 68 tcx: tcx,
476ff2be 69 code: ObligationCauseCode::MiscObligation
e9174d1e
SL
70 }
71 }
72
e9174d1e
SL
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) {
8bb4bdeb 85 let tcx = self.tcx;
b039eaaf 86 debug!("check_item_well_formed(it.id={}, it.name={})",
e9174d1e 87 item.id,
8bb4bdeb 88 tcx.item_path_str(tcx.hir.local_def_id(item.id)));
e9174d1e
SL
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 }
9e0c209e 112 hir::ItemImpl(_, hir::ImplPolarity::Negative, _, Some(_), ..) => {
e9174d1e
SL
113 // FIXME(#27579) what amount of WF checking do we need for neg impls?
114
8bb4bdeb
XL
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);
e9174d1e
SL
118 }
119 }
476ff2be
SL
120 hir::ItemFn(.., body_id) => {
121 self.check_item_fn(item, body_id);
e9174d1e
SL
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) => {
9e0c209e
SL
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| {
a7813a04 138 vec![fcx.struct_variant(struct_def)]
e9174d1e
SL
139 });
140
141 self.check_variances_for_type_defn(item, ast_generics);
142 }
143 hir::ItemEnum(ref enum_def, ref ast_generics) => {
c30ab7b3 144 self.check_type_defn(item, true, |fcx| {
a7813a04 145 fcx.enum_variants(enum_def)
e9174d1e
SL
146 });
147
148 self.check_variances_for_type_defn(item, ast_generics);
149 }
476ff2be
SL
150 hir::ItemTrait(..) => {
151 self.check_trait(item);
e9174d1e
SL
152 }
153 _ => {}
154 }
155 }
156
32a655c1
SL
157 fn check_associated_item(&mut self,
158 item_id: ast::NodeId,
159 span: Span,
160 sig_if_method: Option<&hir::MethodSig>) {
e9174d1e 161 let code = self.code.clone();
a7813a04
XL
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;
e9174d1e 165
32a655c1 166 let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
e9174d1e 167
476ff2be 168 let (mut implied_bounds, self_ty) = match item.container {
a7813a04
XL
169 ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
170 ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span),
476ff2be 171 fcx.tcx.item_type(def_id))
e9174d1e
SL
172 };
173
476ff2be
SL
174 match item.kind {
175 ty::AssociatedKind::Const => {
176 let ty = fcx.tcx.item_type(item.def_id);
177 let ty = fcx.instantiate_type_scheme(span, free_substs, &ty);
e9174d1e
SL
178 fcx.register_wf_obligation(ty, span, code.clone());
179 }
476ff2be
SL
180 ty::AssociatedKind::Method => {
181 reject_shadowing_type_parameters(fcx.tcx, item.def_id);
182 let method_ty = fcx.tcx.item_type(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);
8bb4bdeb
XL
185 let sig = method_ty.fn_sig();
186 this.check_fn_or_method(fcx, span, sig, &predicates,
9cc50fc6 187 free_id_outlive, &mut implied_bounds);
5bcae85e 188 let sig_if_method = sig_if_method.expect("bad signature for method");
476ff2be 189 this.check_method_receiver(fcx, sig_if_method, &item,
9cc50fc6 190 free_id_outlive, self_ty);
e9174d1e 191 }
476ff2be
SL
192 ty::AssociatedKind::Type => {
193 if item.defaultness.has_value() {
194 let ty = fcx.tcx.item_type(item.def_id);
195 let ty = fcx.instantiate_type_scheme(span, free_substs, &ty);
e9174d1e
SL
196 fcx.register_wf_obligation(ty, span, code.clone());
197 }
198 }
199 }
200
201 implied_bounds
202 })
203 }
204
a7813a04 205 fn for_item<'tcx>(&self, item: &hir::Item)
8bb4bdeb 206 -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
a7813a04 207 self.for_id(item.id, item.span)
e9174d1e
SL
208 }
209
a7813a04 210 fn for_id<'tcx>(&self, id: ast::NodeId, span: Span)
8bb4bdeb 211 -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
a7813a04 212 CheckWfFcxBuilder {
8bb4bdeb 213 inherited: Inherited::build(self.tcx, id),
a7813a04
XL
214 code: self.code.clone(),
215 id: id,
216 span: span
217 }
e9174d1e
SL
218 }
219
220 /// In a type definition, we check that to ensure that the types of the fields are well-formed.
9e0c209e
SL
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>>
e9174d1e 223 {
a7813a04 224 self.for_item(item).with_fcx(|fcx, this| {
e9174d1e
SL
225 let variants = lookup_fields(fcx);
226
227 for variant in &variants {
228 // For DST, all intermediate types must be sized.
9e0c209e
SL
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] {
476ff2be 231 fcx.register_bound(
9e0c209e 232 field.ty,
476ff2be 233 fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
9e0c209e
SL
234 traits::ObligationCause::new(field.span,
235 fcx.body_id,
236 traits::FieldSized));
e9174d1e
SL
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
a7813a04 245 let free_substs = &fcx.parameter_environment.free_substs;
32a655c1 246 let def_id = fcx.tcx.hir.local_def_id(item.id);
476ff2be 247 let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
e9174d1e
SL
248 this.check_where_clauses(fcx, item.span, &predicates);
249
250 vec![] // no implied bounds in a struct def'n
251 });
252 }
253
476ff2be 254 fn check_auto_trait(&mut self, trait_def_id: DefId, span: Span) {
9e0c209e
SL
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
8bb4bdeb 265 let predicates = self.tcx.item_predicates(trait_def_id);
9e0c209e
SL
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
8bb4bdeb 280 let has_ty_params = self.tcx.item_generics(trait_def_id).types.len() > 1;
9e0c209e
SL
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;
8bb4bdeb
XL
291 if !self.tcx.associated_item_def_ids(trait_def_id).is_empty() {
292 error_380(self.tcx, span);
9e0c209e 293 } else if has_ty_params {
8bb4bdeb 294 err = Some(struct_span_err!(self.tcx.sess, span, E0567,
9e0c209e
SL
295 "traits with auto impls (`e.g. impl \
296 Trait for ..`) can not have type parameters"));
297 } else if has_predicates {
8bb4bdeb 298 err = Some(struct_span_err!(self.tcx.sess, span, E0568,
9e0c209e
SL
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
476ff2be 315 fn check_trait(&mut self, item: &hir::Item) {
8bb4bdeb 316 let trait_def_id = self.tcx.hir.local_def_id(item.id);
e9174d1e 317
8bb4bdeb 318 if self.tcx.trait_has_default_impl(trait_def_id) {
476ff2be 319 self.check_auto_trait(trait_def_id, item.span);
e9174d1e
SL
320 }
321
a7813a04
XL
322 self.for_item(item).with_fcx(|fcx, this| {
323 let free_substs = &fcx.parameter_environment.free_substs;
476ff2be 324 let predicates = fcx.instantiate_bounds(item.span, trait_def_id, free_substs);
e9174d1e
SL
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,
32a655c1 332 body_id: hir::BodyId)
e9174d1e 333 {
a7813a04
XL
334 self.for_item(item).with_fcx(|fcx, this| {
335 let free_substs = &fcx.parameter_environment.free_substs;
32a655c1 336 let def_id = fcx.tcx.hir.local_def_id(item.id);
476ff2be
SL
337 let ty = fcx.tcx.item_type(def_id);
338 let item_ty = fcx.instantiate_type_scheme(item.span, free_substs, &ty);
8bb4bdeb 339 let sig = item_ty.fn_sig();
e9174d1e 340
476ff2be 341 let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
e9174d1e
SL
342
343 let mut implied_bounds = vec![];
32a655c1 344 let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id);
8bb4bdeb 345 this.check_fn_or_method(fcx, item.span, sig, &predicates,
9cc50fc6 346 free_id_outlive, &mut implied_bounds);
e9174d1e
SL
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
a7813a04 356 self.for_item(item).with_fcx(|fcx, this| {
32a655c1 357 let ty = fcx.tcx.item_type(fcx.tcx.hir.local_def_id(item.id));
e9174d1e 358 let item_ty = fcx.instantiate_type_scheme(item.span,
a7813a04 359 &fcx.parameter_environment
e9174d1e 360 .free_substs,
476ff2be 361 &ty);
e9174d1e
SL
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
a7813a04
XL
376 self.for_item(item).with_fcx(|fcx, this| {
377 let free_substs = &fcx.parameter_environment.free_substs;
32a655c1 378 let item_def_id = fcx.tcx.hir.local_def_id(item.id);
e9174d1e
SL
379
380 match *ast_trait_ref {
381 Some(ref ast_trait_ref) => {
a7813a04 382 let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap();
e9174d1e
SL
383 let trait_ref =
384 fcx.instantiate_type_scheme(
385 ast_trait_ref.path.span, free_substs, &trait_ref);
386 let obligations =
a7813a04 387 ty::wf::trait_obligations(fcx,
e9174d1e
SL
388 fcx.body_id,
389 &trait_ref,
9cc50fc6 390 ast_trait_ref.path.span);
e9174d1e
SL
391 for obligation in obligations {
392 fcx.register_predicate(obligation);
393 }
394 }
395 None => {
476ff2be 396 let self_ty = fcx.tcx.item_type(item_def_id);
e9174d1e
SL
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
476ff2be 402 let predicates = fcx.instantiate_bounds(item.span, item_def_id, free_substs);
e9174d1e
SL
403 this.check_where_clauses(fcx, item.span, &predicates);
404
476ff2be 405 fcx.impl_implied_bounds(item_def_id, item.span)
e9174d1e
SL
406 });
407 }
408
a7813a04
XL
409 fn check_where_clauses<'fcx, 'tcx>(&mut self,
410 fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
411 span: Span,
412 predicates: &ty::InstantiatedPredicates<'tcx>)
e9174d1e
SL
413 {
414 let obligations =
415 predicates.predicates
416 .iter()
a7813a04 417 .flat_map(|p| ty::wf::predicate_obligations(fcx,
e9174d1e
SL
418 fcx.body_id,
419 p,
9cc50fc6 420 span));
e9174d1e
SL
421
422 for obligation in obligations {
423 fcx.register_predicate(obligation);
424 }
425 }
426
a7813a04
XL
427 fn check_fn_or_method<'fcx, 'tcx>(&mut self,
428 fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
429 span: Span,
8bb4bdeb 430 sig: ty::PolyFnSig<'tcx>,
a7813a04
XL
431 predicates: &ty::InstantiatedPredicates<'tcx>,
432 free_id_outlive: CodeExtent,
433 implied_bounds: &mut Vec<Ty<'tcx>>)
e9174d1e 434 {
a7813a04 435 let free_substs = &fcx.parameter_environment.free_substs;
8bb4bdeb
XL
436 let sig = fcx.instantiate_type_scheme(span, free_substs, &sig);
437 let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &sig);
e9174d1e 438
476ff2be
SL
439 for input_ty in sig.inputs() {
440 fcx.register_wf_obligation(&input_ty, span, self.code.clone());
e9174d1e 441 }
476ff2be 442 implied_bounds.extend(sig.inputs());
e9174d1e 443
476ff2be 444 fcx.register_wf_obligation(sig.output(), span, self.code.clone());
e9174d1e 445
5bcae85e 446 // FIXME(#25759) return types should not be implied bounds
476ff2be 447 implied_bounds.push(sig.output());
e9174d1e
SL
448
449 self.check_where_clauses(fcx, span, predicates);
450 }
451
a7813a04
XL
452 fn check_method_receiver<'fcx, 'tcx>(&mut self,
453 fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
5bcae85e 454 method_sig: &hir::MethodSig,
476ff2be 455 method: &ty::AssociatedItem,
a7813a04
XL
456 free_id_outlive: CodeExtent,
457 self_ty: ty::Ty<'tcx>)
9cc50fc6
SL
458 {
459 // check that the type of the method's receiver matches the
460 // method's first parameter.
476ff2be
SL
461 debug!("check_method_receiver({:?}, self_ty={:?})",
462 method, self_ty);
9cc50fc6 463
476ff2be
SL
464 if !method.method_has_self_argument {
465 return;
466 }
5bcae85e 467
32a655c1 468 let span = method_sig.decl.inputs[0].span;
5bcae85e
SL
469
470 let free_substs = &fcx.parameter_environment.free_substs;
476ff2be
SL
471 let method_ty = fcx.tcx.item_type(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());
5bcae85e
SL
474
475 debug!("check_method_receiver: sig={:?}", sig);
476
476ff2be
SL
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 };
9cc50fc6 488 let rcvr_ty = fcx.instantiate_type_scheme(span, free_substs, &rcvr_ty);
a7813a04
XL
489 let rcvr_ty = fcx.tcx.liberate_late_bound_regions(free_id_outlive,
490 &ty::Binder(rcvr_ty));
9cc50fc6
SL
491
492 debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
493
476ff2be 494 let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
32a655c1
SL
495 if let Some(mut err) = fcx.demand_eqtype_with_origin(&cause, rcvr_ty, self_arg_ty) {
496 err.emit();
497 }
9cc50fc6
SL
498 }
499
e9174d1e
SL
500 fn check_variances_for_type_defn(&self,
501 item: &hir::Item,
502 ast_generics: &hir::Generics)
503 {
8bb4bdeb
XL
504 let item_def_id = self.tcx.hir.local_def_id(item.id);
505 let ty = self.tcx.item_type(item_def_id);
506 if self.tcx.has_error_field(ty) {
5bcae85e
SL
507 return;
508 }
509
8bb4bdeb 510 let ty_predicates = self.tcx.item_predicates(item_def_id);
9e0c209e 511 assert_eq!(ty_predicates.parent, None);
8bb4bdeb 512 let variances = self.tcx.item_variances(item_def_id);
e9174d1e 513
476ff2be 514 let mut constrained_parameters: FxHashSet<_> =
9e0c209e
SL
515 variances.iter().enumerate()
516 .filter(|&(_, &variance)| variance != ty::Bivariant)
517 .map(|(index, _)| Parameter(index as u32))
e9174d1e
SL
518 .collect();
519
a7813a04 520 identify_constrained_type_params(ty_predicates.predicates.as_slice(),
e9174d1e
SL
521 None,
522 &mut constrained_parameters);
523
9e0c209e
SL
524 for (index, _) in variances.iter().enumerate() {
525 if constrained_parameters.contains(&Parameter(index as u32)) {
e9174d1e
SL
526 continue;
527 }
528
9e0c209e
SL
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 };
e9174d1e
SL
537 self.report_bivariance(span, name);
538 }
539 }
540
e9174d1e
SL
541 fn report_bivariance(&self,
542 span: Span,
543 param_name: ast::Name)
544 {
8bb4bdeb 545 let mut err = error_392(self.tcx, span, param_name);
e9174d1e 546
8bb4bdeb 547 let suggested_marker_id = self.tcx.lang_items.phantom_data();
e9174d1e
SL
548 match suggested_marker_id {
549 Some(def_id) => {
a7813a04 550 err.help(
e9174d1e
SL
551 &format!("consider removing `{}` or using a marker such as `{}`",
552 param_name,
8bb4bdeb 553 self.tcx.item_path_str(def_id)));
e9174d1e
SL
554 }
555 None => {
556 // no lang items, no help!
557 }
558 }
9cc50fc6 559 err.emit();
e9174d1e
SL
560 }
561}
562
476ff2be
SL
563fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) {
564 let generics = tcx.item_generics(def_id);
565 let parent = tcx.item_generics(generics.parent.unwrap());
566 let impl_params: FxHashMap<_, _> = parent.types
567 .iter()
568 .map(|tp| (tp.name, tp.def_id))
569 .collect();
9e0c209e
SL
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
476ff2be 574 let type_span = tcx.def_span(method_param.def_id);
e9174d1e 575
9e0c209e
SL
576 // The expectation here is that the original trait declaration is
577 // local so it should be okay to just unwrap everything.
476ff2be
SL
578 let trait_def_id = impl_params[&method_param.name];
579 let trait_decl_span = tcx.def_span(trait_def_id);
9e0c209e 580 error_194(tcx, type_span, trait_decl_span, method_param.name);
e9174d1e
SL
581 }
582 }
583}
584
8bb4bdeb 585impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
476ff2be
SL
586 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
587 NestedVisitorMap::None
588 }
589
e9174d1e
SL
590 fn visit_item(&mut self, i: &hir::Item) {
591 debug!("visit_item: {:?}", i);
592 self.check_item_well_formed(i);
92a42be0 593 intravisit::walk_item(self, i);
e9174d1e
SL
594 }
595
596 fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
597 debug!("visit_trait_item: {:?}", trait_item);
5bcae85e 598 let method_sig = match trait_item.node {
32a655c1 599 hir::TraitItemKind::Method(ref sig, _) => Some(sig),
5bcae85e
SL
600 _ => None
601 };
32a655c1 602 self.check_associated_item(trait_item.id, trait_item.span, method_sig);
92a42be0 603 intravisit::walk_trait_item(self, trait_item)
e9174d1e
SL
604 }
605
606 fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
607 debug!("visit_impl_item: {:?}", impl_item);
5bcae85e
SL
608 let method_sig = match impl_item.node {
609 hir::ImplItemKind::Method(ref sig, _) => Some(sig),
610 _ => None
611 };
32a655c1 612 self.check_associated_item(impl_item.id, impl_item.span, method_sig);
92a42be0 613 intravisit::walk_impl_item(self, impl_item)
e9174d1e
SL
614 }
615}
616
617///////////////////////////////////////////////////////////////////////////
618// ADT
619
620struct AdtVariant<'tcx> {
621 fields: Vec<AdtField<'tcx>>,
622}
623
624struct AdtField<'tcx> {
625 ty: Ty<'tcx>,
626 span: Span,
627}
628
a7813a04
XL
629impl<'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| {
32a655c1 634 let field_ty = self.tcx.item_type(self.tcx.hir.local_def_id(field.id));
a7813a04
XL
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 }
e9174d1e 644
a7813a04
XL
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 }
e9174d1e 650
a7813a04
XL
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);
9e0c209e 658 trait_ref.substs.types().collect()
a7813a04 659 }
e9174d1e 660
a7813a04
XL
661 None => {
662 // Inherent impl: take implied bounds from the self type.
476ff2be 663 let self_ty = self.tcx.item_type(impl_def_id);
a7813a04
XL
664 let self_ty = self.instantiate_type_scheme(span, free_substs, &self_ty);
665 vec![self_ty]
666 }
e9174d1e
SL
667 }
668 }
669}
670
8bb4bdeb
XL
671fn error_192(tcx: TyCtxt, span: Span) {
672 span_err!(tcx.sess, span, E0192,
e9174d1e
SL
673 "negative impls are only allowed for traits with \
674 default impls (e.g., `Send` and `Sync`)")
675}
676
8bb4bdeb
XL
677fn error_380(tcx: TyCtxt, span: Span) {
678 span_err!(tcx.sess, span, E0380,
9e0c209e 679 "traits with default impls (`e.g. impl \
e9174d1e
SL
680 Trait for ..`) must have no methods or associated items")
681}
682
8bb4bdeb 683fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name)
9cc50fc6 684 -> DiagnosticBuilder<'tcx> {
8bb4bdeb 685 let mut err = struct_span_err!(tcx.sess, span, E0392,
9e0c209e
SL
686 "parameter `{}` is never used", param_name);
687 err.span_label(span, &format!("unused type parameter"));
688 err
e9174d1e
SL
689}
690
9e0c209e
SL
691fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) {
692 struct_span_err!(tcx.sess, span, E0194,
e9174d1e 693 "type parameter `{}` shadows another type parameter of the same name",
9e0c209e
SL
694 name)
695 .span_label(span, &format!("shadows another type parameter"))
696 .span_label(trait_decl_span, &format!("first `{}` declared here", name))
697 .emit();
e9174d1e 698}