Skip to content

Commit 3001ae7

Browse files
varkoryodaldevoid
andcommitted
Implement wfcheck for const parameters
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
1 parent a8361eb commit 3001ae7

File tree

1 file changed

+50
-9
lines changed

1 file changed

+50
-9
lines changed

src/librustc_typeck/check/wfcheck.rs

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc::traits::{self, ObligationCauseCode};
66
use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable, ToPredicate};
77
use rustc::ty::subst::{Subst, InternalSubsts};
88
use rustc::util::nodemap::{FxHashSet, FxHashMap};
9+
use rustc::mir::interpret::ConstValue;
910
use rustc::middle::lang_items;
1011
use rustc::infer::opaque_types::may_define_existential_type;
1112

@@ -436,7 +437,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
436437
// struct Foo<T = Vec<[u32]>> { .. }
437438
// Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
438439
for param in &generics.params {
439-
if let GenericParamDefKind::Type {..} = param.kind {
440+
if let GenericParamDefKind::Type { .. } = param.kind {
440441
if is_our_default(&param) {
441442
let ty = fcx.tcx.type_of(param.def_id);
442443
// ignore dependent defaults -- that is, where the default of one type
@@ -464,7 +465,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
464465
// All regions are identity.
465466
fcx.tcx.mk_param_from_def(param)
466467
}
467-
GenericParamDefKind::Type {..} => {
468+
GenericParamDefKind::Type { .. } => {
468469
// If the param has a default,
469470
if is_our_default(param) {
470471
let default_ty = fcx.tcx.type_of(param.def_id);
@@ -477,6 +478,10 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
477478
// Mark unwanted params as err.
478479
fcx.tcx.types.err.into()
479480
}
481+
GenericParamDefKind::Const => {
482+
// FIXME(const_generics:defaults)
483+
fcx.tcx.types.err.into()
484+
}
480485
}
481486
});
482487
// Now we build the substituted predicates.
@@ -497,6 +502,16 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
497502
fn visit_region(&mut self, _: ty::Region<'tcx>) -> bool {
498503
true
499504
}
505+
506+
fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
507+
if let ty::LazyConst::Evaluated(ty::Const {
508+
val: ConstValue::Param(param),
509+
..
510+
}) = c {
511+
self.params.insert(param.index);
512+
}
513+
c.super_visit_with(self)
514+
}
500515
}
501516
let mut param_count = CountParams::default();
502517
let has_region = pred.visit_with(&mut param_count);
@@ -617,11 +632,10 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
617632
for (subst, param) in substs.iter().zip(&generics.params) {
618633
match subst.unpack() {
619634
ty::subst::UnpackedKind::Type(ty) => match ty.sty {
620-
ty::Param(..) => {},
635+
ty::Param(..) => {}
621636
// prevent `fn foo() -> Foo<u32>` from being defining
622637
_ => {
623-
tcx
624-
.sess
638+
tcx.sess
625639
.struct_span_err(
626640
span,
627641
"non-defining existential type use \
@@ -636,8 +650,9 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
636650
),
637651
)
638652
.emit();
639-
},
640-
}, // match ty
653+
}
654+
}
655+
641656
ty::subst::UnpackedKind::Lifetime(region) => {
642657
let param_span = tcx.def_span(param.def_id);
643658
if let ty::ReStatic = region {
@@ -658,7 +673,31 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
658673
} else {
659674
seen.entry(region).or_default().push(param_span);
660675
}
661-
},
676+
}
677+
678+
ty::subst::UnpackedKind::Const(ct) => match ct {
679+
ty::LazyConst::Evaluated(ty::Const {
680+
val: ConstValue::Param(_),
681+
..
682+
}) => {}
683+
_ => {
684+
tcx.sess
685+
.struct_span_err(
686+
span,
687+
"non-defining existential type use \
688+
in defining scope",
689+
)
690+
.span_note(
691+
tcx.def_span(param.def_id),
692+
&format!(
693+
"used non-generic const {} for \
694+
generic parameter",
695+
ty,
696+
),
697+
)
698+
.emit();
699+
}
700+
}
662701
} // match subst
663702
} // for (subst, param)
664703
for (_, spans) in seen {
@@ -942,7 +981,9 @@ fn reject_shadowing_parameters(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) {
942981
let parent = tcx.generics_of(generics.parent.unwrap());
943982
let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
944983
GenericParamDefKind::Lifetime => None,
945-
GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
984+
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
985+
Some((param.name, param.def_id))
986+
}
946987
}).collect();
947988

948989
for method_param in &generics.params {

0 commit comments

Comments
 (0)