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 astconv
::ExplicitSelf
;
13 use constrained_type_params
::{identify_constrained_type_params, Parameter}
;
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
;
25 use errors
::DiagnosticBuilder
;
27 use rustc
::hir
::intravisit
::{self, Visitor, NestedVisitorMap}
;
30 pub struct CheckTypeWellFormedVisitor
<'ccx
, 'tcx
:'ccx
> {
31 ccx
: &'ccx CrateCtxt
<'ccx
, 'tcx
>,
32 code
: ObligationCauseCode
<'tcx
>,
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
>,
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
>>
50 let code
= self.code
.clone();
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
{
59 fcx
.select_all_obligations_or_error();
60 fcx
.regionck_item(id
, span
, &wf_tys
);
65 impl<'ccx
, 'gcx
> CheckTypeWellFormedVisitor
<'ccx
, 'gcx
> {
66 pub fn new(ccx
: &'ccx CrateCtxt
<'ccx
, 'gcx
>)
67 -> CheckTypeWellFormedVisitor
<'ccx
, 'gcx
> {
68 CheckTypeWellFormedVisitor
{
70 code
: ObligationCauseCode
::MiscObligation
74 fn tcx(&self) -> TyCtxt
<'ccx
, 'gcx
, 'gcx
> {
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:
82 /// struct Ref<'a, T> { x: &'a T }
84 /// because the type did not declare that `T:'a`.
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
89 fn check_item_well_formed(&mut self, item
: &hir
::Item
) {
91 debug
!("check_item_well_formed(it.id={}, it.name={})",
93 ccx
.tcx
.item_path_str(ccx
.tcx
.map
.local_def_id(item
.id
)));
96 /// Right now we check that every default trait implementation
97 /// has an implementation of itself. Basically, a case like:
99 /// `impl Trait for T {}`
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.
106 /// Since there's such a requirement, we need to check *just* positive
107 /// implementations, otherwise things like:
109 /// impl !Send for T {}
111 /// won't be allowed unless there's an *explicit* implementation of `Send`
113 hir
::ItemImpl(_
, hir
::ImplPolarity
::Positive
, _
,
114 ref trait_ref
, ref self_ty
, _
) => {
115 self.check_impl(item
, self_ty
, trait_ref
);
117 hir
::ItemImpl(_
, hir
::ImplPolarity
::Negative
, _
, Some(_
), ..) => {
118 // FIXME(#27579) what amount of WF checking do we need for neg impls?
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
);
125 hir
::ItemFn(.., body_id
) => {
126 self.check_item_fn(item
, body_id
);
128 hir
::ItemStatic(..) => {
129 self.check_item_type(item
);
131 hir
::ItemConst(..) => {
132 self.check_item_type(item
);
134 hir
::ItemStruct(ref struct_def
, ref ast_generics
) => {
135 self.check_type_defn(item
, false, |fcx
| {
136 vec
![fcx
.struct_variant(struct_def
)]
139 self.check_variances_for_type_defn(item
, ast_generics
);
141 hir
::ItemUnion(ref struct_def
, ref ast_generics
) => {
142 self.check_type_defn(item
, true, |fcx
| {
143 vec
![fcx
.struct_variant(struct_def
)]
146 self.check_variances_for_type_defn(item
, ast_generics
);
148 hir
::ItemEnum(ref enum_def
, ref ast_generics
) => {
149 self.check_type_defn(item
, true, |fcx
| {
150 fcx
.enum_variants(enum_def
)
153 self.check_variances_for_type_defn(item
, ast_generics
);
155 hir
::ItemTrait(..) => {
156 self.check_trait(item
);
162 fn check_trait_or_impl_item(&mut self,
163 item_id
: ast
::NodeId
,
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
;
171 let item
= fcx
.tcx
.associated_item(fcx
.tcx
.map
.local_def_id(item_id
));
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
))
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());
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
,
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
);
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());
213 fn for_item
<'tcx
>(&self, item
: &hir
::Item
)
214 -> CheckWfFcxBuilder
<'ccx
, 'gcx
, 'tcx
> {
215 self.for_id(item
.id
, item
.span
)
218 fn for_id
<'tcx
>(&self, id
: ast
::NodeId
, span
: Span
)
219 -> CheckWfFcxBuilder
<'ccx
, 'gcx
, 'tcx
> {
221 inherited
: self.ccx
.inherited(id
),
222 code
: self.code
.clone(),
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
>>
232 self.for_item(item
).with_fcx(|fcx
, this
| {
233 let variants
= lookup_fields(fcx
);
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
] {
241 fcx
.tcx
.require_lang_item(lang_items
::SizedTraitLangItem
),
242 traits
::ObligationCause
::new(field
.span
,
244 traits
::FieldSized
));
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())
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
);
258 vec
![] // no implied bounds in a struct def'n
262 fn check_auto_trait(&mut self, trait_def_id
: DefId
, span
: Span
) {
263 // We want to ensure:
265 // 1) that there are no items contained within
266 // the trait defintion
268 // 2) that the definition doesn't violate the no-super trait rule
271 // 3) that the trait definition does not have any type parameters
273 let predicates
= self.tcx().item_predicates(trait_def_id
);
275 // We must exclude the Self : Trait predicate contained by all
278 predicates
.predicates
.iter().any(|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
)
288 let has_ty_params
= self.tcx().item_generics(trait_def_id
).types
.len() > 1;
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>`.
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.
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"));
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.
316 e
.note("the new auto trait rules are the result of a \
317 recent soundness fix; see #29859 for more details");
323 fn check_trait(&mut self, item
: &hir
::Item
) {
324 let trait_def_id
= self.tcx().map
.local_def_id(item
.id
);
326 if self.tcx().trait_has_default_impl(trait_def_id
) {
327 self.check_auto_trait(trait_def_id
, item
.span
);
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
);
338 fn check_item_fn(&mut self,
340 body_id
: hir
::ExprId
)
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
,
350 span_bug
!(item
.span
, "Fn item without fn type");
354 let predicates
= fcx
.instantiate_bounds(item
.span
, def_id
, free_substs
);
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
);
364 fn check_item_type(&mut self,
367 debug
!("check_item_type: {:?}", item
);
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
376 fcx
.register_wf_obligation(item_ty
, item
.span
, this
.code
.clone());
378 vec
![] // no implied bounds in a const etc
382 fn check_impl(&mut self,
384 ast_self_ty
: &hir
::Ty
,
385 ast_trait_ref
: &Option
<hir
::TraitRef
>)
387 debug
!("check_impl: {:?}", item
);
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
);
393 match *ast_trait_ref
{
394 Some(ref ast_trait_ref
) => {
395 let trait_ref
= fcx
.tcx
.impl_trait_ref(item_def_id
).unwrap();
397 fcx
.instantiate_type_scheme(
398 ast_trait_ref
.path
.span
, free_substs
, &trait_ref
);
400 ty
::wf
::trait_obligations(fcx
,
403 ast_trait_ref
.path
.span
);
404 for obligation
in obligations
{
405 fcx
.register_predicate(obligation
);
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());
415 let predicates
= fcx
.instantiate_bounds(item
.span
, item_def_id
, free_substs
);
416 this
.check_where_clauses(fcx
, item
.span
, &predicates
);
418 fcx
.impl_implied_bounds(item_def_id
, item
.span
)
422 fn check_where_clauses
<'fcx
, 'tcx
>(&mut self,
423 fcx
: &FnCtxt
<'fcx
, 'gcx
, 'tcx
>,
425 predicates
: &ty
::InstantiatedPredicates
<'tcx
>)
428 predicates
.predicates
430 .flat_map(|p
| ty
::wf
::predicate_obligations(fcx
,
435 for obligation
in obligations
{
436 fcx
.register_predicate(obligation
);
440 fn check_fn_or_method
<'fcx
, 'tcx
>(&mut self,
441 fcx
: &FnCtxt
<'fcx
, 'gcx
, 'tcx
>,
443 fty
: &'tcx ty
::BareFnTy
<'tcx
>,
444 predicates
: &ty
::InstantiatedPredicates
<'tcx
>,
445 free_id_outlive
: CodeExtent
,
446 implied_bounds
: &mut Vec
<Ty
<'tcx
>>)
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
);
452 for input_ty
in sig
.inputs() {
453 fcx
.register_wf_obligation(&input_ty
, span
, self.code
.clone());
455 implied_bounds
.extend(sig
.inputs());
457 fcx
.register_wf_obligation(sig
.output(), span
, self.code
.clone());
459 // FIXME(#25759) return types should not be implied bounds
460 implied_bounds
.push(sig
.output());
462 self.check_where_clauses(fcx
, span
, predicates
);
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
>)
472 // check that the type of the method's receiver matches the
473 // method's first parameter.
474 debug
!("check_method_receiver({:?}, self_ty={:?})",
477 if !method
.method_has_self_argument
{
481 let span
= method_sig
.decl
.inputs
[0].pat
.span
;
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());
488 debug
!("check_method_receiver: sig={:?}", sig
);
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
{
499 ExplicitSelf
::ByBox
=> fcx
.tcx
.mk_box(self_ty
)
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
));
505 debug
!("check_method_receiver: receiver ty = {:?}", rcvr_ty
);
507 let cause
= fcx
.cause(span
, ObligationCauseCode
::MethodReceiver
);
508 fcx
.demand_eqtype_with_origin(&cause
, rcvr_ty
, self_arg_ty
);
511 fn check_variances_for_type_defn(&self,
513 ast_generics
: &hir
::Generics
)
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
) {
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
);
525 let mut constrained_parameters
: FxHashSet
<_
> =
526 variances
.iter().enumerate()
527 .filter(|&(_
, &variance
)| variance
!= ty
::Bivariant
)
528 .map(|(index
, _
)| Parameter(index
as u32))
531 identify_constrained_type_params(ty_predicates
.predicates
.as_slice(),
533 &mut constrained_parameters
);
535 for (index
, _
) in variances
.iter().enumerate() {
536 if constrained_parameters
.contains(&Parameter(index
as u32)) {
540 let (span
, name
) = if index
< ast_generics
.lifetimes
.len() {
541 (ast_generics
.lifetimes
[index
].lifetime
.span
,
542 ast_generics
.lifetimes
[index
].lifetime
.name
)
544 let index
= index
- ast_generics
.lifetimes
.len();
545 (ast_generics
.ty_params
[index
].span
,
546 ast_generics
.ty_params
[index
].name
)
548 self.report_bivariance(span
, name
);
552 fn report_bivariance(&self,
554 param_name
: ast
::Name
)
556 let mut err
= error_392(self.ccx
, span
, param_name
);
558 let suggested_marker_id
= self.tcx().lang_items
.phantom_data();
559 match suggested_marker_id
{
562 &format
!("consider removing `{}` or using a marker such as `{}`",
564 self.tcx().item_path_str(def_id
)));
567 // no lang items, no help!
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
579 .map(|tp
| (tp
.name
, tp
.def_id
))
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
);
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
);
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
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
);
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
),
613 self.check_trait_or_impl_item(trait_item
.id
, trait_item
.span
, method_sig
);
614 intravisit
::walk_trait_item(self, trait_item
)
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
),
623 self.check_trait_or_impl_item(impl_item
.id
, impl_item
.span
, method_sig
);
624 intravisit
::walk_impl_item(self, impl_item
)
628 ///////////////////////////////////////////////////////////////////////////
631 struct AdtVariant
<'tcx
> {
632 fields
: Vec
<AdtField
<'tcx
>>,
635 struct AdtField
<'tcx
> {
640 impl<'a
, 'gcx
, 'tcx
> FnCtxt
<'a
, 'gcx
, 'tcx
> {
641 fn struct_variant(&self, struct_def
: &hir
::VariantData
) -> AdtVariant
<'tcx
> {
643 struct_def
.fields().iter()
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
650 AdtField { ty: field_ty, span: field.span }
653 AdtVariant { fields: fields }
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
))
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()
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
);
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`)")
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")
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"));
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",
706 .span_label(span
, &format
!("shadows another type parameter"))
707 .span_label(trait_decl_span
, &format
!("first `{}` declared here", name
))