@@ -6,6 +6,7 @@ use rustc::traits::{self, ObligationCauseCode};
66use rustc:: ty:: { self , Lift , Ty , TyCtxt , TyKind , GenericParamDefKind , TypeFoldable , ToPredicate } ;
77use rustc:: ty:: subst:: { Subst , InternalSubsts } ;
88use rustc:: util:: nodemap:: { FxHashSet , FxHashMap } ;
9+ use rustc:: mir:: interpret:: ConstValue ;
910use rustc:: middle:: lang_items;
1011use 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