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::{self, 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, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 if ty::tls::with(|tcx| tcx.sess.verbose()) {
32 write!(f, "Obligation(predicate={:?},cause={:?},depth={})",
37 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::VtableAutoImpl(ref t) =>
53 super::VtableClosure(ref d) =>
56 super::VtableGenerator(ref d) =>
59 super::VtableFnPointer(ref d) =>
60 write!(f, "VtableFnPointer({:?})", d),
62 super::VtableObject(ref d) =>
65 super::VtableParam(ref n) =>
66 write!(f, "VtableParam({:?})", n),
68 super::VtableBuiltin(ref d) =>
74 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
75 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 write!(f, "VtableImpl(impl_def_id={:?}, substs={:?}, nested={:?})",
83 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> {
84 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85 write!(f, "VtableGenerator(closure_def_id={:?}, substs={:?}, nested={:?})",
92 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 write!(f, "VtableClosure(closure_def_id={:?}, substs={:?}, nested={:?})",
101 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 write!(f, "VtableBuiltin(nested={:?})", self.nested)
107 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableAutoImplData<N> {
108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109 write!(f, "VtableAutoImplData(trait_def_id={:?}, nested={:?})",
115 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 write!(f, "VtableObject(upcast={:?}, vtable_base={}, nested={:?})",
118 self.upcast_trait_ref,
124 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> {
125 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126 write!(f, "VtableFnPointer(fn_ty={:?}, nested={:?})",
132 impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 write!(f, "FulfillmentError({:?},{:?})",
140 impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> {
141 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
143 super::CodeSelectionError(ref e) => write!(f, "{:?}", e),
144 super::CodeProjectionError(ref e) => write!(f, "{:?}", e),
145 super::CodeSubtypeError(ref a, ref b) =>
146 write!(f, "CodeSubtypeError({:?}, {:?})", a, b),
147 super::CodeAmbiguity => write!(f, "Ambiguity")
152 impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154 write!(f, "MismatchedProjectionTypes({:?})", self.err)
158 ///////////////////////////////////////////////////////////////////////////
159 // Lift implementations
161 impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
162 type Lifted = traits::SelectionError<'tcx>;
163 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
165 super::Unimplemented => Some(super::Unimplemented),
166 super::OutputTypeParameterMismatch(a, b, ref err) => {
167 tcx.lift(&(a, b)).and_then(|(a, b)| {
168 tcx.lift(err).map(|err| {
169 super::OutputTypeParameterMismatch(a, b, err)
173 super::TraitNotObjectSafe(def_id) => {
174 Some(super::TraitNotObjectSafe(def_id))
176 super::ConstEvalFailure(ref err) => {
177 tcx.lift(err).map(super::ConstEvalFailure)
183 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
184 type Lifted = traits::ObligationCauseCode<'tcx>;
185 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
187 super::ReturnNoExpression => Some(super::ReturnNoExpression),
188 super::MiscObligation => Some(super::MiscObligation),
189 super::SliceOrArrayElem => Some(super::SliceOrArrayElem),
190 super::TupleElem => Some(super::TupleElem),
191 super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
192 super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
193 super::ReferenceOutlivesReferent(ty) => {
194 tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
196 super::ObjectTypeBound(ty, r) => {
197 tcx.lift(&ty).and_then(|ty| {
198 tcx.lift(&r).and_then(|r| {
199 Some(super::ObjectTypeBound(ty, r))
203 super::ObjectCastObligation(ty) => {
204 tcx.lift(&ty).map(super::ObjectCastObligation)
206 super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
207 super::TupleInitializerSized => Some(super::TupleInitializerSized),
208 super::StructInitializerSized => Some(super::StructInitializerSized),
209 super::VariableType(id) => Some(super::VariableType(id)),
210 super::ReturnType(id) => Some(super::ReturnType(id)),
211 super::SizedReturnType => Some(super::SizedReturnType),
212 super::SizedYieldType => Some(super::SizedYieldType),
213 super::RepeatVec => Some(super::RepeatVec),
214 super::FieldSized(item) => Some(super::FieldSized(item)),
215 super::ConstSized => Some(super::ConstSized),
216 super::SharedStatic => Some(super::SharedStatic),
217 super::BuiltinDerivedObligation(ref cause) => {
218 tcx.lift(cause).map(super::BuiltinDerivedObligation)
220 super::ImplDerivedObligation(ref cause) => {
221 tcx.lift(cause).map(super::ImplDerivedObligation)
223 super::CompareImplMethodObligation { item_name,
225 trait_item_def_id } => {
226 Some(super::CompareImplMethodObligation {
232 super::ExprAssignable => Some(super::ExprAssignable),
233 super::MatchExpressionArm { arm_span, source } => {
234 Some(super::MatchExpressionArm { arm_span,
237 super::IfExpression => Some(super::IfExpression),
238 super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
239 super::EquatePredicate => Some(super::EquatePredicate),
240 super::MainFunctionType => Some(super::MainFunctionType),
241 super::StartFunctionType => Some(super::StartFunctionType),
242 super::IntrinsicType => Some(super::IntrinsicType),
243 super::MethodReceiver => Some(super::MethodReceiver),
244 super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
249 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
250 type Lifted = traits::DerivedObligationCause<'tcx>;
251 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
252 tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
253 tcx.lift(&*self.parent_code).map(|code| {
254 traits::DerivedObligationCause {
255 parent_trait_ref: trait_ref,
256 parent_code: Rc::new(code)
263 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
264 type Lifted = traits::ObligationCause<'tcx>;
265 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
266 tcx.lift(&self.code).map(|code| {
267 traits::ObligationCause {
269 body_id: self.body_id,
277 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
278 type Lifted = traits::Vtable<'tcx, ()>;
279 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
281 traits::VtableImpl(traits::VtableImplData {
286 tcx.lift(&substs).map(|substs| {
287 traits::VtableImpl(traits::VtableImplData {
294 traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
295 traits::VtableGenerator(traits::VtableGeneratorData {
300 tcx.lift(&substs).map(|substs| {
301 traits::VtableGenerator(traits::VtableGeneratorData {
302 closure_def_id: closure_def_id,
308 traits::VtableClosure(traits::VtableClosureData {
313 tcx.lift(&substs).map(|substs| {
314 traits::VtableClosure(traits::VtableClosureData {
321 traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
322 tcx.lift(&fn_ty).map(|fn_ty| {
323 traits::VtableFnPointer(traits::VtableFnPointerData {
329 traits::VtableParam(n) => Some(traits::VtableParam(n)),
330 traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
331 traits::VtableObject(traits::VtableObjectData {
336 tcx.lift(&upcast_trait_ref).map(|trait_ref| {
337 traits::VtableObject(traits::VtableObjectData {
338 upcast_trait_ref: trait_ref,
348 ///////////////////////////////////////////////////////////////////////////
349 // TypeFoldable implementations.
351 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O>
353 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
355 cause: self.cause.clone(),
356 recursion_depth: self.recursion_depth,
357 predicate: self.predicate.fold_with(folder),
358 param_env: self.param_env.fold_with(folder),
362 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
363 self.predicate.visit_with(visitor)
367 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
368 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
369 traits::VtableImplData {
370 impl_def_id: self.impl_def_id,
371 substs: self.substs.fold_with(folder),
372 nested: self.nested.fold_with(folder),
376 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
377 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
381 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
382 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
383 traits::VtableGeneratorData {
384 closure_def_id: self.closure_def_id,
385 substs: self.substs.fold_with(folder),
386 nested: self.nested.fold_with(folder),
390 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
391 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
395 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
396 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
397 traits::VtableClosureData {
398 closure_def_id: self.closure_def_id,
399 substs: self.substs.fold_with(folder),
400 nested: self.nested.fold_with(folder),
404 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
405 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
409 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
410 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
411 traits::VtableAutoImplData {
412 trait_def_id: self.trait_def_id,
413 nested: self.nested.fold_with(folder),
417 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
418 self.nested.visit_with(visitor)
422 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
423 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
424 traits::VtableBuiltinData {
425 nested: self.nested.fold_with(folder),
429 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
430 self.nested.visit_with(visitor)
434 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
435 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
436 traits::VtableObjectData {
437 upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
438 vtable_base: self.vtable_base,
439 nested: self.nested.fold_with(folder),
443 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
444 self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
448 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
449 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
450 traits::VtableFnPointerData {
451 fn_ty: self.fn_ty.fold_with(folder),
452 nested: self.nested.fold_with(folder),
456 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
457 self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
461 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
462 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
464 traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
465 traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)),
466 traits::VtableGenerator(ref d) => {
467 traits::VtableGenerator(d.fold_with(folder))
469 traits::VtableClosure(ref d) => {
470 traits::VtableClosure(d.fold_with(folder))
472 traits::VtableFnPointer(ref d) => {
473 traits::VtableFnPointer(d.fold_with(folder))
475 traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
476 traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
477 traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
481 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
483 traits::VtableImpl(ref v) => v.visit_with(visitor),
484 traits::VtableAutoImpl(ref t) => t.visit_with(visitor),
485 traits::VtableGenerator(ref d) => d.visit_with(visitor),
486 traits::VtableClosure(ref d) => d.visit_with(visitor),
487 traits::VtableFnPointer(ref d) => d.visit_with(visitor),
488 traits::VtableParam(ref n) => n.visit_with(visitor),
489 traits::VtableBuiltin(ref d) => d.visit_with(visitor),
490 traits::VtableObject(ref d) => d.visit_with(visitor),
495 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
496 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
498 value: self.value.fold_with(folder),
499 obligations: self.obligations.fold_with(folder),
503 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
504 self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
508 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
509 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
511 super::ExprAssignable |
512 super::MatchExpressionArm { arm_span: _, source: _ } |
513 super::IfExpression |
514 super::IfExpressionWithNoElse |
515 super::EquatePredicate |
516 super::MainFunctionType |
517 super::StartFunctionType |
518 super::IntrinsicType |
519 super::MethodReceiver |
520 super::MiscObligation |
521 super::SliceOrArrayElem |
523 super::ItemObligation(_) |
524 super::AssignmentLhsSized |
525 super::TupleInitializerSized |
526 super::StructInitializerSized |
527 super::VariableType(_) |
528 super::ReturnType(_) |
529 super::SizedReturnType |
530 super::SizedYieldType |
531 super::ReturnNoExpression |
533 super::FieldSized(_) |
535 super::SharedStatic |
536 super::BlockTailExpression(_) |
537 super::CompareImplMethodObligation { .. } => self.clone(),
539 super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
540 super::ReferenceOutlivesReferent(ty) => {
541 super::ReferenceOutlivesReferent(ty.fold_with(folder))
543 super::ObjectTypeBound(ty, r) => {
544 super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
546 super::ObjectCastObligation(ty) => {
547 super::ObjectCastObligation(ty.fold_with(folder))
549 super::BuiltinDerivedObligation(ref cause) => {
550 super::BuiltinDerivedObligation(cause.fold_with(folder))
552 super::ImplDerivedObligation(ref cause) => {
553 super::ImplDerivedObligation(cause.fold_with(folder))
558 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
560 super::ExprAssignable |
561 super::MatchExpressionArm { arm_span: _, source: _ } |
562 super::IfExpression |
563 super::IfExpressionWithNoElse |
564 super::EquatePredicate |
565 super::MainFunctionType |
566 super::StartFunctionType |
567 super::IntrinsicType |
568 super::MethodReceiver |
569 super::MiscObligation |
570 super::SliceOrArrayElem |
572 super::ItemObligation(_) |
573 super::AssignmentLhsSized |
574 super::TupleInitializerSized |
575 super::StructInitializerSized |
576 super::VariableType(_) |
577 super::ReturnType(_) |
578 super::SizedReturnType |
579 super::SizedYieldType |
580 super::ReturnNoExpression |
582 super::FieldSized(_) |
584 super::SharedStatic |
585 super::BlockTailExpression(_) |
586 super::CompareImplMethodObligation { .. } => false,
588 super::ProjectionWf(proj) => proj.visit_with(visitor),
589 super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
590 super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
591 super::ObjectCastObligation(ty) => ty.visit_with(visitor),
592 super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
593 super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
598 impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
599 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
600 traits::DerivedObligationCause {
601 parent_trait_ref: self.parent_trait_ref.fold_with(folder),
602 parent_code: self.parent_code.fold_with(folder)
606 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
607 self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
611 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
612 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
613 traits::ObligationCause {
615 body_id: self.body_id,
616 code: self.code.fold_with(folder),
620 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
621 self.code.visit_with(visitor)