diff --git a/Cargo.lock b/Cargo.lock index 1344d4152d9aa..a39e468e3d978 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3491,6 +3491,7 @@ version = "0.0.0" dependencies = [ "itertools 0.11.0", "rustc_ast", + "rustc_lexer", "rustc_span", "thin-vec", ] diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs index bdf5143b0f706..cbc1afc6bf1e8 100644 --- a/compiler/rustc_ast/src/util/comments.rs +++ b/compiler/rustc_ast/src/util/comments.rs @@ -1,6 +1,5 @@ use crate::token::CommentKind; -use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, CharPos, FileName, Pos, Symbol}; +use rustc_span::{BytePos, Symbol}; #[cfg(test)] mod tests; @@ -131,126 +130,3 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol { } data } - -/// Returns `None` if the first `col` chars of `s` contain a non-whitespace char. -/// Otherwise returns `Some(k)` where `k` is first char offset after that leading -/// whitespace. Note that `k` may be outside bounds of `s`. -fn all_whitespace(s: &str, col: CharPos) -> Option { - let mut idx = 0; - for (i, ch) in s.char_indices().take(col.to_usize()) { - if !ch.is_whitespace() { - return None; - } - idx = i + ch.len_utf8(); - } - Some(idx) -} - -fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str { - let len = s.len(); - match all_whitespace(s, col) { - Some(col) => { - if col < len { - &s[col..] - } else { - "" - } - } - None => s, - } -} - -fn split_block_comment_into_lines(text: &str, col: CharPos) -> Vec { - let mut res: Vec = vec![]; - let mut lines = text.lines(); - // just push the first line - res.extend(lines.next().map(|it| it.to_string())); - // for other lines, strip common whitespace prefix - for line in lines { - res.push(trim_whitespace_prefix(line, col).to_string()) - } - res -} - -// it appears this function is called only from pprust... that's -// probably not a good thing. -pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec { - let sm = SourceMap::new(sm.path_mapping().clone()); - let source_file = sm.new_source_file(path, src); - let text = (*source_file.src.as_ref().unwrap()).clone(); - - let text: &str = text.as_str(); - let start_bpos = source_file.start_pos; - let mut pos = 0; - let mut comments: Vec = Vec::new(); - let mut code_to_the_left = false; - - if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { - comments.push(Comment { - style: CommentStyle::Isolated, - lines: vec![text[..shebang_len].to_string()], - pos: start_bpos, - }); - pos += shebang_len; - } - - for token in rustc_lexer::tokenize(&text[pos..]) { - let token_text = &text[pos..pos + token.len as usize]; - match token.kind { - rustc_lexer::TokenKind::Whitespace => { - if let Some(mut idx) = token_text.find('\n') { - code_to_the_left = false; - while let Some(next_newline) = &token_text[idx + 1..].find('\n') { - idx += 1 + next_newline; - comments.push(Comment { - style: CommentStyle::BlankLine, - lines: vec![], - pos: start_bpos + BytePos((pos + idx) as u32), - }); - } - } - } - rustc_lexer::TokenKind::BlockComment { doc_style, .. } => { - if doc_style.is_none() { - let code_to_the_right = !matches!( - text[pos + token.len as usize..].chars().next(), - Some('\r' | '\n') - ); - let style = match (code_to_the_left, code_to_the_right) { - (_, true) => CommentStyle::Mixed, - (false, false) => CommentStyle::Isolated, - (true, false) => CommentStyle::Trailing, - }; - - // Count the number of chars since the start of the line by rescanning. - let pos_in_file = start_bpos + BytePos(pos as u32); - let line_begin_in_file = source_file.line_begin_pos(pos_in_file); - let line_begin_pos = (line_begin_in_file - start_bpos).to_usize(); - let col = CharPos(text[line_begin_pos..pos].chars().count()); - - let lines = split_block_comment_into_lines(token_text, col); - comments.push(Comment { style, lines, pos: pos_in_file }) - } - } - rustc_lexer::TokenKind::LineComment { doc_style } => { - if doc_style.is_none() { - comments.push(Comment { - style: if code_to_the_left { - CommentStyle::Trailing - } else { - CommentStyle::Isolated - }, - lines: vec![token_text.to_string()], - pos: start_bpos + BytePos(pos as u32), - }) - } - } - _ => { - code_to_the_left = true; - } - } - pos += token.len as usize; - } - - comments -} diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index 12a08f06558ba..b38a2915a43df 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" # tidy-alphabetical-start itertools = "0.11" rustc_ast = { path = "../rustc_ast" } +rustc_lexer = { path = "../rustc_lexer" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 6e1974f48b26b..6119c6c84f8b7 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -14,7 +14,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; -use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; +use rustc_ast::util::comments::{Comment, CommentStyle}; use rustc_ast::util::parser; use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind}; use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; @@ -24,7 +24,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_span::edition::Edition; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol}; -use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; +use rustc_span::{BytePos, CharPos, FileName, Pos, Span, DUMMY_SP}; use std::borrow::Cow; use thin_vec::ThinVec; @@ -59,6 +59,127 @@ pub struct Comments<'a> { current: usize, } +/// Returns `None` if the first `col` chars of `s` contain a non-whitespace char. +/// Otherwise returns `Some(k)` where `k` is first char offset after that leading +/// whitespace. Note that `k` may be outside bounds of `s`. +fn all_whitespace(s: &str, col: CharPos) -> Option { + let mut idx = 0; + for (i, ch) in s.char_indices().take(col.to_usize()) { + if !ch.is_whitespace() { + return None; + } + idx = i + ch.len_utf8(); + } + Some(idx) +} + +fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str { + let len = s.len(); + match all_whitespace(s, col) { + Some(col) => { + if col < len { + &s[col..] + } else { + "" + } + } + None => s, + } +} + +fn split_block_comment_into_lines(text: &str, col: CharPos) -> Vec { + let mut res: Vec = vec![]; + let mut lines = text.lines(); + // just push the first line + res.extend(lines.next().map(|it| it.to_string())); + // for other lines, strip common whitespace prefix + for line in lines { + res.push(trim_whitespace_prefix(line, col).to_string()) + } + res +} + +fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec { + let sm = SourceMap::new(sm.path_mapping().clone()); + let source_file = sm.new_source_file(path, src); + let text = (*source_file.src.as_ref().unwrap()).clone(); + + let text: &str = text.as_str(); + let start_bpos = source_file.start_pos; + let mut pos = 0; + let mut comments: Vec = Vec::new(); + let mut code_to_the_left = false; + + if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { + comments.push(Comment { + style: CommentStyle::Isolated, + lines: vec![text[..shebang_len].to_string()], + pos: start_bpos, + }); + pos += shebang_len; + } + + for token in rustc_lexer::tokenize(&text[pos..]) { + let token_text = &text[pos..pos + token.len as usize]; + match token.kind { + rustc_lexer::TokenKind::Whitespace => { + if let Some(mut idx) = token_text.find('\n') { + code_to_the_left = false; + while let Some(next_newline) = &token_text[idx + 1..].find('\n') { + idx += 1 + next_newline; + comments.push(Comment { + style: CommentStyle::BlankLine, + lines: vec![], + pos: start_bpos + BytePos((pos + idx) as u32), + }); + } + } + } + rustc_lexer::TokenKind::BlockComment { doc_style, .. } => { + if doc_style.is_none() { + let code_to_the_right = !matches!( + text[pos + token.len as usize..].chars().next(), + Some('\r' | '\n') + ); + let style = match (code_to_the_left, code_to_the_right) { + (_, true) => CommentStyle::Mixed, + (false, false) => CommentStyle::Isolated, + (true, false) => CommentStyle::Trailing, + }; + + // Count the number of chars since the start of the line by rescanning. + let pos_in_file = start_bpos + BytePos(pos as u32); + let line_begin_in_file = source_file.line_begin_pos(pos_in_file); + let line_begin_pos = (line_begin_in_file - start_bpos).to_usize(); + let col = CharPos(text[line_begin_pos..pos].chars().count()); + + let lines = split_block_comment_into_lines(token_text, col); + comments.push(Comment { style, lines, pos: pos_in_file }) + } + } + rustc_lexer::TokenKind::LineComment { doc_style } => { + if doc_style.is_none() { + comments.push(Comment { + style: if code_to_the_left { + CommentStyle::Trailing + } else { + CommentStyle::Isolated + }, + lines: vec![token_text.to_string()], + pos: start_bpos + BytePos(pos as u32), + }) + } + } + _ => { + code_to_the_left = true; + } + } + pos += token.len as usize; + } + + comments +} + impl<'a> Comments<'a> { pub fn new(sm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> { let comments = gather_comments(sm, filename, input); diff --git a/compiler/rustc_error_codes/src/error_codes/E0716.md b/compiler/rustc_error_codes/src/error_codes/E0716.md index c3546cd744f7b..be60716a26426 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0716.md +++ b/compiler/rustc_error_codes/src/error_codes/E0716.md @@ -30,7 +30,7 @@ let q = p; Whenever a temporary is created, it is automatically dropped (freed) according to fixed rules. Ordinarily, the temporary is dropped at the end of the enclosing -statement -- in this case, after the `let`. This is illustrated in the example +statement -- in this case, after the `let p`. This is illustrated in the example above by showing that `tmp` would be freed as we exit the block. To fix this problem, you need to create a local variable to store the value in diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index e5b0d0ae0da3a..440d0ad1140c4 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1049,6 +1049,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bound_list.into_iter().map(|(_, path)| path).collect::>().join("\n"); let actual_prefix = rcvr_ty.prefix_string(self.tcx); info!("unimplemented_traits.len() == {}", unimplemented_traits.len()); + let mut long_ty_file = None; let (primary_message, label) = if unimplemented_traits.len() == 1 && unimplemented_traits_only { @@ -1061,8 +1062,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Avoid crashing. return (None, None); } - let OnUnimplementedNote { message, label, .. } = - self.err_ctxt().on_unimplemented_note(trait_ref, &obligation); + let OnUnimplementedNote { message, label, .. } = self + .err_ctxt() + .on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file); (message, label) }) .unwrap() @@ -1076,6 +1078,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }); err.primary_message(primary_message); + if let Some(file) = long_ty_file { + err.note(format!( + "the full name for the type has been written to '{}'", + file.display(), + )); + err.note( + "consider using `--verbose` to print the full type name to the console", + ); + } if let Some(label) = label { custom_span_label = true; err.span_label(span, label); diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 4ecd87e37d3b5..ee863672017d5 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -10,6 +10,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::FnKind; use rustc_hir::{GenericParamKind, PatKind}; use rustc_middle::ty; +use rustc_session::config::CrateType; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::{BytePos, Span}; @@ -331,6 +332,10 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { return; } + if cx.tcx.crate_types().iter().all(|&crate_type| crate_type == CrateType::Executable) { + return; + } + let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 4ba2da95fb324..126bc0c9ec0fc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -16,6 +16,7 @@ use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use std::iter; +use std::path::PathBuf; use crate::errors::{ EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, @@ -110,6 +111,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, trait_ref: ty::PolyTraitRef<'tcx>, obligation: &PredicateObligation<'tcx>, + long_ty_file: &mut Option, ) -> OnUnimplementedNote { let (def_id, args) = self .impl_similar_to(trait_ref, obligation) @@ -265,7 +267,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { })); if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) { - command.evaluate(self.tcx, trait_ref, &flags) + command.evaluate(self.tcx, trait_ref, &flags, long_ty_file) } else { OnUnimplementedNote::default() } @@ -657,6 +659,7 @@ impl<'tcx> OnUnimplementedDirective { tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, options: &[(Symbol, Option)], + long_ty_file: &mut Option, ) -> OnUnimplementedNote { let mut message = None; let mut label = None; @@ -669,6 +672,7 @@ impl<'tcx> OnUnimplementedDirective { options.iter().filter_map(|(k, v)| v.clone().map(|v| (*k, v))).collect(); for command in self.subcommands.iter().chain(Some(self)).rev() { + debug!(?command); if let Some(ref condition) = command.condition && !attr::eval_condition(condition, &tcx.sess, Some(tcx.features()), &mut |cfg| { let value = cfg.value.map(|v| { @@ -680,7 +684,12 @@ impl<'tcx> OnUnimplementedDirective { span: cfg.span, is_diagnostic_namespace_variant: false } - .format(tcx, trait_ref, &options_map) + .format( + tcx, + trait_ref, + &options_map, + long_ty_file + ) ) }); @@ -709,10 +718,14 @@ impl<'tcx> OnUnimplementedDirective { } OnUnimplementedNote { - label: label.map(|l| l.format(tcx, trait_ref, &options_map)), - message: message.map(|m| m.format(tcx, trait_ref, &options_map)), - notes: notes.into_iter().map(|n| n.format(tcx, trait_ref, &options_map)).collect(), - parent_label: parent_label.map(|e_s| e_s.format(tcx, trait_ref, &options_map)), + label: label.map(|l| l.format(tcx, trait_ref, &options_map, long_ty_file)), + message: message.map(|m| m.format(tcx, trait_ref, &options_map, long_ty_file)), + notes: notes + .into_iter() + .map(|n| n.format(tcx, trait_ref, &options_map, long_ty_file)) + .collect(), + parent_label: parent_label + .map(|e_s| e_s.format(tcx, trait_ref, &options_map, long_ty_file)), append_const_msg, } } @@ -814,6 +827,7 @@ impl<'tcx> OnUnimplementedFormatString { tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, options: &FxHashMap, + long_ty_file: &mut Option, ) -> String { let name = tcx.item_name(trait_ref.def_id); let trait_str = tcx.def_path_str(trait_ref.def_id); @@ -824,7 +838,11 @@ impl<'tcx> OnUnimplementedFormatString { .filter_map(|param| { let value = match param.kind { GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { - trait_ref.args[param.index as usize].to_string() + if let Some(ty) = trait_ref.args[param.index as usize].as_type() { + tcx.short_ty_string(ty, long_ty_file) + } else { + trait_ref.args[param.index as usize].to_string() + } } GenericParamDefKind::Lifetime => return None, }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index bca7b2327495c..16290c8dbcafb 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2671,6 +2671,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) where T: ToPredicate<'tcx>, { + let mut long_ty_file = None; + let tcx = self.tcx; let predicate = predicate.to_predicate(tcx); match *cause_code { @@ -2853,21 +2855,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } ObligationCauseCode::Coercion { source, target } => { - let mut file = None; - let source = tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut file); - let target = tcx.short_ty_string(self.resolve_vars_if_possible(target), &mut file); + let source = + tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file); + let target = + tcx.short_ty_string(self.resolve_vars_if_possible(target), &mut long_ty_file); err.note(with_forced_trimmed_paths!(format!( "required for the cast from `{source}` to `{target}`", ))); - if let Some(file) = file { - err.note(format!( - "the full name for the type has been written to '{}'", - file.display(), - )); - err.note( - "consider using `--verbose` to print the full type name to the console", - ); - } } ObligationCauseCode::RepeatElementCopy { is_constable, @@ -3170,8 +3164,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Don't print the tuple of capture types 'print: { if !is_upvar_tys_infer_tuple { - let mut file = None; - let ty_str = tcx.short_ty_string(ty, &mut file); + let ty_str = tcx.short_ty_string(ty, &mut long_ty_file); let msg = format!("required because it appears within the type `{ty_str}`"); match ty.kind() { ty::Adt(def, _) => match tcx.opt_item_ident(def.did()) { @@ -3269,9 +3262,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut parent_trait_pred = self.resolve_vars_if_possible(data.derived.parent_trait_pred); let parent_def_id = parent_trait_pred.def_id(); - let mut file = None; - let self_ty_str = - tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file); + let self_ty_str = tcx + .short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut long_ty_file); let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string(); let msg = format!("required for `{self_ty_str}` to implement `{trait_name}`"); let mut is_auto_trait = false; @@ -3329,15 +3321,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } }; - if let Some(file) = file { - err.note(format!( - "the full type name has been written to '{}'", - file.display(), - )); - err.note( - "consider using `--verbose` to print the full type name to the console", - ); - } let mut parent_predicate = parent_trait_pred; let mut data = &data.derived; let mut count = 0; @@ -3378,22 +3361,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { count, pluralize!(count) )); - let mut file = None; - let self_ty = - tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file); + let self_ty = tcx.short_ty_string( + parent_trait_pred.skip_binder().self_ty(), + &mut long_ty_file, + ); err.note(format!( "required for `{self_ty}` to implement `{}`", parent_trait_pred.print_modifiers_and_trait_path() )); - if let Some(file) = file { - err.note(format!( - "the full type name has been written to '{}'", - file.display(), - )); - err.note( - "consider using `--verbose` to print the full type name to the console", - ); - } } // #74711: avoid a stack overflow ensure_sufficient_stack(|| { @@ -3502,7 +3477,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::OpaqueReturnType(expr_info) => { if let Some((expr_ty, expr_span)) = expr_info { - let expr_ty = with_forced_trimmed_paths!(self.ty_to_string(expr_ty)); + let expr_ty = self.tcx.short_ty_string(expr_ty, &mut long_ty_file); err.span_label( expr_span, with_forced_trimmed_paths!(format!( @@ -3512,6 +3487,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } } + + if let Some(file) = long_ty_file { + err.note(format!( + "the full name for the type has been written to '{}'", + file.display(), + )); + err.note("consider using `--verbose` to print the full type name to the console"); + } } #[instrument( @@ -4769,20 +4752,21 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>( } else { String::new() }; - match ty_desc { - Some(desc) => format!( - "{}the trait `{}` is not implemented for {} `{}`{post}", - pre_message, - trait_predicate.print_modifiers_and_trait_path(), - desc, - tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None), - ), - None => format!( - "{}the trait `{}` is not implemented for `{}`{post}", - pre_message, + let desc = match ty_desc { + Some(desc) => format!(" {desc}"), + None => String::new(), + }; + if let ty::ImplPolarity::Positive = trait_predicate.polarity() { + format!( + "{pre_message}the trait `{}` is not implemented for{desc} `{}`{post}", trait_predicate.print_modifiers_and_trait_path(), tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None), - ), + ) + } else { + // "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is + // not implemented for `T`". + // FIXME: add note explaining explicit negative trait bounds. + format!("{pre_message}the trait bound `{trait_predicate}` is not satisfied{post}") } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 3aaed398f57c7..62933bce76b77 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -395,6 +395,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { kind: _, } = *obligation.cause.code() { + debug!("ObligationCauseCode::CompareImplItemObligation"); return self.report_extra_impl_obligation( span, impl_item_def_id, @@ -445,18 +446,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) }) .unwrap_or_default(); - let file_note = file.map(|file| format!( + let file_note = file.as_ref().map(|file| format!( "the full trait has been written to '{}'", file.display(), )); + let mut long_ty_file = None; + let OnUnimplementedNote { message, label, notes, parent_label, append_const_msg, - } = self.on_unimplemented_note(trait_ref, &obligation); + } = self.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file); + let have_alt_message = message.is_some() || label.is_some(); let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id()); let is_unsize = @@ -511,6 +515,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); + if let Some(long_ty_file) = long_ty_file { + err.note(format!( + "the full name for the type has been written to '{}'", + long_ty_file.display(), + )); + err.note("consider using `--verbose` to print the full type name to the console"); + } let mut suggested = false; if is_try_conversion { suggested = self.try_conversion_context(&obligation, trait_ref.skip_binder(), &mut err); @@ -758,6 +769,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return err.emit(); } + + err } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 271ea88fff652..58ffa9710d3e6 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -180,7 +180,7 @@ pub struct BTreeMap< /// `ManuallyDrop` to control drop order (needs to be dropped after all the nodes). pub(super) alloc: ManuallyDrop, // For dropck; the `Box` avoids making the `Unpin` impl more strict than before - _marker: PhantomData>, + _marker: PhantomData>, } #[stable(feature = "btree_drop", since = "1.7.0")] diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 52b9ef470dccb..b54f2db88ffc9 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -5,16 +5,16 @@ use super::*; use std::marker::PhantomData; use std::sync::atomic::AtomicU32; -macro_rules! define_handles { +macro_rules! define_client_handles { ( 'owned: $($oty:ident,)* 'interned: $($ity:ident,)* ) => { #[repr(C)] #[allow(non_snake_case)] - pub struct HandleCounters { - $($oty: AtomicU32,)* - $($ity: AtomicU32,)* + pub(super) struct HandleCounters { + $(pub(super) $oty: AtomicU32,)* + $(pub(super) $ity: AtomicU32,)* } impl HandleCounters { @@ -29,22 +29,6 @@ macro_rules! define_handles { } } - // FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`. - #[allow(non_snake_case)] - pub(super) struct HandleStore { - $($oty: handle::OwnedStore,)* - $($ity: handle::InternedStore,)* - } - - impl HandleStore { - pub(super) fn new(handle_counters: &'static HandleCounters) -> Self { - HandleStore { - $($oty: handle::OwnedStore::new(&handle_counters.$oty),)* - $($ity: handle::InternedStore::new(&handle_counters.$ity),)* - } - } - } - $( pub(crate) struct $oty { handle: handle::Handle, @@ -72,53 +56,18 @@ macro_rules! define_handles { } } - impl DecodeMut<'_, '_, HandleStore>> - for Marked - { - fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { - s.$oty.take(handle::Handle::decode(r, &mut ())) - } - } - impl Encode for &$oty { fn encode(self, w: &mut Writer, s: &mut S) { self.handle.encode(w, s); } } - impl<'s, S: server::Types> Decode<'_, 's, HandleStore>> - for &'s Marked - { - fn decode(r: &mut Reader<'_>, s: &'s HandleStore>) -> Self { - &s.$oty[handle::Handle::decode(r, &mut ())] - } - } - impl Encode for &mut $oty { fn encode(self, w: &mut Writer, s: &mut S) { self.handle.encode(w, s); } } - impl<'s, S: server::Types> DecodeMut<'_, 's, HandleStore>> - for &'s mut Marked - { - fn decode( - r: &mut Reader<'_>, - s: &'s mut HandleStore> - ) -> Self { - &mut s.$oty[handle::Handle::decode(r, &mut ())] - } - } - - impl Encode>> - for Marked - { - fn encode(self, w: &mut Writer, s: &mut HandleStore>) { - s.$oty.alloc(self).encode(w, s); - } - } - impl DecodeMut<'_, '_, S> for $oty { fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { $oty { @@ -145,22 +94,6 @@ macro_rules! define_handles { } } - impl DecodeMut<'_, '_, HandleStore>> - for Marked - { - fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { - s.$ity.copy(handle::Handle::decode(r, &mut ())) - } - } - - impl Encode>> - for Marked - { - fn encode(self, w: &mut Writer, s: &mut HandleStore>) { - s.$ity.alloc(self).encode(w, s); - } - } - impl DecodeMut<'_, '_, S> for $ity { fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { $ity { @@ -172,15 +105,7 @@ macro_rules! define_handles { )* } } -define_handles! { - 'owned: - FreeFunctions, - TokenStream, - SourceFile, - - 'interned: - Span, -} +with_api_handle_types!(define_client_handles); // FIXME(eddyb) generate these impls by pattern-matching on the // names of methods - also could use the presence of `fn drop` diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 9b337f23867f4..67c72cf98d405 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -113,6 +113,23 @@ macro_rules! with_api { }; } +// Similar to `with_api`, but only lists the types requiring handles, and they +// are divided into the two storage categories. +macro_rules! with_api_handle_types { + ($m:ident) => { + $m! { + 'owned: + FreeFunctions, + TokenStream, + SourceFile, + + 'interned: + Span, + // Symbol is handled manually + } + }; +} + // FIXME(eddyb) this calls `encode` for each argument, but in reverse, // to match the ordering in `reverse_decode`. macro_rules! reverse_encode { diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index 2ea87d866ff3e..8736d1806fbe9 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -5,8 +5,79 @@ use super::*; use std::cell::Cell; use std::marker::PhantomData; -// FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`. -use super::client::HandleStore; +macro_rules! define_server_handles { + ( + 'owned: $($oty:ident,)* + 'interned: $($ity:ident,)* + ) => { + #[allow(non_snake_case)] + pub(super) struct HandleStore { + $($oty: handle::OwnedStore,)* + $($ity: handle::InternedStore,)* + } + + impl HandleStore { + fn new(handle_counters: &'static client::HandleCounters) -> Self { + HandleStore { + $($oty: handle::OwnedStore::new(&handle_counters.$oty),)* + $($ity: handle::InternedStore::new(&handle_counters.$ity),)* + } + } + } + + $( + impl Encode>> for Marked { + fn encode(self, w: &mut Writer, s: &mut HandleStore>) { + s.$oty.alloc(self).encode(w, s); + } + } + + impl DecodeMut<'_, '_, HandleStore>> + for Marked + { + fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { + s.$oty.take(handle::Handle::decode(r, &mut ())) + } + } + + impl<'s, S: Types> Decode<'_, 's, HandleStore>> + for &'s Marked + { + fn decode(r: &mut Reader<'_>, s: &'s HandleStore>) -> Self { + &s.$oty[handle::Handle::decode(r, &mut ())] + } + } + + impl<'s, S: Types> DecodeMut<'_, 's, HandleStore>> + for &'s mut Marked + { + fn decode( + r: &mut Reader<'_>, + s: &'s mut HandleStore> + ) -> Self { + &mut s.$oty[handle::Handle::decode(r, &mut ())] + } + } + )* + + $( + impl Encode>> for Marked { + fn encode(self, w: &mut Writer, s: &mut HandleStore>) { + s.$ity.alloc(self).encode(w, s); + } + } + + impl DecodeMut<'_, '_, HandleStore>> + for Marked + { + fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { + s.$ity.copy(handle::Handle::decode(r, &mut ())) + } + } + )* + } +} +with_api_handle_types!(define_server_handles); pub trait Types { type FreeFunctions: 'static; diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index 02225d20b26e1..86ce2cc189588 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -109,18 +109,18 @@ impl Encode for Symbol { } } -impl DecodeMut<'_, '_, client::HandleStore>> +impl DecodeMut<'_, '_, server::HandleStore>> for Marked { - fn decode(r: &mut Reader<'_>, s: &mut client::HandleStore>) -> Self { + fn decode(r: &mut Reader<'_>, s: &mut server::HandleStore>) -> Self { Mark::mark(S::intern_symbol(<&str>::decode(r, s))) } } -impl Encode>> +impl Encode>> for Marked { - fn encode(self, w: &mut Writer, s: &mut client::HandleStore>) { + fn encode(self, w: &mut Writer, s: &mut server::HandleStore>) { S::with_symbol_string(&self.unmark(), |sym| sym.encode(w, s)) } } diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 6ec389400ae81..de9bde51f2a30 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -186,11 +186,8 @@ impl f32 { /// let x = 3.5_f32; /// let y = -3.5_f32; /// - /// let abs_difference_x = (x.abs() - x).abs(); - /// let abs_difference_y = (y.abs() - (-y)).abs(); - /// - /// assert!(abs_difference_x <= f32::EPSILON); - /// assert!(abs_difference_y <= f32::EPSILON); + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); /// /// assert!(f32::NAN.abs().is_nan()); /// ``` @@ -276,10 +273,17 @@ impl f32 { /// let x = 4.0_f32; /// let b = 60.0_f32; /// - /// // 100.0 - /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs(); + /// assert_eq!(m.mul_add(x, b), 100.0); + /// assert_eq!(m * x + b, 100.0); /// - /// assert!(abs_difference <= f32::EPSILON); + /// let one_plus_eps = 1.0_f32 + f32::EPSILON; + /// let one_minus_eps = 1.0_f32 - f32::EPSILON; + /// let minus_one = -1.0_f32; + /// + /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps. + /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f32::EPSILON * f32::EPSILON); + /// // Different rounding with the non-fused multiply and add. + /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -426,9 +430,7 @@ impl f32 { /// let negative = -4.0_f32; /// let negative_zero = -0.0_f32; /// - /// let abs_difference = (positive.sqrt() - 2.0).abs(); - /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert_eq!(positive.sqrt(), 2.0); /// assert!(negative.sqrt().is_nan()); /// assert!(negative_zero.sqrt() == negative_zero); /// ``` diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 7385576c33717..944186d602c8f 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -186,11 +186,8 @@ impl f64 { /// let x = 3.5_f64; /// let y = -3.5_f64; /// - /// let abs_difference_x = (x.abs() - x).abs(); - /// let abs_difference_y = (y.abs() - (-y)).abs(); - /// - /// assert!(abs_difference_x < 1e-10); - /// assert!(abs_difference_y < 1e-10); + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); /// /// assert!(f64::NAN.abs().is_nan()); /// ``` @@ -276,10 +273,17 @@ impl f64 { /// let x = 4.0_f64; /// let b = 60.0_f64; /// - /// // 100.0 - /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs(); + /// assert_eq!(m.mul_add(x, b), 100.0); + /// assert_eq!(m * x + b, 100.0); /// - /// assert!(abs_difference < 1e-10); + /// let one_plus_eps = 1.0_f64 + f64::EPSILON; + /// let one_minus_eps = 1.0_f64 - f64::EPSILON; + /// let minus_one = -1.0_f64; + /// + /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps. + /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f64::EPSILON * f64::EPSILON); + /// // Different rounding with the non-fused multiply and add. + /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -426,9 +430,7 @@ impl f64 { /// let negative = -4.0_f64; /// let negative_zero = -0.0_f64; /// - /// let abs_difference = (positive.sqrt() - 2.0).abs(); - /// - /// assert!(abs_difference < 1e-10); + /// assert_eq!(positive.sqrt(), 2.0); /// assert!(negative.sqrt().is_nan()); /// assert!(negative_zero.sqrt() == negative_zero); /// ``` diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 6b1dd1b5af4c9..694cc34cdc171 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1476,11 +1476,10 @@ impl Permissions { /// On Unix-based platforms this checks if *any* of the owner, group or others /// write permission bits are set. It does not check if the current /// user is in the file's assigned group. It also does not check ACLs. - /// Therefore even if this returns true you may not be able to write to the - /// file, and vice versa. The [`PermissionsExt`] trait gives direct access - /// to the permission bits but also does not read ACLs. If you need to - /// accurately know whether or not a file is writable use the `access()` - /// function from libc. + /// Therefore the return value of this function cannot be relied upon + /// to predict whether attempts to read or write the file will actually succeed. + /// The [`PermissionsExt`] trait gives direct access to the permission bits but + /// also does not read ACLs. /// /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt /// diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index d77ac7eb027dc..81200e0061e05 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -9,6 +9,9 @@ pub mod cmath; pub mod locks; pub mod os_str; pub mod path; +#[allow(dead_code)] +#[allow(unused_imports)] +pub mod thread_local; // FIXME(117276): remove this, move feature implementations into individual // submodules. diff --git a/library/std/src/sys/pal/common/mod.rs b/library/std/src/sys/pal/common/mod.rs index b35c5d30b4113..29fc0835d7666 100644 --- a/library/std/src/sys/pal/common/mod.rs +++ b/library/std/src/sys/pal/common/mod.rs @@ -12,8 +12,6 @@ pub mod alloc; pub mod small_c_string; -#[allow(unused_imports)] -pub mod thread_local; #[cfg(test)] mod tests; diff --git a/library/std/src/sys/pal/common/thread_local/fast_local.rs b/library/std/src/sys/thread_local/fast_local.rs similarity index 100% rename from library/std/src/sys/pal/common/thread_local/fast_local.rs rename to library/std/src/sys/thread_local/fast_local.rs diff --git a/library/std/src/sys/pal/common/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs similarity index 100% rename from library/std/src/sys/pal/common/thread_local/mod.rs rename to library/std/src/sys/thread_local/mod.rs diff --git a/library/std/src/sys/pal/common/thread_local/os_local.rs b/library/std/src/sys/thread_local/os_local.rs similarity index 100% rename from library/std/src/sys/pal/common/thread_local/os_local.rs rename to library/std/src/sys/thread_local/os_local.rs diff --git a/library/std/src/sys/pal/common/thread_local/static_local.rs b/library/std/src/sys/thread_local/static_local.rs similarity index 100% rename from library/std/src/sys/pal/common/thread_local/static_local.rs rename to library/std/src/sys/thread_local/static_local.rs diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 76af7fec92648..85de2980133d5 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -205,7 +205,7 @@ cfg_if::cfg_if! { #[doc(hidden)] #[unstable(feature = "thread_local_internals", issue = "none")] pub mod local_impl { - pub use crate::sys::common::thread_local::{thread_local_inner, Key, abort_on_dtor_unwind}; + pub use crate::sys::thread_local::{thread_local_inner, Key, abort_on_dtor_unwind}; } } } diff --git a/tests/ui/lint/lint-non-snake-case-crate-2.stderr b/tests/ui/lint/lint-non-snake-case-crate-2.stderr deleted file mode 100644 index f3207226cd93e..0000000000000 --- a/tests/ui/lint/lint-non-snake-case-crate-2.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: crate `NonSnakeCase` should have a snake case name - | - = help: convert the identifier to snake case: `non_snake_case` -note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate-2.rs:4:9 - | -LL | #![deny(non_snake_case)] - | ^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/lint/lint-non-snake-case-crate-bin.rs b/tests/ui/lint/lint-non-snake-case-crate-bin.rs new file mode 100644 index 0000000000000..ac1a03369ef45 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-bin.rs @@ -0,0 +1,6 @@ +//@ check-pass +#![crate_name = "NonSnakeCase"] + +#![deny(non_snake_case)] + +fn main() {} diff --git a/tests/ui/lint/lint-non-snake-case-crate-2.rs b/tests/ui/lint/lint-non-snake-case-crate-bin2.rs similarity index 54% rename from tests/ui/lint/lint-non-snake-case-crate-2.rs rename to tests/ui/lint/lint-non-snake-case-crate-bin2.rs index b4b816a5a5775..78eb5d1b6cdfb 100644 --- a/tests/ui/lint/lint-non-snake-case-crate-2.rs +++ b/tests/ui/lint/lint-non-snake-case-crate-bin2.rs @@ -1,5 +1,5 @@ //@ compile-flags: --crate-name NonSnakeCase -//@ error-pattern: crate `NonSnakeCase` should have a snake case name +//@ check-pass #![deny(non_snake_case)] diff --git a/tests/ui/lint/lint-non-snake-case-crate-bin3.rs b/tests/ui/lint/lint-non-snake-case-crate-bin3.rs new file mode 100644 index 0000000000000..1e801802b43b9 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-bin3.rs @@ -0,0 +1,7 @@ +//@ check-pass +#![crate_type = "bin"] +#![crate_name = "NonSnakeCase"] + +#![deny(non_snake_case)] + +fn main() {} diff --git a/tests/ui/lint/lint-non-snake-case-crate-cdylib.rs b/tests/ui/lint/lint-non-snake-case-crate-cdylib.rs new file mode 100644 index 0000000000000..d2cd62fd68a8d --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-cdylib.rs @@ -0,0 +1,6 @@ +#![crate_type = "cdylib"] +#![crate_name = "NonSnakeCase"] +//~^ ERROR crate `NonSnakeCase` should have a snake case name +#![deny(non_snake_case)] + +fn main() {} diff --git a/tests/ui/lint/lint-non-snake-case-crate-cdylib.stderr b/tests/ui/lint/lint-non-snake-case-crate-cdylib.stderr new file mode 100644 index 0000000000000..4bb129f31b772 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-cdylib.stderr @@ -0,0 +1,14 @@ +error: crate `NonSnakeCase` should have a snake case name + --> $DIR/lint-non-snake-case-crate-cdylib.rs:2:18 + | +LL | #![crate_name = "NonSnakeCase"] + | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` + | +note: the lint level is defined here + --> $DIR/lint-non-snake-case-crate-cdylib.rs:4:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/lint-non-snake-case-crate-dylib.rs b/tests/ui/lint/lint-non-snake-case-crate-dylib.rs new file mode 100644 index 0000000000000..1ab974c54f6e3 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-dylib.rs @@ -0,0 +1,6 @@ +#![crate_type = "dylib"] +#![crate_name = "NonSnakeCase"] +//~^ ERROR crate `NonSnakeCase` should have a snake case name +#![deny(non_snake_case)] + +fn main() {} diff --git a/tests/ui/lint/lint-non-snake-case-crate-dylib.stderr b/tests/ui/lint/lint-non-snake-case-crate-dylib.stderr new file mode 100644 index 0000000000000..23d40c2394d95 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-dylib.stderr @@ -0,0 +1,14 @@ +error: crate `NonSnakeCase` should have a snake case name + --> $DIR/lint-non-snake-case-crate-dylib.rs:2:18 + | +LL | #![crate_name = "NonSnakeCase"] + | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` + | +note: the lint level is defined here + --> $DIR/lint-non-snake-case-crate-dylib.rs:4:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/lint-non-snake-case-crate.rs b/tests/ui/lint/lint-non-snake-case-crate-lib.rs similarity index 85% rename from tests/ui/lint/lint-non-snake-case-crate.rs rename to tests/ui/lint/lint-non-snake-case-crate-lib.rs index e4e84261a4ee9..79e020f07ba2a 100644 --- a/tests/ui/lint/lint-non-snake-case-crate.rs +++ b/tests/ui/lint/lint-non-snake-case-crate-lib.rs @@ -1,3 +1,4 @@ +#![crate_type = "lib"] #![crate_name = "NonSnakeCase"] //~^ ERROR crate `NonSnakeCase` should have a snake case name #![deny(non_snake_case)] diff --git a/tests/ui/lint/lint-non-snake-case-crate.stderr b/tests/ui/lint/lint-non-snake-case-crate-lib.stderr similarity index 77% rename from tests/ui/lint/lint-non-snake-case-crate.stderr rename to tests/ui/lint/lint-non-snake-case-crate-lib.stderr index 1136b707d595b..6d40a6bdb6c66 100644 --- a/tests/ui/lint/lint-non-snake-case-crate.stderr +++ b/tests/ui/lint/lint-non-snake-case-crate-lib.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name - --> $DIR/lint-non-snake-case-crate.rs:1:18 + --> $DIR/lint-non-snake-case-crate-lib.rs:2:18 | LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate.rs:3:9 + --> $DIR/lint-non-snake-case-crate-lib.rs:4:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/lint-non-snake-case-crate-proc-macro.rs b/tests/ui/lint/lint-non-snake-case-crate-proc-macro.rs new file mode 100644 index 0000000000000..949abe5573c79 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-proc-macro.rs @@ -0,0 +1,6 @@ +#![crate_type = "proc-macro"] +#![crate_name = "NonSnakeCase"] +//~^ ERROR crate `NonSnakeCase` should have a snake case name +#![deny(non_snake_case)] + +fn main() {} diff --git a/tests/ui/lint/lint-non-snake-case-crate-proc-macro.stderr b/tests/ui/lint/lint-non-snake-case-crate-proc-macro.stderr new file mode 100644 index 0000000000000..4963eef88e4b8 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-proc-macro.stderr @@ -0,0 +1,14 @@ +error: crate `NonSnakeCase` should have a snake case name + --> $DIR/lint-non-snake-case-crate-proc-macro.rs:2:18 + | +LL | #![crate_name = "NonSnakeCase"] + | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` + | +note: the lint level is defined here + --> $DIR/lint-non-snake-case-crate-proc-macro.rs:4:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/lint-non-snake-case-crate-rlib.rs b/tests/ui/lint/lint-non-snake-case-crate-rlib.rs new file mode 100644 index 0000000000000..1d5334d81f303 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-rlib.rs @@ -0,0 +1,6 @@ +#![crate_type = "rlib"] +#![crate_name = "NonSnakeCase"] +//~^ ERROR crate `NonSnakeCase` should have a snake case name +#![deny(non_snake_case)] + +fn main() {} diff --git a/tests/ui/lint/lint-non-snake-case-crate-rlib.stderr b/tests/ui/lint/lint-non-snake-case-crate-rlib.stderr new file mode 100644 index 0000000000000..ba0b85f6f0042 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-rlib.stderr @@ -0,0 +1,14 @@ +error: crate `NonSnakeCase` should have a snake case name + --> $DIR/lint-non-snake-case-crate-rlib.rs:2:18 + | +LL | #![crate_name = "NonSnakeCase"] + | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` + | +note: the lint level is defined here + --> $DIR/lint-non-snake-case-crate-rlib.rs:4:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/lint-non-snake-case-crate-staticlib.rs b/tests/ui/lint/lint-non-snake-case-crate-staticlib.rs new file mode 100644 index 0000000000000..fbb4ea7d0b5a8 --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-staticlib.rs @@ -0,0 +1,8 @@ +//@ ignore-wasm + +#![crate_type = "staticlib"] +#![crate_name = "NonSnakeCase"] +//~^ ERROR crate `NonSnakeCase` should have a snake case name +#![deny(non_snake_case)] + +fn main() {} diff --git a/tests/ui/lint/lint-non-snake-case-crate-staticlib.stderr b/tests/ui/lint/lint-non-snake-case-crate-staticlib.stderr new file mode 100644 index 0000000000000..49438414c278b --- /dev/null +++ b/tests/ui/lint/lint-non-snake-case-crate-staticlib.stderr @@ -0,0 +1,14 @@ +error: crate `NonSnakeCase` should have a snake case name + --> $DIR/lint-non-snake-case-crate-staticlib.rs:4:18 + | +LL | #![crate_name = "NonSnakeCase"] + | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` + | +note: the lint level is defined here + --> $DIR/lint-non-snake-case-crate-staticlib.rs:6:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/negative-bounds/simple.stderr b/tests/ui/traits/negative-bounds/simple.stderr index 6d750739e197c..b8d12138794bf 100644 --- a/tests/ui/traits/negative-bounds/simple.stderr +++ b/tests/ui/traits/negative-bounds/simple.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: !Copy` is not satisfied --> $DIR/simple.rs:10:16 | LL | not_copy::(); - | ^ the trait `!Copy` is not implemented for `T` + | ^ the trait bound `T: !Copy` is not satisfied | note: required by a bound in `not_copy` --> $DIR/simple.rs:3:16 @@ -14,7 +14,7 @@ error[E0277]: the trait bound `T: !Copy` is not satisfied --> $DIR/simple.rs:15:16 | LL | not_copy::(); - | ^ the trait `!Copy` is not implemented for `T` + | ^ the trait bound `T: !Copy` is not satisfied | note: required by a bound in `not_copy` --> $DIR/simple.rs:3:16 @@ -26,7 +26,7 @@ error[E0277]: the trait bound `Copyable: !Copy` is not satisfied --> $DIR/simple.rs:30:16 | LL | not_copy::(); - | ^^^^^^^^ the trait `!Copy` is not implemented for `Copyable` + | ^^^^^^^^ the trait bound `Copyable: !Copy` is not satisfied | = help: the trait `Copy` is implemented for `Copyable` note: required by a bound in `not_copy` @@ -44,7 +44,7 @@ error[E0277]: the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied --> $DIR/simple.rs:37:16 | LL | not_copy::(); - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `!Copy` is not implemented for `NotNecessarilyCopyable` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied | note: required by a bound in `not_copy` --> $DIR/simple.rs:3:16 diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs new file mode 100644 index 0000000000000..60c3327902e11 --- /dev/null +++ b/tests/ui/traits/on_unimplemented_long_types.rs @@ -0,0 +1,17 @@ +//@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes +//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" + +pub fn foo() -> impl std::fmt::Display { + //~^ ERROR doesn't implement `std::fmt::Display` + Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( + Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( + Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( + Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( + Some(Some(Some(Some(Some(Some(Some(Some(())))))))), + ))))))))))), + ))))))))))), + ))))))))))), + ))))))))))) +} + +fn main() {} diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr new file mode 100644 index 0000000000000..bddc5695696b5 --- /dev/null +++ b/tests/ui/traits/on_unimplemented_long_types.stderr @@ -0,0 +1,25 @@ +error[E0277]: `Option>>` doesn't implement `std::fmt::Display` + --> $DIR/on_unimplemented_long_types.rs:4:17 + | +LL | pub fn foo() -> impl std::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^^^^ `Option>>` cannot be formatted with the default formatter +LL | +LL | / Some(Some(Some(Some(Some(Some(Some(Some(Some(S... +LL | | Some(Some(Some(Some(Some(Some(Some(Some(So... +LL | | Some(Some(Some(Some(Some(Some(Some(Som... +LL | | Some(Some(Some(Some(Some(Some(Some... +... | +LL | | ))))))))))), +LL | | ))))))))))) + | |_______________- return type was inferred to be `Option>>` here + | + = note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console + = help: the trait `std::fmt::Display` is not implemented for `Option>>` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.