pub fn report_arg_count_mismatch(
        &self,
        span: Span,
        found_span: Option<Span>,
        expected_args: Vec<ArgKind>,
        found_args: Vec<ArgKind>,
        is_closure: bool,
    ) -> DiagnosticBuilder<'tcx> {
        let kind = if is_closure { "closure" } else { "function" };

        let args_str = |arguments: &[ArgKind], other: &[ArgKind]| {
            let arg_length = arguments.len();
            let distinct = match &other[..] {
                &[ArgKind::Tuple(..)] => true,
                _ => false,
            };
            match (arg_length, arguments.get(0)) {
                (1, Some(&ArgKind::Tuple(_, ref fields))) => {
                    format!("a single {}-tuple as argument", fields.len())
                }
                _ => format!("{} {}argument{}",
                             arg_length,
                             if distinct && arg_length > 1 { "distinct " } else { "" },
                             pluralize!(arg_length))
            }
        };

        let expected_str = args_str(&expected_args, &found_args);
        let found_str = args_str(&found_args, &expected_args);

        let mut err = struct_span_err!(
            self.tcx.sess,
            span,
            E0593,
            "{} is expected to take {}, but it takes {}",
            kind,
            expected_str,
            found_str,
        );

        err.span_label(span, format!("expected {} that takes {}", kind, expected_str));

        if let Some(found_span) = found_span {
            err.span_label(found_span, format!("takes {}", found_str));

            // move |_| { ... }
            // ^^^^^^^^-- def_span
            //
            // move |_| { ... }
            // ^^^^^-- prefix
            let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span);
            // move |_| { ... }
            //      ^^^-- pipe_span
            let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) {
                span
            } else {
                found_span
            };

            // Suggest to take and ignore the arguments with expected_args_length `_`s if
            // found arguments is empty (assume the user just wants to ignore args in this case).
            // For example, if `expected_args_length` is 2, suggest `|_, _|`.
            if found_args.is_empty() && is_closure {
                let underscores = vec!["_"; expected_args.len()].join(", ");
                err.span_suggestion(
                    pipe_span,
                    &format!(
                        "consider changing the closure to take and ignore the expected argument{}",
                        if expected_args.len() < 2 {
                            ""
                        } else {
                            "s"
                        }
                    ),
                    format!("|{}|", underscores),
                    Applicability::MachineApplicable,
                );
            }

            if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
                if fields.len() == expected_args.len() {
                    let sugg = fields.iter()
                        .map(|(name, _)| name.to_owned())
                        .collect::<Vec<String>>()
                        .join(", ");
                    err.span_suggestion(
                        found_span,
                        "change the closure to take multiple arguments instead of a single tuple",
                        format!("|{}|", sugg),
                        Applicability::MachineApplicable,
                    );
                }
            }
            if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
                if fields.len() == found_args.len() && is_closure {
                    let sugg = format!(
                        "|({}){}|",
                        found_args.iter()
                            .map(|arg| match arg {
                                ArgKind::Arg(name, _) => name.to_owned(),
                                _ => "_".to_owned(),
                            })
                            .collect::<Vec<String>>()
                            .join(", "),
                        // add type annotations if available
                        if found_args.iter().any(|arg| match arg {
                            ArgKind::Arg(_, ty) => ty != "_",
                            _ => false,
                        }) {
                            format!(": ({})",
                                    fields.iter()
                                        .map(|(_, ty)| ty.to_owned())
                                        .collect::<Vec<String>>()
                                        .join(", "))
                        } else {
                            String::new()
                        },
                    );
                    err.span_suggestion(
                        found_span,
                        "change the closure to accept a tuple instead of individual arguments",
                        sugg,
                        Applicability::MachineApplicable,
                    );
                }
            }
        }

        err
    }
/// Reports an error when the number of arguments needed by a
/// trait match doesn't match the number that the expression
/// provides.
Reports an error when the number of arguments needed by a
trait match doesn't match the number that the expression
provides.
Reports an error when the number of arguments needed by a trait match doesn ' t match the number that the expression provides .
pub fn report_arg_count_mismatch(
        &self,
        span: Span,
        found_span: Option<Span>,
        expected_args: Vec<ArgKind>,
        found_args: Vec<ArgKind>,
        is_closure: bool,
    ) -> DiagnosticBuilder<'tcx> {
        let kind = if is_closure { "closure" } else { "function" };
        let args_str = |arguments: &[ArgKind], other: &[ArgKind]| {
            let arg_length = arguments.len();
            let distinct = match &other[..] {
                &[ArgKind::Tuple(..)] => true,
                _ => false,
            };
            match (arg_length, arguments.get(0)) {
                (1, Some(&ArgKind::Tuple(_, ref fields))) => {
                    format!("a single {}-tuple as argument", fields.len())
                }
                _ => format!("{} {}argument{}",
                             arg_length,
                             if distinct && arg_length > 1 { "distinct " } else { "" },
                             pluralize!(arg_length))
            }
        };
        let expected_str = args_str(&expected_args, &found_args);
        let found_str = args_str(&found_args, &expected_args);
        let mut err = struct_span_err!(
            self.tcx.sess,
            span,
            E0593,
            "{} is expected to take {}, but it takes {}",
            kind,
            expected_str,
            found_str,
        );
        err.span_label(span, format!("expected {} that takes {}", kind, expected_str));
        if let Some(found_span) = found_span {
            err.span_label(found_span, format!("takes {}", found_str));
            // move |_| { ... }
            // ^^^^^^^^-- def_span
            //
            // move |_| { ... }
            // ^^^^^-- prefix
            let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span);
            // move |_| { ... }
            //      ^^^-- pipe_span
            let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) {
                span
            } else {
                found_span
            };
            // Suggest to take and ignore the arguments with expected_args_length `_`s if
            // found arguments is empty (assume the user just wants to ignore args in this case).
            // For example, if `expected_args_length` is 2, suggest `|_, _|`.
            if found_args.is_empty() && is_closure {
                let underscores = vec!["_"; expected_args.len()].join(", ");
                err.span_suggestion(
                    pipe_span,
                    &format!(
                        "consider changing the closure to take and ignore the expected argument{}",
                        if expected_args.len() < 2 {
                            ""
                        } else {
                            "s"
                        }
                    ),
                    format!("|{}|", underscores),
                    Applicability::MachineApplicable,
                );
            }
            if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
                if fields.len() == expected_args.len() {
                    let sugg = fields.iter()
                        .map(|(name, _)| name.to_owned())
                        .collect::<Vec<String>>()
                        .join(", ");
                    err.span_suggestion(
                        found_span,
                        "change the closure to take multiple arguments instead of a single tuple",
                        format!("|{}|", sugg),
                        Applicability::MachineApplicable,
                    );
                }
            }
            if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
                if fields.len() == found_args.len() && is_closure {
                    let sugg = format!(
                        "|({}){}|",
                        found_args.iter()
                            .map(|arg| match arg {
                                ArgKind::Arg(name, _) => name.to_owned(),
                                _ => "_".to_owned(),
                            })
                            .collect::<Vec<String>>()
                            .join(", "),
                        // add type annotations if available
                        if found_args.iter().any(|arg| match arg {
                            ArgKind::Arg(_, ty) => ty != "_",
                            _ => false,
                        }) {
                            format!(": ({})",
                                    fields.iter()
                                        .map(|(_, ty)| ty.to_owned())
                                        .collect::<Vec<String>>()
                                        .join(", "))
                        } else {
                            String::new()
                        },
                    );
                    err.span_suggestion(
                        found_span,
                        "change the closure to accept a tuple instead of individual arguments",
                        sugg,
                        Applicability::MachineApplicable,
                    );
                }
            }
        }
        err
    }
