Skip to content

Commit e3cff79

Browse files
committed
normalize types in MIR typeck after erasing regions
1 parent f3bfa31 commit e3cff79

File tree

2 files changed

+53
-25
lines changed

2 files changed

+53
-25
lines changed

src/librustc_mir/transform/type_check.rs

+24-25
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,6 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
118118
self.cx.infcx.tcx
119119
}
120120

121-
fn infcx(&self) -> &'a InferCtxt<'a, 'gcx, 'tcx> {
122-
self.cx.infcx
123-
}
124-
125121
fn sanitize_type(&mut self, parent: &fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> {
126122
if ty.needs_infer() || ty.has_escaping_regions() || ty.references_error() {
127123
span_mirbug_and_err!(self, parent, "bad type {:?}", ty)
@@ -292,30 +288,11 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
292288
};
293289

294290
if let Some(field) = variant.fields.get(field.index()) {
295-
Ok(self.normalize(field.ty(tcx, substs)))
291+
Ok(self.cx.normalize(&field.ty(tcx, substs)))
296292
} else {
297293
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
298294
}
299295
}
300-
301-
fn normalize(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
302-
let infcx = self.infcx();
303-
let mut selcx = traits::SelectionContext::new(infcx);
304-
let cause = traits::ObligationCause::misc(self.last_span, 0);
305-
let traits::Normalized { value: ty, obligations } =
306-
traits::normalize(&mut selcx, cause, &ty);
307-
308-
debug!("normalize: ty={:?} obligations={:?}",
309-
ty,
310-
obligations);
311-
312-
let mut fulfill_cx = &mut self.cx.fulfillment_cx;
313-
for obligation in obligations {
314-
fulfill_cx.register_predicate_obligation(infcx, obligation);
315-
}
316-
317-
ty
318-
}
319296
}
320297

321298
pub struct TypeChecker<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
@@ -373,7 +350,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
373350
}
374351
}
375352

376-
fn check_terminator(&self,
353+
fn check_terminator(&mut self,
377354
mir: &Mir<'tcx>,
378355
term: &Terminator<'tcx>) {
379356
debug!("check_terminator: {:?}", term);
@@ -431,6 +408,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
431408
}
432409
};
433410
let sig = tcx.erase_late_bound_regions(&func_ty.sig);
411+
let sig = self.normalize(&sig);
434412
self.check_call_dest(mir, term, &sig, destination);
435413

436414
if self.is_box_free(func) {
@@ -558,6 +536,27 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
558536
}
559537
}
560538

539+
540+
fn normalize<T>(&mut self, value: &T) -> T
541+
where T: fmt::Debug + TypeFoldable<'tcx>
542+
{
543+
let mut selcx = traits::SelectionContext::new(self.infcx);
544+
let cause = traits::ObligationCause::misc(self.last_span, 0);
545+
let traits::Normalized { value, obligations } =
546+
traits::normalize(&mut selcx, cause, value);
547+
548+
debug!("normalize: value={:?} obligations={:?}",
549+
value,
550+
obligations);
551+
552+
let mut fulfill_cx = &mut self.fulfillment_cx;
553+
for obligation in obligations {
554+
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
555+
}
556+
557+
value
558+
}
559+
561560
fn verify_obligations(&mut self, mir: &Mir<'tcx>) {
562561
self.last_span = mir.span;
563562
if let Err(e) = self.fulfillment_cx.select_all_or_error(self.infcx) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2016 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.
4+
//
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.
10+
11+
#![feature(rustc_attrs)]
12+
13+
trait Trait {
14+
type Type;
15+
}
16+
17+
impl<'a> Trait for &'a () {
18+
type Type = u32;
19+
}
20+
21+
#[rustc_mir]
22+
fn foo<'a>(t: <&'a () as Trait>::Type) -> <&'a () as Trait>::Type {
23+
t
24+
}
25+
26+
#[rustc_mir]
27+
fn main() {
28+
assert_eq!(foo(4), 4);
29+
}

0 commit comments

Comments
 (0)