1 // Copyright 2012-2015 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.
12 use traits::project::Normalized;
13 use ty::{Lift, TyCtxt};
14 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
19 // structural impls for the structs in traits
21 impl<'tcx, T: fmt::Debug> fmt::Debug for Normalized<'tcx, T> {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 write!(f, "Normalized({:?},{:?})",
29 impl<'tcx> fmt::Debug for traits::RegionObligation<'tcx> {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})",
36 impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 write!(f, "Obligation(predicate={:?},depth={})",
44 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> {
45 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 super::VtableImpl(ref v) =>
50 super::VtableDefaultImpl(ref t) =>
53 super::VtableClosure(ref d) =>
56 super::VtableFnPointer(ref d) =>
57 write!(f, "VtableFnPointer({:?})", d),
59 super::VtableObject(ref d) =>
62 super::VtableParam(ref n) =>
63 write!(f, "VtableParam({:?})", n),
65 super::VtableBuiltin(ref d) =>
71 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 write!(f, "VtableImpl(impl_def_id={:?}, substs={:?}, nested={:?})",
80 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
81 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 write!(f, "VtableClosure(closure_def_id={:?}, substs={:?}, nested={:?})",
89 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 write!(f, "VtableBuiltin(nested={:?})", self.nested)
95 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableDefaultImplData<N> {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 write!(f, "VtableDefaultImplData(trait_def_id={:?}, nested={:?})",
103 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 write!(f, "VtableObject(upcast={:?}, vtable_base={}, nested={:?})",
106 self.upcast_trait_ref,
112 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> {
113 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114 write!(f, "VtableFnPointer(fn_ty={:?}, nested={:?})",
120 impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> {
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 write!(f, "FulfillmentError({:?},{:?})",
128 impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> {
129 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 super::CodeSelectionError(ref e) => write!(f, "{:?}", e),
132 super::CodeProjectionError(ref e) => write!(f, "{:?}", e),
133 super::CodeSubtypeError(ref a, ref b) =>
134 write!(f, "CodeSubtypeError({:?}, {:?})", a, b),
135 super::CodeAmbiguity => write!(f, "Ambiguity")
140 impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
141 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142 write!(f, "MismatchedProjectionTypes({:?})", self.err)
146 ///////////////////////////////////////////////////////////////////////////
147 // Lift implementations
149 impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
150 type Lifted = traits::SelectionError<'tcx>;
151 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
153 super::Unimplemented => Some(super::Unimplemented),
154 super::OutputTypeParameterMismatch(a, b, ref err) => {
155 tcx.lift(&(a, b)).and_then(|(a, b)| {
156 tcx.lift(err).map(|err| {
157 super::OutputTypeParameterMismatch(a, b, err)
161 super::TraitNotObjectSafe(def_id) => {
162 Some(super::TraitNotObjectSafe(def_id))
168 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
169 type Lifted = traits::ObligationCauseCode<'tcx>;
170 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
172 super::ReturnNoExpression => Some(super::ReturnNoExpression),
173 super::MiscObligation => Some(super::MiscObligation),
174 super::SliceOrArrayElem => Some(super::SliceOrArrayElem),
175 super::TupleElem => Some(super::TupleElem),
176 super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
177 super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
178 super::ReferenceOutlivesReferent(ty) => {
179 tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
181 super::ObjectTypeBound(ty, r) => {
182 tcx.lift(&ty).and_then(|ty| {
183 tcx.lift(&r).and_then(|r| {
184 Some(super::ObjectTypeBound(ty, r))
188 super::ObjectCastObligation(ty) => {
189 tcx.lift(&ty).map(super::ObjectCastObligation)
191 super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
192 super::StructInitializerSized => Some(super::StructInitializerSized),
193 super::VariableType(id) => Some(super::VariableType(id)),
194 super::ReturnType => Some(super::ReturnType),
195 super::RepeatVec => Some(super::RepeatVec),
196 super::FieldSized => Some(super::FieldSized),
197 super::ConstSized => Some(super::ConstSized),
198 super::SharedStatic => Some(super::SharedStatic),
199 super::BuiltinDerivedObligation(ref cause) => {
200 tcx.lift(cause).map(super::BuiltinDerivedObligation)
202 super::ImplDerivedObligation(ref cause) => {
203 tcx.lift(cause).map(super::ImplDerivedObligation)
205 super::CompareImplMethodObligation { item_name,
209 Some(super::CompareImplMethodObligation {
210 item_name: item_name,
211 impl_item_def_id: impl_item_def_id,
212 trait_item_def_id: trait_item_def_id,
216 super::ExprAssignable => {
217 Some(super::ExprAssignable)
219 super::MatchExpressionArm { arm_span, source } => {
220 Some(super::MatchExpressionArm { arm_span: arm_span,
223 super::IfExpression => {
224 Some(super::IfExpression)
226 super::IfExpressionWithNoElse => {
227 Some(super::IfExpressionWithNoElse)
229 super::EquatePredicate => {
230 Some(super::EquatePredicate)
232 super::MainFunctionType => {
233 Some(super::MainFunctionType)
235 super::StartFunctionType => {
236 Some(super::StartFunctionType)
238 super::IntrinsicType => {
239 Some(super::IntrinsicType)
241 super::MethodReceiver => {
242 Some(super::MethodReceiver)
248 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
249 type Lifted = traits::DerivedObligationCause<'tcx>;
250 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
251 tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
252 tcx.lift(&*self.parent_code).map(|code| {
253 traits::DerivedObligationCause {
254 parent_trait_ref: trait_ref,
255 parent_code: Rc::new(code)
262 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
263 type Lifted = traits::ObligationCause<'tcx>;
264 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
265 tcx.lift(&self.code).map(|code| {
266 traits::ObligationCause {
268 body_id: self.body_id,
276 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
277 type Lifted = traits::Vtable<'tcx, ()>;
278 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
280 traits::VtableImpl(traits::VtableImplData {
285 tcx.lift(&substs).map(|substs| {
286 traits::VtableImpl(traits::VtableImplData {
287 impl_def_id: impl_def_id,
293 traits::VtableDefaultImpl(t) => Some(traits::VtableDefaultImpl(t)),
294 traits::VtableClosure(traits::VtableClosureData {
299 tcx.lift(&substs).map(|substs| {
300 traits::VtableClosure(traits::VtableClosureData {
301 closure_def_id: closure_def_id,
307 traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
308 tcx.lift(&fn_ty).map(|fn_ty| {
309 traits::VtableFnPointer(traits::VtableFnPointerData {
315 traits::VtableParam(n) => Some(traits::VtableParam(n)),
316 traits::VtableBuiltin(d) => Some(traits::VtableBuiltin(d)),
317 traits::VtableObject(traits::VtableObjectData {
322 tcx.lift(&upcast_trait_ref).map(|trait_ref| {
323 traits::VtableObject(traits::VtableObjectData {
324 upcast_trait_ref: trait_ref,
325 vtable_base: vtable_base,
334 ///////////////////////////////////////////////////////////////////////////
335 // TypeFoldable implementations.
337 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O>
339 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
341 cause: self.cause.clone(),
342 recursion_depth: self.recursion_depth,
343 predicate: self.predicate.fold_with(folder),
347 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
348 self.predicate.visit_with(visitor)
352 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
353 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
354 traits::VtableImplData {
355 impl_def_id: self.impl_def_id,
356 substs: self.substs.fold_with(folder),
357 nested: self.nested.fold_with(folder),
361 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
362 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
366 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
367 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
368 traits::VtableClosureData {
369 closure_def_id: self.closure_def_id,
370 substs: self.substs.fold_with(folder),
371 nested: self.nested.fold_with(folder),
375 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
376 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
380 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultImplData<N> {
381 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
382 traits::VtableDefaultImplData {
383 trait_def_id: self.trait_def_id,
384 nested: self.nested.fold_with(folder),
388 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
389 self.nested.visit_with(visitor)
393 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
394 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
395 traits::VtableBuiltinData {
396 nested: self.nested.fold_with(folder),
400 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
401 self.nested.visit_with(visitor)
405 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
406 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
407 traits::VtableObjectData {
408 upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
409 vtable_base: self.vtable_base,
410 nested: self.nested.fold_with(folder),
414 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
415 self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
419 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
420 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
421 traits::VtableFnPointerData {
422 fn_ty: self.fn_ty.fold_with(folder),
423 nested: self.nested.fold_with(folder),
427 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
428 self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
432 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
433 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
435 traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
436 traits::VtableDefaultImpl(ref t) => traits::VtableDefaultImpl(t.fold_with(folder)),
437 traits::VtableClosure(ref d) => {
438 traits::VtableClosure(d.fold_with(folder))
440 traits::VtableFnPointer(ref d) => {
441 traits::VtableFnPointer(d.fold_with(folder))
443 traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
444 traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
445 traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
449 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
451 traits::VtableImpl(ref v) => v.visit_with(visitor),
452 traits::VtableDefaultImpl(ref t) => t.visit_with(visitor),
453 traits::VtableClosure(ref d) => d.visit_with(visitor),
454 traits::VtableFnPointer(ref d) => d.visit_with(visitor),
455 traits::VtableParam(ref n) => n.visit_with(visitor),
456 traits::VtableBuiltin(ref d) => d.visit_with(visitor),
457 traits::VtableObject(ref d) => d.visit_with(visitor),
462 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
463 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
465 value: self.value.fold_with(folder),
466 obligations: self.obligations.fold_with(folder),
470 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
471 self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
475 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
476 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
478 super::ExprAssignable |
479 super::MatchExpressionArm { arm_span: _, source: _ } |
480 super::IfExpression |
481 super::IfExpressionWithNoElse |
482 super::EquatePredicate |
483 super::MainFunctionType |
484 super::StartFunctionType |
485 super::IntrinsicType |
486 super::MethodReceiver |
487 super::MiscObligation |
488 super::SliceOrArrayElem |
490 super::ItemObligation(_) |
491 super::AssignmentLhsSized |
492 super::StructInitializerSized |
493 super::VariableType(_) |
495 super::ReturnNoExpression |
499 super::SharedStatic |
500 super::CompareImplMethodObligation { .. } => self.clone(),
502 super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
503 super::ReferenceOutlivesReferent(ty) => {
504 super::ReferenceOutlivesReferent(ty.fold_with(folder))
506 super::ObjectTypeBound(ty, r) => {
507 super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
509 super::ObjectCastObligation(ty) => {
510 super::ObjectCastObligation(ty.fold_with(folder))
512 super::BuiltinDerivedObligation(ref cause) => {
513 super::BuiltinDerivedObligation(cause.fold_with(folder))
515 super::ImplDerivedObligation(ref cause) => {
516 super::ImplDerivedObligation(cause.fold_with(folder))
521 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
523 super::ExprAssignable |
524 super::MatchExpressionArm { arm_span: _, source: _ } |
525 super::IfExpression |
526 super::IfExpressionWithNoElse |
527 super::EquatePredicate |
528 super::MainFunctionType |
529 super::StartFunctionType |
530 super::IntrinsicType |
531 super::MethodReceiver |
532 super::MiscObligation |
533 super::SliceOrArrayElem |
535 super::ItemObligation(_) |
536 super::AssignmentLhsSized |
537 super::StructInitializerSized |
538 super::VariableType(_) |
540 super::ReturnNoExpression |
544 super::SharedStatic |
545 super::CompareImplMethodObligation { .. } => false,
547 super::ProjectionWf(proj) => proj.visit_with(visitor),
548 super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
549 super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
550 super::ObjectCastObligation(ty) => ty.visit_with(visitor),
551 super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
552 super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
557 impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
558 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
559 traits::DerivedObligationCause {
560 parent_trait_ref: self.parent_trait_ref.fold_with(folder),
561 parent_code: self.parent_code.fold_with(folder)
565 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
566 self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
570 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
571 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
572 traits::ObligationCause {
574 body_id: self.body_id,
575 code: self.code.fold_with(folder),
579 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
580 self.code.visit_with(visitor)