Skip to content

Commit d7fdeff

Browse files
varkoryodaldevoid
andcommitted
Add generic consts to BottomUpFolder
Co-Authored-By: Gabriel Smith <[email protected]>
1 parent 77447de commit d7fdeff

File tree

4 files changed

+60
-14
lines changed

4 files changed

+60
-14
lines changed

src/librustc/infer/opaque_types/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,8 +676,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
676676
let tcx = self.infcx.tcx;
677677
value.fold_with(&mut BottomUpFolder {
678678
tcx,
679-
reg_op: |reg| reg,
680-
fldop: |ty| {
679+
ty_op: |ty| {
681680
if let ty::Opaque(def_id, substs) = ty.sty {
682681
// Check that this is `impl Trait` type is
683682
// declared by `parent_def_id` -- i.e., one whose
@@ -776,6 +775,8 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
776775

777776
ty
778777
},
778+
lt_op: |lt| lt,
779+
ct_op: |ct| ct,
779780
})
780781
}
781782

src/librustc/ty/fold.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,29 +193,37 @@ pub trait TypeVisitor<'tcx> : Sized {
193193
///////////////////////////////////////////////////////////////////////////
194194
// Some sample folders
195195

196-
pub struct BottomUpFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F, G>
196+
pub struct BottomUpFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a, F, G, H>
197197
where F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
198198
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
199+
H: FnMut(&'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx>,
199200
{
200201
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
201-
pub fldop: F,
202-
pub reg_op: G,
202+
pub ty_op: F,
203+
pub lt_op: G,
204+
pub ct_op: H,
203205
}
204206

205-
impl<'a, 'gcx, 'tcx, F, G> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'a, 'gcx, 'tcx, F, G>
207+
impl<'a, 'gcx, 'tcx, F, G, H> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'a, 'gcx, 'tcx, F, G, H>
206208
where F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
207209
G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
210+
H: FnMut(&'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx>,
208211
{
209212
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
210213

211214
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
212-
let t1 = ty.super_fold_with(self);
213-
(self.fldop)(t1)
215+
let t = ty.super_fold_with(self);
216+
(self.ty_op)(t)
214217
}
215218

216219
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
217220
let r = r.super_fold_with(self);
218-
(self.reg_op)(r)
221+
(self.lt_op)(r)
222+
}
223+
224+
fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
225+
let c = c.super_fold_with(self);
226+
(self.ct_op)(c)
219227
}
220228
}
221229

src/librustc_typeck/check/wfcheck.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
616616
let mut substituted_predicates = Vec::new();
617617
ty.fold_with(&mut ty::fold::BottomUpFolder {
618618
tcx: fcx.tcx,
619-
fldop: |ty| {
619+
ty_op: |ty| {
620620
if let ty::Opaque(def_id, substs) = ty.sty {
621621
trace!("check_existential_types: opaque_ty, {:?}, {:?}", def_id, substs);
622622
let generics = tcx.generics_of(def_id);
@@ -739,7 +739,8 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
739739
} // if let Opaque
740740
ty
741741
},
742-
reg_op: |reg| reg,
742+
lt_op: |lt| lt,
743+
ct_op: |ct| ct,
743744
});
744745
substituted_predicates
745746
}

src/librustc_typeck/check/writeback.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ use rustc::infer::InferCtxt;
1111
use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
1212
use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
1313
use rustc::ty::subst::UnpackedKind;
14-
use rustc::ty::{self, Ty, TyCtxt};
14+
use rustc::ty::{self, Ty, TyCtxt, Const, LazyConst};
15+
use rustc::mir::interpret::ConstValue;
1516
use rustc::util::nodemap::DefIdSet;
1617
use rustc_data_structures::sync::Lrc;
1718
use std::mem;
@@ -488,7 +489,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
488489
// figures out the concrete type with `U`, but the stored type is with `T`
489490
instantiated_ty.fold_with(&mut BottomUpFolder {
490491
tcx: self.tcx().global_tcx(),
491-
fldop: |ty| {
492+
ty_op: |ty| {
492493
trace!("checking type {:?}", ty);
493494
// find a type parameter
494495
if let ty::Param(..) = ty.sty {
@@ -520,7 +521,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
520521
}
521522
ty
522523
},
523-
reg_op: |region| {
524+
lt_op: |region| {
524525
match region {
525526
// ignore static regions
526527
ty::ReStatic => region,
@@ -564,6 +565,41 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
564565
}
565566
}
566567
},
568+
ct_op: |ct| {
569+
trace!("checking const {:?}", ct);
570+
// find a const parameter
571+
if let LazyConst::Evaluated(Const { ty, val }) = ct {
572+
if let ConstValue::Param(..) = val {
573+
// look it up in the substitution list
574+
assert_eq!(opaque_defn.substs.len(), generics.params.len());
575+
for (subst, param) in opaque_defn.substs.iter()
576+
.zip(&generics.params) {
577+
if let UnpackedKind::Const(subst) = subst.unpack() {
578+
if subst == ct {
579+
// found it in the substitution list, replace with the
580+
// parameter from the existential type
581+
return self.tcx()
582+
.global_tcx()
583+
.mk_const_param(param.index, param.name, ty);
584+
}
585+
}
586+
}
587+
self.tcx()
588+
.sess
589+
.struct_span_err(
590+
span,
591+
&format!(
592+
"const parameter `{}` is part of concrete type but not \
593+
used in parameter list for existential type",
594+
ct,
595+
),
596+
)
597+
.emit();
598+
return self.tcx().types.ct_err;
599+
}
600+
}
601+
ct
602+
}
567603
})
568604
};
569605

0 commit comments

Comments
 (0)