]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_ast_passes/ast_validation.rs
Auto merge of #71664 - Dylan-DPC:rollup-eng60x9, r=Dylan-DPC
[rust.git] / src / librustc_ast_passes / ast_validation.rs
index 4f076c963c1b60b7a626a186677c1f7aaba7ca24..395fd7460850f1de623bfbe733735eaa5d31501d 100644 (file)
@@ -6,6 +6,7 @@
 // This pass is supposed to perform only simple checks not requiring name resolution
 // or type checking or some other kind of complex analysis.
 
+use itertools::{Either, Itertools};
 use rustc_ast::ast::*;
 use rustc_ast::attr;
 use rustc_ast::expand::is_proc_macro_attr;
@@ -560,28 +561,6 @@ fn check_c_varadic_type(&self, fk: FnKind<'a>) {
         }
     }
 
-    /// We currently do not permit const generics in `const fn`,
-    /// as this is tantamount to allowing compile-time dependent typing.
-    ///
-    /// FIXME(const_generics): Is this really true / necessary? Discuss with @varkor.
-    /// At any rate, the restriction feels too syntactic. Consider moving it to e.g. typeck.
-    fn check_const_fn_const_generic(&self, span: Span, sig: &FnSig, generics: &Generics) {
-        if let Const::Yes(const_span) = sig.header.constness {
-            // Look for const generics and error if we find any.
-            for param in &generics.params {
-                if let GenericParamKind::Const { .. } = param.kind {
-                    self.err_handler()
-                        .struct_span_err(
-                            span,
-                            "const parameters are not permitted in const functions",
-                        )
-                        .span_label(const_span, "`const` because of this")
-                        .emit();
-                }
-            }
-        }
-    }
-
     fn check_item_named(&self, ident: Ident, kind: &str) {
         if ident.name != kw::Underscore {
             return;
@@ -640,7 +619,7 @@ fn deny_items(&self, trait_items: &[P<AssocItem>], ident_span: Span) {
         }
     }
 
-    fn suggest_correct_generic_order(&self, data: &AngleBracketedArgs) -> String {
+    fn correct_generic_order_suggestion(&self, data: &AngleBracketedArgs) -> String {
         // Lifetimes always come first.
         let lt_sugg = data.args.iter().filter_map(|arg| match arg {
             AngleBracketedArg::Arg(lt @ GenericArg::Lifetime(_)) => {
@@ -649,11 +628,12 @@ fn suggest_correct_generic_order(&self, data: &AngleBracketedArgs) -> String {
             _ => None,
         });
         let args_sugg = data.args.iter().filter_map(|a| match a {
-            AngleBracketedArg::Arg(GenericArg::Lifetime(_)) => None,
+            AngleBracketedArg::Arg(GenericArg::Lifetime(_)) | AngleBracketedArg::Constraint(_) => {
+                None
+            }
             AngleBracketedArg::Arg(arg) => Some(pprust::to_string(|s| s.print_generic_arg(arg))),
-            AngleBracketedArg::Constraint(_) => None,
         });
-        // Cosntraints always come last.
+        // Constraints always come last.
         let constraint_sugg = data.args.iter().filter_map(|a| match a {
             AngleBracketedArg::Arg(_) => None,
             AngleBracketedArg::Constraint(c) => {
@@ -673,22 +653,11 @@ fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) {
             return;
         }
         // Find all generic argument coming after the first constraint...
-        let constraint_spans = data
-            .args
-            .iter()
-            .filter_map(|arg| match arg {
-                AngleBracketedArg::Constraint(c) => Some(c.span),
-                _ => None,
-            })
-            .collect::<Vec<_>>();
-        let arg_spans = data
-            .args
-            .iter()
-            .filter_map(|arg| match arg {
-                AngleBracketedArg::Arg(a) => Some(a.span()),
-                _ => None,
-            })
-            .collect::<Vec<_>>();
+        let (constraint_spans, arg_spans): (Vec<Span>, Vec<Span>) =
+            data.args.iter().partition_map(|arg| match arg {
+                AngleBracketedArg::Constraint(c) => Either::Left(c.span),
+                AngleBracketedArg::Arg(a) => Either::Right(a.span()),
+            });
         let args_len = arg_spans.len();
         let constraint_len = constraint_spans.len();
         // ...and then error:
@@ -697,15 +666,13 @@ fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) {
                 arg_spans.clone(),
                 "generic arguments must come before the first constraint",
             )
-            .span_labels(
-                constraint_spans,
-                &format!(
-                    "the constraint{} {} provided here",
-                    pluralize!(constraint_len),
-                    if constraint_len == 1 { "is" } else { "are" }
-                ),
+            .span_label(constraint_spans[0], &format!("constraint{}", pluralize!(constraint_len)))
+            .span_label(
+                *arg_spans.iter().last().unwrap(),
+                &format!("generic argument{}", pluralize!(args_len)),
             )
-            .span_labels(arg_spans, "generic argument")
+            .span_labels(constraint_spans, "")
+            .span_labels(arg_spans, "")
             .span_suggestion_verbose(
                 data.span,
                 &format!(
@@ -713,7 +680,7 @@ fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) {
                     pluralize!(constraint_len),
                     pluralize!(args_len)
                 ),
-                self.suggest_correct_generic_order(&data),
+                self.correct_generic_order_suggestion(&data),
                 Applicability::MachineApplicable,
             )
             .emit();
@@ -977,9 +944,8 @@ fn visit_item(&mut self, item: &'a Item) {
                         .emit();
                 }
             }
-            ItemKind::Fn(def, ref sig, ref generics, ref body) => {
+            ItemKind::Fn(def, _, _, ref body) => {
                 self.check_defaultness(item.span, def);
-                self.check_const_fn_const_generic(item.span, sig, generics);
 
                 if body.is_none() {
                     let msg = "free function without a body";