@@ -21,7 +21,7 @@ use syntax::visit::{self, Visitor};
2121use syntax:: { span_err, struct_span_err, walk_list} ;
2222use syntax_ext:: proc_macro_decls:: is_proc_macro_attr;
2323use syntax_pos:: { Span , MultiSpan } ;
24- use errors:: Applicability ;
24+ use errors:: { Applicability , FatalError } ;
2525use log:: debug;
2626
2727#[ derive( Copy , Clone , Debug ) ]
@@ -368,6 +368,8 @@ fn validate_generics_order<'a>(
368368 let mut max_param: Option < ParamKindOrd > = None ;
369369 let mut out_of_order = FxHashMap :: default ( ) ;
370370 let mut param_idents = vec ! [ ] ;
371+ let mut found_type = false ;
372+ let mut found_const = false ;
371373
372374 for ( kind, bounds, span, ident) in generics {
373375 if let Some ( ident) = ident {
@@ -381,6 +383,11 @@ fn validate_generics_order<'a>(
381383 }
382384 Some ( _) | None => * max_param = Some ( kind) ,
383385 } ;
386+ match kind {
387+ ParamKindOrd :: Type => found_type = true ,
388+ ParamKindOrd :: Const => found_const = true ,
389+ _ => { }
390+ }
384391 }
385392
386393 let mut ordered_params = "<" . to_string ( ) ;
@@ -408,8 +415,8 @@ fn validate_generics_order<'a>(
408415 GenericPosition :: Arg => "argument" ,
409416 } ;
410417
411- for ( param_ord, ( max_param, spans) ) in out_of_order {
412- let mut err = handler. struct_span_err ( spans,
418+ for ( param_ord, ( max_param, spans) ) in & out_of_order {
419+ let mut err = handler. struct_span_err ( spans. clone ( ) ,
413420 & format ! (
414421 "{} {pos}s must be declared prior to {} {pos}s" ,
415422 param_ord,
@@ -430,6 +437,13 @@ fn validate_generics_order<'a>(
430437 }
431438 err. emit ( ) ;
432439 }
440+
441+ // FIXME(const_generics): we shouldn't have to abort here at all, but we currently get ICEs
442+ // if we don't. Const parameters and type parameters can currently conflict if they
443+ // are out-of-order.
444+ if !out_of_order. is_empty ( ) && found_type && found_const {
445+ FatalError . raise ( ) ;
446+ }
433447}
434448
435449impl < ' a > Visitor < ' a > for AstValidator < ' a > {
0 commit comments