diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2016-06-01 12:57:42 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2016-06-01 12:57:42 +0530 |
| commit | e214c3e2da41a2f561bdff13c01a21278a65403b (patch) | |
| tree | 3a4bdcc001afc95d73642f375366a7a49f959638 | |
| parent | eba82bb569903ce4f96af8e90e2a55feca816634 (diff) | |
| parent | e3cff797a7dcc2358b37c170dc9d83d34d118725 (diff) | |
| download | rust-e214c3e2da41a2f561bdff13c01a21278a65403b.tar.gz rust-e214c3e2da41a2f561bdff13c01a21278a65403b.zip | |
Rollup merge of #33970 - arielb1:normal-type-check, r=eddyb
normalize types in MIR typeck after erasing regions this fixes the MIR bug @frankmcsherry encountered. r? @eddyb
| -rw-r--r-- | src/librustc_mir/transform/type_check.rs | 49 | ||||
| -rw-r--r-- | src/test/run-pass/mir_call_with_associated_type.rs | 29 |
2 files changed, 53 insertions, 25 deletions
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 40157aa934c..80c56a5dc08 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -118,10 +118,6 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { self.cx.infcx.tcx } - fn infcx(&self) -> &'a InferCtxt<'a, 'gcx, 'tcx> { - self.cx.infcx - } - fn sanitize_type(&mut self, parent: &fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> { if ty.needs_infer() || ty.has_escaping_regions() || ty.references_error() { span_mirbug_and_err!(self, parent, "bad type {:?}", ty) @@ -292,30 +288,11 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { }; if let Some(field) = variant.fields.get(field.index()) { - Ok(self.normalize(field.ty(tcx, substs))) + Ok(self.cx.normalize(&field.ty(tcx, substs))) } else { Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) } } - - fn normalize(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - let infcx = self.infcx(); - let mut selcx = traits::SelectionContext::new(infcx); - let cause = traits::ObligationCause::misc(self.last_span, 0); - let traits::Normalized { value: ty, obligations } = - traits::normalize(&mut selcx, cause, &ty); - - debug!("normalize: ty={:?} obligations={:?}", - ty, - obligations); - - let mut fulfill_cx = &mut self.cx.fulfillment_cx; - for obligation in obligations { - fulfill_cx.register_predicate_obligation(infcx, obligation); - } - - ty - } } pub struct TypeChecker<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { @@ -373,7 +350,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } - fn check_terminator(&self, + fn check_terminator(&mut self, mir: &Mir<'tcx>, term: &Terminator<'tcx>) { debug!("check_terminator: {:?}", term); @@ -431,6 +408,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } }; let sig = tcx.erase_late_bound_regions(&func_ty.sig); + let sig = self.normalize(&sig); self.check_call_dest(mir, term, &sig, destination); if self.is_box_free(func) { @@ -558,6 +536,27 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } + + fn normalize<T>(&mut self, value: &T) -> T + where T: fmt::Debug + TypeFoldable<'tcx> + { + let mut selcx = traits::SelectionContext::new(self.infcx); + let cause = traits::ObligationCause::misc(self.last_span, 0); + let traits::Normalized { value, obligations } = + traits::normalize(&mut selcx, cause, value); + + debug!("normalize: value={:?} obligations={:?}", + value, + obligations); + + let mut fulfill_cx = &mut self.fulfillment_cx; + for obligation in obligations { + fulfill_cx.register_predicate_obligation(self.infcx, obligation); + } + + value + } + fn verify_obligations(&mut self, mir: &Mir<'tcx>) { self.last_span = mir.span; if let Err(e) = self.fulfillment_cx.select_all_or_error(self.infcx) { diff --git a/src/test/run-pass/mir_call_with_associated_type.rs b/src/test/run-pass/mir_call_with_associated_type.rs new file mode 100644 index 00000000000..08401c275a5 --- /dev/null +++ b/src/test/run-pass/mir_call_with_associated_type.rs @@ -0,0 +1,29 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] + +trait Trait { + type Type; +} + +impl<'a> Trait for &'a () { + type Type = u32; +} + +#[rustc_mir] +fn foo<'a>(t: <&'a () as Trait>::Type) -> <&'a () as Trait>::Type { + t +} + +#[rustc_mir] +fn main() { + assert_eq!(foo(4), 4); +} |
