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.
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.
11 use check::{Inherited, FnCtxt};
12 use constrained_type_params::{identify_constrained_type_params, Parameter};
14 use hir::def_id::DefId;
15 use rustc::traits::{self, ObligationCauseCode};
16 use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind};
17 use rustc::ty::subst::Substs;
18 use rustc::ty::util::ExplicitSelf;
19 use rustc::util::nodemap::{FxHashSet, FxHashMap};
20 use rustc::middle::lang_items;
23 use syntax::feature_gate::{self, GateIssue};
25 use errors::{DiagnosticBuilder, DiagnosticId};
27 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
30 /// Helper type of a temporary returned by .for_item(...).
31 /// Necessary because we can't write the following bound:
32 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
33 struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
34 inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
37 param_env: ty::ParamEnv<'tcx>,
40 impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
41 fn with_fcx<F>(&'tcx mut self, f: F) where
42 F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>,
43 TyCtxt<'b, 'gcx, 'gcx>) -> Vec<Ty<'tcx>>
47 let param_env = self.param_env;
48 self.inherited.enter(|inh| {
49 let fcx = FnCtxt::new(&inh, param_env, id);
50 if !inh.tcx.features().trivial_bounds {
51 // As predicates are cached rather than obligations, this
52 // needsto be called first so that they are checked with an
54 check_false_global_bounds(&fcx, span, id);
56 let wf_tys = f(&fcx, fcx.tcx.global_tcx());
57 fcx.select_all_obligations_or_error();
58 fcx.regionck_item(id, span, &wf_tys);
63 /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
64 /// well-formed, meaning that they do not require any constraints not declared in the struct
65 /// definition itself. For example, this definition would be illegal:
67 /// struct Ref<'a, T> { x: &'a T }
69 /// because the type did not declare that `T:'a`.
71 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
72 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
74 pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
75 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
76 let item = tcx.hir.expect_item(node_id);
78 debug!("check_item_well_formed(it.id={}, it.name={})",
80 tcx.item_path_str(def_id));
83 // Right now we check that every default trait implementation
84 // has an implementation of itself. Basically, a case like:
86 // `impl Trait for T {}`
88 // has a requirement of `T: Trait` which was required for default
89 // method implementations. Although this could be improved now that
90 // there's a better infrastructure in place for this, it's being left
91 // for a follow-up work.
93 // Since there's such a requirement, we need to check *just* positive
94 // implementations, otherwise things like:
96 // impl !Send for T {}
98 // won't be allowed unless there's an *explicit* implementation of `Send`
100 hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => {
101 let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id))
102 .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
103 if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
104 tcx.sess.span_err(item.span, "impls of auto traits cannot be default");
106 if polarity == hir::ImplPolarity::Positive {
107 check_impl(tcx, item, self_ty, trait_ref);
109 // FIXME(#27579) what amount of WF checking do we need for neg impls?
110 if trait_ref.is_some() && !is_auto {
111 span_err!(tcx.sess, item.span, E0192,
112 "negative impls are only allowed for \
113 auto traits (e.g., `Send` and `Sync`)")
118 check_item_fn(tcx, item);
120 hir::ItemStatic(..) => {
121 check_item_type(tcx, item);
123 hir::ItemConst(..) => {
124 check_item_type(tcx, item);
126 hir::ItemStruct(ref struct_def, ref ast_generics) => {
127 check_type_defn(tcx, item, false, |fcx| {
128 vec![fcx.non_enum_variant(struct_def)]
131 check_variances_for_type_defn(tcx, item, ast_generics);
133 hir::ItemUnion(ref struct_def, ref ast_generics) => {
134 check_type_defn(tcx, item, true, |fcx| {
135 vec![fcx.non_enum_variant(struct_def)]
138 check_variances_for_type_defn(tcx, item, ast_generics);
140 hir::ItemEnum(ref enum_def, ref ast_generics) => {
141 check_type_defn(tcx, item, true, |fcx| {
142 fcx.enum_variants(enum_def)
145 check_variances_for_type_defn(tcx, item, ast_generics);
147 hir::ItemTrait(..) => {
148 check_trait(tcx, item);
154 pub fn check_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
155 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
156 let trait_item = tcx.hir.expect_trait_item(node_id);
158 let method_sig = match trait_item.node {
159 hir::TraitItemKind::Method(ref sig, _) => Some(sig),
162 check_associated_item(tcx, trait_item.id, trait_item.span, method_sig);
165 pub fn check_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
166 let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
167 let impl_item = tcx.hir.expect_impl_item(node_id);
169 let method_sig = match impl_item.node {
170 hir::ImplItemKind::Method(ref sig, _) => Some(sig),
173 check_associated_item(tcx, impl_item.id, impl_item.span, method_sig);
176 fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
177 item_id: ast::NodeId,
179 sig_if_method: Option<&hir::MethodSig>) {
180 let code = ObligationCauseCode::MiscObligation;
181 for_id(tcx, item_id, span).with_fcx(|fcx, tcx| {
182 let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
184 let (mut implied_bounds, self_ty) = match item.container {
185 ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
186 ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span),
187 fcx.tcx.type_of(def_id))
191 ty::AssociatedKind::Const => {
192 let ty = fcx.tcx.type_of(item.def_id);
193 let ty = fcx.normalize_associated_types_in(span, &ty);
194 fcx.register_wf_obligation(ty, span, code.clone());
196 ty::AssociatedKind::Method => {
197 reject_shadowing_parameters(fcx.tcx, item.def_id);
198 let sig = fcx.tcx.fn_sig(item.def_id);
199 let sig = fcx.normalize_associated_types_in(span, &sig);
200 check_fn_or_method(tcx, fcx, span, sig,
201 item.def_id, &mut implied_bounds);
202 let sig_if_method = sig_if_method.expect("bad signature for method");
203 check_method_receiver(fcx, sig_if_method, &item, self_ty);
205 ty::AssociatedKind::Type => {
206 if item.defaultness.has_value() {
207 let ty = fcx.tcx.type_of(item.def_id);
208 let ty = fcx.normalize_associated_types_in(span, &ty);
209 fcx.register_wf_obligation(ty, span, code.clone());
218 fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, item: &hir::Item)
219 -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
220 for_id(tcx, item.id, item.span)
223 fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span)
224 -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
225 let def_id = tcx.hir.local_def_id(id);
227 inherited: Inherited::build(tcx, def_id),
230 param_env: tcx.param_env(def_id),
234 /// In a type definition, we check that to ensure that the types of the fields are well-formed.
235 fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
236 item: &hir::Item, all_sized: bool, mut lookup_fields: F)
237 where F: for<'fcx, 'gcx, 'tcx2> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx2>) -> Vec<AdtVariant<'tcx2>>
239 for_item(tcx, item).with_fcx(|fcx, fcx_tcx| {
240 let variants = lookup_fields(fcx);
241 let def_id = fcx.tcx.hir.local_def_id(item.id);
242 let packed = fcx.tcx.adt_def(def_id).repr.packed();
244 for variant in &variants {
245 // For DST, or when drop needs to copy things around, all
246 // intermediate types must be sized.
247 let needs_drop_copy = || {
249 let ty = variant.fields.last().unwrap().ty;
250 let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx)
252 span_bug!(item.span, "inference variables in {:?}", ty)
254 ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))
259 variant.fields.is_empty() ||
266 for field in &variant.fields[..variant.fields.len() - unsized_len] {
269 fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
270 traits::ObligationCause::new(field.span,
272 traits::FieldSized(match item.node.adt_kind() {
278 // All field types must be well-formed.
279 for field in &variant.fields {
280 fcx.register_wf_obligation(field.ty, field.span,
281 ObligationCauseCode::MiscObligation)
285 check_where_clauses(tcx, fcx, item.span, def_id);
287 vec![] // no implied bounds in a struct def'n
291 fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
292 let trait_def_id = tcx.hir.local_def_id(item.id);
293 for_item(tcx, item).with_fcx(|fcx, _| {
294 check_where_clauses(tcx, fcx, item.span, trait_def_id);
299 fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
300 for_item(tcx, item).with_fcx(|fcx, tcx| {
301 let def_id = fcx.tcx.hir.local_def_id(item.id);
302 let sig = fcx.tcx.fn_sig(def_id);
303 let sig = fcx.normalize_associated_types_in(item.span, &sig);
304 let mut implied_bounds = vec![];
305 check_fn_or_method(tcx, fcx, item.span, sig,
306 def_id, &mut implied_bounds);
311 fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
314 debug!("check_item_type: {:?}", item);
316 for_item(tcx, item).with_fcx(|fcx, _this| {
317 let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id));
318 let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
320 fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation);
322 vec![] // no implied bounds in a const etc
326 fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
328 ast_self_ty: &hir::Ty,
329 ast_trait_ref: &Option<hir::TraitRef>)
331 debug!("check_impl: {:?}", item);
333 for_item(tcx, item).with_fcx(|fcx, tcx| {
334 let item_def_id = fcx.tcx.hir.local_def_id(item.id);
336 match *ast_trait_ref {
337 Some(ref ast_trait_ref) => {
338 let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap();
340 fcx.normalize_associated_types_in(
341 ast_trait_ref.path.span, &trait_ref);
343 ty::wf::trait_obligations(fcx,
347 ast_trait_ref.path.span);
348 for obligation in obligations {
349 fcx.register_predicate(obligation);
353 let self_ty = fcx.tcx.type_of(item_def_id);
354 let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty);
355 fcx.register_wf_obligation(self_ty, ast_self_ty.span,
356 ObligationCauseCode::MiscObligation);
360 check_where_clauses(tcx, fcx, item.span, item_def_id);
362 fcx.impl_implied_bounds(item_def_id, item.span)
366 /// Checks where clauses and inline bounds that are declared on def_id.
367 fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
368 fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
371 use ty::subst::Subst;
372 use rustc::ty::TypeFoldable;
374 let mut predicates = fcx.tcx.predicates_of(def_id);
375 let mut substituted_predicates = Vec::new();
377 let generics = tcx.generics_of(def_id);
378 let is_our_default = |def: &ty::GenericParamDef| {
380 GenericParamDefKind::Type { has_default, .. } => {
381 has_default && def.index >= generics.parent_count as u32
387 // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
388 // For example this forbids the declaration:
389 // struct Foo<T = Vec<[u32]>> { .. }
390 // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
391 for param in &generics.params {
392 if let GenericParamDefKind::Type {..} = param.kind {
393 if is_our_default(¶m) {
394 let ty = fcx.tcx.type_of(param.def_id);
395 // ignore dependent defaults -- that is, where the default of one type
396 // parameter includes another (e.g., <T, U = T>). In those cases, we can't
397 // be sure if it will error or not as user might always specify the other.
398 if !ty.needs_subst() {
399 fcx.register_wf_obligation(ty, fcx.tcx.def_span(param.def_id),
400 ObligationCauseCode::MiscObligation);
406 // Check that trait predicates are WF when params are substituted by their defaults.
407 // We don't want to overly constrain the predicates that may be written but we want to
408 // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
409 // Therefore we check if a predicate which contains a single type param
410 // with a concrete default is WF with that default substituted.
411 // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
413 // First we build the defaulted substitution.
414 let substs = Substs::for_item(fcx.tcx, def_id, |param, _| {
416 GenericParamDefKind::Lifetime => {
417 // All regions are identity.
418 fcx.tcx.mk_param_from_def(param)
420 GenericParamDefKind::Type {..} => {
421 // If the param has a default,
422 if is_our_default(param) {
423 let default_ty = fcx.tcx.type_of(param.def_id);
424 // and it's not a dependent default
425 if !default_ty.needs_subst() {
426 // then substitute with the default.
427 return default_ty.into();
430 // Mark unwanted params as err.
431 fcx.tcx.types.err.into()
435 // Now we build the substituted predicates.
436 for &pred in predicates.predicates.iter() {
437 struct CountParams { params: FxHashSet<u32> }
438 impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
439 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
442 self.params.insert(p.idx);
443 t.super_visit_with(self)
445 _ => t.super_visit_with(self)
449 fn visit_region(&mut self, _: ty::Region<'tcx>) -> bool {
453 let mut param_count = CountParams { params: FxHashSet() };
454 let has_region = pred.visit_with(&mut param_count);
455 let substituted_pred = pred.subst(fcx.tcx, substs);
456 // Don't check non-defaulted params, dependent defaults (including lifetimes)
457 // or preds with multiple params.
458 if substituted_pred.references_error() || param_count.params.len() > 1
462 // Avoid duplication of predicates that contain no parameters, for example.
463 if !predicates.predicates.contains(&substituted_pred) {
464 substituted_predicates.push(substituted_pred);
468 predicates.predicates.extend(substituted_predicates);
469 let predicates = predicates.instantiate_identity(fcx.tcx);
470 let predicates = fcx.normalize_associated_types_in(span, &predicates);
473 predicates.predicates
475 .flat_map(|p| ty::wf::predicate_obligations(fcx,
481 for obligation in obligations {
482 fcx.register_predicate(obligation);
486 fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
487 fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
489 sig: ty::PolyFnSig<'tcx>,
491 implied_bounds: &mut Vec<Ty<'tcx>>)
493 let sig = fcx.normalize_associated_types_in(span, &sig);
494 let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig);
496 for input_ty in sig.inputs() {
497 fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation);
499 implied_bounds.extend(sig.inputs());
501 fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation);
503 // FIXME(#25759) return types should not be implied bounds
504 implied_bounds.push(sig.output());
506 check_where_clauses(tcx, fcx, span, def_id);
509 fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
510 method_sig: &hir::MethodSig,
511 method: &ty::AssociatedItem,
514 // check that the method has a valid receiver type, given the type `Self`
515 debug!("check_method_receiver({:?}, self_ty={:?})",
518 if !method.method_has_self_argument {
522 let span = method_sig.decl.inputs[0].span;
524 let sig = fcx.tcx.fn_sig(method.def_id);
525 let sig = fcx.normalize_associated_types_in(span, &sig);
526 let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig);
528 debug!("check_method_receiver: sig={:?}", sig);
530 let self_ty = fcx.normalize_associated_types_in(span, &self_ty);
531 let self_ty = fcx.tcx.liberate_late_bound_regions(
533 &ty::Binder::bind(self_ty)
536 let self_arg_ty = sig.inputs()[0];
538 let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
539 let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty);
540 let self_arg_ty = fcx.tcx.liberate_late_bound_regions(
542 &ty::Binder::bind(self_arg_ty)
545 let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers();
548 if let Some((potential_self_ty, _)) = autoderef.next() {
549 debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`",
550 potential_self_ty, self_ty);
552 if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() {
553 autoderef.finalize();
554 if let Some(mut err) = fcx.demand_eqtype_with_origin(
555 &cause, self_ty, potential_self_ty) {
561 fcx.tcx.sess.diagnostic().mut_span_err(
562 span, &format!("invalid `self` type: {:?}", self_arg_ty))
563 .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty))
564 .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
565 .code(DiagnosticId::Error("E0307".into()))
571 let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok();
572 let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty);
574 if !fcx.tcx.features().arbitrary_self_types {
576 ExplicitSelf::ByValue |
577 ExplicitSelf::ByReference(_, _) |
578 ExplicitSelf::ByBox => (),
580 ExplicitSelf::ByRawPointer(_) => {
581 feature_gate::feature_err(
582 &fcx.tcx.sess.parse_sess,
583 "arbitrary_self_types",
586 "raw pointer `self` is unstable")
587 .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
591 ExplicitSelf::Other => {
592 feature_gate::feature_err(
593 &fcx.tcx.sess.parse_sess,
594 "arbitrary_self_types",
596 GateIssue::Language,"arbitrary `self` types are unstable")
597 .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
604 fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
606 ast_generics: &hir::Generics)
608 let item_def_id = tcx.hir.local_def_id(item.id);
609 let ty = tcx.type_of(item_def_id);
610 if tcx.has_error_field(ty) {
614 let ty_predicates = tcx.predicates_of(item_def_id);
615 assert_eq!(ty_predicates.parent, None);
616 let variances = tcx.variances_of(item_def_id);
618 let mut constrained_parameters: FxHashSet<_> =
619 variances.iter().enumerate()
620 .filter(|&(_, &variance)| variance != ty::Bivariant)
621 .map(|(index, _)| Parameter(index as u32))
624 identify_constrained_type_params(tcx,
625 ty_predicates.predicates.as_slice(),
627 &mut constrained_parameters);
629 for (index, _) in variances.iter().enumerate() {
630 if constrained_parameters.contains(&Parameter(index as u32)) {
634 let (span, name) = match ast_generics.params[index] {
635 hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()),
636 hir::GenericParam::Type(ref tp) => (tp.span, tp.name),
638 report_bivariance(tcx, span, name);
642 fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
644 param_name: ast::Name)
646 let mut err = error_392(tcx, span, param_name);
648 let suggested_marker_id = tcx.lang_items().phantom_data();
649 match suggested_marker_id {
652 &format!("consider removing `{}` or using a marker such as `{}`",
654 tcx.item_path_str(def_id)));
657 // no lang items, no help!
663 fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
664 let generics = tcx.generics_of(def_id);
665 let parent = tcx.generics_of(generics.parent.unwrap());
666 let impl_params: FxHashMap<_, _> =
670 GenericParamDefKind::Lifetime => None,
671 GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
676 for method_param in generics.params.iter() {
677 match method_param.kind {
678 // Shadowing is checked in resolve_lifetime.
679 GenericParamDefKind::Lifetime => continue,
682 if impl_params.contains_key(&method_param.name) {
683 // Tighten up the span to focus on only the shadowing type
684 let type_span = tcx.def_span(method_param.def_id);
686 // The expectation here is that the original trait declaration is
687 // local so it should be okay to just unwrap everything.
688 let trait_def_id = impl_params[&method_param.name];
689 let trait_decl_span = tcx.def_span(trait_def_id);
690 error_194(tcx, type_span, trait_decl_span, &method_param.name.as_str()[..]);
695 /// Feature gates RFC 2056 - trivial bounds, checking for global bounds that
697 fn check_false_global_bounds<'a, 'gcx, 'tcx>(
698 fcx: &FnCtxt<'a, 'gcx, 'tcx>,
702 use rustc::ty::TypeFoldable;
704 let empty_env = ty::ParamEnv::empty();
706 let def_id = fcx.tcx.hir.local_def_id(id);
707 let predicates = fcx.tcx.predicates_of(def_id).predicates;
708 // Check elaborated bounds
709 let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
711 for pred in implied_obligations {
712 // Match the existing behavior.
713 if pred.is_global() && !pred.has_late_bound_regions() {
714 let pred = fcx.normalize_associated_types_in(span, &pred);
715 let obligation = traits::Obligation::new(
716 traits::ObligationCause::new(
719 traits::TrivialBound,
724 fcx.register_predicate(obligation);
728 fcx.select_all_obligations_or_error();
731 pub struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> {
732 tcx: TyCtxt<'a, 'tcx, 'tcx>,
735 impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
736 pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>)
737 -> CheckTypeWellFormedVisitor<'a, 'gcx> {
738 CheckTypeWellFormedVisitor {
744 impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
745 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
746 NestedVisitorMap::None
749 fn visit_item(&mut self, i: &hir::Item) {
750 debug!("visit_item: {:?}", i);
751 let def_id = self.tcx.hir.local_def_id(i.id);
752 ty::maps::queries::check_item_well_formed::ensure(self.tcx, def_id);
753 intravisit::walk_item(self, i);
756 fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
757 debug!("visit_trait_item: {:?}", trait_item);
758 let def_id = self.tcx.hir.local_def_id(trait_item.id);
759 ty::maps::queries::check_trait_item_well_formed::ensure(self.tcx, def_id);
760 intravisit::walk_trait_item(self, trait_item)
763 fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
764 debug!("visit_impl_item: {:?}", impl_item);
765 let def_id = self.tcx.hir.local_def_id(impl_item.id);
766 ty::maps::queries::check_impl_item_well_formed::ensure(self.tcx, def_id);
767 intravisit::walk_impl_item(self, impl_item)
771 ///////////////////////////////////////////////////////////////////////////
774 struct AdtVariant<'tcx> {
775 fields: Vec<AdtField<'tcx>>,
778 struct AdtField<'tcx> {
783 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
784 fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
786 struct_def.fields().iter()
788 let field_ty = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
789 let field_ty = self.normalize_associated_types_in(field.span,
791 AdtField { ty: field_ty, span: field.span }
794 AdtVariant { fields: fields }
797 fn enum_variants(&self, enum_def: &hir::EnumDef) -> Vec<AdtVariant<'tcx>> {
798 enum_def.variants.iter()
799 .map(|variant| self.non_enum_variant(&variant.node.data))
803 fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
804 match self.tcx.impl_trait_ref(impl_def_id) {
805 Some(ref trait_ref) => {
806 // Trait impl: take implied bounds from all types that
807 // appear in the trait reference.
808 let trait_ref = self.normalize_associated_types_in(span, trait_ref);
809 trait_ref.substs.types().collect()
813 // Inherent impl: take implied bounds from the self type.
814 let self_ty = self.tcx.type_of(impl_def_id);
815 let self_ty = self.normalize_associated_types_in(span, &self_ty);
822 fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name)
823 -> DiagnosticBuilder<'tcx> {
824 let mut err = struct_span_err!(tcx.sess, span, E0392,
825 "parameter `{}` is never used", param_name);
826 err.span_label(span, "unused type parameter");
830 fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: &str) {
831 struct_span_err!(tcx.sess, span, E0194,
832 "type parameter `{}` shadows another type parameter of the same name",
834 .span_label(span, "shadows another type parameter")
835 .span_label(trait_decl_span, format!("first `{}` declared here", name))