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::RepeatVec => Some(super::RepeatVec),
213 super::FieldSized(item) => Some(super::FieldSized(item)),
214 super::ConstSized => Some(super::ConstSized),
215 super::SharedStatic => Some(super::SharedStatic),
216 super::BuiltinDerivedObligation(ref cause) => {
217 tcx.lift(cause).map(super::BuiltinDerivedObligation)
219 super::ImplDerivedObligation(ref cause) => {
220 tcx.lift(cause).map(super::ImplDerivedObligation)
222 super::CompareImplMethodObligation { item_name,
224 trait_item_def_id } => {
225 Some(super::CompareImplMethodObligation {
231 super::ExprAssignable => Some(super::ExprAssignable),
232 super::MatchExpressionArm { arm_span, source } => {
233 Some(super::MatchExpressionArm { arm_span,
236 super::IfExpression => Some(super::IfExpression),
237 super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
238 super::EquatePredicate => Some(super::EquatePredicate),
239 super::MainFunctionType => Some(super::MainFunctionType),
240 super::StartFunctionType => Some(super::StartFunctionType),
241 super::IntrinsicType => Some(super::IntrinsicType),
242 super::MethodReceiver => Some(super::MethodReceiver),
243 super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
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 {
293 traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
294 traits::VtableGenerator(traits::VtableGeneratorData {
299 tcx.lift(&substs).map(|substs| {
300 traits::VtableGenerator(traits::VtableGeneratorData {
301 closure_def_id: closure_def_id,
307 traits::VtableClosure(traits::VtableClosureData {
312 tcx.lift(&substs).map(|substs| {
313 traits::VtableClosure(traits::VtableClosureData {
320 traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
321 tcx.lift(&fn_ty).map(|fn_ty| {
322 traits::VtableFnPointer(traits::VtableFnPointerData {
328 traits::VtableParam(n) => Some(traits::VtableParam(n)),
329 traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
330 traits::VtableObject(traits::VtableObjectData {
335 tcx.lift(&upcast_trait_ref).map(|trait_ref| {
336 traits::VtableObject(traits::VtableObjectData {
337 upcast_trait_ref: trait_ref,
347 ///////////////////////////////////////////////////////////////////////////
348 // TypeFoldable implementations.
350 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O>
352 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
354 cause: self.cause.clone(),
355 recursion_depth: self.recursion_depth,
356 predicate: self.predicate.fold_with(folder),
357 param_env: self.param_env.fold_with(folder),
361 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
362 self.predicate.visit_with(visitor)
366 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
367 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
368 traits::VtableImplData {
369 impl_def_id: self.impl_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::VtableGeneratorData<'tcx, N> {
381 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
382 traits::VtableGeneratorData {
383 closure_def_id: self.closure_def_id,
384 substs: self.substs.fold_with(folder),
385 nested: self.nested.fold_with(folder),
389 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
390 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
394 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
395 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
396 traits::VtableClosureData {
397 closure_def_id: self.closure_def_id,
398 substs: self.substs.fold_with(folder),
399 nested: self.nested.fold_with(folder),
403 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
404 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
408 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
409 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
410 traits::VtableAutoImplData {
411 trait_def_id: self.trait_def_id,
412 nested: self.nested.fold_with(folder),
416 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
417 self.nested.visit_with(visitor)
421 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
422 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
423 traits::VtableBuiltinData {
424 nested: self.nested.fold_with(folder),
428 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
429 self.nested.visit_with(visitor)
433 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
434 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
435 traits::VtableObjectData {
436 upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
437 vtable_base: self.vtable_base,
438 nested: self.nested.fold_with(folder),
442 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
443 self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
447 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
448 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
449 traits::VtableFnPointerData {
450 fn_ty: self.fn_ty.fold_with(folder),
451 nested: self.nested.fold_with(folder),
455 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
456 self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
460 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
461 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
463 traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
464 traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)),
465 traits::VtableGenerator(ref d) => {
466 traits::VtableGenerator(d.fold_with(folder))
468 traits::VtableClosure(ref d) => {
469 traits::VtableClosure(d.fold_with(folder))
471 traits::VtableFnPointer(ref d) => {
472 traits::VtableFnPointer(d.fold_with(folder))
474 traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
475 traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
476 traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
480 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
482 traits::VtableImpl(ref v) => v.visit_with(visitor),
483 traits::VtableAutoImpl(ref t) => t.visit_with(visitor),
484 traits::VtableGenerator(ref d) => d.visit_with(visitor),
485 traits::VtableClosure(ref d) => d.visit_with(visitor),
486 traits::VtableFnPointer(ref d) => d.visit_with(visitor),
487 traits::VtableParam(ref n) => n.visit_with(visitor),
488 traits::VtableBuiltin(ref d) => d.visit_with(visitor),
489 traits::VtableObject(ref d) => d.visit_with(visitor),
494 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
495 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
497 value: self.value.fold_with(folder),
498 obligations: self.obligations.fold_with(folder),
502 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
503 self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
507 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
508 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
510 super::ExprAssignable |
511 super::MatchExpressionArm { arm_span: _, source: _ } |
512 super::IfExpression |
513 super::IfExpressionWithNoElse |
514 super::EquatePredicate |
515 super::MainFunctionType |
516 super::StartFunctionType |
517 super::IntrinsicType |
518 super::MethodReceiver |
519 super::MiscObligation |
520 super::SliceOrArrayElem |
522 super::ItemObligation(_) |
523 super::AssignmentLhsSized |
524 super::TupleInitializerSized |
525 super::StructInitializerSized |
526 super::VariableType(_) |
527 super::ReturnType(_) |
528 super::SizedReturnType |
529 super::ReturnNoExpression |
531 super::FieldSized(_) |
533 super::SharedStatic |
534 super::BlockTailExpression(_) |
535 super::CompareImplMethodObligation { .. } => self.clone(),
537 super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
538 super::ReferenceOutlivesReferent(ty) => {
539 super::ReferenceOutlivesReferent(ty.fold_with(folder))
541 super::ObjectTypeBound(ty, r) => {
542 super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
544 super::ObjectCastObligation(ty) => {
545 super::ObjectCastObligation(ty.fold_with(folder))
547 super::BuiltinDerivedObligation(ref cause) => {
548 super::BuiltinDerivedObligation(cause.fold_with(folder))
550 super::ImplDerivedObligation(ref cause) => {
551 super::ImplDerivedObligation(cause.fold_with(folder))
556 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
558 super::ExprAssignable |
559 super::MatchExpressionArm { arm_span: _, source: _ } |
560 super::IfExpression |
561 super::IfExpressionWithNoElse |
562 super::EquatePredicate |
563 super::MainFunctionType |
564 super::StartFunctionType |
565 super::IntrinsicType |
566 super::MethodReceiver |
567 super::MiscObligation |
568 super::SliceOrArrayElem |
570 super::ItemObligation(_) |
571 super::AssignmentLhsSized |
572 super::TupleInitializerSized |
573 super::StructInitializerSized |
574 super::VariableType(_) |
575 super::ReturnType(_) |
576 super::SizedReturnType |
577 super::ReturnNoExpression |
579 super::FieldSized(_) |
581 super::SharedStatic |
582 super::BlockTailExpression(_) |
583 super::CompareImplMethodObligation { .. } => false,
585 super::ProjectionWf(proj) => proj.visit_with(visitor),
586 super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
587 super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
588 super::ObjectCastObligation(ty) => ty.visit_with(visitor),
589 super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
590 super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
595 impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
596 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
597 traits::DerivedObligationCause {
598 parent_trait_ref: self.parent_trait_ref.fold_with(folder),
599 parent_code: self.parent_code.fold_with(folder)
603 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
604 self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
608 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
609 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
610 traits::ObligationCause {
612 body_id: self.body_id,
613 code: self.code.fold_with(folder),
617 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
618 self.code.visit_with(visitor)