|
7 | 7 | //! `tcx.inherent_impls(def_id)`). That value, however, |
8 | 8 | //! is computed by selecting an idea from this table. |
9 | 9 |
|
| 10 | +use std::ops::ControlFlow; |
| 11 | + |
10 | 12 | use rustc_hir as hir; |
11 | 13 | use rustc_hir::attrs::AttributeKind; |
12 | 14 | use rustc_hir::def::DefKind; |
13 | 15 | use rustc_hir::def_id::{DefId, LocalDefId}; |
14 | 16 | use rustc_hir::find_attr; |
15 | 17 | use rustc_middle::bug; |
16 | 18 | use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams, simplify_type}; |
17 | | -use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; |
| 19 | +use rustc_middle::ty::{self, CrateInherentImpls, FieldPath, Ty, TyCtxt}; |
18 | 20 | use rustc_span::{ErrorGuaranteed, sym}; |
19 | 21 |
|
20 | 22 | use crate::errors; |
@@ -112,6 +114,40 @@ impl<'tcx> InherentCollect<'tcx> { |
112 | 114 | } |
113 | 115 | } |
114 | 116 |
|
| 117 | + fn check_field_type( |
| 118 | + &mut self, |
| 119 | + impl_def_id: LocalDefId, |
| 120 | + container: Ty<'tcx>, |
| 121 | + field_path: FieldPath<'tcx>, |
| 122 | + ) -> Result<(), ErrorGuaranteed> { |
| 123 | + if !matches!(container.kind(), ty::Adt(..)) { |
| 124 | + return Err(self |
| 125 | + .tcx |
| 126 | + .dcx() |
| 127 | + .emit_err(errors::InherentTyOutsideNew { span: self.tcx.def_span(impl_def_id) })); |
| 128 | + } |
| 129 | + if field_path |
| 130 | + .walk(self.tcx, container, |base, _, _, _| { |
| 131 | + if let ty::Adt(def, _) = base.kind() |
| 132 | + && !def.did().is_local() |
| 133 | + { |
| 134 | + ControlFlow::Break(()) |
| 135 | + } else { |
| 136 | + ControlFlow::Continue(()) |
| 137 | + } |
| 138 | + }) |
| 139 | + .is_none() |
| 140 | + { |
| 141 | + self.impls_map |
| 142 | + .incoherent_impls |
| 143 | + .entry(SimplifiedType::Field) |
| 144 | + .or_default() |
| 145 | + .push(impl_def_id); |
| 146 | + } |
| 147 | + |
| 148 | + Ok(()) |
| 149 | + } |
| 150 | + |
115 | 151 | fn check_primitive_impl( |
116 | 152 | &mut self, |
117 | 153 | impl_def_id: LocalDefId, |
@@ -166,6 +202,7 @@ impl<'tcx> InherentCollect<'tcx> { |
166 | 202 | } |
167 | 203 | match *self_ty.kind() { |
168 | 204 | ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()), |
| 205 | + ty::Field(container, field_path) => self.check_field_type(id, container, field_path), |
169 | 206 | ty::Foreign(did) => self.check_def_id(id, self_ty, did), |
170 | 207 | ty::Dynamic(data, ..) if data.principal_def_id().is_some() => { |
171 | 208 | self.check_def_id(id, self_ty, data.principal_def_id().unwrap()) |
|
0 commit comments