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::TupleInitializerSized => Some(super::TupleInitializerSized),
193 super::StructInitializerSized => Some(super::StructInitializerSized),
194 super::VariableType(id) => Some(super::VariableType(id)),
195 super::ReturnType(id) => Some(super::ReturnType(id)),
196 super::SizedReturnType => Some(super::SizedReturnType),
197 super::RepeatVec => Some(super::RepeatVec),
198 super::FieldSized(item) => Some(super::FieldSized(item)),
199 super::ConstSized => Some(super::ConstSized),
200 super::SharedStatic => Some(super::SharedStatic),
201 super::BuiltinDerivedObligation(ref cause) => {
202 tcx.lift(cause).map(super::BuiltinDerivedObligation)
204 super::ImplDerivedObligation(ref cause) => {
205 tcx.lift(cause).map(super::ImplDerivedObligation)
207 super::CompareImplMethodObligation { item_name,
211 Some(super::CompareImplMethodObligation {
218 super::ExprAssignable => Some(super::ExprAssignable),
219 super::MatchExpressionArm { arm_span, source } => {
220 Some(super::MatchExpressionArm { arm_span,
223 super::IfExpression => Some(super::IfExpression),
224 super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
225 super::EquatePredicate => Some(super::EquatePredicate),
226 super::MainFunctionType => Some(super::MainFunctionType),
227 super::StartFunctionType => Some(super::StartFunctionType),
228 super::IntrinsicType => Some(super::IntrinsicType),
229 super::MethodReceiver => Some(super::MethodReceiver),
230 super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
235 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
236 type Lifted = traits::DerivedObligationCause<'tcx>;
237 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
238 tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
239 tcx.lift(&*self.parent_code).map(|code| {
240 traits::DerivedObligationCause {
241 parent_trait_ref: trait_ref,
242 parent_code: Rc::new(code)
249 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
250 type Lifted = traits::ObligationCause<'tcx>;
251 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
252 tcx.lift(&self.code).map(|code| {
253 traits::ObligationCause {
255 body_id: self.body_id,
263 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
264 type Lifted = traits::Vtable<'tcx, ()>;
265 fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
267 traits::VtableImpl(traits::VtableImplData {
272 tcx.lift(&substs).map(|substs| {
273 traits::VtableImpl(traits::VtableImplData {
280 traits::VtableDefaultImpl(t) => Some(traits::VtableDefaultImpl(t)),
281 traits::VtableClosure(traits::VtableClosureData {
286 tcx.lift(&substs).map(|substs| {
287 traits::VtableClosure(traits::VtableClosureData {
294 traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
295 tcx.lift(&fn_ty).map(|fn_ty| {
296 traits::VtableFnPointer(traits::VtableFnPointerData {
302 traits::VtableParam(n) => Some(traits::VtableParam(n)),
303 traits::VtableBuiltin(d) => Some(traits::VtableBuiltin(d)),
304 traits::VtableObject(traits::VtableObjectData {
309 tcx.lift(&upcast_trait_ref).map(|trait_ref| {
310 traits::VtableObject(traits::VtableObjectData {
311 upcast_trait_ref: trait_ref,
321 ///////////////////////////////////////////////////////////////////////////
322 // TypeFoldable implementations.
324 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O>
326 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
328 cause: self.cause.clone(),
329 recursion_depth: self.recursion_depth,
330 predicate: self.predicate.fold_with(folder),
331 param_env: self.param_env.fold_with(folder),
335 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
336 self.predicate.visit_with(visitor)
340 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
341 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
342 traits::VtableImplData {
343 impl_def_id: self.impl_def_id,
344 substs: self.substs.fold_with(folder),
345 nested: self.nested.fold_with(folder),
349 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
350 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
354 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
355 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
356 traits::VtableClosureData {
357 closure_def_id: self.closure_def_id,
358 substs: self.substs.fold_with(folder),
359 nested: self.nested.fold_with(folder),
363 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
364 self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
368 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultImplData<N> {
369 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
370 traits::VtableDefaultImplData {
371 trait_def_id: self.trait_def_id,
372 nested: self.nested.fold_with(folder),
376 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
377 self.nested.visit_with(visitor)
381 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
382 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
383 traits::VtableBuiltinData {
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::VtableObjectData<'tcx, N> {
394 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
395 traits::VtableObjectData {
396 upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
397 vtable_base: self.vtable_base,
398 nested: self.nested.fold_with(folder),
402 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
403 self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
407 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
408 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
409 traits::VtableFnPointerData {
410 fn_ty: self.fn_ty.fold_with(folder),
411 nested: self.nested.fold_with(folder),
415 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
416 self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
420 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
421 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
423 traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
424 traits::VtableDefaultImpl(ref t) => traits::VtableDefaultImpl(t.fold_with(folder)),
425 traits::VtableClosure(ref d) => {
426 traits::VtableClosure(d.fold_with(folder))
428 traits::VtableFnPointer(ref d) => {
429 traits::VtableFnPointer(d.fold_with(folder))
431 traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
432 traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
433 traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
437 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
439 traits::VtableImpl(ref v) => v.visit_with(visitor),
440 traits::VtableDefaultImpl(ref t) => t.visit_with(visitor),
441 traits::VtableClosure(ref d) => d.visit_with(visitor),
442 traits::VtableFnPointer(ref d) => d.visit_with(visitor),
443 traits::VtableParam(ref n) => n.visit_with(visitor),
444 traits::VtableBuiltin(ref d) => d.visit_with(visitor),
445 traits::VtableObject(ref d) => d.visit_with(visitor),
450 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
451 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
453 value: self.value.fold_with(folder),
454 obligations: self.obligations.fold_with(folder),
458 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
459 self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
463 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
464 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
466 super::ExprAssignable |
467 super::MatchExpressionArm { arm_span: _, source: _ } |
468 super::IfExpression |
469 super::IfExpressionWithNoElse |
470 super::EquatePredicate |
471 super::MainFunctionType |
472 super::StartFunctionType |
473 super::IntrinsicType |
474 super::MethodReceiver |
475 super::MiscObligation |
476 super::SliceOrArrayElem |
478 super::ItemObligation(_) |
479 super::AssignmentLhsSized |
480 super::TupleInitializerSized |
481 super::StructInitializerSized |
482 super::VariableType(_) |
483 super::ReturnType(_) |
484 super::SizedReturnType |
485 super::ReturnNoExpression |
487 super::FieldSized(_) |
489 super::SharedStatic |
490 super::BlockTailExpression(_) |
491 super::CompareImplMethodObligation { .. } => self.clone(),
493 super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
494 super::ReferenceOutlivesReferent(ty) => {
495 super::ReferenceOutlivesReferent(ty.fold_with(folder))
497 super::ObjectTypeBound(ty, r) => {
498 super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
500 super::ObjectCastObligation(ty) => {
501 super::ObjectCastObligation(ty.fold_with(folder))
503 super::BuiltinDerivedObligation(ref cause) => {
504 super::BuiltinDerivedObligation(cause.fold_with(folder))
506 super::ImplDerivedObligation(ref cause) => {
507 super::ImplDerivedObligation(cause.fold_with(folder))
512 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
514 super::ExprAssignable |
515 super::MatchExpressionArm { arm_span: _, source: _ } |
516 super::IfExpression |
517 super::IfExpressionWithNoElse |
518 super::EquatePredicate |
519 super::MainFunctionType |
520 super::StartFunctionType |
521 super::IntrinsicType |
522 super::MethodReceiver |
523 super::MiscObligation |
524 super::SliceOrArrayElem |
526 super::ItemObligation(_) |
527 super::AssignmentLhsSized |
528 super::TupleInitializerSized |
529 super::StructInitializerSized |
530 super::VariableType(_) |
531 super::ReturnType(_) |
532 super::SizedReturnType |
533 super::ReturnNoExpression |
535 super::FieldSized(_) |
537 super::SharedStatic |
538 super::BlockTailExpression(_) |
539 super::CompareImplMethodObligation { .. } => false,
541 super::ProjectionWf(proj) => proj.visit_with(visitor),
542 super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
543 super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
544 super::ObjectCastObligation(ty) => ty.visit_with(visitor),
545 super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
546 super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
551 impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
552 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
553 traits::DerivedObligationCause {
554 parent_trait_ref: self.parent_trait_ref.fold_with(folder),
555 parent_code: self.parent_code.fold_with(folder)
559 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
560 self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
564 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
565 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
566 traits::ObligationCause {
568 body_id: self.body_id,
569 code: self.code.fold_with(folder),
573 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
574 self.code.visit_with(visitor)