diff options
251 files changed, 2786 insertions, 736 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe67a14c0fe..a07342ee96c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -288,7 +288,7 @@ jobs: - name: dist-x86_64-apple env: SCRIPT: "./x.py dist" - RUST_CONFIGURE_ARGS: "--host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" + RUST_CONFIGURE_ARGS: "--host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 NO_LLVM_ASSERTIONS: 1 diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 2124f1efb99..9c6ad47427d 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -63,7 +63,11 @@ impl LitKind { unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| { match unescaped_char { Ok(c) => buf.push(c), - Err(_) => error = Err(LitError::LexerError), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } } }); error?; @@ -83,7 +87,11 @@ impl LitKind { unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| { match unescaped_char { Ok(c) => buf.push(c), - Err(_) => error = Err(LitError::LexerError), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } } }); error?; @@ -100,7 +108,11 @@ impl LitKind { unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| { match unescaped_byte { Ok(c) => buf.push(c), - Err(_) => error = Err(LitError::LexerError), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } } }); error?; @@ -114,7 +126,11 @@ impl LitKind { unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| { match unescaped_byte { Ok(c) => buf.push(c), - Err(_) => error = Err(LitError::LexerError), + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } } }); error?; diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 0fddb0ee4cc..3acf69ec2b7 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1443,16 +1443,19 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplTraitContext::disallowed(), ), bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()), - bounds: this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| { - match *bound { - // Ignore `?Trait` bounds. - // They were copied into type parameters already. - GenericBound::Trait(_, TraitBoundModifier::Maybe) => None, - _ => Some( - this.lower_param_bound(bound, ImplTraitContext::disallowed()), - ), - } - })), + bounds: this.arena.alloc_from_iter(bounds.iter().map( + |bound| match bound { + // We used to ignore `?Trait` bounds, as they were copied into type + // parameters already, but we need to keep them around only for + // diagnostics when we suggest removal of `?Sized` bounds. See + // `suggest_constraining_type_param`. This will need to change if + // we ever allow something *other* than `?Sized`. + GenericBound::Trait(p, TraitBoundModifier::Maybe) => { + hir::GenericBound::Unsized(p.span) + } + _ => this.lower_param_bound(bound, ImplTraitContext::disallowed()), + }, + )), span, }) }) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3bd42ba6090..581f177ad14 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2160,12 +2160,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { tpb: &GenericBound, itctx: ImplTraitContext<'_, 'hir>, ) -> hir::GenericBound<'hir> { - match *tpb { - GenericBound::Trait(ref ty, modifier) => hir::GenericBound::Trait( - self.lower_poly_trait_ref(ty, itctx), - self.lower_trait_bound_modifier(modifier), + match tpb { + GenericBound::Trait(p, modifier) => hir::GenericBound::Trait( + self.lower_poly_trait_ref(p, itctx), + self.lower_trait_bound_modifier(*modifier), ), - GenericBound::Outlives(ref lifetime) => { + GenericBound::Outlives(lifetime) => { hir::GenericBound::Outlives(self.lower_lifetime(lifetime)) } } diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 45661ac1562..8199c44ee2a 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -444,6 +444,30 @@ impl Diagnostic { self } + /// Prints out a message with multiple suggested edits of the code. + /// See also [`Diagnostic::span_suggestion()`]. + pub fn multipart_suggestions( + &mut self, + msg: &str, + suggestions: impl Iterator<Item = Vec<(Span, String)>>, + applicability: Applicability, + ) -> &mut Self { + self.suggestions.push(CodeSuggestion { + substitutions: suggestions + .map(|sugg| Substitution { + parts: sugg + .into_iter() + .map(|(span, snippet)| SubstitutionPart { snippet, span }) + .collect(), + }) + .collect(), + msg: msg.to_owned(), + style: SuggestionStyle::ShowCode, + applicability, + tool_metadata: Default::default(), + }); + self + } /// Prints out a message with a suggested edit of the code. If the suggestion is presented /// inline, it will only show the message and not the suggestion. /// diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 282877d5dd1..d35b2924803 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -301,6 +301,20 @@ impl<'a> DiagnosticBuilder<'a> { self } + /// See [`Diagnostic::multipart_suggestions()`]. + pub fn multipart_suggestions( + &mut self, + msg: &str, + suggestions: impl Iterator<Item = Vec<(Span, String)>>, + applicability: Applicability, + ) -> &mut Self { + if !self.0.allow_suggestions { + return self; + } + self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability); + self + } + /// See [`Diagnostic::span_suggestion_short()`]. pub fn span_suggestion_short( &mut self, diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index b97593b92b3..9aee86c9e57 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -45,6 +45,8 @@ crate struct ParserAnyMacro<'a> { lint_node_id: NodeId, is_trailing_mac: bool, arm_span: Span, + /// Whether or not this macro is defined in the current crate + is_local: bool, } crate fn annotate_err_with_kind( @@ -124,6 +126,7 @@ impl<'a> ParserAnyMacro<'a> { lint_node_id, arm_span, is_trailing_mac, + is_local, } = *self; let snapshot = &mut parser.clone(); let fragment = match parse_ast_fragment(parser, kind) { @@ -138,13 +141,15 @@ impl<'a> ParserAnyMacro<'a> { // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`, // but `m!()` is allowed in expression positions (cf. issue #34706). if kind == AstFragmentKind::Expr && parser.token == token::Semi { - parser.sess.buffer_lint_with_diagnostic( - SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, - parser.token.span, - lint_node_id, - "trailing semicolon in macro used in expression position", - BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident), - ); + if is_local { + parser.sess.buffer_lint_with_diagnostic( + SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, + parser.token.span, + lint_node_id, + "trailing semicolon in macro used in expression position", + BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident), + ); + } parser.bump(); } @@ -162,6 +167,7 @@ struct MacroRulesMacroExpander { lhses: Vec<mbe::TokenTree>, rhses: Vec<mbe::TokenTree>, valid: bool, + is_local: bool, } impl TTMacroExpander for MacroRulesMacroExpander { @@ -183,6 +189,7 @@ impl TTMacroExpander for MacroRulesMacroExpander { input, &self.lhses, &self.rhses, + self.is_local, ) } } @@ -210,6 +217,7 @@ fn generic_extension<'cx>( arg: TokenStream, lhses: &[mbe::TokenTree], rhses: &[mbe::TokenTree], + is_local: bool, ) -> Box<dyn MacResult + 'cx> { let sess = &cx.sess.parse_sess; @@ -311,6 +319,7 @@ fn generic_extension<'cx>( lint_node_id: cx.current_expansion.lint_node_id, is_trailing_mac: cx.current_expansion.is_trailing_mac, arm_span, + is_local, }); } Failure(token, msg) => match best_failure { @@ -544,6 +553,9 @@ pub fn compile_declarative_macro( lhses, rhses, valid, + // Macros defined in the current crate have a real node id, + // whereas macros from an external crate have a dummy id. + is_local: def.id != DUMMY_NODE_ID, })) } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 1ec9a0518b8..638330c904d 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -683,6 +683,10 @@ declare_features! ( /// Allows the `?` operator in const contexts. (active, const_try, "1.56.0", Some(74935), None), + /// Allows upcasting trait objects via supertraits. + /// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. + (incomplete, trait_upcasting, "1.56.0", Some(65991), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index db7fe6cb12f..aac5d296f17 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -442,6 +442,7 @@ pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>), + Unsized(Span), Outlives(Lifetime), } @@ -458,6 +459,7 @@ impl GenericBound<'_> { GenericBound::Trait(t, ..) => t.span, GenericBound::LangItemTrait(_, span, ..) => *span, GenericBound::Outlives(l) => l.span, + GenericBound::Unsized(span) => *span, } } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 17835493cda..ae186d66004 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -889,6 +889,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB visitor.visit_generic_args(span, args); } GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), + GenericBound::Unsized(_) => {} } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 90ceb1d5c91..2b372392575 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2230,6 +2230,9 @@ impl<'a> State<'a> { GenericBound::Outlives(lt) => { self.print_lifetime(lt); } + GenericBound::Unsized(_) => { + self.s.word("?Sized"); + } } } } diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index b4dd0fc2449..9a96c03cd3c 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -7,7 +7,7 @@ use std::str::Chars; #[cfg(test)] mod tests; -/// Errors that can occur during string unescaping. +/// Errors and warnings that can occur during string unescaping. #[derive(Debug, PartialEq, Eq)] pub enum EscapeError { /// Expected 1 char, but 0 were found. @@ -56,6 +56,20 @@ pub enum EscapeError { NonAsciiCharInByte, /// Non-ascii character in byte string literal. NonAsciiCharInByteString, + + /// After a line ending with '\', the next line contains whitespace + /// characters that are not skipped. + UnskippedWhitespaceWarning, +} + +impl EscapeError { + /// Returns true for actual errors, as opposed to warnings. + pub fn is_fatal(&self) -> bool { + match self { + EscapeError::UnskippedWhitespaceWarning => false, + _ => true, + } + } } /// Takes a contents of a literal (without quotes) and produces a @@ -283,7 +297,7 @@ where // if unescaped '\' character is followed by '\n'. // For details see [Rust language reference] // (https://doc.rust-lang.org/reference/tokens.html#string-literals). - skip_ascii_whitespace(&mut chars); + skip_ascii_whitespace(&mut chars, start, callback); continue; } _ => scan_escape(first_char, &mut chars, mode), @@ -297,13 +311,25 @@ where callback(start..end, unescaped_char); } - fn skip_ascii_whitespace(chars: &mut Chars<'_>) { + fn skip_ascii_whitespace<F>(chars: &mut Chars<'_>, start: usize, callback: &mut F) + where + F: FnMut(Range<usize>, Result<char, EscapeError>), + { let str = chars.as_str(); let first_non_space = str .bytes() .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') .unwrap_or(str.len()); - *chars = str[first_non_space..].chars() + let tail = &str[first_non_space..]; + if let Some(c) = tail.chars().nth(0) { + // For error reporting, we would like the span to contain the character that was not + // skipped. The +1 is necessary to account for the leading \ that started the escape. + let end = start + first_non_space + c.len_utf8() + 1; + if c.is_whitespace() { + callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning)); + } + } + *chars = tail.chars(); } } diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs index f2b751a78f2..1f4dbb20f4e 100644 --- a/compiler/rustc_lexer/src/unescape/tests.rs +++ b/compiler/rustc_lexer/src/unescape/tests.rs @@ -99,6 +99,25 @@ fn test_unescape_char_good() { } #[test] +fn test_unescape_str_warn() { + fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) { + let mut unescaped = Vec::with_capacity(literal.len()); + unescape_literal(literal, Mode::Str, &mut |range, res| unescaped.push((range, res))); + assert_eq!(unescaped, expected); + } + + check( + "\\\n \u{a0} x", + &[ + (0..5, Err(EscapeError::UnskippedWhitespaceWarning)), + (3..5, Ok('\u{a0}')), + (5..6, Ok(' ')), + (6..7, Ok('x')), + ], + ); +} + +#[test] fn test_unescape_str_good() { fn check(literal_text: &str, expected: &str) { let mut buf = Ok(String::with_capacity(literal_text.len())); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index c431c048ca0..2b580452a60 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -161,7 +161,15 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { if let Some(must_use_op) = must_use_op { cx.struct_span_lint(UNUSED_MUST_USE, expr.span, |lint| { - lint.build(&format!("unused {} that must be used", must_use_op)).emit() + let mut lint = lint.build(&format!("unused {} that must be used", must_use_op)); + lint.span_label(expr.span, &format!("the {} produces a value", must_use_op)); + lint.span_suggestion_verbose( + expr.span.shrink_to_lo(), + "use `let _ = ...` to ignore the resulting value", + "let _ = ".to_string(), + Applicability::MachineApplicable, + ); + lint.emit(); }); op_warned = true; } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 5b1cd0bcb3f..7195c41eae9 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2799,7 +2799,7 @@ declare_lint! { /// [issue #79813]: https://github.com/rust-lang/rust/issues/79813 /// [future-incompatible]: ../index.md#future-incompatible-lints pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, - Allow, + Warn, "trailing semicolon in macro body used as expression", @future_incompatible = FutureIncompatibleInfo { reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>", diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 452d1b19a18..964b7cace9c 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -182,7 +182,7 @@ fn main() { } else if target.contains("windows-gnu") { println!("cargo:rustc-link-lib=shell32"); println!("cargo:rustc-link-lib=uuid"); - } else if target.contains("netbsd") || target.contains("haiku") { + } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") { println!("cargo:rustc-link-lib=z"); } cmd.args(&components); diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index bfb4c0cb538..4cfb104bee3 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -2,6 +2,7 @@ use crate::ty::TyKind::*; use crate::ty::{InferTy, TyCtxt, TyS}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -105,6 +106,116 @@ pub fn suggest_arbitrary_trait_bound( true } +fn suggest_removing_unsized_bound( + generics: &hir::Generics<'_>, + err: &mut DiagnosticBuilder<'_>, + param_name: &str, + param: &hir::GenericParam<'_>, + def_id: Option<DefId>, +) { + // See if there's a `?Sized` bound that can be removed to suggest that. + // First look at the `where` clause because we can have `where T: ?Sized`, but that + // `?Sized` bound is *also* included in the `GenericParam` as a bound, which breaks + // the spans. Hence the somewhat involved logic that follows. + let mut where_unsized_bounds = FxHashSet::default(); + for (where_pos, predicate) in generics.where_clause.predicates.iter().enumerate() { + match predicate { + WherePredicate::BoundPredicate(WhereBoundPredicate { + bounded_ty: + hir::Ty { + kind: + hir::TyKind::Path(hir::QPath::Resolved( + None, + hir::Path { + segments: [segment], + res: hir::def::Res::Def(hir::def::DefKind::TyParam, _), + .. + }, + )), + .. + }, + bounds, + span, + .. + }) if segment.ident.as_str() == param_name => { + for (pos, bound) in bounds.iter().enumerate() { + match bound { + hir::GenericBound::Unsized(_) => {} + hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe) + if poly.trait_ref.trait_def_id() == def_id => {} + _ => continue, + } + let sp = match ( + bounds.len(), + pos, + generics.where_clause.predicates.len(), + where_pos, + ) { + // where T: ?Sized + // ^^^^^^^^^^^^^^^ + (1, _, 1, _) => generics.where_clause.span, + // where Foo: Bar, T: ?Sized, + // ^^^^^^^^^^^ + (1, _, len, pos) if pos == len - 1 => generics.where_clause.predicates + [pos - 1] + .span() + .shrink_to_hi() + .to(*span), + // where T: ?Sized, Foo: Bar, + // ^^^^^^^^^^^ + (1, _, _, pos) => { + span.until(generics.where_clause.predicates[pos + 1].span()) + } + // where T: ?Sized + Bar, Foo: Bar, + // ^^^^^^^^^ + (_, 0, _, _) => bound.span().to(bounds[1].span().shrink_to_lo()), + // where T: Bar + ?Sized, Foo: Bar, + // ^^^^^^^^^ + (_, pos, _, _) => bounds[pos - 1].span().shrink_to_hi().to(bound.span()), + }; + where_unsized_bounds.insert(bound.span()); + err.span_suggestion_verbose( + sp, + "consider removing the `?Sized` bound to make the \ + type parameter `Sized`", + String::new(), + Applicability::MaybeIncorrect, + ); + } + } + _ => {} + } + } + for (pos, bound) in param.bounds.iter().enumerate() { + match bound { + hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe) + if poly.trait_ref.trait_def_id() == def_id + && !where_unsized_bounds.contains(&bound.span()) => + { + let sp = match (param.bounds.len(), pos) { + // T: ?Sized, + // ^^^^^^^^ + (1, _) => param.span.shrink_to_hi().to(bound.span()), + // T: ?Sized + Bar, + // ^^^^^^^^^ + (_, 0) => bound.span().to(param.bounds[1].span().shrink_to_lo()), + // T: Bar + ?Sized, + // ^^^^^^^^^ + (_, pos) => param.bounds[pos - 1].span().shrink_to_hi().to(bound.span()), + }; + err.span_suggestion_verbose( + sp, + "consider removing the `?Sized` bound to make the type parameter \ + `Sized`", + String::new(), + Applicability::MaybeIncorrect, + ); + } + _ => {} + } + } +} + /// Suggest restricting a type param with a new bound. pub fn suggest_constraining_type_param( tcx: TyCtxt<'_>, @@ -130,6 +241,7 @@ pub fn suggest_constraining_type_param( if def_id == tcx.lang_items().sized_trait() { // Type parameters are already `Sized` by default. err.span_label(param.span, &format!("this type parameter needs to be `{}`", constraint)); + suggest_removing_unsized_bound(generics, err, param_name, param, def_id); return true; } let mut suggest_restrict = |span| { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index 2e854ea5be7..a9bfbb51573 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -12,7 +12,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::{self, suggest_constraining_type_param, Ty}; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::sym; -use rustc_span::{MultiSpan, Span, DUMMY_SP}; +use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtExt; use crate::dataflow::drop_flag_effects; @@ -1393,18 +1393,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); - let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) { - Ok(mut string) => { + let (sugg_span, suggestion) = match tcx.sess.source_map().span_to_snippet(args_span) { + Ok(string) => { if string.starts_with("async ") { - string.insert_str(6, "move "); + let pos = args_span.lo() + BytePos(6); + (args_span.with_lo(pos).with_hi(pos), "move ".to_string()) } else if string.starts_with("async|") { - string.insert_str(5, " move"); + let pos = args_span.lo() + BytePos(5); + (args_span.with_lo(pos).with_hi(pos), " move".to_string()) } else { - string.insert_str(0, "move "); - }; - string + (args_span.shrink_to_lo(), "move ".to_string()) + } } - Err(_) => "move |<args>| <body>".to_string(), + Err(_) => (args_span, "move |<args>| <body>".to_string()), }; let kind = match use_span.generator_kind() { Some(generator_kind) => match generator_kind { @@ -1420,8 +1421,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut err = self.cannot_capture_in_long_lived_closure(args_span, kind, captured_var, var_span); - err.span_suggestion( - args_span, + err.span_suggestion_verbose( + sugg_span, &format!( "to force the {} to take ownership of {} (and any \ other referenced variables), use the `move` keyword", diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs index 3f87d9c7ac9..2be23159bf5 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs @@ -2,7 +2,8 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_middle::mir::*; use rustc_middle::ty; use rustc_span::source_map::DesugaringKind; -use rustc_span::{sym, Span}; +use rustc_span::{sym, Span, DUMMY_SP}; +use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions; use crate::borrow_check::diagnostics::UseSpans; use crate::borrow_check::prefixes::PrefixSet; @@ -384,36 +385,44 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } }; - if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { - let def_id = match *move_place.ty(self.body, self.infcx.tcx).ty.kind() { - ty::Adt(self_def, _) => self_def.did, - ty::Foreign(def_id) - | ty::FnDef(def_id, _) - | ty::Closure(def_id, _) - | ty::Generator(def_id, ..) - | ty::Opaque(def_id, _) => def_id, - _ => return err, + let ty = move_place.ty(self.body, self.infcx.tcx).ty; + let def_id = match *ty.kind() { + ty::Adt(self_def, _) => self_def.did, + ty::Foreign(def_id) + | ty::FnDef(def_id, _) + | ty::Closure(def_id, _) + | ty::Generator(def_id, ..) + | ty::Opaque(def_id, _) => def_id, + _ => return err, + }; + let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id); + let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id); + if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) { + err.span_suggestion_verbose( + span.shrink_to_hi(), + &format!( + "consider borrowing the `{}`'s content", + if is_option { "Option" } else { "Result" } + ), + ".as_ref()".to_string(), + Applicability::MaybeIncorrect, + ); + } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) { + let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) { + Some(def_id) => type_known_to_meet_bound_modulo_regions( + &self.infcx, + self.param_env, + self.infcx.tcx.mk_imm_ref(self.infcx.tcx.lifetimes.re_erased, ty), + def_id, + DUMMY_SP, + ), + _ => false, }; - let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id); - let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id); - if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) { - err.span_suggestion( - span, - &format!( - "consider borrowing the `{}`'s content", - if is_option { "Option" } else { "Result" } - ), - format!("{}.as_ref()", snippet), - Applicability::MaybeIncorrect, - ); - } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) - && self.infcx.tcx.is_diagnostic_item(sym::vec_type, def_id) - { - // FIXME: suggest for anything that implements `IntoIterator`. - err.span_suggestion( - span, - "consider iterating over a slice of the `Vec<_>`'s content", - format!("&{}", snippet), + if suggest { + err.span_suggestion_verbose( + span.shrink_to_lo(), + &format!("consider iterating over a slice of the `{}`'s content", ty), + "&".to_string(), Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 98befe4066b..1e65cc27154 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -505,7 +505,8 @@ impl<'a> StringReader<'a> { // identifier tokens. fn report_unknown_prefix(&self, start: BytePos) { let prefix_span = self.mk_sp(start, self.pos); - let msg = format!("prefix `{}` is unknown", self.str_from_to(start, self.pos)); + let prefix_str = self.str_from_to(start, self.pos); + let msg = format!("prefix `{}` is unknown", prefix_str); let expn_data = prefix_span.ctxt().outer_expn_data(); @@ -513,12 +514,19 @@ impl<'a> StringReader<'a> { // In Rust 2021, this is a hard error. let mut err = self.sess.span_diagnostic.struct_span_err(prefix_span, &msg); err.span_label(prefix_span, "unknown prefix"); - if expn_data.is_root() { + if prefix_str == "rb" { + err.span_suggestion_verbose( + prefix_span, + "use `br` for a raw byte string", + "br".to_string(), + Applicability::MaybeIncorrect, + ); + } else if expn_data.is_root() { err.span_suggestion_verbose( prefix_span.shrink_to_hi(), "consider inserting whitespace here", " ".into(), - Applicability::MachineApplicable, + Applicability::MaybeIncorrect, ); } err.note("prefixed identifiers and literals are reserved since Rust 2021"); diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index a580f0c55d0..1c5be61130b 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -253,6 +253,12 @@ pub(crate) fn emit_unescape_error( let msg = "invalid trailing slash in literal"; handler.struct_span_err(span, msg).span_label(span, msg).emit(); } + EscapeError::UnskippedWhitespaceWarning => { + let (c, char_span) = last_char(); + let msg = + format!("non-ASCII whitespace symbol '{}' is not skipped", c.escape_unicode()); + handler.struct_span_warn(span, &msg).span_label(char_span, &msg).emit(); + } } } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9818bd8d314..273fbea3580 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1770,7 +1770,7 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(span, &msg); let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { - self.sess.expr_parentheses_needed(&mut err, *sp, None); + self.sess.expr_parentheses_needed(&mut err, *sp); } err.span_label(span, "expected expression"); err diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index ef05f64da94..b774c76103f 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -358,7 +358,7 @@ impl<'a> Parser<'a> { &format!("expected expression, found `{}`", pprust::token_to_string(&self.token),), ); err.span_label(self.token.span, "expected expression"); - self.sess.expr_parentheses_needed(&mut err, lhs.span, Some(pprust::expr_to_string(&lhs))); + self.sess.expr_parentheses_needed(&mut err, lhs.span); err.emit(); } @@ -696,20 +696,18 @@ impl<'a> Parser<'a> { let expr = mk_expr(self, lhs, self.mk_ty(path.span, TyKind::Path(None, path))); - let expr_str = self - .span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - self.struct_span_err(self.token.span, &msg) .span_label( self.look_ahead(1, |t| t.span).to(span_after_type), "interpreted as generic arguments", ) .span_label(self.token.span, format!("not interpreted as {}", op_noun)) - .span_suggestion( - expr.span, + .multipart_suggestion( &format!("try {} the cast value", op_verb), - format!("({})", expr_str), + vec![ + (expr.span.shrink_to_lo(), "(".to_string()), + (expr.span.shrink_to_hi(), ")".to_string()), + ], Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 7219e39ea6b..b03b5459981 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -763,7 +763,7 @@ impl<'a> Parser<'a> { let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { - self.sess.expr_parentheses_needed(&mut err, *sp, None); + self.sess.expr_parentheses_needed(&mut err, *sp); } Err(err) diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index 4f8dc7d16d4..34302c3fb42 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -689,6 +689,7 @@ impl<'tcx> DumpVisitor<'tcx> { (Some(self.tcx.require_lang_item(lang_item, Some(span))), span) } hir::GenericBound::Outlives(..) => continue, + hir::GenericBound::Unsized(_) => continue, }; if let Some(id) = def_id { diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 226fde2343a..a007b530302 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -228,20 +228,12 @@ impl ParseSess { /// Extend an error with a suggestion to wrap an expression with parentheses to allow the /// parser to continue parsing the following operation as part of the same expression. - pub fn expr_parentheses_needed( - &self, - err: &mut DiagnosticBuilder<'_>, - span: Span, - alt_snippet: Option<String>, - ) { - if let Some(snippet) = self.source_map().span_to_snippet(span).ok().or(alt_snippet) { - err.span_suggestion( - span, - "parentheses are required to parse this as an expression", - format!("({})", snippet), - Applicability::MachineApplicable, - ); - } + pub fn expr_parentheses_needed(&self, err: &mut DiagnosticBuilder<'_>, span: Span) { + err.multipart_suggestion( + "parentheses are required to parse this as an expression", + vec![(span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string())], + Applicability::MachineApplicable, + ); } pub fn save_proc_macro_span(&self, span: Span) -> usize { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 295e53aba35..1ac489f600a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1270,6 +1270,7 @@ symbols! { trace_macros, track_caller, trait_alias, + trait_upcasting, transmute, transparent, transparent_enums, 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 9a33875d6e4..712fea84a8b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1163,15 +1163,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if is_object_safe { // Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`. // Get all the return values and collect their span and suggestion. - if let Some(mut suggestions) = visitor + let mut suggestions: Vec<_> = visitor .returns .iter() - .map(|expr| { - let snip = sm.span_to_snippet(expr.span).ok()?; - Some((expr.span, format!("Box::new({})", snip))) + .flat_map(|expr| { + vec![ + (expr.span.shrink_to_lo(), "Box::new(".to_string()), + (expr.span.shrink_to_hi(), ")".to_string()), + ] + .into_iter() }) - .collect::<Option<Vec<_>>>() - { + .collect(); + if !suggestions.is_empty() { // Add the suggestion for the return type. suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj))); err.multipart_suggestion( diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 752f6a8debc..c7bf1f2a943 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -693,22 +693,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let may_apply = match (source.kind(), target.kind()) { // Trait+Kx+'a -> Trait+Ky+'b (upcasts). (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => { - // Upcasts permit two things: - // - // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo` - // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b` - // - // Note that neither of these changes requires any - // change at runtime. Eventually this will be - // generalized. - // - // We always upcast when we can because of reason - // #2 (region bounds). - data_a.principal_def_id() == data_b.principal_def_id() - && data_b - .auto_traits() - // All of a's auto traits need to be in b's auto traits. - .all(|b| data_a.auto_traits().any(|a| a == b)) + // See `confirm_builtin_unsize_candidate` for more info. + let auto_traits_compatible = data_b + .auto_traits() + // All of a's auto traits need to be in b's auto traits. + .all(|b| data_a.auto_traits().any(|a| a == b)); + auto_traits_compatible } // `T` -> `Trait` diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index f8297ee3a07..0c2099593a2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -703,10 +703,56 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match (source.kind(), target.kind()) { // Trait+Kx+'a -> Trait+Ky+'b (upcasts). (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { - // See `assemble_candidates_for_unsizing` for more info. - let iter = data_a - .principal() - .map(|b| b.map_bound(ty::ExistentialPredicate::Trait)) + // Upcast coercions permit several things: + // + // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo` + // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b` + // 3. Tightening trait to its super traits, eg. `Foo` to `Bar` if `Foo: Bar` + // + // Note that neither of the first two of these changes requires any + // change at runtime. The third needs to change pointer metadata at runtime. + // + // We always perform upcasting coercions when we can because of reason + // #2 (region bounds). + + // We already checked the compatiblity of auto traits within `assemble_candidates_for_unsizing`. + + let principal_a = data_a.principal(); + let principal_def_id_b = data_b.principal_def_id(); + + let existential_predicate = if let Some(principal_a) = principal_a { + let source_trait_ref = principal_a.with_self_ty(tcx, source); + let target_trait_did = principal_def_id_b.ok_or_else(|| Unimplemented)?; + let upcast_idx = util::supertraits(tcx, source_trait_ref) + .position(|upcast_trait_ref| upcast_trait_ref.def_id() == target_trait_did) + .ok_or_else(|| Unimplemented)?; + // FIXME(crlf0710): This is less than ideal, for example, + // if the trait is defined as `trait Foo: Bar<u32> + Bar<i32>`, + // the coercion from Box<Foo> to Box<dyn Bar<_>> is actually ambiguous. + // We currently make this coercion fail for now. + // + // see #65991 for more information. + if util::supertraits(tcx, source_trait_ref) + .skip(upcast_idx + 1) + .any(|upcast_trait_ref| upcast_trait_ref.def_id() == target_trait_did) + { + return Err(Unimplemented); + } + let target_trait_ref = + util::supertraits(tcx, source_trait_ref).nth(upcast_idx).unwrap(); + let existential_predicate = target_trait_ref.map_bound(|trait_ref| { + ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty( + tcx, trait_ref, + )) + }); + Some(existential_predicate) + } else if principal_def_id_b.is_none() { + None + } else { + return Err(Unimplemented); + }; + + let iter = existential_predicate .into_iter() .chain( data_a diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 9871b14754e..92583f2b0ea 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -943,7 +943,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { false, ); } - hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {} + hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) + | hir::GenericBound::Unsized(_) => {} hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self .instantiate_lang_item_trait_ref( lang_item, span, hir_id, args, param_ty, bounds, diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index ba76b9c8dd5..a83b39a1108 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -576,6 +576,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { )]; let mut has_unsized_tuple_coercion = false; + let mut has_trait_upcasting_coercion = false; // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where @@ -590,7 +591,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { if traits.contains(&trait_pred.def_id()) => { if unsize_did == trait_pred.def_id() { + let self_ty = trait_pred.self_ty(); let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty(); + if let (ty::Dynamic(ref data_a, ..), ty::Dynamic(ref data_b, ..)) = + (self_ty.kind(), unsize_ty.kind()) + { + if data_a.principal_def_id() != data_b.principal_def_id() { + debug!("coerce_unsized: found trait upcasting coercion"); + has_trait_upcasting_coercion = true; + } + } if let ty::Tuple(..) = unsize_ty.kind() { debug!("coerce_unsized: found unsized tuple coercion"); has_unsized_tuple_coercion = true; @@ -666,6 +676,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { .emit(); } + if has_trait_upcasting_coercion && !self.tcx().features().trait_upcasting { + feature_err( + &self.tcx.sess.parse_sess, + sym::trait_upcasting, + self.cause.span, + "trait upcasting coercion is experimental", + ) + .emit(); + } + Ok(coercion) } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 3ea59906d3d..e5a00f70639 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut}; use rustc_span::symbol::sym; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use super::method::probe; @@ -415,7 +415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, - ) -> Option<(Span, &'static str, String, Applicability)> { + ) -> Option<(Span, &'static str, String, Applicability, bool /* verbose */)> { let sess = self.sess(); let sp = expr.span; @@ -441,12 +441,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind { if let Ok(src) = sm.span_to_snippet(sp) { - if let Some(src) = replace_prefix(&src, "b\"", "\"") { + if let Some(_) = replace_prefix(&src, "b\"", "\"") { + let pos = sp.lo() + BytePos(1); return Some(( - sp, + sp.with_hi(pos), "consider removing the leading `b`", - src, + String::new(), Applicability::MachineApplicable, + true, )); } } @@ -455,12 +457,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind { if let Ok(src) = sm.span_to_snippet(sp) { - if let Some(src) = replace_prefix(&src, "\"", "b\"") { + if let Some(_) = replace_prefix(&src, "\"", "b\"") { return Some(( - sp, + sp.shrink_to_lo(), "consider adding a leading `b`", - src, + "b".to_string(), Applicability::MachineApplicable, + true, )); } } @@ -520,6 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg.1, sugg.2, Applicability::MachineApplicable, + false, )); } let field_name = if is_struct_pat_shorthand_field { @@ -539,13 +543,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // | | // consider dereferencing here: `*opt` | // expected mutable reference, found enum `Option` - if let Ok(src) = sm.span_to_snippet(left_expr.span) { + if sm.span_to_snippet(left_expr.span).is_ok() { return Some(( - left_expr.span, + left_expr.span.shrink_to_lo(), "consider dereferencing here to assign to the mutable \ borrowed piece of memory", - format!("*{}", src), + "*".to_string(), Applicability::MachineApplicable, + true, )); } } @@ -557,12 +562,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "consider mutably borrowing here", format!("{}&mut {}", field_name, sugg_expr), Applicability::MachineApplicable, + false, ), hir::Mutability::Not => ( sp, "consider borrowing here", format!("{}&{}", field_name, sugg_expr), Applicability::MachineApplicable, + false, ), }); } @@ -584,24 +591,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(call_span) = iter::successors(Some(expr.span), |s| s.parent()).find(|&s| sp.contains(s)) { - if let Ok(code) = sm.span_to_snippet(call_span) { + if sm.span_to_snippet(call_span).is_ok() { return Some(( - sp, + sp.with_hi(call_span.lo()), "consider removing the borrow", - code, + String::new(), Applicability::MachineApplicable, + true, )); } } return None; } if sp.contains(expr.span) { - if let Ok(code) = sm.span_to_snippet(expr.span) { + if sm.span_to_snippet(expr.span).is_ok() { return Some(( - sp, + sp.with_hi(expr.span.lo()), "consider removing the borrow", - code, + String::new(), Applicability::MachineApplicable, + true, )); } } @@ -616,36 +625,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if steps > 0 { // The pointer type implements `Copy` trait so the suggestion is always valid. if let Ok(src) = sm.span_to_snippet(sp) { - let derefs = &"*".repeat(steps); - if let Some((src, applicability)) = match mutbl_b { + let derefs = "*".repeat(steps); + if let Some((span, src, applicability)) = match mutbl_b { hir::Mutability::Mut => { - let new_prefix = "&mut ".to_owned() + derefs; + let new_prefix = "&mut ".to_owned() + &derefs; match mutbl_a { hir::Mutability::Mut => { - replace_prefix(&src, "&mut ", &new_prefix) - .map(|s| (s, Applicability::MachineApplicable)) + replace_prefix(&src, "&mut ", &new_prefix).map(|_| { + let pos = sp.lo() + BytePos(5); + let sp = sp.with_lo(pos).with_hi(pos); + (sp, derefs, Applicability::MachineApplicable) + }) } hir::Mutability::Not => { - replace_prefix(&src, "&", &new_prefix) - .map(|s| (s, Applicability::Unspecified)) + replace_prefix(&src, "&", &new_prefix).map(|_| { + let pos = sp.lo() + BytePos(1); + let sp = sp.with_lo(pos).with_hi(pos); + ( + sp, + format!("mut {}", derefs), + Applicability::Unspecified, + ) + }) } } } hir::Mutability::Not => { - let new_prefix = "&".to_owned() + derefs; + let new_prefix = "&".to_owned() + &derefs; match mutbl_a { hir::Mutability::Mut => { - replace_prefix(&src, "&mut ", &new_prefix) - .map(|s| (s, Applicability::MachineApplicable)) + replace_prefix(&src, "&mut ", &new_prefix).map(|_| { + let lo = sp.lo() + BytePos(1); + let hi = sp.lo() + BytePos(5); + let sp = sp.with_lo(lo).with_hi(hi); + (sp, derefs, Applicability::MachineApplicable) + }) } hir::Mutability::Not => { - replace_prefix(&src, "&", &new_prefix) - .map(|s| (s, Applicability::MachineApplicable)) + replace_prefix(&src, "&", &new_prefix).map(|_| { + let pos = sp.lo() + BytePos(1); + let sp = sp.with_lo(pos).with_hi(pos); + (sp, derefs, Applicability::MachineApplicable) + }) } } } } { - return Some((sp, "consider dereferencing", src, applicability)); + return Some(( + span, + "consider dereferencing", + src, + applicability, + true, + )); } } } @@ -669,6 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { message, suggestion, Applicability::MachineApplicable, + false, )); } else if self.infcx.type_is_copy_modulo_regions( self.param_env, @@ -682,21 +715,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { "consider dereferencing the type" }; - let suggestion = if is_struct_pat_shorthand_field { - format!("{}: *{}", code, code) + let (span, suggestion) = if is_struct_pat_shorthand_field { + (expr.span, format!("{}: *{}", code, code)) } else if self.is_else_if_block(expr) { // Don't suggest nonsense like `else *if` return None; } else if let Some(expr) = self.maybe_get_block_expr(expr.hir_id) { - format!("*{}", sm.span_to_snippet(expr.span).unwrap_or(code)) + (expr.span.shrink_to_lo(), "*".to_string()) } else { - format!("*{}", code) + (expr.span.shrink_to_lo(), "*".to_string()) }; return Some(( - expr.span, + span, message, suggestion, Applicability::MachineApplicable, + true, )); } } diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index cfe1d1c6871..08258aac96f 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -344,7 +344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(sp) = tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) { - tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp, None); + tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp); } err.emit(); oprnd_t = tcx.ty_error(); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 54aab271fdb..0acf1d26e25 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -213,8 +213,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, ) { let expr = expr.peel_blocks(); - if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) { - err.span_suggestion(sp, msg, suggestion, applicability); + if let Some((sp, msg, suggestion, applicability, verbose)) = + self.check_ref(expr, found, expected) + { + if verbose { + err.span_suggestion_verbose(sp, msg, suggestion, applicability); + } else { + err.span_suggestion(sp, msg, suggestion, applicability); + } } else if let (ty::FnDef(def_id, ..), true) = (&found.kind(), self.suggest_fn_call(err, expr, expected, found)) { @@ -234,29 +240,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None // do not suggest code that is already there (#53348) } else { let method_call_list = [".to_vec()", ".to_string()"]; - let sugg = if receiver.ends_with(".clone()") + let mut sugg = if receiver.ends_with(".clone()") && method_call_list.contains(&method_call.as_str()) { let max_len = receiver.rfind('.').unwrap(); - format!("{}{}", &receiver[..max_len], method_call) + vec![( + expr.span, + format!("{}{}", &receiver[..max_len], method_call), + )] } else { if expr.precedence().order() < ExprPrecedence::MethodCall.order() { - format!("({}){}", receiver, method_call) + vec![ + (expr.span.shrink_to_lo(), "(".to_string()), + (expr.span.shrink_to_hi(), format!("){}", method_call)), + ] } else { - format!("{}{}", receiver, method_call) + vec![(expr.span.shrink_to_hi(), method_call)] } }; - Some(if is_struct_pat_shorthand_field { - format!("{}: {}", receiver, sugg) - } else { - sugg - }) + if is_struct_pat_shorthand_field { + sugg.insert( + 0, + (expr.span.shrink_to_lo(), format!("{}: ", receiver)), + ); + } + Some(sugg) } }) .peekable(); if suggestions.peek().is_some() { - err.span_suggestions( - expr.span, + err.multipart_suggestions( "try using a conversion method", suggestions, Applicability::MaybeIncorrect, @@ -283,14 +296,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } let boxed_found = self.tcx.mk_box(found); - if let (true, Ok(snippet)) = ( - self.can_coerce(boxed_found, expected), - self.sess().source_map().span_to_snippet(expr.span), - ) { - err.span_suggestion( - expr.span, + if self.can_coerce(boxed_found, expected) { + err.multipart_suggestion( "store this in the heap by calling `Box::new`", - format!("Box::new({})", snippet), + vec![ + (expr.span.shrink_to_lo(), "Box::new(".to_string()), + (expr.span.shrink_to_hi(), ")".to_string()), + ], Applicability::MachineApplicable, ); err.note( @@ -357,19 +369,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let boxed_found = self.tcx.mk_box(found); let new_found = self.tcx.mk_lang_item(boxed_found, LangItem::Pin).unwrap(); - if let (true, Ok(snippet)) = ( - self.can_coerce(new_found, expected), - self.sess().source_map().span_to_snippet(expr.span), - ) { + if self.can_coerce(new_found, expected) { match found.kind() { ty::Adt(def, _) if def.is_box() => { err.help("use `Box::pin`"); } _ => { - err.span_suggestion( - expr.span, + err.multipart_suggestion( "you need to pin and box this expression", - format!("Box::pin({})", snippet), + vec![ + (expr.span.shrink_to_lo(), "Box::pin(".to_string()), + (expr.span.shrink_to_hi(), ")".to_string()), + ], Applicability::MachineApplicable, ); } @@ -547,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sp = self.tcx.sess.source_map().start_point(expr.span); if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) { // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }` - self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None); + self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp); } } diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index f13e23914f7..6eb8af98640 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -5,7 +5,7 @@ use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{Ref, Ty}; +use rustc_middle::ty::{Adt, Ref, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::Underscore; use rustc_span::symbol::{sym, Ident}; @@ -255,16 +255,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name.name )); - let self_ty = self + let self_ty_name = self .sess() .source_map() .span_to_snippet(self_ty_span) .unwrap_or_else(|_| self_ty.to_string()); + let self_ty_generics_count = match self_ty.kind() { + // Get the number of generics the self type has (if an Adt) unless we can determine that + // the user has written the self type with generics already which we (naively) do by looking + // for a "<" in `self_ty_name`. + Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(), + _ => 0, + }; + let self_ty_generics = if self_ty_generics_count > 0 { + format!("<{}>", vec!["_"; self_ty_generics_count].join(", ")) + } else { + String::new() + }; lint.span_suggestion( span, "disambiguate the associated function", - format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,), + format!( + "<{}{} as {}>::{}", + self_ty_name, self_ty_generics, trait_name, method_name.name, + ), Applicability::MachineApplicable, ); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 997fdcefe03..ce74d6fec9e 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2230,7 +2230,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP let constness = match modifier { hir::TraitBoundModifier::MaybeConst => hir::Constness::NotConst, hir::TraitBoundModifier::None => constness, - hir::TraitBoundModifier::Maybe => bug!("this wasn't handled"), + // We ignore `where T: ?Sized`, it is already part of + // type parameter `T`. + hir::TraitBoundModifier::Maybe => continue, }; let mut bounds = Bounds::default(); @@ -2260,6 +2262,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP predicates.extend(bounds.predicates(tcx, ty)); } + hir::GenericBound::Unsized(_) => {} + hir::GenericBound::Outlives(lifetime) => { let region = <dyn AstConv<'_>>::ast_region_to_region(&icx, lifetime, None); @@ -2521,6 +2525,7 @@ fn predicates_from_bound<'tcx>( ); bounds.predicates(astconv.tcx(), param_ty) } + hir::GenericBound::Unsized(_) => vec![], hir::GenericBound::Outlives(ref lifetime) => { let region = astconv.ast_region_to_region(lifetime, None); let pred = ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(param_ty, region)) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 06a7c335bf0..ba47da4821b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1372,9 +1372,11 @@ impl<T, A: Allocator> Vec<T, A> { /// assert_eq!(v, [1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[track_caller] pub fn remove(&mut self, index: usize) -> T { #[cold] #[inline(never)] + #[track_caller] fn assert_failed(index: usize, len: usize) -> ! { panic!("removal index (is {}) should be < len (is {})", index, len); } diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 78b799cd709..3bc9f71375c 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -293,6 +293,28 @@ impl<T, const N: usize> [T; N] { /// Returns an array of the same size as `self`, with function `f` applied to each element /// in order. /// + /// If you don't necessarily need a new fixed-size array, consider using + /// [`Iterator::map`] instead. + /// + /// + /// # Note on performance and stack usage + /// + /// Unfortunately, usages of this method are currently not always optimized + /// as well as they could be. This mainly concerns large arrays, as mapping + /// over small arrays seem to be optimized just fine. Also note that in + /// debug mode (i.e. without any optimizations), this method can use a lot + /// of stack space (a few times the size of the array or more). + /// + /// Therefore, in performance-critical code, try to avoid using this method + /// on large arrays or check the emitted code. Also try to avoid chained + /// maps (e.g. `arr.map(...).map(...)`). + /// + /// In many cases, you can instead use [`Iterator::map`] by calling `.iter()` + /// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you + /// really need a new array of the same size as the result. Rust's lazy + /// iterators tend to get optimized very well. + /// + /// /// # Examples /// /// ``` diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 3ab40f1faa1..032df7f5a80 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -71,6 +71,16 @@ impl<T: Sized> NonNull<T> { /// a `T`, which means this must not be used as a "not yet initialized" /// sentinel value. Types that lazily allocate must track initialization by /// some other means. + /// + /// # Examples + /// + /// ``` + /// use std::ptr::NonNull; + /// + /// let ptr = NonNull::<u32>::dangling(); + /// // Important: don't try to access the value of `ptr` without + /// // initializing it first! The pointer is not null but isn't valid either! + /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.36.0")] #[inline] @@ -155,6 +165,18 @@ impl<T: ?Sized> NonNull<T> { /// # Safety /// /// `ptr` must be non-null. + /// + /// # Examples + /// + /// ``` + /// use std::ptr::NonNull; + /// + /// let mut x = 0u32; + /// let ptr = unsafe { NonNull::new_unchecked(&mut x as *mut _) }; + /// + /// // NEVER DO THAT!!! + /// let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) }; + /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.25.0")] #[inline] @@ -164,6 +186,19 @@ impl<T: ?Sized> NonNull<T> { } /// Creates a new `NonNull` if `ptr` is non-null. + /// + /// # Examples + /// + /// ``` + /// use std::ptr::NonNull; + /// + /// let mut x = 0u32; + /// let ptr = NonNull::<u32>::new(&mut x as *mut _).expect("ptr is null!"); + /// + /// if let Some(ptr) = NonNull::<u32>::new(std::ptr::null_mut()) { + /// unreachable!(); + /// } + /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub fn new(ptr: *mut T) -> Option<Self> { @@ -205,6 +240,22 @@ impl<T: ?Sized> NonNull<T> { } /// Acquires the underlying `*mut` pointer. + /// + /// # Examples + /// + /// ``` + /// use std::ptr::NonNull; + /// + /// let mut x = 0u32; + /// let ptr = NonNull::new(&mut x).expect("ptr is null!"); + /// + /// let x_value = unsafe { *ptr.as_ptr() }; + /// assert_eq!(x_value, 0); + /// + /// unsafe { *ptr.as_ptr() += 2; } + /// let x_value = unsafe { *ptr.as_ptr() }; + /// assert_eq!(x_value, 2); + /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")] #[inline] @@ -239,6 +290,18 @@ impl<T: ?Sized> NonNull<T> { /// (The part about being initialized is not yet fully decided, but until /// it is, the only safe approach is to ensure that they are indeed initialized.) /// + /// # Examples + /// + /// ``` + /// use std::ptr::NonNull; + /// + /// let mut x = 0u32; + /// let ptr = NonNull::new(&mut x as *mut _).expect("ptr is null!"); + /// + /// let ref_x = unsafe { ptr.as_ref() }; + /// println!("{}", ref_x); + /// ``` + /// /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] #[inline] @@ -274,6 +337,19 @@ impl<T: ?Sized> NonNull<T> { /// This applies even if the result of this method is unused! /// (The part about being initialized is not yet fully decided, but until /// it is, the only safe approach is to ensure that they are indeed initialized.) + /// # Examples + /// + /// ``` + /// use std::ptr::NonNull; + /// + /// let mut x = 0u32; + /// let mut ptr = NonNull::new(&mut x).expect("null pointer"); + /// + /// let x_ref = unsafe { ptr.as_mut() }; + /// assert_eq!(*x_ref, 0); + /// *x_ref += 2; + /// assert_eq!(*x_ref, 2); + /// ``` /// /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] @@ -285,6 +361,18 @@ impl<T: ?Sized> NonNull<T> { } /// Casts to a pointer of another type. + /// + /// # Examples + /// + /// ``` + /// use std::ptr::NonNull; + /// + /// let mut x = 0u32; + /// let ptr = NonNull::new(&mut x as *mut _).expect("null pointer"); + /// + /// let casted_ptr = ptr.cast::<i8>(); + /// let raw_ptr: *mut i8 = casted_ptr.as_ptr(); + /// ``` #[stable(feature = "nonnull_cast", since = "1.27.0")] #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.36.0")] #[inline] diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 457b2a3605e..791a88dd97f 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -185,6 +185,13 @@ macro_rules! iterator { } } + fn advance_by(&mut self, n: usize) -> Result<(), usize> { + let advance = cmp::min(n, len!(self)); + // SAFETY: By construction, `advance` does not exceed `self.len()`. + unsafe { self.post_inc_start(advance as isize) }; + if advance == n { Ok(()) } else { Err(advance) } + } + #[inline] fn last(mut self) -> Option<$elem> { self.next_back() @@ -371,6 +378,14 @@ macro_rules! iterator { Some(next_back_unchecked!(self)) } } + + #[inline] + fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + let advance = cmp::min(n, len!(self)); + // SAFETY: By construction, `advance` does not exceed `self.len()`. + unsafe { self.pre_dec_end(advance as isize) }; + if advance == n { Ok(()) } else { Err(advance) } + } } #[stable(feature = "fused", since = "1.26.0")] diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 3a98cd9d2ee..240b894057c 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -135,6 +135,48 @@ fn test_partition_point() { } #[test] +fn test_iterator_advance_by() { + let v = &[0, 1, 2, 3, 4]; + + for i in 0..=v.len() { + let mut iter = v.iter(); + iter.advance_by(i).unwrap(); + assert_eq!(iter.as_slice(), &v[i..]); + } + + let mut iter = v.iter(); + assert_eq!(iter.advance_by(v.len() + 1), Err(v.len())); + assert_eq!(iter.as_slice(), &[]); + + let mut iter = v.iter(); + iter.advance_by(3).unwrap(); + assert_eq!(iter.as_slice(), &v[3..]); + iter.advance_by(2).unwrap(); + assert_eq!(iter.as_slice(), &[]); +} + +#[test] +fn test_iterator_advance_back_by() { + let v = &[0, 1, 2, 3, 4]; + + for i in 0..=v.len() { + let mut iter = v.iter(); + iter.advance_back_by(i).unwrap(); + assert_eq!(iter.as_slice(), &v[..v.len() - i]); + } + + let mut iter = v.iter(); + assert_eq!(iter.advance_back_by(v.len() + 1), Err(v.len())); + assert_eq!(iter.as_slice(), &[]); + + let mut iter = v.iter(); + iter.advance_back_by(3).unwrap(); + assert_eq!(iter.as_slice(), &v[..v.len() - 3]); + iter.advance_back_by(2).unwrap(); + assert_eq!(iter.as_slice(), &[]); +} + +#[test] fn test_iterator_nth() { let v: &[_] = &[0, 1, 2, 3, 4]; for i in 0..v.len() { diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 7afe52a3fd6..676695795ba 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -290,7 +290,7 @@ macro_rules! dbg { // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` // will be malformed. () => { - $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!()); + $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!()) }; ($val:expr $(,)?) => { // Use of `match` here is intentional because it affects the lifetimes diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 128897e580b..59a1d06dabd 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -451,7 +451,7 @@ jobs: - name: dist-x86_64-apple env: SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false + RUST_CONFIGURE_ARGS: --host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.7 NO_LLVM_ASSERTIONS: 1 diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index c8af369a969..d6948622662 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -94,7 +94,7 @@ $ rustdoc src/lib.rs --document-private-items By default, `rustdoc` only documents items that are publicly reachable. ```rust -pub fn public() {} // this item is public and will documented +pub fn public() {} // this item is public and will be documented mod private { // this item is private and will not be documented pub fn unreachable() {} // this item is public, but unreachable, so it will not be documented } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fd79292477c..75ea30bb565 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -128,6 +128,7 @@ impl Clean<GenericBound> for hir::GenericBound<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { match *self { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)), + hir::GenericBound::Unsized(_) => GenericBound::maybe_sized(cx), hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { let def_id = cx.tcx.require_lang_item(lang_item, Some(span)); @@ -562,13 +563,19 @@ impl Clean<Generics> for hir::Generics<'_> { WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds, .. } => { - if bounds.is_empty() { + if let [] | [GenericBound::TraitBound(_, hir::TraitBoundModifier::Maybe)] = + &bounds[..] + { for param in &mut generics.params { match param.kind { GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => { if ¶m.name == name { mem::swap(bounds, ty_bounds); + // We now keep track of `?Sized` obligations in the HIR. + // If we don't clear `ty_bounds` we end up with + // `fn foo<X: ?Sized>(_: X) where X: ?Sized`. + ty_bounds.clear(); break; } } diff --git a/src/llvm-project b/src/llvm-project -Subproject bdb386270f55cb8e95793daa296f27a95a6d483 +Subproject 260e0f8682098faab68af9c608534756ad37836 diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr index 599d0e13557..d0c91c4ab44 100644 --- a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr +++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr @@ -15,7 +15,7 @@ LL | fn test_boxed() -> Box<impl std::future::Future<Output = u32>> { help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | Box::new(async move { x } ) - | ^^^^^^^^^^ + | ^^^^ error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/async-borrowck-escaping-block-error.rs:11:11 @@ -34,7 +34,7 @@ LL | async { *x } help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | async move { *x } - | ^^^^^^^^^^^ + | ^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr index 8bcfcf98920..1bcaaf0d6b3 100644 --- a/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr +++ b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr @@ -14,7 +14,7 @@ LL | Box::new((async || x)()) help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | Box::new((async move || x)()) - | ^^^^^^^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/async-await/issues/issue-62097.nll.stderr b/src/test/ui/async-await/issues/issue-62097.nll.stderr index ab10e5f1810..1139175f8a0 100644 --- a/src/test/ui/async-await/issues/issue-62097.nll.stderr +++ b/src/test/ui/async-await/issues/issue-62097.nll.stderr @@ -14,7 +14,7 @@ LL | foo(|| self.bar()).await; help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword | LL | foo(move || self.bar()).await; - | ^^^^^^^ + | ^^^^ error[E0521]: borrowed data escapes outside of associated function --> $DIR/issue-62097.rs:13:9 diff --git a/src/test/ui/async-await/issues/issue-78938-async-block.stderr b/src/test/ui/async-await/issues/issue-78938-async-block.stderr index 01ffc48d654..22ebd86d85c 100644 --- a/src/test/ui/async-await/issues/issue-78938-async-block.stderr +++ b/src/test/ui/async-await/issues/issue-78938-async-block.stderr @@ -12,9 +12,7 @@ LL | | }); help: to force the async block to take ownership of `room_ref` (and any other referenced variables), use the `move` keyword | LL | let gameloop_handle = spawn(async move { -LL | game_loop(Arc::clone(&room_ref)) -LL | }); - | + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/block-result/issue-5500.stderr b/src/test/ui/block-result/issue-5500.stderr index 9d9f7ac2e4a..ef3e2da81b2 100644 --- a/src/test/ui/block-result/issue-5500.stderr +++ b/src/test/ui/block-result/issue-5500.stderr @@ -4,13 +4,14 @@ error[E0308]: mismatched types LL | fn main() { | - expected `()` because of default return type LL | &panic!() - | ^^^^^^^^^ - | | - | expected `()`, found reference - | help: consider removing the borrow: `panic!()` + | ^^^^^^^^^ expected `()`, found reference | = note: expected unit type `()` found reference `&_` +help: consider removing the borrow + | +LL | panic!() + | -- error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr index 3195120cba2..161e4610d61 100644 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr @@ -14,7 +14,7 @@ LL | spawn(|| books.push(4)); help: to force the closure to take ownership of `books` (and any other referenced variables), use the `move` keyword | LL | spawn(move || books.push(4)); - | ^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr index 3227aa9bb68..b07db6e12ad 100644 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr @@ -14,7 +14,7 @@ LL | Box::new(|| books.push(4)) help: to force the closure to take ownership of `books` (and any other referenced variables), use the `move` keyword | LL | Box::new(move || books.push(4)) - | ^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr index 29bd4b27d6b..311a1b84e0c 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr @@ -15,7 +15,7 @@ LL | fn foo () -> impl FnMut()->() { help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword | LL | let mut c = move || { - | ^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr index 1b0e0902d67..7823e357009 100644 --- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr +++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr @@ -27,7 +27,7 @@ LL | | }) help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | bar(move || { - | ^^^^^^^ + | ^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/const-argument-if-length.full.stderr b/src/test/ui/const-generics/const-argument-if-length.full.stderr index c6088e665a2..a9f1d0eb657 100644 --- a/src/test/ui/const-generics/const-argument-if-length.full.stderr +++ b/src/test/ui/const-generics/const-argument-if-length.full.stderr @@ -10,6 +10,11 @@ LL | if std::mem::size_of::<T>() == 0 { | LL | pub const fn size_of<T>() -> usize { | - required by this bound in `std::mem::size_of` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | pub const fn is_zst<T>() -> usize { + | -- error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/const-argument-if-length.rs:16:12 @@ -21,6 +26,10 @@ LL | value: T, | = note: only the last field of a struct may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | pub struct AtLeastByte<T> { + | -- help: borrowed types always have a statically known size | LL | value: &T, diff --git a/src/test/ui/const-generics/const-argument-if-length.min.stderr b/src/test/ui/const-generics/const-argument-if-length.min.stderr index bc06e8d7fb1..173a1471663 100644 --- a/src/test/ui/const-generics/const-argument-if-length.min.stderr +++ b/src/test/ui/const-generics/const-argument-if-length.min.stderr @@ -17,6 +17,10 @@ LL | value: T, | = note: only the last field of a struct may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | pub struct AtLeastByte<T> { + | -- help: borrowed types always have a statically known size | LL | value: &T, diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr index 2551d68f974..fd8f8b2693a 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr +++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr @@ -2,10 +2,9 @@ error[E0308]: mismatched types --> $DIR/unused-substs-3.rs:16:9 | LL | t = foo; - | ^^^ + | ^^^- help: try using a conversion method: `.to_vec()` | | | cyclic type of infinite size - | help: try using a conversion method: `foo.to_vec()` error: aborting due to previous error diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr index 239569dab09..be289f44f1b 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr +++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr @@ -2,10 +2,9 @@ error[E0308]: mismatched types --> $DIR/unused-substs-5.rs:15:9 | LL | x = q::<_, N>(x); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^- help: try using a conversion method: `.to_vec()` | | | cyclic type of infinite size - | help: try using a conversion method: `q::<_, N>(x).to_vec()` error: aborting due to previous error diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index b3f7b042aac..8c004148a5d 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -2,37 +2,42 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:8:9 | LL | foo(s); - | ^ + | ^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&String` - | help: try using a conversion method: `s.to_string()` error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:14:10 | LL | foo3(u); + | ^ expected `u32`, found `&u32` + | +help: consider dereferencing the borrow + | +LL | foo3(*u); | ^ - | | - | expected `u32`, found `&u32` - | help: consider dereferencing the borrow: `*u` error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:30:9 | LL | foo(&"aaa".to_owned()); - | ^^^^^^^^^^^^^^^^^ - | | - | expected struct `String`, found `&String` - | help: consider removing the borrow: `"aaa".to_owned()` + | ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String` + | +help: consider removing the borrow + | +LL | foo("aaa".to_owned()); + | -- error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:32:9 | LL | foo(&mut "aaa".to_owned()); - | ^^^^^^^^^^^^^^^^^^^^^ - | | - | expected struct `String`, found `&mut String` - | help: consider removing the borrow: `"aaa".to_owned()` + | ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String` + | +help: consider removing the borrow + | +LL | foo("aaa".to_owned()); + | -- error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:2:20 @@ -75,37 +80,45 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:44:17 | LL | let r = R { i }; - | ^ - | | - | expected `u32`, found `&{integer}` - | help: consider dereferencing the borrow: `i: *i` + | ^ expected `u32`, found `&{integer}` + | +help: consider dereferencing the borrow + | +LL | let r = R { i: *i }; + | ^^^^^ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:46:20 | LL | let r = R { i: i }; + | ^ expected `u32`, found `&{integer}` + | +help: consider dereferencing the borrow + | +LL | let r = R { i: *i }; | ^ - | | - | expected `u32`, found `&{integer}` - | help: consider dereferencing the borrow: `*i` error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:55:9 | LL | b + | ^ expected `i32`, found `&{integer}` + | +help: consider dereferencing the borrow + | +LL | *b | ^ - | | - | expected `i32`, found `&{integer}` - | help: consider dereferencing the borrow: `*b` error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:63:9 | LL | b + | ^ expected `i32`, found `&{integer}` + | +help: consider dereferencing the borrow + | +LL | *b | ^ - | | - | expected `i32`, found `&{integer}` - | help: consider dereferencing the borrow: `*b` error[E0308]: `if` and `else` have incompatible types --> $DIR/deref-suggestion.rs:68:12 diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr index ad3e5ab3dc9..017b73a0d86 100644 --- a/src/test/ui/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/diverging-tuple-parts-39485.stderr @@ -13,7 +13,7 @@ LL | fn g() -> &_ { help: consider removing the borrow | LL | panic!() - | ^^^^^^^^ + | -- error[E0308]: mismatched types --> $DIR/diverging-tuple-parts-39485.rs:12:5 diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr index 2d12265df98..6c57dd9316f 100644 --- a/src/test/ui/dst/dst-object-from-unsized-type.stderr +++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr @@ -7,6 +7,10 @@ LL | let u: &dyn Foo = t; | ^ doesn't have a size known at compile-time | = note: required for the cast to the object type `dyn Foo` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn test1<T: Foo>(t: &T) { + | -- error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/dst-object-from-unsized-type.rs:13:23 @@ -17,6 +21,10 @@ LL | let v: &dyn Foo = t as &dyn Foo; | ^ doesn't have a size known at compile-time | = note: required for the cast to the object type `dyn Foo` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn test2<T: Foo>(t: &T) { + | -- error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/dst-object-from-unsized-type.rs:18:28 diff --git a/src/test/ui/estr-subtyping.stderr b/src/test/ui/estr-subtyping.stderr index 268ec63a80d..d929c32633a 100644 --- a/src/test/ui/estr-subtyping.stderr +++ b/src/test/ui/estr-subtyping.stderr @@ -2,10 +2,9 @@ error[E0308]: mismatched types --> $DIR/estr-subtyping.rs:10:15 | LL | wants_uniq(x); - | ^ + | ^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found `&str` - | help: try using a conversion method: `x.to_string()` error: aborting due to previous error diff --git a/src/test/ui/expr/if/if-no-match-bindings.stderr b/src/test/ui/expr/if/if-no-match-bindings.stderr index 3f382e023a7..554cc3a2bcf 100644 --- a/src/test/ui/expr/if/if-no-match-bindings.stderr +++ b/src/test/ui/expr/if/if-no-match-bindings.stderr @@ -2,73 +2,89 @@ error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:18:8 | LL | if b_ref() {} - | ^^^^^^^ - | | - | expected `bool`, found `&bool` - | help: consider dereferencing the borrow: `*b_ref()` + | ^^^^^^^ expected `bool`, found `&bool` + | +help: consider dereferencing the borrow + | +LL | if *b_ref() {} + | ^ error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:19:8 | LL | if b_mut_ref() {} - | ^^^^^^^^^^^ - | | - | expected `bool`, found `&mut bool` - | help: consider dereferencing the borrow: `*b_mut_ref()` + | ^^^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider dereferencing the borrow + | +LL | if *b_mut_ref() {} + | ^ error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:20:8 | LL | if &true {} - | ^^^^^ - | | - | expected `bool`, found `&bool` - | help: consider removing the borrow: `true` + | ^^^^^ expected `bool`, found `&bool` + | +help: consider removing the borrow + | +LL | if true {} + | -- error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:21:8 | LL | if &mut true {} - | ^^^^^^^^^ - | | - | expected `bool`, found `&mut bool` - | help: consider removing the borrow: `true` + | ^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider removing the borrow + | +LL | if true {} + | -- error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:24:11 | LL | while b_ref() {} - | ^^^^^^^ - | | - | expected `bool`, found `&bool` - | help: consider dereferencing the borrow: `*b_ref()` + | ^^^^^^^ expected `bool`, found `&bool` + | +help: consider dereferencing the borrow + | +LL | while *b_ref() {} + | ^ error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:25:11 | LL | while b_mut_ref() {} - | ^^^^^^^^^^^ - | | - | expected `bool`, found `&mut bool` - | help: consider dereferencing the borrow: `*b_mut_ref()` + | ^^^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider dereferencing the borrow + | +LL | while *b_mut_ref() {} + | ^ error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:26:11 | LL | while &true {} - | ^^^^^ - | | - | expected `bool`, found `&bool` - | help: consider removing the borrow: `true` + | ^^^^^ expected `bool`, found `&bool` + | +help: consider removing the borrow + | +LL | while true {} + | -- error[E0308]: mismatched types --> $DIR/if-no-match-bindings.rs:27:11 | LL | while &mut true {} - | ^^^^^^^^^ - | | - | expected `bool`, found `&mut bool` - | help: consider removing the borrow: `true` + | ^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider removing the borrow + | +LL | while true {} + | -- error: aborting due to 8 previous errors diff --git a/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs index 7b731a1d71d..74c6e501c91 100644 --- a/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs +++ b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs @@ -19,9 +19,7 @@ // revisions: no thin fat //[no]compile-flags: -C lto=no -// FIXME(#83854) running this revision with 1 CGU triggers llvm assert in register allocator -// when executed in i686-gnu-nopt runner. -//[thin]compile-flags: -C lto=thin -Ccodegen-units=2 +//[thin]compile-flags: -C lto=thin //[fat]compile-flags: -C lto=fat #![feature(core_panic)] diff --git a/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs index 32e6d0c90b2..bc15fcb0e39 100644 --- a/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs +++ b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs @@ -40,9 +40,7 @@ //[no1]compile-flags: -C opt-level=1 -C lto=no //[no2]compile-flags: -C opt-level=2 -C lto=no //[no3]compile-flags: -C opt-level=3 -C lto=no -// FIXME(#83854) running this revision with 1 CGU triggers llvm assert in register allocator -// when executed in dist-i586-gnu-i586-i686-musl runner. -//[thin0]compile-flags: -C opt-level=0 -C lto=thin -Ccodegen-units=2 +//[thin0]compile-flags: -C opt-level=0 -C lto=thin //[thin1]compile-flags: -C opt-level=1 -C lto=thin //[thin2]compile-flags: -C opt-level=2 -C lto=thin //[thin3]compile-flags: -C opt-level=3 -C lto=thin diff --git a/src/test/ui/feature-gates/feature-gate-trait_upcasting.rs b/src/test/ui/feature-gates/feature-gate-trait_upcasting.rs new file mode 100644 index 00000000000..e4102f1cfa7 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-trait_upcasting.rs @@ -0,0 +1,13 @@ +trait Foo {} + +trait Bar: Foo {} + +impl Foo for () {} + +impl Bar for () {} + +fn main() { + let bar: &dyn Bar = &(); + let foo: &dyn Foo = bar; + //~^ ERROR trait upcasting coercion is experimental [E0658] +} diff --git a/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr b/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr new file mode 100644 index 00000000000..bc13a5d7d7b --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr @@ -0,0 +1,12 @@ +error[E0658]: trait upcasting coercion is experimental + --> $DIR/feature-gate-trait_upcasting.rs:11:25 + | +LL | let foo: &dyn Foo = bar; + | ^^^ + | + = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information + = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/hygiene/auxiliary/intercrate.rs b/src/test/ui/hygiene/auxiliary/intercrate.rs index 10d399ba54e..0685358851e 100644 --- a/src/test/ui/hygiene/auxiliary/intercrate.rs +++ b/src/test/ui/hygiene/auxiliary/intercrate.rs @@ -5,7 +5,7 @@ pub mod foo { mod bar { fn f() -> u32 { 1 } pub macro m() { - f(); + f() } } } diff --git a/src/test/ui/hygiene/hygienic-label-1.rs b/src/test/ui/hygiene/hygienic-label-1.rs index 66361eec21a..a06d9255ab5 100644 --- a/src/test/ui/hygiene/hygienic-label-1.rs +++ b/src/test/ui/hygiene/hygienic-label-1.rs @@ -3,5 +3,5 @@ macro_rules! foo { } pub fn main() { - 'x: loop { foo!() } + 'x: loop { foo!(); } } diff --git a/src/test/ui/hygiene/hygienic-label-1.stderr b/src/test/ui/hygiene/hygienic-label-1.stderr index 97a7240b906..c1ed861836c 100644 --- a/src/test/ui/hygiene/hygienic-label-1.stderr +++ b/src/test/ui/hygiene/hygienic-label-1.stderr @@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x` LL | () => { break 'x; } | ^^ undeclared label `'x` ... -LL | 'x: loop { foo!() } - | ------ in this macro invocation +LL | 'x: loop { foo!(); } + | ------- in this macro invocation | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/hygiene/hygienic-label-3.rs b/src/test/ui/hygiene/hygienic-label-3.rs index a81eb842259..ab0559e1b6a 100644 --- a/src/test/ui/hygiene/hygienic-label-3.rs +++ b/src/test/ui/hygiene/hygienic-label-3.rs @@ -4,6 +4,6 @@ macro_rules! foo { pub fn main() { 'x: for _ in 0..1 { - foo!() + foo!(); }; } diff --git a/src/test/ui/hygiene/hygienic-label-3.stderr b/src/test/ui/hygiene/hygienic-label-3.stderr index 52840049f82..29d1b67e09f 100644 --- a/src/test/ui/hygiene/hygienic-label-3.stderr +++ b/src/test/ui/hygiene/hygienic-label-3.stderr @@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x` LL | () => { break 'x; } | ^^ undeclared label `'x` ... -LL | foo!() - | ------ in this macro invocation +LL | foo!(); + | ------- in this macro invocation | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/impl-trait/does-not-live-long-enough.stderr b/src/test/ui/impl-trait/does-not-live-long-enough.stderr index 468c2f36629..73fd5e8ded3 100644 --- a/src/test/ui/impl-trait/does-not-live-long-enough.stderr +++ b/src/test/ui/impl-trait/does-not-live-long-enough.stderr @@ -14,7 +14,7 @@ LL | fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator<Item=&' help: to force the closure to take ownership of `prefix` (and any other referenced variables), use the `move` keyword | LL | self.data.iter().filter(move |s| s.starts_with(prefix)).map(|s| s.as_ref()) - | ^^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 00145d10ed7..0ecec5eea36 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -140,14 +140,15 @@ LL | fn bam() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type LL | if true { LL | return Struct; - | ^^^^^^ - | | - | expected struct `Box`, found struct `Struct` - | help: store this in the heap by calling `Box::new`: `Box::new(Struct)` + | ^^^^^^ expected struct `Box`, found struct `Struct` | = note: expected struct `Box<(dyn Trait + 'static)>` found struct `Struct` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | return Box::new(Struct); + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:5 @@ -156,14 +157,15 @@ LL | fn bam() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type ... LL | 42 - | ^^ - | | - | expected struct `Box`, found integer - | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | ^^ expected struct `Box`, found integer | = note: expected struct `Box<(dyn Trait + 'static)>` found type `{integer}` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | Box::new(42) + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:16 @@ -172,14 +174,15 @@ LL | fn baq() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type LL | if true { LL | return 0; - | ^ - | | - | expected struct `Box`, found integer - | help: store this in the heap by calling `Box::new`: `Box::new(0)` + | ^ expected struct `Box`, found integer | = note: expected struct `Box<(dyn Trait + 'static)>` found type `{integer}` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | return Box::new(0); + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:5 @@ -188,14 +191,15 @@ LL | fn baq() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type ... LL | 42 - | ^^ - | | - | expected struct `Box`, found integer - | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | ^^ expected struct `Box`, found integer | = note: expected struct `Box<(dyn Trait + 'static)>` found type `{integer}` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | Box::new(42) + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9 @@ -204,14 +208,15 @@ LL | fn baz() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type LL | if true { LL | Struct - | ^^^^^^ - | | - | expected struct `Box`, found struct `Struct` - | help: store this in the heap by calling `Box::new`: `Box::new(Struct)` + | ^^^^^^ expected struct `Box`, found struct `Struct` | = note: expected struct `Box<(dyn Trait + 'static)>` found struct `Struct` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | Box::new(Struct) + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9 @@ -220,14 +225,15 @@ LL | fn baz() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type ... LL | 42 - | ^^ - | | - | expected struct `Box`, found integer - | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | ^^ expected struct `Box`, found integer | = note: expected struct `Box<(dyn Trait + 'static)>` found type `{integer}` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | Box::new(42) + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9 @@ -236,14 +242,15 @@ LL | fn baw() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type LL | if true { LL | 0 - | ^ - | | - | expected struct `Box`, found integer - | help: store this in the heap by calling `Box::new`: `Box::new(0)` + | ^ expected struct `Box`, found integer | = note: expected struct `Box<(dyn Trait + 'static)>` found type `{integer}` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | Box::new(0) + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9 @@ -252,14 +259,15 @@ LL | fn baw() -> Box<dyn Trait> { | -------------- expected `Box<(dyn Trait + 'static)>` because of return type ... LL | 42 - | ^^ - | | - | expected struct `Box`, found integer - | help: store this in the heap by calling `Box::new`: `Box::new(42)` + | ^^ expected struct `Box`, found integer | = note: expected struct `Box<(dyn Trait + 'static)>` found type `{integer}` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | Box::new(42) + | ^^^^^^^^^ ^ error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:60:13 diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr index e7d90f00d24..957ab2a7548 100644 --- a/src/test/ui/infinite/infinite-autoderef.stderr +++ b/src/test/ui/infinite/infinite-autoderef.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/infinite-autoderef.rs:20:13 | LL | x = box x; - | ^^^^^ - | | - | cyclic type of infinite size - | help: try using a conversion method: `(box x).to_string()` + | ^^^^^ cyclic type of infinite size + | +help: try using a conversion method + | +LL | x = (box x).to_string(); + | ^ ^^^^^^^^^^^^^ error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:25:5 diff --git a/src/test/ui/issues/issue-11515.rs b/src/test/ui/issues/issue-11515.rs index a7671b9282a..2072f9c47e2 100644 --- a/src/test/ui/issues/issue-11515.rs +++ b/src/test/ui/issues/issue-11515.rs @@ -1,10 +1,10 @@ #![feature(box_syntax)] struct Test { - func: Box<dyn FnMut() + 'static> + func: Box<dyn FnMut() + 'static>, } fn main() { let closure: Box<dyn Fn() + 'static> = Box::new(|| ()); - let test = box Test { func: closure }; //~ ERROR mismatched types + let test = box Test { func: closure }; //~ ERROR trait upcasting coercion is experimental [E0658] } diff --git a/src/test/ui/issues/issue-11515.stderr b/src/test/ui/issues/issue-11515.stderr index 7935615ad7e..a70e7c416bc 100644 --- a/src/test/ui/issues/issue-11515.stderr +++ b/src/test/ui/issues/issue-11515.stderr @@ -1,12 +1,12 @@ -error[E0308]: mismatched types +error[E0658]: trait upcasting coercion is experimental --> $DIR/issue-11515.rs:9:33 | LL | let test = box Test { func: closure }; - | ^^^^^^^ expected trait `FnMut`, found trait `Fn` + | ^^^^^^^ | - = note: expected struct `Box<(dyn FnMut() + 'static)>` - found struct `Box<(dyn Fn() + 'static)>` + = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information + = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 1be26949b25..99ff9ac0a0d 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -2,46 +2,66 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com --> $DIR/issue-22644.rs:8:31 | LL | println!("{}", a as usize < long_name); - | ---------- ^ --------- interpreted as generic arguments - | | | - | | not interpreted as comparison - | help: try comparing the cast value: `(a as usize)` + | ^ --------- interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}", (a as usize) < long_name); + | ^ ^ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:9:33 | LL | println!("{}{}", a as usize < long_name, long_name); - | ---------- ^ -------------------- interpreted as generic arguments - | | | - | | not interpreted as comparison - | help: try comparing the cast value: `(a as usize)` + | ^ -------------------- interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}{}", (a as usize) < long_name, long_name); + | ^ ^ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:11:31 | LL | println!("{}", a as usize < 4); - | ---------- ^ - interpreted as generic arguments - | | | - | | not interpreted as comparison - | help: try comparing the cast value: `(a as usize)` + | ^ - interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}", (a as usize) < 4); + | ^ ^ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:13:31 | LL | println!("{}{}", a: usize < long_name, long_name); - | -------- ^ -------------------- interpreted as generic arguments - | | | - | | not interpreted as comparison - | help: try comparing the cast value: `(a: usize)` + | ^ -------------------- interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}{}", (a: usize) < long_name, long_name); + | ^ ^ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:15:29 | LL | println!("{}", a: usize < 4); - | -------- ^ - interpreted as generic arguments - | | | - | | not interpreted as comparison - | help: try comparing the cast value: `(a: usize)` + | ^ - interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}", (a: usize) < 4); + | ^ ^ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:20:20 @@ -80,10 +100,14 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a shi --> $DIR/issue-22644.rs:32:31 | LL | println!("{}", a as usize << long_name); - | ---------- ^^ --------- interpreted as generic arguments - | | | - | | not interpreted as shift - | help: try shifting the cast value: `(a as usize)` + | ^^ --------- interpreted as generic arguments + | | + | not interpreted as shift + | +help: try shifting the cast value + | +LL | println!("{}", (a as usize) << long_name); + | ^ ^ error: expected type, found `4` --> $DIR/issue-22644.rs:34:28 diff --git a/src/test/ui/issues/issue-32122-1.stderr b/src/test/ui/issues/issue-32122-1.stderr index dfbd3223efc..b3362ae44b6 100644 --- a/src/test/ui/issues/issue-32122-1.stderr +++ b/src/test/ui/issues/issue-32122-1.stderr @@ -2,14 +2,16 @@ error[E0308]: mismatched types --> $DIR/issue-32122-1.rs:16:24 | LL | let _: *const u8 = &a; - | --------- ^^ - | | | - | | expected `u8`, found struct `Foo` - | | help: consider dereferencing: `&*a` + | --------- ^^ expected `u8`, found struct `Foo` + | | | expected due to this | = note: expected raw pointer `*const u8` found reference `&Foo` +help: consider dereferencing + | +LL | let _: *const u8 = &*a; + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-32122-2.stderr b/src/test/ui/issues/issue-32122-2.stderr index 2e199e2a19f..bcf71638127 100644 --- a/src/test/ui/issues/issue-32122-2.stderr +++ b/src/test/ui/issues/issue-32122-2.stderr @@ -2,14 +2,16 @@ error[E0308]: mismatched types --> $DIR/issue-32122-2.rs:27:24 | LL | let _: *const u8 = &a; - | --------- ^^ - | | | - | | expected `u8`, found struct `Emm` - | | help: consider dereferencing: `&***a` + | --------- ^^ expected `u8`, found struct `Emm` + | | | expected due to this | = note: expected raw pointer `*const u8` found reference `&Emm` +help: consider dereferencing + | +LL | let _: *const u8 = &***a; + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-42954.stderr b/src/test/ui/issues/issue-42954.stderr index 8227f8df1e0..4f41c95323a 100644 --- a/src/test/ui/issues/issue-42954.stderr +++ b/src/test/ui/issues/issue-42954.stderr @@ -2,15 +2,18 @@ error: `<` is interpreted as a start of generic arguments for `u32`, not a compa --> $DIR/issue-42954.rs:7:19 | LL | $i as u32 < 0 - | --------- ^ - interpreted as generic arguments - | | | - | | not interpreted as comparison - | help: try comparing the cast value: `($i as u32)` + | ^ - interpreted as generic arguments + | | + | not interpreted as comparison ... LL | is_plainly_printable!(c); | ------------------------- in this macro invocation | = note: this error originates in the macro `is_plainly_printable` (in Nightly builds, run with -Z macro-backtrace for more info) +help: try comparing the cast value + | +LL | ($i as u32) < 0 + | ^ ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr b/src/test/ui/issues/issue-50687-ice-on-borrow.stderr index f6adfc87dad..a9404c1c46a 100644 --- a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr +++ b/src/test/ui/issues/issue-50687-ice-on-borrow.stderr @@ -2,14 +2,16 @@ error[E0308]: mismatched types --> $DIR/issue-50687-ice-on-borrow.rs:40:17 | LL | let _: () = Borrow::borrow(&owned); - | -- ^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `()`, found reference - | | help: consider dereferencing the borrow: `*Borrow::borrow(&owned)` + | -- ^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found reference + | | | expected due to this | = note: expected unit type `()` found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: () = *Borrow::borrow(&owned); + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-71676-1.stderr b/src/test/ui/issues/issue-71676-1.stderr index bbabc2202dc..14913c93bf7 100644 --- a/src/test/ui/issues/issue-71676-1.stderr +++ b/src/test/ui/issues/issue-71676-1.stderr @@ -2,53 +2,61 @@ error[E0308]: mismatched types --> $DIR/issue-71676-1.rs:43:24 | LL | let _: *const u8 = &a; - | --------- ^^ - | | | - | | expected `u8`, found struct `Emm` - | | help: consider dereferencing: `&***a` + | --------- ^^ expected `u8`, found struct `Emm` + | | | expected due to this | = note: expected raw pointer `*const u8` found reference `&Emm` +help: consider dereferencing + | +LL | let _: *const u8 = &***a; + | ^^^ error[E0308]: mismatched types --> $DIR/issue-71676-1.rs:46:22 | LL | let _: *mut u8 = &a; - | ------- ^^ - | | | - | | types differ in mutability - | | help: consider dereferencing: `&mut ***a` + | ------- ^^ types differ in mutability + | | | expected due to this | = note: expected raw pointer `*mut u8` found reference `&Emm` +help: consider dereferencing + | +LL | let _: *mut u8 = &mut ***a; + | ^^^^^^^ error[E0308]: mismatched types --> $DIR/issue-71676-1.rs:49:24 | LL | let _: *const u8 = &mut a; - | --------- ^^^^^^ - | | | - | | expected `u8`, found struct `Emm` - | | help: consider dereferencing: `&***a` + | --------- ^^^^^^ expected `u8`, found struct `Emm` + | | | expected due to this | = note: expected raw pointer `*const u8` found mutable reference `&mut Emm` +help: consider dereferencing + | +LL | let _: *const u8 = &***a; + | ^^^ error[E0308]: mismatched types --> $DIR/issue-71676-1.rs:52:22 | LL | let _: *mut u8 = &mut a; - | ------- ^^^^^^ - | | | - | | expected `u8`, found struct `Emm` - | | help: consider dereferencing: `&mut ***a` + | ------- ^^^^^^ expected `u8`, found struct `Emm` + | | | expected due to this | = note: expected raw pointer `*mut u8` found mutable reference `&mut Emm` +help: consider dereferencing + | +LL | let _: *mut u8 = &mut ***a; + | ^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-71676-2.stderr b/src/test/ui/issues/issue-71676-2.stderr index ebdd345809a..0544deda4ae 100644 --- a/src/test/ui/issues/issue-71676-2.stderr +++ b/src/test/ui/issues/issue-71676-2.stderr @@ -2,14 +2,16 @@ error[E0308]: mismatched types --> $DIR/issue-71676-2.rs:41:22 | LL | let _: *mut u8 = &a; - | ------- ^^ - | | | - | | types differ in mutability - | | help: consider dereferencing: `&mut ***a` + | ------- ^^ types differ in mutability + | | | expected due to this | = note: expected raw pointer `*mut u8` found reference `&Emm` +help: consider dereferencing + | +LL | let _: *mut u8 = &mut ***a; + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-77218.stderr b/src/test/ui/issues/issue-77218.stderr index 4f6fbaa2265..f945f7f38f9 100644 --- a/src/test/ui/issues/issue-77218.stderr +++ b/src/test/ui/issues/issue-77218.stderr @@ -21,10 +21,12 @@ error[E0308]: mismatched types --> $DIR/issue-77218.rs:3:16 | LL | while Some(0) = value.get(0) { + | ^ expected integer, found `&u8` + | +help: consider dereferencing the borrow + | +LL | while Some(*0) = value.get(0) { | ^ - | | - | expected integer, found `&u8` - | help: consider dereferencing the borrow: `*0` error[E0308]: mismatched types --> $DIR/issue-77218.rs:3:11 diff --git a/src/test/ui/json-bom-plus-crlf-multifile.stderr b/src/test/ui/json-bom-plus-crlf-multifile.stderr index da8849a8284..02f3bc687cb 100644 --- a/src/test/ui/json-bom-plus-crlf-multifile.stderr +++ b/src/test/ui/json-bom-plus-crlf-multifile.stderr @@ -24,7 +24,7 @@ This error occurs when an expression was used in a place where the compiler expected an expression of a different type. It can occur in several cases, the most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. -"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types +"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":622,"byte_end":622,"line_start":17,"line_end":17,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. @@ -52,7 +52,7 @@ This error occurs when an expression was used in a place where the compiler expected an expression of a different type. It can occur in several cases, the most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. -"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types +"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":682,"byte_end":682,"line_start":19,"line_end":19,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. @@ -80,7 +80,7 @@ This error occurs when an expression was used in a place where the compiler expected an expression of a different type. It can occur in several cases, the most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. -"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types +"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":746,"byte_end":746,"line_start":23,"line_end":23,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. diff --git a/src/test/ui/json-bom-plus-crlf.stderr b/src/test/ui/json-bom-plus-crlf.stderr index 811206f9aa0..df6bd7286a6 100644 --- a/src/test/ui/json-bom-plus-crlf.stderr +++ b/src/test/ui/json-bom-plus-crlf.stderr @@ -24,7 +24,7 @@ This error occurs when an expression was used in a place where the compiler expected an expression of a different type. It can occur in several cases, the most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. -"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types +"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":607,"byte_end":607,"line_start":16,"line_end":16,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. @@ -52,7 +52,7 @@ This error occurs when an expression was used in a place where the compiler expected an expression of a different type. It can occur in several cases, the most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. -"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types +"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":667,"byte_end":667,"line_start":18,"line_end":18,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. @@ -80,7 +80,7 @@ This error occurs when an expression was used in a place where the compiler expected an expression of a different type. It can occur in several cases, the most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. -"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types +"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":731,"byte_end":731,"line_start":22,"line_end":22,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. diff --git a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr index 34470119112..1fef8fc69e2 100644 --- a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr +++ b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr @@ -14,7 +14,7 @@ LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a)); help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword | LL | [0].iter().flat_map(|a| [0].iter().map(move |_| &a)); - | ^^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr index d6b1cf3ae1f..6a5fdac4d91 100644 --- a/src/test/ui/lint/fn_must_use.stderr +++ b/src/test/ui/lint/fn_must_use.stderr @@ -47,13 +47,23 @@ warning: unused comparison that must be used --> $DIR/fn_must_use.rs:74:5 | LL | 2 == 3; - | ^^^^^^ + | ^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 2 == 3; + | ^^^^^^^ warning: unused comparison that must be used --> $DIR/fn_must_use.rs:75:5 | LL | m == n; - | ^^^^^^ + | ^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = m == n; + | ^^^^^^^ warning: 8 warnings emitted diff --git a/src/test/ui/lint/must-use-ops.stderr b/src/test/ui/lint/must-use-ops.stderr deleted file mode 100644 index 3fb80f7e798..00000000000 --- a/src/test/ui/lint/must-use-ops.stderr +++ /dev/null @@ -1,134 +0,0 @@ -warning: unused comparison that must be used - --> $DIR/must-use-ops.rs:12:5 - | -LL | val == 1; - | ^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/must-use-ops.rs:5:9 - | -LL | #![warn(unused_must_use)] - | ^^^^^^^^^^^^^^^ - -warning: unused comparison that must be used - --> $DIR/must-use-ops.rs:13:5 - | -LL | val < 1; - | ^^^^^^^ - -warning: unused comparison that must be used - --> $DIR/must-use-ops.rs:14:5 - | -LL | val <= 1; - | ^^^^^^^^ - -warning: unused comparison that must be used - --> $DIR/must-use-ops.rs:15:5 - | -LL | val != 1; - | ^^^^^^^^ - -warning: unused comparison that must be used - --> $DIR/must-use-ops.rs:16:5 - | -LL | val >= 1; - | ^^^^^^^^ - -warning: unused comparison that must be used - --> $DIR/must-use-ops.rs:17:5 - | -LL | val > 1; - | ^^^^^^^ - -warning: unused arithmetic operation that must be used - --> $DIR/must-use-ops.rs:20:5 - | -LL | val + 2; - | ^^^^^^^ - -warning: unused arithmetic operation that must be used - --> $DIR/must-use-ops.rs:21:5 - | -LL | val - 2; - | ^^^^^^^ - -warning: unused arithmetic operation that must be used - --> $DIR/must-use-ops.rs:22:5 - | -LL | val / 2; - | ^^^^^^^ - -warning: unused arithmetic operation that must be used - --> $DIR/must-use-ops.rs:23:5 - | -LL | val * 2; - | ^^^^^^^ - -warning: unused arithmetic operation that must be used - --> $DIR/must-use-ops.rs:24:5 - | -LL | val % 2; - | ^^^^^^^ - -warning: unused logical operation that must be used - --> $DIR/must-use-ops.rs:27:5 - | -LL | true && true; - | ^^^^^^^^^^^^ - -warning: unused logical operation that must be used - --> $DIR/must-use-ops.rs:28:5 - | -LL | false || true; - | ^^^^^^^^^^^^^ - -warning: unused bitwise operation that must be used - --> $DIR/must-use-ops.rs:31:5 - | -LL | 5 ^ val; - | ^^^^^^^ - -warning: unused bitwise operation that must be used - --> $DIR/must-use-ops.rs:32:5 - | -LL | 5 & val; - | ^^^^^^^ - -warning: unused bitwise operation that must be used - --> $DIR/must-use-ops.rs:33:5 - | -LL | 5 | val; - | ^^^^^^^ - -warning: unused bitwise operation that must be used - --> $DIR/must-use-ops.rs:34:5 - | -LL | 5 << val; - | ^^^^^^^^ - -warning: unused bitwise operation that must be used - --> $DIR/must-use-ops.rs:35:5 - | -LL | 5 >> val; - | ^^^^^^^^ - -warning: unused unary operation that must be used - --> $DIR/must-use-ops.rs:38:5 - | -LL | !val; - | ^^^^ - -warning: unused unary operation that must be used - --> $DIR/must-use-ops.rs:39:5 - | -LL | -val; - | ^^^^ - -warning: unused unary operation that must be used - --> $DIR/must-use-ops.rs:40:5 - | -LL | *val_pointer; - | ^^^^^^^^^^^^ - -warning: 21 warnings emitted - diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs deleted file mode 100644 index 6f9e6ec0a57..00000000000 --- a/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs +++ /dev/null @@ -1,15 +0,0 @@ -// check-pass -// Ensure that trailing semicolons are allowed by default - -macro_rules! foo { - () => { - true; - } -} - -fn main() { - let val = match true { - true => false, - _ => foo!() - }; -} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs new file mode 100644 index 00000000000..781391cc574 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs @@ -0,0 +1,4 @@ +#[macro_export] +macro_rules! my_macro { + () => { true; } +} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs new file mode 100644 index 00000000000..374506366f8 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs @@ -0,0 +1,9 @@ +// aux-build:foreign-crate.rs +// check-pass + +extern crate foreign_crate; + +// Test that we do not lint for a macro in a foreign crate +fn main() { + let _ = foreign_crate::my_macro!(); +} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs new file mode 100644 index 00000000000..2c63311e659 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs @@ -0,0 +1,16 @@ +// check-pass +// Ensure that trailing semicolons cause warnings by default + +macro_rules! foo { + () => { + true; //~ WARN trailing semicolon in macro + //~| WARN this was previously + } +} + +fn main() { + let _val = match true { + true => false, + _ => foo!() + }; +} diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr new file mode 100644 index 00000000000..d770a8c8f36 --- /dev/null +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr @@ -0,0 +1,16 @@ +warning: trailing semicolon in macro used in expression position + --> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13 + | +LL | true; + | ^ +... +LL | _ => foo!() + | ------ in this macro invocation + | + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> + = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 1 warning emitted + diff --git a/src/test/ui/lint/unused-borrows.stderr b/src/test/ui/lint/unused-borrows.stderr index 24899fe992b..e91e02df476 100644 --- a/src/test/ui/lint/unused-borrows.stderr +++ b/src/test/ui/lint/unused-borrows.stderr @@ -2,43 +2,72 @@ error: unused borrow that must be used --> $DIR/unused-borrows.rs:6:5 | LL | &42; - | ^^^ + | ^^^ the borrow produces a value | note: the lint level is defined here --> $DIR/unused-borrows.rs:1:9 | LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = &42; + | ^^^^^^^ error: unused borrow that must be used --> $DIR/unused-borrows.rs:9:5 | LL | &mut foo(42); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ the borrow produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = &mut foo(42); + | ^^^^^^^ error: unused borrow that must be used --> $DIR/unused-borrows.rs:12:5 | LL | &&42; - | ^^^^ + | ^^^^ the borrow produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = &&42; + | ^^^^^^^ error: unused borrow that must be used --> $DIR/unused-borrows.rs:15:5 | LL | &&mut 42; - | ^^^^^^^^ + | ^^^^^^^^ the borrow produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = &&mut 42; + | ^^^^^^^ error: unused borrow that must be used --> $DIR/unused-borrows.rs:18:5 | LL | &mut &42; - | ^^^^^^^^ + | ^^^^^^^^ the borrow produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = &mut &42; + | ^^^^^^^ error: unused borrow that must be used --> $DIR/unused-borrows.rs:23:5 | LL | && foo(42); - | ^^^^^^^^^^ + | ^^^^^^^^^^ the borrow produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = && foo(42); + | ^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs index b76b4321d62..b76b4321d62 100644 --- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate.rs +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate2.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs index b76b4321d62..b76b4321d62 100644 --- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate2.rs +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate3.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs index b76b4321d62..b76b4321d62 100644 --- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate3.rs +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate4.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs index d11c69f812a..d11c69f812a 100644 --- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate4.rs +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate5.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs index d11c69f812a..d11c69f812a 100644 --- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate5.rs +++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs diff --git a/src/test/ui/unused/issue-30730.rs b/src/test/ui/lint/unused/issue-30730.rs index d6be90c8148..d6be90c8148 100644 --- a/src/test/ui/unused/issue-30730.rs +++ b/src/test/ui/lint/unused/issue-30730.rs diff --git a/src/test/ui/unused/issue-30730.stderr b/src/test/ui/lint/unused/issue-30730.stderr index b299e99a3a9..b299e99a3a9 100644 --- a/src/test/ui/unused/issue-30730.stderr +++ b/src/test/ui/lint/unused/issue-30730.stderr diff --git a/src/test/ui/unused/issue-46576.rs b/src/test/ui/lint/unused/issue-46576.rs index 15f458f3844..15f458f3844 100644 --- a/src/test/ui/unused/issue-46576.rs +++ b/src/test/ui/lint/unused/issue-46576.rs diff --git a/src/test/ui/unused/issue-46576.stderr b/src/test/ui/lint/unused/issue-46576.stderr index 6f4d97068b3..6f4d97068b3 100644 --- a/src/test/ui/unused/issue-46576.stderr +++ b/src/test/ui/lint/unused/issue-46576.stderr diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs index 0ad014e3361..0ad014e3361 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr index 2ef655efdbd..2ef655efdbd 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.fixed b/src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed index 1350b7ca699..1350b7ca699 100644 --- a/src/test/ui/lint/issue-54180-unused-ref-field.fixed +++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.rs b/src/test/ui/lint/unused/issue-54180-unused-ref-field.rs index 7b3392b609a..7b3392b609a 100644 --- a/src/test/ui/lint/issue-54180-unused-ref-field.rs +++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.rs diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.stderr b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr index c501aa25f13..c501aa25f13 100644 --- a/src/test/ui/lint/issue-54180-unused-ref-field.stderr +++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.fixed b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed index 0b3fe9371f7..0b3fe9371f7 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.fixed +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs index 1e78ec5f7d9..1e78ec5f7d9 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr index e6d0a359c5c..e6d0a359c5c 100644 --- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr diff --git a/src/test/ui/unused/issue-59896.rs b/src/test/ui/lint/unused/issue-59896.rs index ff9f19acf84..ff9f19acf84 100644 --- a/src/test/ui/unused/issue-59896.rs +++ b/src/test/ui/lint/unused/issue-59896.rs diff --git a/src/test/ui/unused/issue-59896.stderr b/src/test/ui/lint/unused/issue-59896.stderr index 95b7938ae03..95b7938ae03 100644 --- a/src/test/ui/unused/issue-59896.stderr +++ b/src/test/ui/lint/unused/issue-59896.stderr diff --git a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.rs b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs index e3631d014d6..e3631d014d6 100644 --- a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.rs +++ b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs diff --git a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.stderr b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr index 8aefe243a94..8aefe243a94 100644 --- a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.stderr +++ b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr diff --git a/src/test/ui/unused/issue-70041.rs b/src/test/ui/lint/unused/issue-70041.rs index 22e42295eed..22e42295eed 100644 --- a/src/test/ui/unused/issue-70041.rs +++ b/src/test/ui/lint/unused/issue-70041.rs diff --git a/src/test/ui/unused/issue-70041.stderr b/src/test/ui/lint/unused/issue-70041.stderr index ecd618eae8b..ecd618eae8b 100644 --- a/src/test/ui/unused/issue-70041.stderr +++ b/src/test/ui/lint/unused/issue-70041.stderr diff --git a/src/test/ui/lint/issue-71290-unused-paren-binop.rs b/src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs index 24d77e36d94..24d77e36d94 100644 --- a/src/test/ui/lint/issue-71290-unused-paren-binop.rs +++ b/src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs index 8064c3a88d1..8064c3a88d1 100644 --- a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs +++ b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr index 3f6260dc6e1..3f6260dc6e1 100644 --- a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr +++ b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.fixed b/src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed index aac918f2bc8..aac918f2bc8 100644 --- a/src/test/ui/lint/issue-81314-unused-span-ident.fixed +++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.rs b/src/test/ui/lint/unused/issue-81314-unused-span-ident.rs index 78296f4258d..78296f4258d 100644 --- a/src/test/ui/lint/issue-81314-unused-span-ident.rs +++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.rs diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.stderr b/src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr index 519c71e9413..519c71e9413 100644 --- a/src/test/ui/lint/issue-81314-unused-span-ident.stderr +++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr diff --git a/src/test/ui/lint/unused/issue-85913.rs b/src/test/ui/lint/unused/issue-85913.rs new file mode 100644 index 00000000000..7f3817b6ef1 --- /dev/null +++ b/src/test/ui/lint/unused/issue-85913.rs @@ -0,0 +1,13 @@ +#![deny(unused_must_use)] + +pub fn fun() -> i32 { + function() && return 1; + //~^ ERROR: unused logical operation that must be used + return 0; +} + +fn function() -> bool { + true +} + +fn main() {} diff --git a/src/test/ui/lint/unused/issue-85913.stderr b/src/test/ui/lint/unused/issue-85913.stderr new file mode 100644 index 00000000000..4835cfae46f --- /dev/null +++ b/src/test/ui/lint/unused/issue-85913.stderr @@ -0,0 +1,18 @@ +error: unused logical operation that must be used + --> $DIR/issue-85913.rs:4:5 + | +LL | function() && return 1; + | ^^^^^^^^^^^^^^^^^^^^^^ the logical operation produces a value + | +note: the lint level is defined here + --> $DIR/issue-85913.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = function() && return 1; + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/lint-unused-extern-crate.rs b/src/test/ui/lint/unused/lint-unused-extern-crate.rs index d5e4da526a1..d5e4da526a1 100644 --- a/src/test/ui/lint/lint-unused-extern-crate.rs +++ b/src/test/ui/lint/unused/lint-unused-extern-crate.rs diff --git a/src/test/ui/lint/lint-unused-extern-crate.stderr b/src/test/ui/lint/unused/lint-unused-extern-crate.stderr index 46d8f3beeab..46d8f3beeab 100644 --- a/src/test/ui/lint/lint-unused-extern-crate.stderr +++ b/src/test/ui/lint/unused/lint-unused-extern-crate.stderr diff --git a/src/test/ui/lint/lint-unused-imports.rs b/src/test/ui/lint/unused/lint-unused-imports.rs index 4754d888076..4754d888076 100644 --- a/src/test/ui/lint/lint-unused-imports.rs +++ b/src/test/ui/lint/unused/lint-unused-imports.rs diff --git a/src/test/ui/lint/lint-unused-imports.stderr b/src/test/ui/lint/unused/lint-unused-imports.stderr index 0574ca4569f..0574ca4569f 100644 --- a/src/test/ui/lint/lint-unused-imports.stderr +++ b/src/test/ui/lint/unused/lint-unused-imports.stderr diff --git a/src/test/ui/lint/lint-unused-mut-self.fixed b/src/test/ui/lint/unused/lint-unused-mut-self.fixed index 92ce103586c..92ce103586c 100644 --- a/src/test/ui/lint/lint-unused-mut-self.fixed +++ b/src/test/ui/lint/unused/lint-unused-mut-self.fixed diff --git a/src/test/ui/lint/lint-unused-mut-self.rs b/src/test/ui/lint/unused/lint-unused-mut-self.rs index 70736ce216e..70736ce216e 100644 --- a/src/test/ui/lint/lint-unused-mut-self.rs +++ b/src/test/ui/lint/unused/lint-unused-mut-self.rs diff --git a/src/test/ui/lint/lint-unused-mut-self.stderr b/src/test/ui/lint/unused/lint-unused-mut-self.stderr index 01a524bd323..01a524bd323 100644 --- a/src/test/ui/lint/lint-unused-mut-self.stderr +++ b/src/test/ui/lint/unused/lint-unused-mut-self.stderr diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/unused/lint-unused-mut-variables.rs index 67ec7facf17..67ec7facf17 100644 --- a/src/test/ui/lint/lint-unused-mut-variables.rs +++ b/src/test/ui/lint/unused/lint-unused-mut-variables.rs diff --git a/src/test/ui/lint/lint-unused-mut-variables.stderr b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr index 805ed2b40bb..805ed2b40bb 100644 --- a/src/test/ui/lint/lint-unused-mut-variables.stderr +++ b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/unused/lint-unused-variables.rs index 6850e999242..6850e999242 100644 --- a/src/test/ui/lint/lint-unused-variables.rs +++ b/src/test/ui/lint/unused/lint-unused-variables.rs diff --git a/src/test/ui/lint/lint-unused-variables.stderr b/src/test/ui/lint/unused/lint-unused-variables.stderr index d6e684e8306..d6e684e8306 100644 --- a/src/test/ui/lint/lint-unused-variables.stderr +++ b/src/test/ui/lint/unused/lint-unused-variables.stderr diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/unused/must-use-ops.rs index 3e425727e78..3e425727e78 100644 --- a/src/test/ui/lint/must-use-ops.rs +++ b/src/test/ui/lint/unused/must-use-ops.rs diff --git a/src/test/ui/lint/unused/must-use-ops.stderr b/src/test/ui/lint/unused/must-use-ops.stderr new file mode 100644 index 00000000000..4dd739088b9 --- /dev/null +++ b/src/test/ui/lint/unused/must-use-ops.stderr @@ -0,0 +1,238 @@ +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:12:5 + | +LL | val == 1; + | ^^^^^^^^ the comparison produces a value + | +note: the lint level is defined here + --> $DIR/must-use-ops.rs:5:9 + | +LL | #![warn(unused_must_use)] + | ^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val == 1; + | ^^^^^^^ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:13:5 + | +LL | val < 1; + | ^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val < 1; + | ^^^^^^^ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:14:5 + | +LL | val <= 1; + | ^^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val <= 1; + | ^^^^^^^ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:15:5 + | +LL | val != 1; + | ^^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val != 1; + | ^^^^^^^ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:16:5 + | +LL | val >= 1; + | ^^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val >= 1; + | ^^^^^^^ + +warning: unused comparison that must be used + --> $DIR/must-use-ops.rs:17:5 + | +LL | val > 1; + | ^^^^^^^ the comparison produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val > 1; + | ^^^^^^^ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:20:5 + | +LL | val + 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val + 2; + | ^^^^^^^ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:21:5 + | +LL | val - 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val - 2; + | ^^^^^^^ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:22:5 + | +LL | val / 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val / 2; + | ^^^^^^^ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:23:5 + | +LL | val * 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val * 2; + | ^^^^^^^ + +warning: unused arithmetic operation that must be used + --> $DIR/must-use-ops.rs:24:5 + | +LL | val % 2; + | ^^^^^^^ the arithmetic operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = val % 2; + | ^^^^^^^ + +warning: unused logical operation that must be used + --> $DIR/must-use-ops.rs:27:5 + | +LL | true && true; + | ^^^^^^^^^^^^ the logical operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = true && true; + | ^^^^^^^ + +warning: unused logical operation that must be used + --> $DIR/must-use-ops.rs:28:5 + | +LL | false || true; + | ^^^^^^^^^^^^^ the logical operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = false || true; + | ^^^^^^^ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:31:5 + | +LL | 5 ^ val; + | ^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 ^ val; + | ^^^^^^^ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:32:5 + | +LL | 5 & val; + | ^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 & val; + | ^^^^^^^ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:33:5 + | +LL | 5 | val; + | ^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 | val; + | ^^^^^^^ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:34:5 + | +LL | 5 << val; + | ^^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 << val; + | ^^^^^^^ + +warning: unused bitwise operation that must be used + --> $DIR/must-use-ops.rs:35:5 + | +LL | 5 >> val; + | ^^^^^^^^ the bitwise operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = 5 >> val; + | ^^^^^^^ + +warning: unused unary operation that must be used + --> $DIR/must-use-ops.rs:38:5 + | +LL | !val; + | ^^^^ the unary operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = !val; + | ^^^^^^^ + +warning: unused unary operation that must be used + --> $DIR/must-use-ops.rs:39:5 + | +LL | -val; + | ^^^^ the unary operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = -val; + | ^^^^^^^ + +warning: unused unary operation that must be used + --> $DIR/must-use-ops.rs:40:5 + | +LL | *val_pointer; + | ^^^^^^^^^^^^ the unary operation produces a value + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = *val_pointer; + | ^^^^^^^ + +warning: 21 warnings emitted + diff --git a/src/test/ui/lint/must_use-array.rs b/src/test/ui/lint/unused/must_use-array.rs index 97825dd2f6c..97825dd2f6c 100644 --- a/src/test/ui/lint/must_use-array.rs +++ b/src/test/ui/lint/unused/must_use-array.rs diff --git a/src/test/ui/lint/must_use-array.stderr b/src/test/ui/lint/unused/must_use-array.stderr index c42223b5198..c42223b5198 100644 --- a/src/test/ui/lint/must_use-array.stderr +++ b/src/test/ui/lint/unused/must_use-array.stderr diff --git a/src/test/ui/lint/must_use-in-stdlib-traits.rs b/src/test/ui/lint/unused/must_use-in-stdlib-traits.rs index 70dddf61fb7..70dddf61fb7 100644 --- a/src/test/ui/lint/must_use-in-stdlib-traits.rs +++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.rs diff --git a/src/test/ui/lint/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr index 76978d29dc8..76978d29dc8 100644 --- a/src/test/ui/lint/must_use-in-stdlib-traits.stderr +++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/unused/must_use-trait.rs index 0aa751443a0..0aa751443a0 100644 --- a/src/test/ui/lint/must_use-trait.rs +++ b/src/test/ui/lint/unused/must_use-trait.rs diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/unused/must_use-trait.stderr index 11555d80825..11555d80825 100644 --- a/src/test/ui/lint/must_use-trait.stderr +++ b/src/test/ui/lint/unused/must_use-trait.stderr diff --git a/src/test/ui/lint/must_use-tuple.rs b/src/test/ui/lint/unused/must_use-tuple.rs index 0f0aa20253c..0f0aa20253c 100644 --- a/src/test/ui/lint/must_use-tuple.rs +++ b/src/test/ui/lint/unused/must_use-tuple.rs diff --git a/src/test/ui/lint/must_use-tuple.stderr b/src/test/ui/lint/unused/must_use-tuple.stderr index 0532d89e039..0532d89e039 100644 --- a/src/test/ui/lint/must_use-tuple.stderr +++ b/src/test/ui/lint/unused/must_use-tuple.stderr diff --git a/src/test/ui/lint/must_use-unit.rs b/src/test/ui/lint/unused/must_use-unit.rs index 4dd4798abb7..4dd4798abb7 100644 --- a/src/test/ui/lint/must_use-unit.rs +++ b/src/test/ui/lint/unused/must_use-unit.rs diff --git a/src/test/ui/lint/must_use-unit.stderr b/src/test/ui/lint/unused/must_use-unit.stderr index 7f25a193508..7f25a193508 100644 --- a/src/test/ui/lint/must_use-unit.stderr +++ b/src/test/ui/lint/unused/must_use-unit.stderr diff --git a/src/test/ui/lint/no-unused-parens-return-block.rs b/src/test/ui/lint/unused/no-unused-parens-return-block.rs index 37dc519a204..37dc519a204 100644 --- a/src/test/ui/lint/no-unused-parens-return-block.rs +++ b/src/test/ui/lint/unused/no-unused-parens-return-block.rs diff --git a/src/test/ui/unused/unused-attr-macro-rules.rs b/src/test/ui/lint/unused/unused-attr-macro-rules.rs index 396137a11d0..396137a11d0 100644 --- a/src/test/ui/unused/unused-attr-macro-rules.rs +++ b/src/test/ui/lint/unused/unused-attr-macro-rules.rs diff --git a/src/test/ui/unused/unused-attr-macro-rules.stderr b/src/test/ui/lint/unused/unused-attr-macro-rules.stderr index 4606be01ac0..4606be01ac0 100644 --- a/src/test/ui/unused/unused-attr-macro-rules.stderr +++ b/src/test/ui/lint/unused/unused-attr-macro-rules.stderr diff --git a/src/test/ui/unused/unused-attr.rs b/src/test/ui/lint/unused/unused-attr.rs index cb8ac0e6a05..cb8ac0e6a05 100644 --- a/src/test/ui/unused/unused-attr.rs +++ b/src/test/ui/lint/unused/unused-attr.rs diff --git a/src/test/ui/unused/unused-attr.stderr b/src/test/ui/lint/unused/unused-attr.stderr index 707521b7802..707521b7802 100644 --- a/src/test/ui/unused/unused-attr.stderr +++ b/src/test/ui/lint/unused/unused-attr.stderr diff --git a/src/test/ui/unused/unused-closure.rs b/src/test/ui/lint/unused/unused-closure.rs index c96c907318c..c96c907318c 100644 --- a/src/test/ui/unused/unused-closure.rs +++ b/src/test/ui/lint/unused/unused-closure.rs diff --git a/src/test/ui/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr index 265d3e8e075..265d3e8e075 100644 --- a/src/test/ui/unused/unused-closure.stderr +++ b/src/test/ui/lint/unused/unused-closure.stderr diff --git a/src/test/ui/unused/unused-doc-comments-edge-cases.rs b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs index fd9baf8c6b9..fd9baf8c6b9 100644 --- a/src/test/ui/unused/unused-doc-comments-edge-cases.rs +++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs diff --git a/src/test/ui/unused/unused-doc-comments-edge-cases.stderr b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr index 14db5f64b0c..14db5f64b0c 100644 --- a/src/test/ui/unused/unused-doc-comments-edge-cases.stderr +++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr diff --git a/src/test/ui/unused/unused-doc-comments-for-macros.rs b/src/test/ui/lint/unused/unused-doc-comments-for-macros.rs index 05828ebb2c3..05828ebb2c3 100644 --- a/src/test/ui/unused/unused-doc-comments-for-macros.rs +++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.rs diff --git a/src/test/ui/unused/unused-doc-comments-for-macros.stderr b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr index f4f5bb71e55..f4f5bb71e55 100644 --- a/src/test/ui/unused/unused-doc-comments-for-macros.stderr +++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr diff --git a/src/test/ui/unused/unused-macro-rules.rs b/src/test/ui/lint/unused/unused-macro-rules.rs index 1a714b8f0a0..1a714b8f0a0 100644 --- a/src/test/ui/unused/unused-macro-rules.rs +++ b/src/test/ui/lint/unused/unused-macro-rules.rs diff --git a/src/test/ui/unused/unused-macro-rules.stderr b/src/test/ui/lint/unused/unused-macro-rules.stderr index 55072bd81bf..55072bd81bf 100644 --- a/src/test/ui/unused/unused-macro-rules.stderr +++ b/src/test/ui/lint/unused/unused-macro-rules.stderr diff --git a/src/test/ui/unused/unused-macro-with-bad-frag-spec.rs b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs index ce187047bb7..ce187047bb7 100644 --- a/src/test/ui/unused/unused-macro-with-bad-frag-spec.rs +++ b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs diff --git a/src/test/ui/unused/unused-macro-with-bad-frag-spec.stderr b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr index 6edf0a2cf8d..6edf0a2cf8d 100644 --- a/src/test/ui/unused/unused-macro-with-bad-frag-spec.stderr +++ b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr diff --git a/src/test/ui/unused/unused-macro-with-follow-violation.rs b/src/test/ui/lint/unused/unused-macro-with-follow-violation.rs index 1666dae69b9..1666dae69b9 100644 --- a/src/test/ui/unused/unused-macro-with-follow-violation.rs +++ b/src/test/ui/lint/unused/unused-macro-with-follow-violation.rs diff --git a/src/test/ui/unused/unused-macro-with-follow-violation.stderr b/src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr index 5eced4f06c0..5eced4f06c0 100644 --- a/src/test/ui/unused/unused-macro-with-follow-violation.stderr +++ b/src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr diff --git a/src/test/ui/unused/unused-macro.rs b/src/test/ui/lint/unused/unused-macro.rs index 302b0727d77..302b0727d77 100644 --- a/src/test/ui/unused/unused-macro.rs +++ b/src/test/ui/lint/unused/unused-macro.rs diff --git a/src/test/ui/unused/unused-macro.stderr b/src/test/ui/lint/unused/unused-macro.stderr index f5eb76179bf..f5eb76179bf 100644 --- a/src/test/ui/unused/unused-macro.stderr +++ b/src/test/ui/lint/unused/unused-macro.stderr diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.fixed b/src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed index c21f18015c1..c21f18015c1 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.fixed +++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.rs b/src/test/ui/lint/unused/unused-mut-warning-captured-var.rs index 3119d83a0eb..3119d83a0eb 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.rs +++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.rs diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.stderr b/src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr index 20aeedcc241..20aeedcc241 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.stderr +++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr diff --git a/src/test/ui/unused/unused-result.rs b/src/test/ui/lint/unused/unused-result.rs index a65e98990dc..a65e98990dc 100644 --- a/src/test/ui/unused/unused-result.rs +++ b/src/test/ui/lint/unused/unused-result.rs diff --git a/src/test/ui/unused/unused-result.stderr b/src/test/ui/lint/unused/unused-result.stderr index 1b1dcab3a1b..1b1dcab3a1b 100644 --- a/src/test/ui/unused/unused-result.stderr +++ b/src/test/ui/lint/unused/unused-result.stderr diff --git a/src/test/ui/unused/useless-comment.rs b/src/test/ui/lint/unused/useless-comment.rs index 7d2e5ab6f2b..7d2e5ab6f2b 100644 --- a/src/test/ui/unused/useless-comment.rs +++ b/src/test/ui/lint/unused/useless-comment.rs diff --git a/src/test/ui/unused/useless-comment.stderr b/src/test/ui/lint/unused/useless-comment.stderr index 0054426fb1e..0054426fb1e 100644 --- a/src/test/ui/unused/useless-comment.stderr +++ b/src/test/ui/lint/unused/useless-comment.stderr diff --git a/src/test/ui/macros/macro-context.rs b/src/test/ui/macros/macro-context.rs index 13e179578ad..d09fdf118e6 100644 --- a/src/test/ui/macros/macro-context.rs +++ b/src/test/ui/macros/macro-context.rs @@ -6,6 +6,8 @@ macro_rules! m { //~| ERROR macro expansion ignores token `;` //~| ERROR cannot find type `i` in this scope //~| ERROR cannot find value `i` in this scope + //~| WARN trailing semicolon in macro + //~| WARN this was previously } fn main() { diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr index 5ed73b7fb93..3b8a6f17491 100644 --- a/src/test/ui/macros/macro-context.stderr +++ b/src/test/ui/macros/macro-context.stderr @@ -64,7 +64,21 @@ LL | let i = m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +warning: trailing semicolon in macro used in expression position + --> $DIR/macro-context.rs:3:15 + | +LL | () => ( i ; typeof ); + | ^ +... +LL | let i = m!(); + | ---- in this macro invocation + | + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> + = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors; 1 warning emitted Some errors have detailed explanations: E0412, E0425. For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/macros/macro-in-expression-context.fixed b/src/test/ui/macros/macro-in-expression-context.fixed index df36db0f49e..f22caf2793f 100644 --- a/src/test/ui/macros/macro-in-expression-context.fixed +++ b/src/test/ui/macros/macro-in-expression-context.fixed @@ -3,6 +3,12 @@ macro_rules! foo { () => { assert_eq!("A", "A"); + //~^ WARN trailing semicolon in macro + //~| WARN this was previously + //~| NOTE macro invocations at the end of a block + //~| NOTE to ignore the value produced by the macro + //~| NOTE for more information + //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default assert_eq!("B", "B"); } //~^^ ERROR macro expansion ignores token `assert_eq` and any following @@ -12,4 +18,10 @@ macro_rules! foo { fn main() { foo!(); //~^ NOTE caused by the macro expansion here + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion } diff --git a/src/test/ui/macros/macro-in-expression-context.rs b/src/test/ui/macros/macro-in-expression-context.rs index b3f5e568967..1a056e582ff 100644 --- a/src/test/ui/macros/macro-in-expression-context.rs +++ b/src/test/ui/macros/macro-in-expression-context.rs @@ -3,6 +3,12 @@ macro_rules! foo { () => { assert_eq!("A", "A"); + //~^ WARN trailing semicolon in macro + //~| WARN this was previously + //~| NOTE macro invocations at the end of a block + //~| NOTE to ignore the value produced by the macro + //~| NOTE for more information + //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default assert_eq!("B", "B"); } //~^^ ERROR macro expansion ignores token `assert_eq` and any following @@ -12,4 +18,10 @@ macro_rules! foo { fn main() { foo!() //~^ NOTE caused by the macro expansion here + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion } diff --git a/src/test/ui/macros/macro-in-expression-context.stderr b/src/test/ui/macros/macro-in-expression-context.stderr index d27d6fbaef7..1840babd61d 100644 --- a/src/test/ui/macros/macro-in-expression-context.stderr +++ b/src/test/ui/macros/macro-in-expression-context.stderr @@ -1,5 +1,5 @@ error: macro expansion ignores token `assert_eq` and any following - --> $DIR/macro-in-expression-context.rs:6:9 + --> $DIR/macro-in-expression-context.rs:12:9 | LL | assert_eq!("B", "B"); | ^^^^^^^^^ @@ -11,5 +11,21 @@ LL | foo!() | = note: the usage of `foo!` is likely invalid in expression context -error: aborting due to previous error +warning: trailing semicolon in macro used in expression position + --> $DIR/macro-in-expression-context.rs:5:29 + | +LL | assert_eq!("A", "A"); + | ^ +... +LL | foo!() + | ------ in this macro invocation + | + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> + = note: macro invocations at the end of a block are treated as expressions + = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo` + = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index 61994e5bfee..7697a375fd8 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -78,10 +78,12 @@ error[E0308]: mismatched types LL | fn f() -> String { | ------ expected `String` because of return type LL | 1+2 - | ^^^ - | | - | expected struct `String`, found integer - | help: try using a conversion method: `(1+2).to_string()` + | ^^^ expected struct `String`, found integer + | +help: try using a conversion method + | +LL | (1+2).to_string() + | ^ ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/abridged.rs:59:5 @@ -89,10 +91,12 @@ error[E0308]: mismatched types LL | fn g() -> String { | ------ expected `String` because of return type LL | -2 - | ^^ - | | - | expected struct `String`, found integer - | help: try using a conversion method: `(-2).to_string()` + | ^^ expected struct `String`, found integer + | +help: try using a conversion method + | +LL | (-2).to_string() + | ^ ^^^^^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr index 26ab5f43a27..3453f031623 100644 --- a/src/test/ui/never_type/issue-52443.stderr +++ b/src/test/ui/never_type/issue-52443.stderr @@ -19,13 +19,14 @@ error[E0308]: mismatched types --> $DIR/issue-52443.rs:2:10 | LL | [(); & { loop { continue } } ]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected `usize`, found reference - | help: consider removing the borrow: `{ loop { continue } }` + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found reference | = note: expected type `usize` found reference `&_` +help: consider removing the borrow + | +LL | [(); { loop { continue } } ]; + | -- error[E0308]: mismatched types --> $DIR/issue-52443.rs:4:17 diff --git a/src/test/ui/occurs-check-2.stderr b/src/test/ui/occurs-check-2.stderr index 7f93697c6f7..b2c8775e78c 100644 --- a/src/test/ui/occurs-check-2.stderr +++ b/src/test/ui/occurs-check-2.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/occurs-check-2.rs:7:9 | LL | f = box g; - | ^^^^^ - | | - | cyclic type of infinite size - | help: try using a conversion method: `(box g).to_string()` + | ^^^^^ cyclic type of infinite size + | +help: try using a conversion method + | +LL | f = (box g).to_string(); + | ^ ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/occurs-check.stderr b/src/test/ui/occurs-check.stderr index 01e2b1f7749..a657106ad91 100644 --- a/src/test/ui/occurs-check.stderr +++ b/src/test/ui/occurs-check.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/occurs-check.rs:5:9 | LL | f = box f; - | ^^^^^ - | | - | cyclic type of infinite size - | help: try using a conversion method: `(box f).to_string()` + | ^^^^^ cyclic type of infinite size + | +help: try using a conversion method + | +LL | f = (box f).to_string(); + | ^ ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/packed/issue-27060-2.stderr b/src/test/ui/packed/issue-27060-2.stderr index 5dbcc96e874..64e061a89b4 100644 --- a/src/test/ui/packed/issue-27060-2.stderr +++ b/src/test/ui/packed/issue-27060-2.stderr @@ -8,6 +8,10 @@ LL | data: T, | = note: the last field of a packed struct may only have a dynamically sized type if it does not need drop to be run = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | pub struct Bad<T> { + | -- help: borrowed types always have a statically known size | LL | data: &T, diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr index 2a701274857..affcb6ed224 100644 --- a/src/test/ui/parser/expr-as-stmt-2.stderr +++ b/src/test/ui/parser/expr-as-stmt-2.stderr @@ -31,12 +31,15 @@ error[E0308]: mismatched types | LL | fn foo(a: Option<u32>, b: Option<u32>) -> bool { | ---- expected `bool` because of return type -LL | if let Some(x) = a { true } else { false } - | ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })` ... LL | / && LL | | if let Some(y) = a { true } else { false } | |______________________________________________^ expected `bool`, found `&&bool` + | +help: parentheses are required to parse this as an expression + | +LL | (if let Some(x) = a { true } else { false }) + | ^ ^ error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr index 067b7edc770..2bb320e7321 100644 --- a/src/test/ui/parser/expr-as-stmt.stderr +++ b/src/test/ui/parser/expr-as-stmt.stderr @@ -2,25 +2,34 @@ error: expected expression, found `+` --> $DIR/expr-as-stmt.rs:8:9 | LL | {2} + {2} - | --- ^ expected expression - | | - | help: parentheses are required to parse this as an expression: `({2})` + | ^ expected expression + | +help: parentheses are required to parse this as an expression + | +LL | ({2}) + {2} + | ^ ^ error: expected expression, found `+` --> $DIR/expr-as-stmt.rs:13:9 | LL | {2} + 2 - | --- ^ expected expression - | | - | help: parentheses are required to parse this as an expression: `({2})` + | ^ expected expression + | +help: parentheses are required to parse this as an expression + | +LL | ({2}) + 2 + | ^ ^ error: expected expression, found `+` --> $DIR/expr-as-stmt.rs:19:12 | LL | { 42 } + foo; - | ------ ^ expected expression - | | - | help: parentheses are required to parse this as an expression: `({ 42 })` + | ^ expected expression + | +help: parentheses are required to parse this as an expression + | +LL | ({ 42 }) + foo; + | ^ ^ error: expected expression, found `>` --> $DIR/expr-as-stmt.rs:32:7 @@ -83,9 +92,12 @@ error[E0614]: type `{integer}` cannot be dereferenced --> $DIR/expr-as-stmt.rs:25:11 | LL | { 3 } * 3 - | ----- ^^^ - | | - | help: parentheses are required to parse this as an expression: `({ 3 })` + | ^^^ + | +help: parentheses are required to parse this as an expression + | +LL | ({ 3 }) * 3 + | ^ ^ error: aborting due to 9 previous errors diff --git a/src/test/ui/proc-macro/nested-nonterminal-tokens.rs b/src/test/ui/proc-macro/nested-nonterminal-tokens.rs index 2f5af10a40a..04d34e21cdc 100644 --- a/src/test/ui/proc-macro/nested-nonterminal-tokens.rs +++ b/src/test/ui/proc-macro/nested-nonterminal-tokens.rs @@ -17,7 +17,7 @@ macro_rules! wrap { (first, $e:expr) => { wrap!(second, $e + 1) }; (second, $e:expr) => { wrap!(third, $e + 2) }; (third, $e:expr) => { - print_bang!($e + 3); + print_bang!($e + 3) }; } diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr b/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr index 328e602ca76..4bd16c71137 100644 --- a/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr +++ b/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr @@ -14,7 +14,7 @@ LL | WrapB::new().set(|t: bool| if t { x } else { y }) // (separate erro help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-big.rs:67:26 @@ -32,7 +32,7 @@ LL | WrapB::new().set(|t: bool| if t { x } else { y }) // (separate erro help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr b/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr index 18610b7cffb..f70e4ea9fbc 100644 --- a/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr +++ b/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr @@ -14,7 +14,7 @@ LL | return f; help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:9:17 @@ -32,7 +32,7 @@ LL | return f; help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:24:17 @@ -50,7 +50,7 @@ LL | f help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:24:17 @@ -68,7 +68,7 @@ LL | f help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:55:17 @@ -86,7 +86,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:55:17 @@ -104,7 +104,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:66:17 @@ -122,7 +122,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:66:17 @@ -140,7 +140,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:90:21 @@ -158,7 +158,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:90:21 @@ -176,7 +176,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:104:21 @@ -194,7 +194,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:104:21 @@ -212,7 +212,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:132:21 @@ -230,7 +230,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:132:21 @@ -248,7 +248,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:147:21 @@ -266,7 +266,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:147:21 @@ -284,7 +284,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:175:21 @@ -302,7 +302,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:175:21 @@ -320,7 +320,7 @@ LL | return Box::new(f); help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:189:21 @@ -338,7 +338,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function --> $DIR/region-borrow-params-issue-29793-small.rs:189:21 @@ -356,7 +356,7 @@ LL | Box::new(f) help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword | LL | let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^ + | ^^^^ error: aborting due to 20 previous errors diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index 4950b654141..23eabfa3b3e 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -478,10 +478,12 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:32:8 | LL | if &let 0 = 0 {} - | ^^^^^^^^^^ - | | - | expected `bool`, found `&bool` - | help: consider removing the borrow: `let 0 = 0` + | ^^^^^^^^^^ expected `bool`, found `&bool` + | +help: consider removing the borrow + | +LL | if let 0 = 0 {} + | -- error[E0614]: type `bool` cannot be dereferenced --> $DIR/disallowed-positions.rs:36:8 @@ -678,10 +680,12 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:96:11 | LL | while &let 0 = 0 {} - | ^^^^^^^^^^ - | | - | expected `bool`, found `&bool` - | help: consider removing the borrow: `let 0 = 0` + | ^^^^^^^^^^ expected `bool`, found `&bool` + | +help: consider removing the borrow + | +LL | while let 0 = 0 {} + | -- error[E0614]: type `bool` cannot be dereferenced --> $DIR/disallowed-positions.rs:100:11 diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed new file mode 100644 index 00000000000..f0d8cb944cf --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed @@ -0,0 +1,37 @@ +// test for https://github.com/rust-lang/rust/issues/86940 +// run-rustfix +// edition:2018 +// check-pass +#![warn(rust_2021_prelude_collisions)] +#![allow(dead_code)] +#![allow(unused_imports)] + +struct Generic<T, U>(T, U); + +trait MyFromIter { + fn from_iter(_: i32) -> Self; +} + +impl MyFromIter for Generic<i32, i32> { + fn from_iter(x: i32) -> Self { + Self(x, x) + } +} + +impl std::iter::FromIterator<i32> for Generic<i32, i32> { + fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self { + todo!() + } +} + +fn main() { + <Generic<_, _> as MyFromIter>::from_iter(1); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) + <Generic::<i32, i32> as MyFromIter>::from_iter(1); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) + <Generic::<_, _> as MyFromIter>::from_iter(1); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) +} diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.rs b/src/test/ui/rust-2021/future-prelude-collision-generic.rs new file mode 100644 index 00000000000..19840537059 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-generic.rs @@ -0,0 +1,37 @@ +// test for https://github.com/rust-lang/rust/issues/86940 +// run-rustfix +// edition:2018 +// check-pass +#![warn(rust_2021_prelude_collisions)] +#![allow(dead_code)] +#![allow(unused_imports)] + +struct Generic<T, U>(T, U); + +trait MyFromIter { + fn from_iter(_: i32) -> Self; +} + +impl MyFromIter for Generic<i32, i32> { + fn from_iter(x: i32) -> Self { + Self(x, x) + } +} + +impl std::iter::FromIterator<i32> for Generic<i32, i32> { + fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self { + todo!() + } +} + +fn main() { + Generic::from_iter(1); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) + Generic::<i32, i32>::from_iter(1); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) + Generic::<_, _>::from_iter(1); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~| this is accepted in the current edition (Rust 2018) +} diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr new file mode 100644 index 00000000000..2c6a63df42f --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr @@ -0,0 +1,34 @@ +warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-generic.rs:28:5 + | +LL | Generic::from_iter(1); + | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter` + | +note: the lint level is defined here + --> $DIR/future-prelude-collision-generic.rs:5:9 + | +LL | #![warn(rust_2021_prelude_collisions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684> + +warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-generic.rs:31:5 + | +LL | Generic::<i32, i32>::from_iter(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter` + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684> + +warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-generic.rs:34:5 + | +LL | Generic::<_, _>::from_iter(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter` + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684> + +warning: 3 warnings emitted + diff --git a/src/test/ui/prelude2021.rs b/src/test/ui/rust-2021/prelude2021.rs index 3a9fd693228..3a9fd693228 100644 --- a/src/test/ui/prelude2021.rs +++ b/src/test/ui/rust-2021/prelude2021.rs diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index 0e40ca67351..2595cd91dc1 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -38,10 +38,12 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:17:9 | LL | f = box f; - | ^^^^^ - | | - | cyclic type of infinite size - | help: try using a conversion method: `(box f).to_string()` + | ^^^^^ cyclic type of infinite size + | +help: try using a conversion method + | +LL | f = (box f).to_string(); + | ^ ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:21:9 diff --git a/src/test/ui/static/bad-const-type.stderr b/src/test/ui/static/bad-const-type.stderr index a9c84b4b41c..dcc1ee07cbd 100644 --- a/src/test/ui/static/bad-const-type.stderr +++ b/src/test/ui/static/bad-const-type.stderr @@ -2,10 +2,9 @@ error[E0308]: mismatched types --> $DIR/bad-const-type.rs:1:20 | LL | static i: String = 10; - | ^^ + | ^^- help: try using a conversion method: `.to_string()` | | | expected struct `String`, found integer - | help: try using a conversion method: `10.to_string()` error: aborting due to previous error diff --git a/src/test/ui/str/str-lit-type-mismatch.stderr b/src/test/ui/str/str-lit-type-mismatch.stderr index 64ddfcc9b47..e8e2c4e24f5 100644 --- a/src/test/ui/str/str-lit-type-mismatch.stderr +++ b/src/test/ui/str/str-lit-type-mismatch.stderr @@ -2,40 +2,46 @@ error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:2:20 | LL | let x: &[u8] = "foo"; - | ----- ^^^^^ - | | | - | | expected slice `[u8]`, found `str` - | | help: consider adding a leading `b`: `b"foo"` + | ----- ^^^^^ expected slice `[u8]`, found `str` + | | | expected due to this | = note: expected reference `&[u8]` found reference `&'static str` +help: consider adding a leading `b` + | +LL | let x: &[u8] = b"foo"; + | ^ error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:3:23 | LL | let y: &[u8; 4] = "baaa"; - | -------- ^^^^^^ - | | | - | | expected array `[u8; 4]`, found `str` - | | help: consider adding a leading `b`: `b"baaa"` + | -------- ^^^^^^ expected array `[u8; 4]`, found `str` + | | | expected due to this | = note: expected reference `&[u8; 4]` found reference `&'static str` +help: consider adding a leading `b` + | +LL | let y: &[u8; 4] = b"baaa"; + | ^ error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:4:19 | LL | let z: &str = b"foo"; - | ---- ^^^^^^ - | | | - | | expected `str`, found array `[u8; 3]` - | | help: consider removing the leading `b`: `"foo"` + | ---- ^^^^^^ expected `str`, found array `[u8; 3]` + | | | expected due to this | = note: expected reference `&str` found reference `&'static [u8; 3]` +help: consider removing the leading `b` + | +LL | let z: &str = "foo"; + | -- error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr index 18ba7254446..ac3902dc6de 100644 --- a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr +++ b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr @@ -91,6 +91,10 @@ LL | struct X<T>(T); | ^ - ...if indirection were used here: `Box<T>` | | | this could be changed to `T: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | struct Struct5<T>{ + | -- error: aborting due to 5 previous errors diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index d5d51324e63..119599c22a6 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -5,13 +5,14 @@ LL | fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, | - this type parameter ----------------------- expected `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` because of return type LL | // We could instead use an `async` block, but this way we have no std spans. LL | x - | ^ - | | - | expected struct `Pin`, found type parameter `F` - | help: you need to pin and box this expression: `Box::pin(x)` + | ^ expected struct `Pin`, found type parameter `F` | = note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` found type parameter `F` +help: you need to pin and box this expression + | +LL | Box::pin(x) + | ^^^^^^^^^ ^ error[E0308]: mismatched types --> $DIR/expected-boxed-future-isnt-pinned.rs:18:5 @@ -31,14 +32,15 @@ error[E0308]: mismatched types LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> { | - this type parameter LL | Pin::new(x) - | ^ - | | - | expected struct `Box`, found type parameter `F` - | help: store this in the heap by calling `Box::new`: `Box::new(x)` + | ^ expected struct `Box`, found type parameter `F` | = note: expected struct `Box<dyn Future<Output = i32> + Send>` found type parameter `F` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +help: store this in the heap by calling `Box::new` + | +LL | Pin::new(Box::new(x)) + | ^^^^^^^^^ ^ error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned --> $DIR/expected-boxed-future-isnt-pinned.rs:22:5 diff --git a/src/test/ui/suggestions/for-i-in-vec.fixed b/src/test/ui/suggestions/for-i-in-vec.fixed index ec7358bd08a..223ddf0f0ad 100644 --- a/src/test/ui/suggestions/for-i-in-vec.fixed +++ b/src/test/ui/suggestions/for-i-in-vec.fixed @@ -3,12 +3,15 @@ struct Foo { v: Vec<u32>, + h: std::collections::HashMap<i32, i32>, } impl Foo { fn bar(&self) { for _ in &self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference } + for _ in &self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference + } } } diff --git a/src/test/ui/suggestions/for-i-in-vec.rs b/src/test/ui/suggestions/for-i-in-vec.rs index 304fe8cc81f..7942698cc8e 100644 --- a/src/test/ui/suggestions/for-i-in-vec.rs +++ b/src/test/ui/suggestions/for-i-in-vec.rs @@ -3,12 +3,15 @@ struct Foo { v: Vec<u32>, + h: std::collections::HashMap<i32, i32>, } impl Foo { fn bar(&self) { for _ in self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference } + for _ in self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference + } } } diff --git a/src/test/ui/suggestions/for-i-in-vec.stderr b/src/test/ui/suggestions/for-i-in-vec.stderr index 48f3f423ac6..011fdf34c28 100644 --- a/src/test/ui/suggestions/for-i-in-vec.stderr +++ b/src/test/ui/suggestions/for-i-in-vec.stderr @@ -1,12 +1,25 @@ error[E0507]: cannot move out of `self.v` which is behind a shared reference - --> $DIR/for-i-in-vec.rs:10:18 + --> $DIR/for-i-in-vec.rs:11:18 | LL | for _ in self.v { - | ^^^^^^ - | | - | move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait - | help: consider iterating over a slice of the `Vec<_>`'s content: `&self.v` + | ^^^^^^ move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait + | +help: consider iterating over a slice of the `Vec<u32>`'s content + | +LL | for _ in &self.v { + | ^ + +error[E0507]: cannot move out of `self.h` which is behind a shared reference + --> $DIR/for-i-in-vec.rs:13:18 + | +LL | for _ in self.h { + | ^^^^^^ move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait + | +help: consider iterating over a slice of the `HashMap<i32, i32>`'s content + | +LL | for _ in &self.h { + | ^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/suggestions/format-borrow.stderr b/src/test/ui/suggestions/format-borrow.stderr index 0881b024712..15cb845a06d 100644 --- a/src/test/ui/suggestions/format-borrow.stderr +++ b/src/test/ui/suggestions/format-borrow.stderr @@ -2,41 +2,53 @@ error[E0308]: mismatched types --> $DIR/format-borrow.rs:2:21 | LL | let a: String = &String::from("a"); - | ------ ^^^^^^^^^^^^^^^^^^ - | | | - | | expected struct `String`, found `&String` - | | help: consider removing the borrow: `String::from("a")` + | ------ ^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String` + | | | expected due to this + | +help: consider removing the borrow + | +LL | let a: String = String::from("a"); + | -- error[E0308]: mismatched types --> $DIR/format-borrow.rs:4:21 | LL | let b: String = &format!("b"); - | ------ ^^^^^^^^^^^^^ - | | | - | | expected struct `String`, found `&String` - | | help: consider removing the borrow: `format!("b")` + | ------ ^^^^^^^^^^^^^ expected struct `String`, found `&String` + | | | expected due to this + | +help: consider removing the borrow + | +LL | let b: String = format!("b"); + | -- error[E0308]: mismatched types --> $DIR/format-borrow.rs:6:21 | LL | let c: String = &mut format!("c"); - | ------ ^^^^^^^^^^^^^^^^^ - | | | - | | expected struct `String`, found `&mut String` - | | help: consider removing the borrow: `format!("c")` + | ------ ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String` + | | | expected due to this + | +help: consider removing the borrow + | +LL | let c: String = format!("c"); + | -- error[E0308]: mismatched types --> $DIR/format-borrow.rs:8:21 | LL | let d: String = &mut (format!("d")); - | ------ ^^^^^^^^^^^^^^^^^^^ - | | | - | | expected struct `String`, found `&mut String` - | | help: consider removing the borrow: `format!("d")` + | ------ ^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String` + | | | expected due to this + | +help: consider removing the borrow + | +LL | let d: String = format!("d")); + | -- error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/issue-52820.stderr b/src/test/ui/suggestions/issue-52820.stderr index ece784de3e2..62c04584d3c 100644 --- a/src/test/ui/suggestions/issue-52820.stderr +++ b/src/test/ui/suggestions/issue-52820.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/issue-52820.rs:9:9 | LL | guts, - | ^^^^ - | | - | expected struct `String`, found `&str` - | help: try using a conversion method: `guts: guts.to_string()` + | ^^^^ expected struct `String`, found `&str` + | +help: try using a conversion method + | +LL | guts: guts.to_string(), + | ^^^^^ ^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/issue-52820.rs:10:17 diff --git a/src/test/ui/suggestions/issue-59819.stderr b/src/test/ui/suggestions/issue-59819.stderr index 43e0016ee20..ac9b6d975f4 100644 --- a/src/test/ui/suggestions/issue-59819.stderr +++ b/src/test/ui/suggestions/issue-59819.stderr @@ -2,30 +2,35 @@ error[E0308]: mismatched types --> $DIR/issue-59819.rs:28:18 | LL | let y: i32 = x; - | --- ^ - | | | - | | expected `i32`, found struct `Foo` - | | help: consider dereferencing the type: `*x` + | --- ^ expected `i32`, found struct `Foo` + | | | expected due to this + | +help: consider dereferencing the type + | +LL | let y: i32 = *x; + | ^ error[E0308]: mismatched types --> $DIR/issue-59819.rs:30:18 | LL | let b: i32 = a; - | --- ^ - | | | - | | expected `i32`, found `&{integer}` - | | help: consider dereferencing the borrow: `*a` + | --- ^ expected `i32`, found `&{integer}` + | | | expected due to this + | +help: consider dereferencing the borrow + | +LL | let b: i32 = *a; + | ^ error[E0308]: mismatched types --> $DIR/issue-59819.rs:34:21 | LL | let g: String = f; - | ------ ^ + | ------ ^- help: try using a conversion method: `.to_string()` | | | | | expected struct `String`, found struct `Bar` - | | help: try using a conversion method: `f.to_string()` | expected due to this error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/issue-82361.stderr b/src/test/ui/suggestions/issue-82361.stderr index 4c78293ebb7..91b380e4e0d 100644 --- a/src/test/ui/suggestions/issue-82361.stderr +++ b/src/test/ui/suggestions/issue-82361.stderr @@ -6,12 +6,14 @@ LL | | a | | - expected because of this LL | | } else { LL | | b - | | ^ - | | | - | | expected `usize`, found `&usize` - | | help: consider dereferencing the borrow: `*b` + | | ^ expected `usize`, found `&usize` LL | | }; | |_____- `if` and `else` have incompatible types + | +help: consider dereferencing the borrow + | +LL | *b + | ^ error[E0308]: `if` and `else` have incompatible types --> $DIR/issue-82361.rs:16:9 @@ -21,12 +23,14 @@ LL | | 1 | | - expected because of this LL | | } else { LL | | &1 - | | ^^ - | | | - | | expected integer, found `&{integer}` - | | help: consider removing the borrow: `1` + | | ^^ expected integer, found `&{integer}` LL | | }; | |_____- `if` and `else` have incompatible types + | +help: consider removing the borrow + | +LL | 1 + | -- error[E0308]: `if` and `else` have incompatible types --> $DIR/issue-82361.rs:22:9 @@ -36,12 +40,14 @@ LL | | 1 | | - expected because of this LL | | } else { LL | | &mut 1 - | | ^^^^^^ - | | | - | | expected integer, found `&mut {integer}` - | | help: consider removing the borrow: `1` + | | ^^^^^^ expected integer, found `&mut {integer}` LL | | }; | |_____- `if` and `else` have incompatible types + | +help: consider removing the borrow + | +LL | 1 + | -- error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/issue-83943.stderr b/src/test/ui/suggestions/issue-83943.stderr index a26700ea3c7..885106e8429 100644 --- a/src/test/ui/suggestions/issue-83943.stderr +++ b/src/test/ui/suggestions/issue-83943.stderr @@ -6,10 +6,9 @@ LL | | "A".to_string() | | --------------- expected because of this LL | | } else { LL | | "B" - | | ^^^ + | | ^^^- help: try using a conversion method: `.to_string()` | | | | | expected struct `String`, found `&str` - | | help: try using a conversion method: `"B".to_string()` LL | | }; | |_____- `if` and `else` have incompatible types diff --git a/src/test/ui/suggestions/mut-ref-reassignment.stderr b/src/test/ui/suggestions/mut-ref-reassignment.stderr index 327bbee1968..13b6182c0f5 100644 --- a/src/test/ui/suggestions/mut-ref-reassignment.stderr +++ b/src/test/ui/suggestions/mut-ref-reassignment.stderr @@ -9,7 +9,7 @@ LL | opt = None; help: consider dereferencing here to assign to the mutable borrowed piece of memory | LL | *opt = None; - | ^^^^ + | ^ error[E0308]: mismatched types --> $DIR/mut-ref-reassignment.rs:6:11 @@ -31,7 +31,7 @@ LL | opt = Some(String::new()) help: consider dereferencing here to assign to the mutable borrowed piece of memory | LL | *opt = Some(String::new()) - | ^^^^ + | ^ error[E0308]: mismatched types --> $DIR/mut-ref-reassignment.rs:14:11 diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr index c00a0f1700b..94766530091 100644 --- a/src/test/ui/suggestions/option-content-move.stderr +++ b/src/test/ui/suggestions/option-content-move.stderr @@ -2,19 +2,23 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc --> $DIR/option-content-move.rs:11:20 | LL | if selection.1.unwrap().contains(selection.0) { - | ^^^^^^^^^^^ - | | - | move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait - | help: consider borrowing the `Option`'s content: `selection.1.as_ref()` + | ^^^^^^^^^^^ move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait + | +help: consider borrowing the `Option`'s content + | +LL | if selection.1.as_ref().unwrap().contains(selection.0) { + | ^^^^^^^^^ error[E0507]: cannot move out of `selection.1` which is behind a shared reference --> $DIR/option-content-move.rs:29:20 | LL | if selection.1.unwrap().contains(selection.0) { - | ^^^^^^^^^^^ - | | - | move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait - | help: consider borrowing the `Result`'s content: `selection.1.as_ref()` + | ^^^^^^^^^^^ move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait + | +help: consider borrowing the `Result`'s content + | +LL | if selection.1.as_ref().unwrap().contains(selection.0) { + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/raw-byte-string-prefix.rs b/src/test/ui/suggestions/raw-byte-string-prefix.rs new file mode 100644 index 00000000000..576561c315c --- /dev/null +++ b/src/test/ui/suggestions/raw-byte-string-prefix.rs @@ -0,0 +1,10 @@ +// `br` and `rb` are easy to confuse; check that we issue a suggestion to help. + +// edition:2021 + +fn main() { + rb"abc"; + //~^ ERROR: prefix `rb` is unknown + //~| HELP: use `br` for a raw byte string + //~| ERROR: expected one of +} diff --git a/src/test/ui/suggestions/raw-byte-string-prefix.stderr b/src/test/ui/suggestions/raw-byte-string-prefix.stderr new file mode 100644 index 00000000000..1498f5ac935 --- /dev/null +++ b/src/test/ui/suggestions/raw-byte-string-prefix.stderr @@ -0,0 +1,20 @@ +error: prefix `rb` is unknown + --> $DIR/raw-byte-string-prefix.rs:6:5 + | +LL | rb"abc"; + | ^^ unknown prefix + | + = note: prefixed identifiers and literals are reserved since Rust 2021 +help: use `br` for a raw byte string + | +LL | br"abc"; + | ^^ + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"abc"` + --> $DIR/raw-byte-string-prefix.rs:6:7 + | +LL | rb"abc"; + | ^^^^^ expected one of 8 possible tokens + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/trait-bounds/unsized-bound.rs b/src/test/ui/trait-bounds/unsized-bound.rs new file mode 100644 index 00000000000..035b8ef1bde --- /dev/null +++ b/src/test/ui/trait-bounds/unsized-bound.rs @@ -0,0 +1,32 @@ +trait Trait<A> {} +impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} +//~^ ERROR E0277 +//~| ERROR E0277 +impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} +//~^ ERROR E0277 +//~| ERROR E0277 +//~| ERROR E0277 +trait Trait2<A> {} +impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {} +//~^ ERROR E0277 +//~| ERROR E0277 +trait Trait3<A> {} +impl<A> Trait3<A> for A where A: ?Sized {} +//~^ ERROR E0277 +trait Trait4<A> {} +impl<A: ?Sized> Trait4<A> for A {} +//~^ ERROR E0277 +trait Trait5<A, B> {} +impl<X, Y> Trait5<X, Y> for X where X: ?Sized {} +//~^ ERROR E0277 +trait Trait6<A, B> {} +impl<X: ?Sized, Y> Trait6<X, Y> for X {} +//~^ ERROR E0277 +trait Trait7<A, B> {} +impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {} +//~^ ERROR E0277 +trait Trait8<A, B> {} +impl<X, Y: ?Sized> Trait8<X, Y> for X {} +//~^ ERROR E0277 + +fn main() {} diff --git a/src/test/ui/trait-bounds/unsized-bound.stderr b/src/test/ui/trait-bounds/unsized-bound.stderr new file mode 100644 index 00000000000..30163ab7978 --- /dev/null +++ b/src/test/ui/trait-bounds/unsized-bound.stderr @@ -0,0 +1,234 @@ +error[E0277]: the size for values of type `B` cannot be known at compilation time + --> $DIR/unsized-bound.rs:2:12 + | +LL | trait Trait<A> {} + | - required by this bound in `Trait` +LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} + | - ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = note: required because it appears within the type `(A, B)` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait<A: ?Sized> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `A` cannot be known at compilation time + --> $DIR/unsized-bound.rs:2:30 + | +LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} + | - ^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {} + | -- + +error[E0277]: the size for values of type `C` cannot be known at compilation time + --> $DIR/unsized-bound.rs:5:31 + | +LL | trait Trait<A> {} + | - required by this bound in `Trait` +... +LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} + | - ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = note: required because it appears within the type `(A, B, C)` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A, B: ?Sized, C> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait<A: ?Sized> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `A` cannot be known at compilation time + --> $DIR/unsized-bound.rs:5:52 + | +LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} + | - ^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {} + | -- + +error[E0277]: the size for values of type `B` cannot be known at compilation time + --> $DIR/unsized-bound.rs:5:52 + | +LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} + | - ^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} + | -- + +error[E0277]: the size for values of type `B` cannot be known at compilation time + --> $DIR/unsized-bound.rs:10:28 + | +LL | trait Trait2<A> {} + | - required by this bound in `Trait2` +LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {} + | - ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = note: required because it appears within the type `(A, B)` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A: ?Sized, B> Trait2<(A, B)> for (A, B) {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait2<A: ?Sized> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `A` cannot be known at compilation time + --> $DIR/unsized-bound.rs:10:47 + | +LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {} + | - ^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {} + | -- + +error[E0277]: the size for values of type `A` cannot be known at compilation time + --> $DIR/unsized-bound.rs:14:9 + | +LL | trait Trait3<A> {} + | - required by this bound in `Trait3` +LL | impl<A> Trait3<A> for A where A: ?Sized {} + | - ^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A> Trait3<A> for A {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait3<A: ?Sized> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `A` cannot be known at compilation time + --> $DIR/unsized-bound.rs:17:17 + | +LL | trait Trait4<A> {} + | - required by this bound in `Trait4` +LL | impl<A: ?Sized> Trait4<A> for A {} + | - ^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<A> Trait4<A> for A {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait4<A: ?Sized> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized-bound.rs:20:12 + | +LL | trait Trait5<A, B> {} + | - required by this bound in `Trait5` +LL | impl<X, Y> Trait5<X, Y> for X where X: ?Sized {} + | - ^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X, Y> Trait5<X, Y> for X {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait5<A: ?Sized, B> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized-bound.rs:23:20 + | +LL | trait Trait6<A, B> {} + | - required by this bound in `Trait6` +LL | impl<X: ?Sized, Y> Trait6<X, Y> for X {} + | - ^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X, Y> Trait6<X, Y> for X {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait6<A: ?Sized, B> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `Y` cannot be known at compilation time + --> $DIR/unsized-bound.rs:26:12 + | +LL | trait Trait7<A, B> {} + | - required by this bound in `Trait7` +LL | impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {} + | - ^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X, Y> Trait7<X, Y> for X {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait7<A, B: ?Sized> {} + | ^^^^^^^^ + +error[E0277]: the size for values of type `Y` cannot be known at compilation time + --> $DIR/unsized-bound.rs:29:20 + | +LL | trait Trait8<A, B> {} + | - required by this bound in `Trait8` +LL | impl<X, Y: ?Sized> Trait8<X, Y> for X {} + | - ^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X, Y> Trait8<X, Y> for X {} + | -- +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Trait8<A, B: ?Sized> {} + | ^^^^^^^^ + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/suggest-where-clause.stderr b/src/test/ui/traits/suggest-where-clause.stderr index f15e7e35839..47f287807d4 100644 --- a/src/test/ui/traits/suggest-where-clause.stderr +++ b/src/test/ui/traits/suggest-where-clause.stderr @@ -11,6 +11,11 @@ LL | mem::size_of::<U>(); | LL | pub const fn size_of<T>() -> usize { | - required by this bound in `std::mem::size_of` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn check<T: Iterator, U>() { + | -- error[E0277]: the size for values of type `U` cannot be known at compilation time --> $DIR/suggest-where-clause.rs:10:5 @@ -31,6 +36,10 @@ note: required because it appears within the type `Misc<U>` | LL | struct Misc<T:?Sized>(T); | ^^^^ +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn check<T: Iterator, U>() { + | -- error[E0277]: the trait bound `u64: From<T>` is not satisfied --> $DIR/suggest-where-clause.rs:15:5 diff --git a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs new file mode 100644 index 00000000000..277d9eabe4f --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax, trait_upcasting)] +#![allow(incomplete_features)] + +struct Test { + func: Box<dyn FnMut() + 'static>, +} + +fn main() { + let closure: Box<dyn Fn() + 'static> = Box::new(|| ()); + let mut test = box Test { func: closure }; + (test.func)(); +} diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs new file mode 100644 index 00000000000..6986ad62172 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs @@ -0,0 +1,22 @@ +// check-fail +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Bar<T> { + fn bar(&self, _: T) {} +} + +trait Foo : Bar<i32> + Bar<u32> { + fn foo(&self, _: ()) {} +} + +struct S; + +impl Bar<i32> for S {} +impl Bar<u32> for S {} +impl Foo for S {} + +fn main() { + let s: &dyn Foo = &S; + let t: &dyn Bar<_> = s; //~ ERROR mismatched types +} diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr new file mode 100644 index 00000000000..e9670ad7def --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/multiple-occurence-ambiguousity.rs:21:26 + | +LL | let t: &dyn Bar<_> = s; + | ----------- ^ expected trait `Bar`, found trait `Foo` + | | + | expected due to this + | + = note: expected reference `&dyn Bar<_>` + found reference `&dyn Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs new file mode 100644 index 00000000000..1a0e5072843 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs @@ -0,0 +1,33 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo: Bar<i32> + Bar<u32> {} +trait Bar<T> { + fn bar(&self) -> Option<T> { + None + } +} + +fn test_specific(x: &dyn Foo) { + let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo: Bar<i32>` is not satisfied + let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied +} + +fn test_unknown_version(x: &dyn Foo) { + let _ = x as &dyn Bar<_>; // Ambiguous + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied +} + +fn test_infer_version(x: &dyn Foo) { + let a = x as &dyn Bar<_>; // FIXME: OK, eventually + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied + let _: Option<u32> = a.bar(); +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr new file mode 100644 index 00000000000..6aaa8a4a904 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr @@ -0,0 +1,80 @@ +error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<i32>` + --> $DIR/type-checking-test-1.rs:12:13 + | +LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually + | ^^^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually + | ^ + +error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>` + --> $DIR/type-checking-test-1.rs:15:13 + | +LL | let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually + | ^^^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let _ = &x as &dyn Bar<u32>; // FIXME: OK, eventually + | ^ + +error[E0277]: the trait bound `&dyn Foo: Bar<i32>` is not satisfied + --> $DIR/type-checking-test-1.rs:12:13 + | +LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually + | ^ the trait `Bar<i32>` is not implemented for `&dyn Foo` + | + = note: required for the cast to the object type `dyn Bar<i32>` + +error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied + --> $DIR/type-checking-test-1.rs:15:13 + | +LL | let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually + | ^ the trait `Bar<u32>` is not implemented for `&dyn Foo` + | + = note: required for the cast to the object type `dyn Bar<u32>` + +error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` + --> $DIR/type-checking-test-1.rs:21:13 + | +LL | let _ = x as &dyn Bar<_>; // Ambiguous + | ^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let _ = &x as &dyn Bar<_>; // Ambiguous + | ^ + +error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied + --> $DIR/type-checking-test-1.rs:21:13 + | +LL | let _ = x as &dyn Bar<_>; // Ambiguous + | ^ the trait `Bar<_>` is not implemented for `&dyn Foo` + | + = note: required for the cast to the object type `dyn Bar<_>` + +error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>` + --> $DIR/type-checking-test-1.rs:27:13 + | +LL | let a = x as &dyn Bar<_>; // FIXME: OK, eventually + | ^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let a = &x as &dyn Bar<_>; // FIXME: OK, eventually + | ^ + +error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied + --> $DIR/type-checking-test-1.rs:27:13 + | +LL | let a = x as &dyn Bar<_>; // FIXME: OK, eventually + | ^ the trait `Bar<u32>` is not implemented for `&dyn Foo` + | + = note: required for the cast to the object type `dyn Bar<u32>` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0277, E0605. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs new file mode 100644 index 00000000000..326df74211e --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs @@ -0,0 +1,34 @@ +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo<T>: Bar<i32> + Bar<T> {} +trait Bar<T> { + fn bar(&self) -> Option<T> { + None + } +} + +fn test_specific(x: &dyn Foo<i32>) { + let _ = x as &dyn Bar<i32>; // OK +} + +fn test_specific2(x: &dyn Foo<u32>) { + let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied +} + +fn test_specific3(x: &dyn Foo<i32>) { + let _ = x as &dyn Bar<u32>; // Error + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied +} + +fn test_infer_arg(x: &dyn Foo<u32>) { + let a = x as &dyn Bar<_>; // Ambiguous + //~^ ERROR non-primitive cast + //~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied + let _ = a.bar(); +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr new file mode 100644 index 00000000000..a38f8a14604 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr @@ -0,0 +1,61 @@ +error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<i32>` + --> $DIR/type-checking-test-2.rs:16:13 + | +LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually + | ^^^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually + | ^ + +error[E0277]: the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied + --> $DIR/type-checking-test-2.rs:16:13 + | +LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually + | ^ the trait `Bar<i32>` is not implemented for `&dyn Foo<u32>` + | + = note: required for the cast to the object type `dyn Bar<i32>` + +error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>` + --> $DIR/type-checking-test-2.rs:22:13 + | +LL | let _ = x as &dyn Bar<u32>; // Error + | ^^^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let _ = &x as &dyn Bar<u32>; // Error + | ^ + +error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied + --> $DIR/type-checking-test-2.rs:22:13 + | +LL | let _ = x as &dyn Bar<u32>; // Error + | ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>` + | + = note: required for the cast to the object type `dyn Bar<u32>` + +error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>` + --> $DIR/type-checking-test-2.rs:28:13 + | +LL | let a = x as &dyn Bar<_>; // Ambiguous + | ^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | let a = &x as &dyn Bar<_>; // Ambiguous + | ^ + +error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied + --> $DIR/type-checking-test-2.rs:28:13 + | +LL | let a = x as &dyn Bar<_>; // Ambiguous + | ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>` + | + = note: required for the cast to the object type `dyn Bar<_>` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0277, E0605. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs new file mode 100644 index 00000000000..49c24e404dc --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs @@ -0,0 +1,22 @@ +// ignore-compare-mode-nll +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo<'a>: Bar<'a> {} +trait Bar<'a> {} + +fn test_correct(x: &dyn Foo<'static>) { + let _ = x as &dyn Bar<'static>; +} + +fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + let _ = x as &dyn Bar<'a>; // Error + //~^ ERROR mismatched types +} + +fn test_wrong2<'a>(x: &dyn Foo<'a>) { + let _ = x as &dyn Bar<'static>; // Error + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr new file mode 100644 index 00000000000..593ee0a3430 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/type-checking-test-3.rs:13:13 + | +LL | let _ = x as &dyn Bar<'a>; // Error + | ^ lifetime mismatch + | + = note: expected trait object `dyn Bar<'a>` + found trait object `dyn Bar<'static>` +note: the lifetime `'a` as defined on the function body at 12:16... + --> $DIR/type-checking-test-3.rs:12:16 + | +LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error[E0308]: mismatched types + --> $DIR/type-checking-test-3.rs:18:13 + | +LL | let _ = x as &dyn Bar<'static>; // Error + | ^ lifetime mismatch + | + = note: expected trait object `dyn Bar<'static>` + found trait object `dyn Bar<'a>` +note: the lifetime `'a` as defined on the function body at 17:16... + --> $DIR/type-checking-test-3.rs:17:16 + | +LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs new file mode 100644 index 00000000000..9b27fd46f7a --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -0,0 +1,32 @@ +// ignore-compare-mode-nll +#![feature(trait_upcasting)] +#![allow(incomplete_features)] + +trait Foo<'a>: Bar<'a, 'a> {} +trait Bar<'a, 'b> { + fn get_b(&self) -> Option<&'a u32> { + None + } +} + +fn test_correct(x: &dyn Foo<'static>) { + let _ = x as &dyn Bar<'static, 'static>; +} + +fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + let _ = x as &dyn Bar<'static, 'a>; // Error + //~^ ERROR mismatched types +} + +fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { + let _ = x as &dyn Bar<'a, 'static>; // Error + //~^ ERROR mismatched types +} + +fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + let y = x as &dyn Bar<'_, '_>; + //~^ ERROR `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement + y.get_b() // ERROR +} + +fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr new file mode 100644 index 00000000000..811e524eda7 --- /dev/null +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -0,0 +1,47 @@ +error[E0308]: mismatched types + --> $DIR/type-checking-test-4.rs:17:13 + | +LL | let _ = x as &dyn Bar<'static, 'a>; // Error + | ^ lifetime mismatch + | + = note: expected trait object `dyn Bar<'static, 'a>` + found trait object `dyn Bar<'static, 'static>` +note: the lifetime `'a` as defined on the function body at 16:16... + --> $DIR/type-checking-test-4.rs:16:16 + | +LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error[E0308]: mismatched types + --> $DIR/type-checking-test-4.rs:22:13 + | +LL | let _ = x as &dyn Bar<'a, 'static>; // Error + | ^ lifetime mismatch + | + = note: expected trait object `dyn Bar<'a, 'static>` + found trait object `dyn Bar<'static, 'static>` +note: the lifetime `'a` as defined on the function body at 21:16... + --> $DIR/type-checking-test-4.rs:21:16 + | +LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { + | ^^ + = note: ...does not necessarily outlive the static lifetime + +error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/type-checking-test-4.rs:27:27 + | +LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ------------ this data with lifetime `'a`... +LL | let y = x as &dyn Bar<'_, '_>; + | - ^^ + | | + | ...is captured here... +LL | +LL | y.get_b() // ERROR + | --------- ...and is required to live as long as `'static` here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0759. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.rs b/src/test/ui/type-alias-impl-trait/issue-74280.rs new file mode 100644 index 00000000000..d5b90a49b05 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74280.rs @@ -0,0 +1,13 @@ +// Regression test for #74280. + +#![feature(type_alias_impl_trait)] + +type Test = impl Copy; + +fn test() -> Test { + let y = || -> Test { () }; + //~^ ERROR: concrete type differs from previous defining opaque type use + 7 +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr new file mode 100644 index 00000000000..79c7df788f4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/issue-74280.rs:8:13 + | +LL | let y = || -> Test { () }; + | ^^^^^^^^^^^^^^^^^ expected `i32`, got `()` + | +note: previous use here + --> $DIR/issue-74280.rs:7:1 + | +LL | fn test() -> Test { + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.rs b/src/test/ui/type-alias-impl-trait/issue-77179.rs new file mode 100644 index 00000000000..31c45a2093a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-77179.rs @@ -0,0 +1,14 @@ +// Regression test for #77179. + +#![feature(type_alias_impl_trait)] + +type Pointer<T> = impl std::ops::Deref<Target=T>; + +fn test() -> Pointer<_> { + //~^ ERROR: the type placeholder `_` is not allowed within types + Box::new(1) +} + +fn main() { + test(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.stderr b/src/test/ui/type-alias-impl-trait/issue-77179.stderr new file mode 100644 index 00000000000..593aeeacb83 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-77179.stderr @@ -0,0 +1,12 @@ +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-77179.rs:7:22 + | +LL | fn test() -> Pointer<_> { + | --------^- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `Box<i32>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/conversion-methods.stderr b/src/test/ui/typeck/conversion-methods.stderr index 4f47e1fd0ff..15848c66c15 100644 --- a/src/test/ui/typeck/conversion-methods.stderr +++ b/src/test/ui/typeck/conversion-methods.stderr @@ -2,44 +2,43 @@ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:5:41 | LL | let _tis_an_instants_play: String = "'Tis a fond Ambush—"; - | ------ ^^^^^^^^^^^^^^^^^^^^^ + | ------ ^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` | | | | | expected struct `String`, found `&str` - | | help: try using a conversion method: `"'Tis a fond Ambush—".to_string()` | expected due to this error[E0308]: mismatched types --> $DIR/conversion-methods.rs:6:40 | LL | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise"); - | ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_path_buf()` | | | | | expected struct `PathBuf`, found `&Path` - | | help: try using a conversion method: `Path::new("/ern/her/own/surprise").to_path_buf()` | expected due to this error[E0308]: mismatched types --> $DIR/conversion-methods.rs:9:40 | LL | let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here - | ------ ^ + | ------ ^- help: try using a conversion method: `.to_string()` | | | | | expected struct `String`, found integer - | | help: try using a conversion method: `2.to_string()` | expected due to this error[E0308]: mismatched types --> $DIR/conversion-methods.rs:12:47 | LL | let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; - | ---------- ^^^^^^^^^^ - | | | - | | expected struct `Vec`, found `&[{integer}; 3]` - | | help: try using a conversion method: `(&[1, 2, 3]).to_vec()` + | ---------- ^^^^^^^^^^ expected struct `Vec`, found `&[{integer}; 3]` + | | | expected due to this | = note: expected struct `Vec<usize>` found reference `&[{integer}; 3]` +help: try using a conversion method + | +LL | let _prove_piercing_earnest: Vec<usize> = (&[1, 2, 3]).to_vec(); + | ^ ^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr index b916bbe8ad1..ef86c624e9b 100644 --- a/src/test/ui/union/union-sized-field.stderr +++ b/src/test/ui/union/union-sized-field.stderr @@ -8,6 +8,10 @@ LL | value: T, | = note: no field of a union may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | union Foo<T> { + | -- help: borrowed types always have a statically known size | LL | value: &T, @@ -27,6 +31,10 @@ LL | value: T, | = note: only the last field of a struct may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | struct Foo2<T> { + | -- help: borrowed types always have a statically known size | LL | value: &T, @@ -46,6 +54,10 @@ LL | Value(T), | = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | enum Foo3<T> { + | -- help: borrowed types always have a statically known size | LL | Value(&T), diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr index 19978ae24ca..35bba1c103a 100644 --- a/src/test/ui/unsized/unsized-bare-typaram.stderr +++ b/src/test/ui/unsized/unsized-bare-typaram.stderr @@ -7,6 +7,11 @@ LL | fn foo<T: ?Sized>() { bar::<T>() } | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` + | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn foo<T>() { bar::<T>() } + | -- error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr index 601db7d1cd9..f66ce2af304 100644 --- a/src/test/ui/unsized/unsized-enum.stderr +++ b/src/test/ui/unsized/unsized-enum.stderr @@ -16,6 +16,10 @@ LL | enum Foo<U> { FooSome(U), FooNone } | ^ - ...if indirection were used here: `Box<U>` | | | this could be changed to `U: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn foo2<T>() { not_sized::<Foo<T>>() } + | -- error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-enum2.stderr b/src/test/ui/unsized/unsized-enum2.stderr index 1b6c8585815..b9a03d904af 100644 --- a/src/test/ui/unsized/unsized-enum2.stderr +++ b/src/test/ui/unsized/unsized-enum2.stderr @@ -9,6 +9,10 @@ LL | VA(W), | = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | enum E<W, X: ?Sized, Y: ?Sized, Z: ?Sized> { + | -- help: borrowed types always have a statically known size | LL | VA(&W), @@ -29,6 +33,10 @@ LL | VB{x: X}, | = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | enum E<W: ?Sized, X, Y: ?Sized, Z: ?Sized> { + | -- help: borrowed types always have a statically known size | LL | VB{x: &X}, @@ -49,6 +57,10 @@ LL | VC(isize, Y), | = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | enum E<W: ?Sized, X: ?Sized, Y, Z: ?Sized> { + | -- help: borrowed types always have a statically known size | LL | VC(isize, &Y), @@ -69,6 +81,10 @@ LL | VD{u: isize, x: Z}, | = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z> { + | -- help: borrowed types always have a statically known size | LL | VD{u: isize, x: &Z}, diff --git a/src/test/ui/unsized/unsized-fn-arg.fixed b/src/test/ui/unsized/unsized-fn-arg.fixed index 2c686c6c2b2..fd9b159a481 100644 --- a/src/test/ui/unsized/unsized-fn-arg.fixed +++ b/src/test/ui/unsized/unsized-fn-arg.fixed @@ -2,5 +2,5 @@ #![crate_type="lib"] #![allow(unused)] -fn f<T: ?Sized>(t: &T) {} +fn f<T>(t: &T) {} //~^ ERROR the size for values of type `T` cannot be known at compilation time diff --git a/src/test/ui/unsized/unsized-fn-arg.stderr b/src/test/ui/unsized/unsized-fn-arg.stderr index 6b802ddf542..acb8a598d2c 100644 --- a/src/test/ui/unsized/unsized-fn-arg.stderr +++ b/src/test/ui/unsized/unsized-fn-arg.stderr @@ -7,6 +7,10 @@ LL | fn f<T: ?Sized>(t: T) {} | this type parameter needs to be `std::marker::Sized` | = help: unsized fn params are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f<T>(t: T) {} + | -- help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn f<T: ?Sized>(t: &T) {} diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr index 9d072eda4e8..99f75d8c5b3 100644 --- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -16,6 +16,10 @@ LL | struct S5<Y>(Y); | ^ - ...if indirection were used here: `Box<Y>` | | | this could be changed to `Y: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X> S5<X> { + | -- error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index e38375bff46..71693b8130d 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -16,6 +16,10 @@ LL | struct Foo<T> { data: T } | ^ - ...if indirection were used here: `Box<T>` | | | this could be changed to `T: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn foo2<T>() { not_sized::<Foo<T>>() } + | -- error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/unsized-struct.rs:13:24 @@ -33,6 +37,10 @@ note: required because it appears within the type `Bar<T>` | LL | struct Bar<T: ?Sized> { data: T } | ^^^ +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn bar2<T>() { is_sized::<Bar<T>>() } + | -- error: aborting due to 2 previous errors diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr index aef0d0cbb83..201dbf85d20 100644 --- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr @@ -16,6 +16,10 @@ LL | struct S5<Y>(Y); | ^ - ...if indirection were used here: `Box<Y>` | | | this could be changed to `Y: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X> T3<X> for S5<X> { + | -- error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr index f48d4ef9f14..f8f8aa8e3e9 100644 --- a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -9,6 +9,10 @@ LL | impl<X: ?Sized> T2<X> for S4<X> { | | | this type parameter needs to be `std::marker::Sized` | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X> T2<X> for S4<X> { + | -- help: consider relaxing the implicit `Sized` restriction | LL | trait T2<Z: ?Sized> { diff --git a/src/test/ui/unsized/unsized3.stderr b/src/test/ui/unsized/unsized3.stderr index bd36008aca0..10ddfe34eac 100644 --- a/src/test/ui/unsized/unsized3.stderr +++ b/src/test/ui/unsized/unsized3.stderr @@ -9,6 +9,10 @@ LL | f2::<X>(x); LL | fn f2<X>(x: &X) { | - required by this bound in `f2` | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f1<X>(x: &X) { + | -- help: consider relaxing the implicit `Sized` restriction | LL | fn f2<X: ?Sized>(x: &X) { @@ -25,6 +29,10 @@ LL | f4::<X>(x); LL | fn f4<X: T>(x: &X) { | - required by this bound in `f4` | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f3<X: T>(x: &X) { + | -- help: consider relaxing the implicit `Sized` restriction | LL | fn f4<X: T + ?Sized>(x: &X) { @@ -46,6 +54,10 @@ note: required because it appears within the type `S<X>` | LL | struct S<X: ?Sized> { | ^ +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f8<X>(x1: &S<X>, x2: &S<X>) { + | -- help: consider relaxing the implicit `Sized` restriction | LL | fn f5<Y: ?Sized>(x: &Y) {} @@ -65,6 +77,10 @@ note: required because it appears within the type `S<X>` LL | struct S<X: ?Sized> { | ^ = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f9<X>(x1: Box<S<X>>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:45:9 @@ -81,6 +97,10 @@ LL | struct S<X: ?Sized> { | ^ = note: required because it appears within the type `({integer}, S<X>)` = note: tuples must have a statically known size to be initialized +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f10<X>(x1: Box<S<X>>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:45:8 @@ -99,6 +119,10 @@ note: required because it appears within the type `S<X>` LL | struct S<X: ?Sized> { | ^ = note: required because it appears within the type `({integer}, S<X>)` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f10<X>(x1: Box<S<X>>) { + | -- help: consider relaxing the implicit `Sized` restriction | LL | fn f5<Y: ?Sized>(x: &Y) {} diff --git a/src/test/ui/unsized/unsized5.stderr b/src/test/ui/unsized/unsized5.stderr index 0bfd4565529..6e5b3556429 100644 --- a/src/test/ui/unsized/unsized5.stderr +++ b/src/test/ui/unsized/unsized5.stderr @@ -8,6 +8,10 @@ LL | f1: X, | = note: only the last field of a struct may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | struct S1<X> { + | -- help: borrowed types always have a statically known size | LL | f1: &X, @@ -28,6 +32,10 @@ LL | g: X, | = note: only the last field of a struct may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | struct S2<X> { + | -- help: borrowed types always have a statically known size | LL | g: &X, @@ -83,6 +91,10 @@ LL | V1(X, isize), | = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | enum E<X> { + | -- help: borrowed types always have a statically known size | LL | V1(&X, isize), @@ -102,6 +114,10 @@ LL | V2{f1: X, f: isize}, | = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | enum F<X> { + | -- help: borrowed types always have a statically known size | LL | V2{f1: &X, f: isize}, diff --git a/src/test/ui/unsized/unsized6.stderr b/src/test/ui/unsized/unsized6.stderr index 8e5734dffb1..5eff89d971f 100644 --- a/src/test/ui/unsized/unsized6.stderr +++ b/src/test/ui/unsized/unsized6.stderr @@ -9,6 +9,10 @@ LL | let y: Y; | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f1<W: ?Sized, X: ?Sized, Y, Z: ?Sized>(x: &X) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:7:12 @@ -20,6 +24,10 @@ LL | let _: (isize, (X, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f1<W: ?Sized, X, Y: ?Sized, Z: ?Sized>(x: &X) { + | -- error[E0277]: the size for values of type `Z` cannot be known at compilation time --> $DIR/unsized6.rs:11:12 @@ -31,6 +39,10 @@ LL | let y: (isize, (Z, usize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z>(x: &X) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:15:9 @@ -42,6 +54,10 @@ LL | let y: X; | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f2<X, Y: ?Sized>(x: &X) { + | -- error[E0277]: the size for values of type `Y` cannot be known at compilation time --> $DIR/unsized6.rs:17:12 @@ -53,6 +69,10 @@ LL | let y: (isize, (Y, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f2<X: ?Sized, Y>(x: &X) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:22:9 @@ -64,6 +84,10 @@ LL | let y: X = *x1; | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:24:9 @@ -76,6 +100,10 @@ LL | let y = *x2; | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:26:10 @@ -88,6 +116,10 @@ LL | let (y, z) = (*x3, 4); | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:30:9 @@ -99,6 +131,10 @@ LL | let y: X = *x1; | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:32:9 @@ -111,6 +147,10 @@ LL | let y = *x2; | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:34:10 @@ -123,6 +163,10 @@ LL | let (y, z) = (*x3, 4); | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) { + | -- error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:38:18 @@ -133,6 +177,10 @@ LL | fn g1<X: ?Sized>(x: X) {} | this type parameter needs to be `std::marker::Sized` | = help: unsized fn params are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn g1<X>(x: X) {} + | -- help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn g1<X: ?Sized>(x: &X) {} @@ -147,6 +195,10 @@ LL | fn g2<X: ?Sized + T>(x: X) {} | this type parameter needs to be `std::marker::Sized` | = help: unsized fn params are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | fn g2<X: T>(x: X) {} + | -- help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn g2<X: ?Sized + T>(x: &X) {} diff --git a/src/test/ui/unsized/unsized7.stderr b/src/test/ui/unsized/unsized7.stderr index 7dbddd4ed24..e0d95e21296 100644 --- a/src/test/ui/unsized/unsized7.stderr +++ b/src/test/ui/unsized/unsized7.stderr @@ -9,6 +9,10 @@ LL | impl<X: ?Sized + T> T1<X> for S3<X> { | | | this type parameter needs to be `std::marker::Sized` | +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL | impl<X: T> T1<X> for S3<X> { + | -- help: consider relaxing the implicit `Sized` restriction | LL | trait T1<Z: T + ?Sized> { diff --git a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr index c38727316cd..320b3bb42f8 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr @@ -25,10 +25,12 @@ error[E0308]: mismatched types --> $DIR/ice-6250.rs:12:14 | LL | Some(reference) = cache.data.get(key) { - | ^^^^^^^^^ - | | - | expected integer, found `&i32` - | help: consider dereferencing the borrow: `*reference` + | ^^^^^^^^^ expected integer, found `&i32` + | +help: consider dereferencing the borrow + | +LL | Some(*reference) = cache.data.get(key) { + | ^ error[E0308]: mismatched types --> $DIR/ice-6250.rs:12:9 diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.rs b/src/tools/clippy/tests/ui/needless_borrow_pat.rs index f0926220755..7a8137778b4 100644 --- a/src/tools/clippy/tests/ui/needless_borrow_pat.rs +++ b/src/tools/clippy/tests/ui/needless_borrow_pat.rs @@ -7,7 +7,7 @@ fn f1(_: &str) {} macro_rules! m1 { ($e:expr) => { - f1($e); + f1($e) }; } macro_rules! m3 { diff --git a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs index c7235e1c221..cd6db8ddc88 100644 --- a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs +++ b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs @@ -7,7 +7,7 @@ fn f1(_: &str) {} macro_rules! m2 { ($e:expr) => { - f1(*$e); + f1(*$e) }; } macro_rules! m3 { |
