<commit_before>use Destination::*;

use syntax_pos::{SourceFile, Span, MultiSpan};

use crate::{
    Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic,
    SuggestionStyle, SourceMapperDyn, DiagnosticId,
};
use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style};
use crate::styled_buffer::StyledBuffer;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use std::borrow::Cow;
use std::io::prelude::*;
use std::io;
use std::cmp::{min, Reverse};
use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter};
use termcolor::{WriteColor, Color, Buffer};

const ANONYMIZED_LINE_NUM: &str = "LL";

/// Emitter trait for emitting errors.
pub trait Emitter {
    /// Emit a structured diagnostic.
    fn emit(&mut self, db: &DiagnosticBuilder<'_>);

    /// Check if should show explanations about "rustc --explain"
    fn should_show_explain(&self) -> bool {
        true
    }
}

impl Emitter for EmitterWriter {
    fn emit(&mut self, db: &DiagnosticBuilder<'_>) {
        let mut primary_span = db.span.clone();
        let mut children = db.children.clone();
        let mut suggestions: &[_] = &[];

        if let Some((sugg, rest)) = db.suggestions.split_first() {
            if rest.is_empty() &&
               // don't display multi-suggestions as labels
               sugg.substitutions.len() == 1 &&
               // don't display multipart suggestions as labels
               sugg.substitutions[0].parts.len() == 1 &&
               // don't display long messages as labels
               sugg.msg.split_whitespace().count() < 10 &&
               // don't display multiline suggestions as labels
               !sugg.substitutions[0].parts[0].snippet.contains('\n') {
                let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
                let msg = if substitution.len() == 0 || sugg.style.hide_inline() {
                    // This substitution is only removal or we explicitly don't want to show the
                    // code inline, don't show it
                    format!("help: {}", sugg.msg)
                } else {
                    format!("help: {}: `{}`", sugg.msg, substitution)
                };
                primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
            } else {
                // if there are multiple suggestions, print them all in full
                // to be consistent. We could try to figure out if we can
                // make one (or the first one) inline, but that would give
                // undue importance to a semi-random suggestion
                suggestions = &db.suggestions;
            }
        }

        self.fix_multispans_in_std_macros(&mut primary_span,
                                          &mut children,
                                          db.handler.flags.external_macro_backtrace);<commit_msg>Never inline HideCodeAlways suggestions<commit_after>use Destination::*;

use syntax_pos::{SourceFile, Span, MultiSpan};

use crate::{
    Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic,
    SuggestionStyle, SourceMapperDyn, DiagnosticId,
};
use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style};
use crate::styled_buffer::StyledBuffer;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use std::borrow::Cow;
use std::io::prelude::*;
use std::io;
use std::cmp::{min, Reverse};
use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter};
use termcolor::{WriteColor, Color, Buffer};

const ANONYMIZED_LINE_NUM: &str = "LL";

/// Emitter trait for emitting errors.
pub trait Emitter {
    /// Emit a structured diagnostic.
    fn emit(&mut self, db: &DiagnosticBuilder<'_>);

    /// Check if should show explanations about "rustc --explain"
    fn should_show_explain(&self) -> bool {
        true
    }
}

impl Emitter for EmitterWriter {
    fn emit(&mut self, db: &DiagnosticBuilder<'_>) {
        let mut primary_span = db.span.clone();
        let mut children = db.children.clone();
        let mut suggestions: &[_] = &[];

        if let Some((sugg, rest)) = db.suggestions.split_first() {
            if rest.is_empty() &&
               // don't display multi-suggestions as labels
               sugg.substitutions.len() == 1 &&
               // don't display multipart suggestions as labels
               sugg.substitutions[0].parts.len() == 1 &&
               // don't display long messages as labels
               sugg.msg.split_whitespace().count() < 10 &&
               // don't display multiline suggestions as labels
               !sugg.substitutions[0].parts[0].snippet.contains('\n') &&
               // when this style is set we want the suggestion to be a message, not inline
               sugg.style != SuggestionStyle::HideCodeAlways
            {
                let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
                let msg = if substitution.len() == 0 || sugg.style.hide_inline() {
                    // This substitution is only removal or we explicitly don't want to show the
                    // code inline, don't show it
                    format!("help: {}", sugg.msg)
                } else {
                    format!("help: {}: `{}`", sugg.msg, substitution)
                };
                primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
            } else {
                // if there are multiple suggestions, print them all in full
                // to be consistent. We could try to figure out if we can
                // make one (or the first one) inline, but that would give
                // undue importance to a semi-random suggestion
                suggestions = &db.suggestions;
            }
        }

        self.fix_multispans_in_std_macros(&mut primary_span,
                                          &mut children,
                                          db.handler.flags.external_macro_backtrace);
{'fraction_non_alphanumeric': 0.11566424322538003, 'fraction_numerical': 0.0039656311962987445, 'mean_word_length': 2.1641400940930478, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2338438', 'n_tokens_mistral': 1707, 'n_tokens_neox': 1622, 'n_words': 455}