pub fn report_arg_count_mismatch ( & self , span : Span , found_span : Option < Span > , expected_args : Vec < ArgKind > , found_args : Vec < ArgKind > , is_closure : bool , ) -> DiagnosticBuilder < ' tcx > { let kind = if is_closure { " " } else { " " } ; let args_str = | arguments : & [ ArgKind ] , other : & [ ArgKind ] | { let arg_length = arguments . len ( ) ; let distinct = match & other [ .. ] { & [ ArgKind :: Tuple ( .. ) ] => true , _ => false , } ; match ( arg_length , arguments . get ( 0 ) ) { ( 1 , Some ( & ArgKind :: Tuple ( _ , ref fields ) ) ) => { format ! ( " " fields len ( ) ) } _ => format ! ( " " arg_length if distinct arg_length 1 { " " } else { " " } pluralize ( arg_length ) ) } } ; let expected_str = args_str ( & expected_args , & found_args ) ; let found_str = args_str ( & found_args , & expected_args ) ; let mut err = struct_span_err ! ( self tcx sess span E0593 " " kind expected_str found_str ) ; err . span_label ( span , format ! ( " " kind expected_str ) ) ; if let Some ( found_span ) = found_span { err . span_label ( found_span , format ! ( " " found_str ) ) ; // move |_| { ... } // ^^^^^^^^-- def_span // // move |_| { ... } // ^^^^^-- prefix let prefix_span = self . tcx . sess . source_map ( ) . span_until_non_whitespace ( found_span ) ; // move |_| { ... } //      ^^^-- pipe_span let pipe_span = if let Some ( span ) = found_span . trim_start ( prefix_span ) { span } else { found_span } ; // Suggest to take and ignore the arguments with expected_args_length `_`s if // found arguments is empty (assume the user just wants to ignore args in this case). // For example, if `expected_args_length` is 2, suggest `|_, _|`. if found_args . is_empty ( ) && is_closure { let underscores = vec ! [ " " expected_args len ( ) ] . join ( " " ) ; err . span_suggestion ( pipe_span , & format ! ( " " if expected_args len ( ) 2 { " " } else { " " } ) , format ! ( " " underscores ) , Applicability :: MachineApplicable , ) ; } if let & [ ArgKind :: Tuple ( _ , ref fields ) ] = & found_args [ .. ] { if fields . len ( ) == expected_args . len ( ) { let sugg = fields . iter ( ) . map ( | ( name , _ ) | name . to_owned ( ) ) . collect :: < Vec < String > > ( ) . join ( " " ) ; err . span_suggestion ( found_span , " " , format ! ( " " sugg ) , Applicability :: MachineApplicable , ) ; } } if let & [ ArgKind :: Tuple ( _ , ref fields ) ] = & expected_args [ .. ] { if fields . len ( ) == found_args . len ( ) && is_closure { let sugg = format ! ( " " found_args iter ( ) map ( arg match arg { ArgKind Arg ( name ) name to_owned ( ) " " to_owned ( ) } ) collect Vec String ( ) join ( " " ) // add type annotations if available if found_args iter ( ) any ( arg match arg { ArgKind Arg ( ty ) ty " " false } ) { format ( " " fields iter ( ) map ( ( ty ) ty to_owned ( ) ) collect Vec String ( ) join ( " " ) ) } else { String new ( ) } ) ; err . span_suggestion ( found_span , " " , sugg , Applicability :: MachineApplicable , ) ; } } } err }
Reports an error when the number of arguments needed by a
trait match doesn't match the number that the expression
provides.
Reports an error when the number of arguments needed by a trait match doesn ' t match the number that the expression provides .
&self
span
Span
found_span
Option<Span>
expected_args
Vec<ArgKind>
found_args
Vec<ArgKind>
is_closure
bool