diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0077dec889d..77738b2c5cc 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -46,7 +46,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID}; @@ -55,11 +55,9 @@ use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_index::vec::{Idx, IndexVec}; use rustc_query_system::ich::StableHashingContext; -use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS; -use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::lint::LintBuffer; use rustc_session::utils::{FlattenNonterminals, NtToTokenstream}; use rustc_session::Session; -use rustc_span::edition::Edition; use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{respan, DesugaringKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1184,11 +1182,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::Ty<'hir> { let id = self.lower_node_id(t.id); let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx); - let ty = self.ty_path(id, t.span, qpath); - if let hir::TyKind::TraitObject(..) = ty.kind { - self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global()); - } - ty + self.ty_path(id, t.span, qpath) } fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> { @@ -1285,9 +1279,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span)); (bounds, lifetime_bound) }); - if kind != TraitObjectSyntax::Dyn { - self.maybe_lint_bare_trait(t.span, t.id, false); - } hir::TyKind::TraitObject(bounds, lifetime_bound, kind) } TyKind::ImplTrait(def_node_id, ref bounds) => { @@ -2380,39 +2371,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { name: hir::LifetimeName::Implicit(missing), } } - - fn maybe_lint_bare_trait(&mut self, span: Span, id: NodeId, is_global: bool) { - // FIXME(davidtwco): This is a hack to detect macros which produce spans of the - // call site which do not have a macro backtrace. See #61963. - let is_macro_callsite = self - .sess - .source_map() - .span_to_snippet(span) - .map(|snippet| snippet.starts_with("#[")) - .unwrap_or(true); - if !is_macro_callsite { - if span.edition() < Edition::Edition2021 { - self.resolver.lint_buffer().buffer_lint_with_diagnostic( - BARE_TRAIT_OBJECTS, - id, - span, - "trait objects without an explicit `dyn` are deprecated", - BuiltinLintDiagnostics::BareTraitObject(span, is_global), - ) - } else { - let msg = "trait objects must include the `dyn` keyword"; - let label = "add `dyn` keyword before this trait"; - let mut err = struct_span_err!(self.sess, span, E0782, "{}", msg,); - err.span_suggestion_verbose( - span.shrink_to_lo(), - label, - String::from("dyn "), - Applicability::MachineApplicable, - ); - err.emit(); - } - } - } } /// Helper struct for delayed construction of GenericArgs. diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index d67d872b884..768cb99510f 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -8,13 +8,14 @@ use rustc_expand::base::{self, *}; use rustc_parse::parser::Parser; use rustc_parse_format as parse; use rustc_session::lint; +use rustc_session::parse::ParseSess; use rustc_span::symbol::Ident; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{InnerSpan, Span}; use rustc_target::asm::InlineAsmArch; use smallvec::smallvec; -struct AsmArgs { +pub struct AsmArgs { templates: Vec>, operands: Vec<(ast::InlineAsmOperand, Span)>, named_args: FxHashMap, @@ -31,15 +32,28 @@ fn parse_args<'a>( is_global_asm: bool, ) -> Result> { let mut p = ecx.new_parser_from_tts(tts); + let sess = &ecx.sess.parse_sess; + parse_asm_args(&mut p, sess, sp, is_global_asm) +} + +// Primarily public for rustfmt consumption. +// Internal consumers should continue to leverage `expand_asm`/`expand__global_asm` +pub fn parse_asm_args<'a>( + p: &mut Parser<'a>, + sess: &'a ParseSess, + sp: Span, + is_global_asm: bool, +) -> Result> { + let diag = &sess.span_diagnostic; if p.token == token::Eof { - return Err(ecx.struct_span_err(sp, "requires at least a template string argument")); + return Err(diag.struct_span_err(sp, "requires at least a template string argument")); } // Detect use of the legacy llvm_asm! syntax (which used to be called asm!) if !is_global_asm && p.look_ahead(1, |t| *t == token::Colon || *t == token::ModSep) { let mut err = - ecx.struct_span_err(sp, "the legacy LLVM-style asm! syntax is no longer supported"); + diag.struct_span_err(sp, "the legacy LLVM-style asm! syntax is no longer supported"); err.note("consider migrating to the new asm! syntax specified in RFC 2873"); err.note("alternatively, switch to llvm_asm! to keep your code working as it is"); return Err(err); @@ -61,7 +75,7 @@ fn parse_args<'a>( if !p.eat(&token::Comma) { if allow_templates { // After a template string, we always expect *only* a comma... - let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`"); + let mut err = diag.struct_span_err(p.token.span, "expected token: `,`"); err.span_label(p.token.span, "expected `,`"); p.maybe_annotate_with_ascription(&mut err, false); return Err(err); @@ -76,14 +90,14 @@ fn parse_args<'a>( // Parse clobber_abi if p.eat_keyword(sym::clobber_abi) { - parse_clobber_abi(&mut p, &mut args)?; + parse_clobber_abi(p, &mut args)?; allow_templates = false; continue; } // Parse options if p.eat_keyword(sym::options) { - parse_options(&mut p, &mut args, is_global_asm)?; + parse_options(p, &mut args, is_global_asm)?; allow_templates = false; continue; } @@ -103,25 +117,25 @@ fn parse_args<'a>( let mut explicit_reg = false; let op = if !is_global_asm && p.eat_keyword(kw::In) { - let reg = parse_reg(&mut p, &mut explicit_reg)?; + let reg = parse_reg(p, &mut explicit_reg)?; if p.eat_keyword(kw::Underscore) { - let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands"); + let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands"); return Err(err); } let expr = p.parse_expr()?; ast::InlineAsmOperand::In { reg, expr } } else if !is_global_asm && p.eat_keyword(sym::out) { - let reg = parse_reg(&mut p, &mut explicit_reg)?; + let reg = parse_reg(p, &mut explicit_reg)?; let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) }; ast::InlineAsmOperand::Out { reg, expr, late: false } } else if !is_global_asm && p.eat_keyword(sym::lateout) { - let reg = parse_reg(&mut p, &mut explicit_reg)?; + let reg = parse_reg(p, &mut explicit_reg)?; let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) }; ast::InlineAsmOperand::Out { reg, expr, late: true } } else if !is_global_asm && p.eat_keyword(sym::inout) { - let reg = parse_reg(&mut p, &mut explicit_reg)?; + let reg = parse_reg(p, &mut explicit_reg)?; if p.eat_keyword(kw::Underscore) { - let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands"); + let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands"); return Err(err); } let expr = p.parse_expr()?; @@ -133,9 +147,9 @@ fn parse_args<'a>( ast::InlineAsmOperand::InOut { reg, expr, late: false } } } else if !is_global_asm && p.eat_keyword(sym::inlateout) { - let reg = parse_reg(&mut p, &mut explicit_reg)?; + let reg = parse_reg(p, &mut explicit_reg)?; if p.eat_keyword(kw::Underscore) { - let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands"); + let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands"); return Err(err); } let expr = p.parse_expr()?; @@ -154,7 +168,7 @@ fn parse_args<'a>( match expr.kind { ast::ExprKind::Path(..) => {} _ => { - let err = ecx + let err = diag .struct_span_err(expr.span, "argument to `sym` must be a path expression"); return Err(err); } @@ -173,7 +187,7 @@ fn parse_args<'a>( } else { "expected operand, clobber_abi, options, or additional template string" }; - let mut err = ecx.struct_span_err(template.span, errstr); + let mut err = diag.struct_span_err(template.span, errstr); err.span_label(template.span, errstr); return Err(err); } @@ -193,31 +207,31 @@ fn parse_args<'a>( // clobber_abi/options. We do this at the end once we have the full span // of the argument available. if !args.options_spans.is_empty() { - ecx.struct_span_err(span, "arguments are not allowed after options") + diag.struct_span_err(span, "arguments are not allowed after options") .span_labels(args.options_spans.clone(), "previous options") .span_label(span, "argument") .emit(); } else if let Some((_, abi_span)) = args.clobber_abis.last() { - ecx.struct_span_err(span, "arguments are not allowed after clobber_abi") + diag.struct_span_err(span, "arguments are not allowed after clobber_abi") .span_label(*abi_span, "clobber_abi") .span_label(span, "argument") .emit(); } if explicit_reg { if name.is_some() { - ecx.struct_span_err(span, "explicit register arguments cannot have names").emit(); + diag.struct_span_err(span, "explicit register arguments cannot have names").emit(); } args.reg_args.insert(slot); } else if let Some(name) = name { if let Some(&prev) = args.named_args.get(&name) { - ecx.struct_span_err(span, &format!("duplicate argument named `{}`", name)) + diag.struct_span_err(span, &format!("duplicate argument named `{}`", name)) .span_label(args.operands[prev].1, "previously here") .span_label(span, "duplicate argument") .emit(); continue; } if !args.reg_args.is_empty() { - let mut err = ecx.struct_span_err( + let mut err = diag.struct_span_err( span, "named arguments cannot follow explicit register arguments", ); @@ -230,7 +244,7 @@ fn parse_args<'a>( args.named_args.insert(name, slot); } else { if !args.named_args.is_empty() || !args.reg_args.is_empty() { - let mut err = ecx.struct_span_err( + let mut err = diag.struct_span_err( span, "positional arguments cannot follow named arguments \ or explicit register arguments", @@ -251,21 +265,21 @@ fn parse_args<'a>( && args.options.contains(ast::InlineAsmOptions::READONLY) { let spans = args.options_spans.clone(); - ecx.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive") + diag.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive") .emit(); } if args.options.contains(ast::InlineAsmOptions::PURE) && args.options.contains(ast::InlineAsmOptions::NORETURN) { let spans = args.options_spans.clone(); - ecx.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive") + diag.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive") .emit(); } if args.options.contains(ast::InlineAsmOptions::PURE) && !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY) { let spans = args.options_spans.clone(); - ecx.struct_span_err( + diag.struct_span_err( spans, "the `pure` option must be combined with either `nomem` or `readonly`", ) @@ -296,14 +310,14 @@ fn parse_args<'a>( } } if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output { - ecx.struct_span_err( + diag.struct_span_err( args.options_spans.clone(), "asm with the `pure` option must have at least one output", ) .emit(); } if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() { - let err = ecx + let err = diag .struct_span_err(outputs_sp, "asm outputs are not allowed with the `noreturn` option"); // Bail out now since this is likely to confuse MIR @@ -312,7 +326,7 @@ fn parse_args<'a>( if args.clobber_abis.len() > 0 { if is_global_asm { - let err = ecx.struct_span_err( + let err = diag.struct_span_err( args.clobber_abis.iter().map(|(_, span)| *span).collect::>(), "`clobber_abi` cannot be used with `global_asm!`", ); @@ -321,7 +335,7 @@ fn parse_args<'a>( return Err(err); } if !regclass_outputs.is_empty() { - ecx.struct_span_err( + diag.struct_span_err( regclass_outputs.clone(), "asm with `clobber_abi` must specify explicit registers for outputs", ) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d768f06c4f0..d9faa6777ea 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -616,19 +616,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match self.size_and_align_of(metadata, &field)? { Some(size_and_align) => size_and_align, None => { - // A field with extern type. If this field is at offset 0, we behave - // like the underlying extern type. - // FIXME: Once we have made decisions for how to handle size and alignment - // of `extern type`, this should be adapted. It is just a temporary hack - // to get some code to work that probably ought to work. - if sized_size == Size::ZERO { - return Ok(None); - } else { - span_bug!( - self.cur_span(), - "Fields cannot be extern types, unless they are at offset 0" - ) - } + // A field with an extern type. We don't know the actual dynamic size + // or the alignment. + return Ok(None); } }; diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 851c2a6bb2e..818b95b7fc4 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -362,21 +362,15 @@ where // Re-use parent metadata to determine dynamic field layout. // With custom DSTS, this *will* execute user-defined code, but the same // happens at run-time so that's okay. - let align = match self.size_and_align_of(&base.meta, &field_layout)? { - Some((_, align)) => align, - None if offset == Size::ZERO => { - // An extern type at offset 0, we fall back to its static alignment. - // FIXME: Once we have made decisions for how to handle size and alignment - // of `extern type`, this should be adapted. It is just a temporary hack - // to get some code to work that probably ought to work. - field_layout.align.abi + match self.size_and_align_of(&base.meta, &field_layout)? { + Some((_, align)) => (base.meta, offset.align_to(align)), + None => { + // For unsized types with an extern type tail we perform no adjustments. + // NOTE: keep this in sync with `PlaceRef::project_field` in the codegen backend. + assert!(matches!(base.meta, MemPlaceMeta::None)); + (base.meta, offset) } - None => span_bug!( - self.cur_span(), - "cannot compute offset for extern type field at non-0 offset" - ), - }; - (base.meta, offset.align_to(align)) + } } else { // base.meta could be present; we might be accessing a sized field of an unsized // struct. diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 71db58f2d8b..ba1b8caa368 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -633,16 +633,6 @@ pub trait LintContext: Sized { } }, BuiltinLintDiagnostics::Normal => (), - BuiltinLintDiagnostics::BareTraitObject(span, is_global) => { - let (sugg, app) = match sess.source_map().span_to_snippet(span) { - Ok(s) if is_global => { - (format!("dyn ({})", s), Applicability::MachineApplicable) - } - Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), - Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), - }; - db.span_suggestion(span, "use `dyn`", sugg, app); - } BuiltinLintDiagnostics::AbsPathWithModule(span) => { let (sugg, app) = match sess.source_map().span_to_snippet(span) { Ok(ref s) => { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index da1edcf6fe3..ed24b94e2fd 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -169,7 +169,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } if !(type_permits_lack_of_use || fn_warned || op_warned) { - cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| lint.build("unused result").emit()); + cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| { + lint.build(&format!("unused result of type `{}`", ty)).emit() + }); } // Returns whether an error has been emitted (and thus another does not need to be later). diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 3f504d75dfc..e22c9c68de6 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -285,7 +285,6 @@ pub enum ExternDepSpec { #[derive(PartialEq, Debug)] pub enum BuiltinLintDiagnostics { Normal, - BareTraitObject(Span, /* is_global */ bool), AbsPathWithModule(Span), ProcMacroDeriveResolutionFallback(Span), MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 78e33544655..e2de9f12aaa 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -771,11 +771,24 @@ rustc_queries! { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } cache_on_disk_if { true } load_cached(tcx, id) { - let typeck_results: Option> = tcx - .on_disk_cache().as_ref() - .and_then(|c| c.try_load_query_result(*tcx, id)); + #[cfg(bootstrap)] + { + match match tcx.on_disk_cache().as_ref() { + Some(c) => c.try_load_query_result(*tcx, id), + None => None, + } { + Some(x) => Some(&*tcx.arena.alloc(x)), + None => None, + } + } + #[cfg(not(bootstrap))] + { + let typeck_results: Option> = tcx + .on_disk_cache().as_ref() + .and_then(|c| c.try_load_query_result(*tcx, id)); - typeck_results.map(|x| &*tcx.arena.alloc(x)) + typeck_results.map(|x| &*tcx.arena.alloc(x)) + } } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 558b1ce082e..8be95b2d95a 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -68,6 +68,12 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { if body.source.promoted.is_some() { return false; } + // Avoid inlining into generators, since their `optimized_mir` is used for layout computation, + // which can create a cycle, even when no attempt is made to inline the function in the other + // direction. + if body.generator.is_some() { + return false; + } let mut this = Inliner { tcx, @@ -202,14 +208,6 @@ impl<'tcx> Inliner<'tcx> { if let Some(callee_def_id) = callee.def_id().as_local() { let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_id); - // Avoid inlining into generators, - // since their `optimized_mir` is used for layout computation, which can - // create a cycle, even when no attempt is made to inline the function - // in the other direction. - if caller_body.generator.is_some() { - return Err("local generator (query cycle avoidance)"); - } - // Avoid a cycle here by only using `instance_mir` only if we have // a lower `HirId` than the callee. This ensures that the callee will // not inline us. This trick only works without incremental compilation. diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 516e301ec3a..618aa3fd002 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -223,7 +223,7 @@ impl<'a> Parser<'a> { (Ident::empty(), ItemKind::Use(tree)) } else if self.check_fn_front_matter(def_final) { // FUNCTION ITEM - let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo)?; + let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis)?; (ident, ItemKind::Fn(Box::new(Fn { defaultness: def(), sig, generics, body }))) } else if self.eat_keyword(kw::Extern) { if self.eat_keyword(kw::Crate) { @@ -1511,9 +1511,16 @@ impl<'a> Parser<'a> { let (ident, is_raw) = self.ident_or_err()?; if !is_raw && ident.is_reserved() { let err = if self.check_fn_front_matter(false) { + let inherited_vis = Visibility { + span: rustc_span::DUMMY_SP, + kind: VisibilityKind::Inherited, + tokens: None, + }; // We use `parse_fn` to get a span for the function let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; - if let Err(mut db) = self.parse_fn(&mut Vec::new(), fn_parse_mode, lo) { + if let Err(mut db) = + self.parse_fn(&mut Vec::new(), fn_parse_mode, lo, &inherited_vis) + { db.delay_as_bug(); } let mut err = self.struct_span_err( @@ -1793,8 +1800,9 @@ impl<'a> Parser<'a> { attrs: &mut Vec, fn_parse_mode: FnParseMode, sig_lo: Span, + vis: &Visibility, ) -> PResult<'a, (Ident, FnSig, Generics, Option>)> { - let header = self.parse_fn_front_matter()?; // `const ... fn` + let header = self.parse_fn_front_matter(vis)?; // `const ... fn` let ident = self.parse_ident()?; // `foo` let mut generics = self.parse_generics()?; // `<'a, T, ...>` let decl = @@ -1903,12 +1911,15 @@ impl<'a> Parser<'a> { /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration, /// up to and including the `fn` keyword. The formal grammar is: /// - /// ``` + /// ```text /// Extern = "extern" StringLit? ; /// FnQual = "const"? "async"? "unsafe"? Extern? ; /// FnFrontMatter = FnQual "fn" ; /// ``` - pub(super) fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> { + /// + /// `vis` represents the visibility that was already parsed, if any. Use + /// `Visibility::Inherited` when no visibility is known. + pub(super) fn parse_fn_front_matter(&mut self, orig_vis: &Visibility) -> PResult<'a, FnHeader> { let sp_start = self.token.span; let constness = self.parse_constness(); @@ -1934,51 +1945,94 @@ impl<'a> Parser<'a> { Ok(false) => unreachable!(), Err(mut err) => { // Qualifier keywords ordering check + enum WrongKw { + Duplicated(Span), + Misplaced(Span), + } - // This will allow the machine fix to directly place the keyword in the correct place - let current_qual_sp = if self.check_keyword(kw::Const) { - Some(async_start_sp) + // This will allow the machine fix to directly place the keyword in the correct place or to indicate + // that the keyword is already present and the second instance should be removed. + let wrong_kw = if self.check_keyword(kw::Const) { + match constness { + Const::Yes(sp) => Some(WrongKw::Duplicated(sp)), + Const::No => Some(WrongKw::Misplaced(async_start_sp)), + } } else if self.check_keyword(kw::Async) { - Some(unsafe_start_sp) + match asyncness { + Async::Yes { span, .. } => Some(WrongKw::Duplicated(span)), + Async::No => Some(WrongKw::Misplaced(unsafe_start_sp)), + } } else if self.check_keyword(kw::Unsafe) { - Some(ext_start_sp) + match unsafety { + Unsafe::Yes(sp) => Some(WrongKw::Duplicated(sp)), + Unsafe::No => Some(WrongKw::Misplaced(ext_start_sp)), + } } else { None }; - if let Some(current_qual_sp) = current_qual_sp { - let current_qual_sp = current_qual_sp.to(self.prev_token.span); - if let Ok(current_qual) = self.span_to_snippet(current_qual_sp) { - let invalid_qual_sp = self.token.uninterpolated_span(); - let invalid_qual = self.span_to_snippet(invalid_qual_sp).unwrap(); + // The keyword is already present, suggest removal of the second instance + if let Some(WrongKw::Duplicated(original_sp)) = wrong_kw { + let original_kw = self + .span_to_snippet(original_sp) + .expect("Span extracted directly from keyword should always work"); + + err.span_suggestion( + self.token.uninterpolated_span(), + &format!("`{}` already used earlier, remove this one", original_kw), + "".to_string(), + Applicability::MachineApplicable, + ) + .span_note(original_sp, &format!("`{}` first seen here", original_kw)); + } + // The keyword has not been seen yet, suggest correct placement in the function front matter + else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw { + let correct_pos_sp = correct_pos_sp.to(self.prev_token.span); + if let Ok(current_qual) = self.span_to_snippet(correct_pos_sp) { + let misplaced_qual_sp = self.token.uninterpolated_span(); + let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap(); err.span_suggestion( - current_qual_sp.to(invalid_qual_sp), - &format!("`{}` must come before `{}`", invalid_qual, current_qual), - format!("{} {}", invalid_qual, current_qual), - Applicability::MachineApplicable, - ).note("keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`"); + correct_pos_sp.to(misplaced_qual_sp), + &format!("`{}` must come before `{}`", misplaced_qual, current_qual), + format!("{} {}", misplaced_qual, current_qual), + Applicability::MachineApplicable, + ).note("keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`"); } } - // Recover incorrect visibility order such as `async pub`. + // Recover incorrect visibility order such as `async pub` else if self.check_keyword(kw::Pub) { let sp = sp_start.to(self.prev_token.span); if let Ok(snippet) = self.span_to_snippet(sp) { - let vis = match self.parse_visibility(FollowedByType::No) { + let current_vis = match self.parse_visibility(FollowedByType::No) { Ok(v) => v, Err(mut d) => { d.cancel(); return Err(err); } }; - let vs = pprust::vis_to_string(&vis); + let vs = pprust::vis_to_string(¤t_vis); let vs = vs.trim_end(); - err.span_suggestion( - sp_start.to(self.prev_token.span), - &format!("visibility `{}` must come before `{}`", vs, snippet), - format!("{} {}", vs, snippet), - Applicability::MachineApplicable, - ); + + // There was no explicit visibility + if matches!(orig_vis.kind, VisibilityKind::Inherited) { + err.span_suggestion( + sp_start.to(self.prev_token.span), + &format!("visibility `{}` must come before `{}`", vs, snippet), + format!("{} {}", vs, snippet), + Applicability::MachineApplicable, + ); + } + // There was an explicit visibility + else { + err.span_suggestion( + current_vis.span, + "there is already a visibility modifier, remove one", + "".to_string(), + Applicability::MachineApplicable, + ) + .span_note(orig_vis.span, "explicit visibility first seen here"); + } } } return Err(err); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 9bfde0e3900..02a774ba129 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -474,7 +474,13 @@ impl<'a> Parser<'a> { params: Vec, recover_return_sign: RecoverReturnSign, ) -> PResult<'a, TyKind> { - let ast::FnHeader { ext, unsafety, constness, asyncness } = self.parse_fn_front_matter()?; + let inherited_vis = rustc_ast::Visibility { + span: rustc_span::DUMMY_SP, + kind: rustc_ast::VisibilityKind::Inherited, + tokens: None, + }; + let ast::FnHeader { ext, unsafety, constness, asyncness } = + self.parse_fn_front_matter(&inherited_vis)?; let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?; let whole_span = lo.to(self.prev_token.span); if let ast::Const::Yes(span) = constness { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 23c3b5af262..8db706c3709 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -13,6 +13,7 @@ use crate::errors::{ }; use crate::middle::resolve_lifetime as rl; use crate::require_c_abi_if_c_variadic; +use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, ErrorReported, FatalError}; use rustc_hir as hir; @@ -24,7 +25,8 @@ use rustc_hir::{GenericArg, GenericArgs}; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable}; -use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; +use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; +use rustc_span::edition::Edition; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -2266,13 +2268,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// Parses the programmer's textual representation of a type into our /// internal notion of a type. pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> { - self.ast_ty_to_ty_inner(ast_ty, false) + self.ast_ty_to_ty_inner(ast_ty, false, false) + } + + /// Parses the programmer's textual representation of a type into our + /// internal notion of a type. This is meant to be used within a path. + pub fn ast_ty_to_ty_in_path(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> { + self.ast_ty_to_ty_inner(ast_ty, false, true) } /// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait /// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors. #[tracing::instrument(level = "debug", skip(self))] - fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> { + fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx> { let tcx = self.tcx(); let result_ty = match ast_ty.kind { @@ -2283,7 +2291,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::TyKind::Rptr(ref region, ref mt) => { let r = self.ast_region_to_region(region, None); debug!(?r); - let t = self.ast_ty_to_ty_inner(mt.ty, true); + let t = self.ast_ty_to_ty_inner(mt.ty, true, false); tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl }) } hir::TyKind::Never => tcx.types.never, @@ -2302,6 +2310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { )) } hir::TyKind::TraitObject(bounds, ref lifetime, _) => { + self.maybe_lint_bare_trait(ast_ty, in_path); self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed) } hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => { @@ -2329,7 +2338,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!(?qself, ?segment); - let ty = self.ast_ty_to_ty(qself); + let ty = self.ast_ty_to_ty_inner(qself, false, true); let res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = qself.kind { path.res @@ -2586,4 +2595,62 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Some(r) } + + fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) { + let tcx = self.tcx(); + if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) = + self_ty.kind + { + let needs_bracket = in_path + && !tcx + .sess + .source_map() + .span_to_prev_source(self_ty.span) + .ok() + .map_or(false, |s| s.trim_end().ends_with('<')); + + let is_global = poly_trait_ref.trait_ref.path.is_global(); + let sugg = Vec::from_iter([ + ( + self_ty.span.shrink_to_lo(), + format!( + "{}dyn {}", + if needs_bracket { "<" } else { "" }, + if is_global { "(" } else { "" }, + ), + ), + ( + self_ty.span.shrink_to_hi(), + format!( + "{}{}", + if is_global { ")" } else { "" }, + if needs_bracket { ">" } else { "" }, + ), + ), + ]); + if self_ty.span.edition() >= Edition::Edition2021 { + let msg = "trait objects must include the `dyn` keyword"; + let label = "add `dyn` keyword before this trait"; + rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg) + .multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable) + .emit(); + } else { + let msg = "trait objects without an explicit `dyn` are deprecated"; + tcx.struct_span_lint_hir( + BARE_TRAIT_OBJECTS, + self_ty.hir_id, + self_ty.span, + |lint| { + lint.build(msg) + .multipart_suggestion_verbose( + "use `dyn`", + sugg, + Applicability::MachineApplicable, + ) + .emit() + }, + ); + } + } + } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 738af9bfb8c..67630fd4e58 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -6,7 +6,6 @@ use crate::check::callee::{self, DeferredCallResolution}; use crate::check::method::{self, MethodCallee, SelfSource}; use crate::check::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy}; -use rustc_ast::TraitObjectSyntax; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported}; @@ -14,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{ExprKind, GenericArg, Node, QPath, TyKind}; +use rustc_hir::{ExprKind, GenericArg, Node, QPath}; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_infer::infer::{InferOk, InferResult}; @@ -28,8 +27,6 @@ use rustc_middle::ty::{ Ty, UserType, }; use rustc_session::lint; -use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS; -use rustc_span::edition::Edition; use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::{original_sp, DUMMY_SP}; use rustc_span::symbol::{kw, sym, Ident}; @@ -855,7 +852,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to be object-safe. // We manually call `register_wf_obligation` in the success path // below. - (>::ast_ty_to_ty(self, qself), qself, segment) + (>::ast_ty_to_ty_in_path(self, qself), qself, segment) } QPath::LangItem(..) => { bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`") @@ -901,7 +898,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); if result.is_ok() { - self.maybe_lint_bare_trait(qpath, hir_id, span); self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None)); } @@ -914,56 +910,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId, span: Span) { - if let QPath::TypeRelative(self_ty, _) = qpath { - if let TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) = - self_ty.kind - { - let msg = "trait objects without an explicit `dyn` are deprecated"; - let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(self_ty.span) { - Ok(s) if poly_trait_ref.trait_ref.path.is_global() => { - (format!("dyn ({})", s), Applicability::MachineApplicable) - } - Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), - Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), - }; - // Wrap in `<..>` if it isn't already. - let sugg = match self.tcx.sess.source_map().span_to_snippet(span) { - Ok(s) if s.starts_with('<') => sugg, - _ => format!("<{}>", sugg), - }; - let sugg_label = "use `dyn`"; - if self.sess().edition() >= Edition::Edition2021 { - let mut err = rustc_errors::struct_span_err!( - self.sess(), - self_ty.span, - E0782, - "{}", - msg, - ); - err.span_suggestion( - self_ty.span, - sugg_label, - sugg, - Applicability::MachineApplicable, - ) - .emit(); - } else { - self.tcx.struct_span_lint_hir( - BARE_TRAIT_OBJECTS, - hir_id, - self_ty.span, - |lint| { - let mut db = lint.build(msg); - db.span_suggestion(self_ty.span, sugg_label, sugg, app); - db.emit() - }, - ); - } - } - } - } - /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise. pub(in super::super) fn get_node_fn_decl( &self, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index da1baa36d6e..67f77f14a6e 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -123,6 +123,7 @@ #![feature(const_num_from_num)] #![feature(const_ops)] #![feature(const_option)] +#![feature(const_option_ext)] #![feature(const_pin)] #![feature(const_replace)] #![feature(const_ptr_is_null)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 015366ed490..8969c6f6171 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -589,12 +589,13 @@ impl Option { #[must_use] #[inline] #[unstable(feature = "option_result_contains", issue = "62358")] - pub fn contains(&self, x: &U) -> bool + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn contains(&self, x: &U) -> bool where - U: PartialEq, + U: ~const PartialEq, { match self { - Some(y) => x == y, + Some(y) => x.eq(y), None => false, } } @@ -660,10 +661,14 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - pub fn as_pin_ref(self: Pin<&Self>) -> Option> { - // SAFETY: `x` is guaranteed to be pinned because it comes from `self` - // which is pinned. - unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) } + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_pin_ref(self: Pin<&Self>) -> Option> { + match Pin::get_ref(self).as_ref() { + // SAFETY: `x` is guaranteed to be pinned because it comes from `self` + // which is pinned. + Some(x) => unsafe { Some(Pin::new_unchecked(x)) }, + None => None, + } } /// Converts from [Pin]<[&mut] Option\> to Option<[Pin]<[&mut] T>>. @@ -672,10 +677,16 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - pub fn as_pin_mut(self: Pin<&mut Self>) -> Option> { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option> { // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`. // `x` is guaranteed to be pinned because it comes from `self` which is pinned. - unsafe { Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x)) } + unsafe { + match Pin::get_unchecked_mut(self).as_mut() { + Some(x) => Some(Pin::new_unchecked(x)), + None => None, + } + } } ///////////////////////////////////////////////////////////////////////// @@ -764,7 +775,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or(self, default: T) -> T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn unwrap_or(self, default: T) -> T + where + T: ~const Drop, + { match self { Some(x) => x, None => default, @@ -782,7 +797,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or_else T>(self, f: F) -> T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn unwrap_or_else(self, f: F) -> T + where + F: ~const FnOnce() -> T, + F: ~const Drop, + { match self { Some(x) => x, None => f(), @@ -812,7 +832,8 @@ impl Option { #[inline] #[track_caller] #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")] - pub unsafe fn unwrap_unchecked(self) -> T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const unsafe fn unwrap_unchecked(self) -> T { debug_assert!(self.is_some()); match self { Some(val) => val, @@ -842,7 +863,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map U>(self, f: F) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn map(self, f: F) -> Option + where + F: ~const FnOnce(T) -> U, + F: ~const Drop, + { match self { Some(x) => Some(f(x)), None => None, @@ -866,7 +892,12 @@ impl Option { /// ``` #[inline] #[unstable(feature = "result_option_inspect", issue = "91345")] - pub fn inspect(self, f: F) -> Self { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn inspect(self, f: F) -> Self + where + F: ~const FnOnce(&T), + F: ~const Drop, + { if let Some(ref x) = self { f(x); } @@ -894,7 +925,13 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map_or U>(self, default: U, f: F) -> U { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn map_or(self, default: U, f: F) -> U + where + F: ~const FnOnce(T) -> U, + F: ~const Drop, + U: ~const Drop, + { match self { Some(t) => f(t), None => default, @@ -917,7 +954,14 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map_or_else U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn map_or_else(self, default: D, f: F) -> U + where + D: ~const FnOnce() -> U, + D: ~const Drop, + F: ~const FnOnce(T) -> U, + F: ~const Drop, + { match self { Some(t) => f(t), None => default(), @@ -947,7 +991,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn ok_or(self, err: E) -> Result { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn ok_or(self, err: E) -> Result + where + E: ~const Drop, + { match self { Some(v) => Ok(v), None => Err(err), @@ -972,7 +1020,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn ok_or_else E>(self, err: F) -> Result { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn ok_or_else(self, err: F) -> Result + where + F: ~const FnOnce() -> E, + F: ~const Drop, + { match self { Some(v) => Ok(v), None => Err(err()), @@ -1049,7 +1102,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn and(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn and(self, optb: Option) -> Option + where + T: ~const Drop, + U: ~const Drop, + { match self { Some(_) => optb, None => None, @@ -1074,7 +1132,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn and_then Option>(self, f: F) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn and_then(self, f: F) -> Option + where + F: ~const FnOnce(T) -> Option, + F: ~const Drop, + { match self { Some(x) => f(x), None => None, @@ -1107,7 +1170,13 @@ impl Option { /// [`Some(t)`]: Some #[inline] #[stable(feature = "option_filter", since = "1.27.0")] - pub fn filter bool>(self, predicate: P) -> Self { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn filter

(self, predicate: P) -> Self + where + T: ~const Drop, + P: ~const FnOnce(&T) -> bool, + P: ~const Drop, + { if let Some(x) = self { if predicate(&x) { return Some(x); @@ -1145,9 +1214,13 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn or(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn or(self, optb: Option) -> Option + where + T: ~const Drop, + { match self { - Some(_) => self, + Some(x) => Some(x), None => optb, } } @@ -1167,9 +1240,14 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn or_else Option>(self, f: F) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn or_else(self, f: F) -> Option + where + F: ~const FnOnce() -> Option, + F: ~const Drop, + { match self { - Some(_) => self, + Some(x) => Some(x), None => f(), } } @@ -1197,7 +1275,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_xor", since = "1.37.0")] - pub fn xor(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn xor(self, optb: Option) -> Option + where + T: ~const Drop, + { match (self, optb) { (Some(a), None) => Some(a), (None, Some(b)) => Some(b), @@ -1231,7 +1313,11 @@ impl Option { #[must_use = "if you intended to set a value, consider assignment instead"] #[inline] #[stable(feature = "option_insert", since = "1.53.0")] - pub fn insert(&mut self, value: T) -> &mut T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn insert(&mut self, value: T) -> &mut T + where + T: ~const Drop, + { *self = Some(value); // SAFETY: the code above just filled the option @@ -1260,8 +1346,18 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - pub fn get_or_insert(&mut self, value: T) -> &mut T { - self.get_or_insert_with(|| value) + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn get_or_insert(&mut self, value: T) -> &mut T + where + T: ~const Drop, + { + if let None = *self { + *self = Some(value); + } + + // SAFETY: a `None` variant for `self` would have been replaced by a `Some` + // variant in the code above. + unsafe { self.as_mut().unwrap_unchecked() } } /// Inserts the default value into the option if it is [`None`], then @@ -1285,11 +1381,17 @@ impl Option { /// ``` #[inline] #[unstable(feature = "option_get_or_insert_default", issue = "82901")] - pub fn get_or_insert_default(&mut self) -> &mut T + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn get_or_insert_default(&mut self) -> &mut T where - T: Default, + T: ~const Default, { - self.get_or_insert_with(Default::default) + #[rustc_allow_const_fn_unstable(const_fn_trait_bound)] + const fn default() -> T { + T::default() + } + + self.get_or_insert_with(default) } /// Inserts a value computed from `f` into the option if it is [`None`], @@ -1311,17 +1413,21 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - pub fn get_or_insert_with T>(&mut self, f: F) -> &mut T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn get_or_insert_with(&mut self, f: F) -> &mut T + where + F: ~const FnOnce() -> T, + F: ~const Drop, + { if let None = *self { - *self = Some(f()); + // the compiler isn't smart enough to know that we are not dropping a `T` + // here and wants us to ensure `T` can be dropped at compile time. + mem::forget(mem::replace(self, Some(f()))) } - match self { - Some(v) => v, - // SAFETY: a `None` variant for `self` would have been replaced by a `Some` - // variant in the code above. - None => unsafe { hint::unreachable_unchecked() }, - } + // SAFETY: a `None` variant for `self` would have been replaced by a `Some` + // variant in the code above. + unsafe { self.as_mut().unwrap_unchecked() } } ///////////////////////////////////////////////////////////////////////// @@ -1391,7 +1497,12 @@ impl Option { /// assert_eq!(x.zip(z), None); /// ``` #[stable(feature = "option_zip_option", since = "1.46.0")] - pub fn zip(self, other: Option) -> Option<(T, U)> { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn zip(self, other: Option) -> Option<(T, U)> + where + T: ~const Drop, + U: ~const Drop, + { match (self, other) { (Some(a), Some(b)) => Some((a, b)), _ => None, @@ -1427,11 +1538,18 @@ impl Option { /// assert_eq!(x.zip_with(None, Point::new), None); /// ``` #[unstable(feature = "option_zip", issue = "70086")] - pub fn zip_with(self, other: Option, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn zip_with(self, other: Option, f: F) -> Option where - F: FnOnce(T, U) -> R, + F: ~const FnOnce(T, U) -> R, + F: ~const Drop, + T: ~const Drop, + U: ~const Drop, { - Some(f(self?, other?)) + match (self, other) { + (Some(a), Some(b)) => Some(f(a, b)), + _ => None, + } } } @@ -1503,8 +1621,12 @@ impl Option<&mut T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "copied", since = "1.35.0")] - pub fn copied(self) -> Option { - self.map(|&mut t| t) + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn copied(self) -> Option { + match self { + Some(&mut t) => Some(t), + None => None, + } } } @@ -1591,7 +1713,11 @@ impl Option { /// [`FromStr`]: crate::str::FromStr #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or_default(self) -> T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn unwrap_or_default(self) -> T + where + T: ~const Default, + { match self { Some(x) => x, None => Default::default(), @@ -1615,8 +1741,15 @@ impl Option { /// assert_eq!(x.as_deref(), None); /// ``` #[stable(feature = "option_deref", since = "1.40.0")] - pub fn as_deref(&self) -> Option<&T::Target> { - self.as_ref().map(|t| t.deref()) + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_deref(&self) -> Option<&T::Target> + where + T: ~const Deref, + { + match self.as_ref() { + Some(t) => Some(t.deref()), + None => None, + } } } @@ -1636,8 +1769,15 @@ impl Option { /// }), Some("HEY".to_owned().as_mut_str())); /// ``` #[stable(feature = "option_deref", since = "1.40.0")] - pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> { - self.as_mut().map(|t| t.deref_mut()) + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target> + where + T: ~const DerefMut, + { + match self.as_mut() { + Some(t) => Some(t.deref_mut()), + None => None, + } } } diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index dacb33619f8..21562acf3d7 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -70,8 +70,10 @@ #![feature(portable_simd)] #![feature(ptr_metadata)] #![feature(once_cell)] +#![feature(option_result_contains)] #![feature(unsized_tuple_coercion)] #![feature(const_option)] +#![feature(const_option_ext)] #![feature(const_result)] #![feature(integer_atomics)] #![feature(int_roundings)] diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index cd07d6c52c2..da692461261 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -86,17 +86,49 @@ fn test_and() { let x: Option = None; assert_eq!(x.and(Some(2)), None); assert_eq!(x.and(None::), None); + + const FOO: Option = Some(1); + const A: Option = FOO.and(Some(2)); + const B: Option = FOO.and(None); + assert_eq!(A, Some(2)); + assert_eq!(B, None); + + const BAR: Option = None; + const C: Option = BAR.and(Some(2)); + const D: Option = BAR.and(None); + assert_eq!(C, None); + assert_eq!(D, None); } #[test] fn test_and_then() { + const fn plus_one(x: isize) -> Option { + Some(x + 1) + } + + const fn none(_: isize) -> Option { + None + } + let x: Option = Some(1); - assert_eq!(x.and_then(|x| Some(x + 1)), Some(2)); - assert_eq!(x.and_then(|_| None::), None); + assert_eq!(x.and_then(plus_one), Some(2)); + assert_eq!(x.and_then(none), None); let x: Option = None; - assert_eq!(x.and_then(|x| Some(x + 1)), None); - assert_eq!(x.and_then(|_| None::), None); + assert_eq!(x.and_then(plus_one), None); + assert_eq!(x.and_then(none), None); + + const FOO: Option = Some(1); + const A: Option = FOO.and_then(plus_one); + const B: Option = FOO.and_then(none); + assert_eq!(A, Some(2)); + assert_eq!(B, None); + + const BAR: Option = None; + const C: Option = BAR.and_then(plus_one); + const D: Option = BAR.and_then(none); + assert_eq!(C, None); + assert_eq!(D, None); } #[test] @@ -108,17 +140,49 @@ fn test_or() { let x: Option = None; assert_eq!(x.or(Some(2)), Some(2)); assert_eq!(x.or(None), None); + + const FOO: Option = Some(1); + const A: Option = FOO.or(Some(2)); + const B: Option = FOO.or(None); + assert_eq!(A, Some(1)); + assert_eq!(B, Some(1)); + + const BAR: Option = None; + const C: Option = BAR.or(Some(2)); + const D: Option = BAR.or(None); + assert_eq!(C, Some(2)); + assert_eq!(D, None); } #[test] fn test_or_else() { + const fn two() -> Option { + Some(2) + } + + const fn none() -> Option { + None + } + let x: Option = Some(1); - assert_eq!(x.or_else(|| Some(2)), Some(1)); - assert_eq!(x.or_else(|| None), Some(1)); + assert_eq!(x.or_else(two), Some(1)); + assert_eq!(x.or_else(none), Some(1)); let x: Option = None; - assert_eq!(x.or_else(|| Some(2)), Some(2)); - assert_eq!(x.or_else(|| None), None); + assert_eq!(x.or_else(two), Some(2)); + assert_eq!(x.or_else(none), None); + + const FOO: Option = Some(1); + const A: Option = FOO.or_else(two); + const B: Option = FOO.or_else(none); + assert_eq!(A, Some(1)); + assert_eq!(B, Some(1)); + + const BAR: Option = None; + const C: Option = BAR.or_else(two); + const D: Option = BAR.or_else(none); + assert_eq!(C, Some(2)); + assert_eq!(D, None); } #[test] @@ -149,15 +213,29 @@ fn test_unwrap_or() { let x: Option = None; assert_eq!(x.unwrap_or(2), 2); + + const A: isize = Some(1).unwrap_or(2); + const B: isize = None.unwrap_or(2); + assert_eq!(A, 1); + assert_eq!(B, 2); } #[test] fn test_unwrap_or_else() { + const fn two() -> isize { + 2 + } + let x: Option = Some(1); - assert_eq!(x.unwrap_or_else(|| 2), 1); + assert_eq!(x.unwrap_or_else(two), 1); let x: Option = None; - assert_eq!(x.unwrap_or_else(|| 2), 2); + assert_eq!(x.unwrap_or_else(two), 2); + + const A: isize = Some(1).unwrap_or_else(two); + const B: isize = None.unwrap_or_else(two); + assert_eq!(A, 1); + assert_eq!(B, 2); } #[test] diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir index d19229aabad..84ccf25ef75 100644 --- a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir +++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir @@ -20,21 +20,16 @@ fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 1 let _3: std::string::String; // in scope 0 at $DIR/generator-drop-cleanup.rs:11:13: 11:15 let _4: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:12:9: 12:14 let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:12:9: 12:14 - let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:10:18: 10:18 - let mut _8: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 - let mut _9: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 + let mut _6: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:10:18: 10:18 + let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 + let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 scope 1 { debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:11:13: 11:15 } - scope 2 (inlined String::new) { // at $DIR/generator-drop-cleanup.rs:11:18: 11:31 - let mut _6: std::vec::Vec; // in scope 2 at $DIR/generator-drop-cleanup.rs:11:18: 11:31 - scope 3 (inlined Vec::::new) { // at $DIR/generator-drop-cleanup.rs:11:18: 11:31 - } - } bb0: { - _9 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 - switchInt(move _9) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 + _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 + switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6 } bb1: { diff --git a/src/test/rustdoc-ui/display-output.rs b/src/test/rustdoc-ui/display-output.rs index 30b32c511b5..c40d99c9d4c 100644 --- a/src/test/rustdoc-ui/display-output.rs +++ b/src/test/rustdoc-ui/display-output.rs @@ -10,6 +10,6 @@ /// #![warn(unused)] /// let x = 12; /// -/// fn foo(x: &std::fmt::Display) {} +/// fn foo(x: &dyn std::fmt::Display) {} /// ``` pub fn foo() {} diff --git a/src/test/rustdoc-ui/display-output.stdout b/src/test/rustdoc-ui/display-output.stdout index f76dec1c850..41c1f41f2cf 100644 --- a/src/test/rustdoc-ui/display-output.stdout +++ b/src/test/rustdoc-ui/display-output.stdout @@ -5,16 +5,6 @@ test $DIR/display-output.rs - foo (line 9) ... ok successes: ---- $DIR/display-output.rs - foo (line 9) stdout ---- -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/display-output.rs:13:12 - | -LL | fn foo(x: &std::fmt::Display) {} - | ^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn std::fmt::Display` - | - = note: `#[warn(bare_trait_objects)]` on by default - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see - warning: unused variable: `x` --> $DIR/display-output.rs:11:5 | @@ -31,13 +21,13 @@ LL | #![warn(unused)] warning: unused variable: `x` --> $DIR/display-output.rs:13:8 | -LL | fn foo(x: &std::fmt::Display) {} +LL | fn foo(x: &dyn std::fmt::Display) {} | ^ help: if this is intentional, prefix it with an underscore: `_x` warning: function is never used: `foo` --> $DIR/display-output.rs:13:4 | -LL | fn foo(x: &std::fmt::Display) {} +LL | fn foo(x: &dyn std::fmt::Display) {} | ^^^ | note: the lint level is defined here @@ -47,7 +37,7 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` -warning: 4 warnings emitted +warning: 3 warnings emitted diff --git a/src/test/ui/closures/closure-expected.stderr b/src/test/ui/closures/closure-expected.stderr index 8b38d5ff459..7ffe3c1ef95 100644 --- a/src/test/ui/closures/closure-expected.stderr +++ b/src/test/ui/closures/closure-expected.stderr @@ -11,8 +11,8 @@ LL | let y = x.or_else(4); note: required by a bound in `Option::::or_else` --> $SRC_DIR/core/src/option.rs:LL:COL | -LL | pub fn or_else Option>(self, f: F) -> Option { - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Option::::or_else` +LL | F: ~const FnOnce() -> Option, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Option::::or_else` error: aborting due to previous error diff --git a/src/test/ui/closures/coerce-unsafe-to-closure.stderr b/src/test/ui/closures/coerce-unsafe-to-closure.stderr index 24db2725347..883348eb98c 100644 --- a/src/test/ui/closures/coerce-unsafe-to-closure.stderr +++ b/src/test/ui/closures/coerce-unsafe-to-closure.stderr @@ -10,8 +10,8 @@ LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); note: required by a bound in `Option::::map` --> $SRC_DIR/core/src/option.rs:LL:COL | -LL | pub fn map U>(self, f: F) -> Option { - | ^^^^^^^^^^^^^^ required by this bound in `Option::::map` +LL | F: ~const FnOnce(T) -> U, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Option::::map` error: aborting due to previous error diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs index ae8863c567d..e12e07a28e7 100644 --- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs +++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs @@ -12,8 +12,6 @@ fn b() { //~^ ERROR expected trait, found constant `BAR` //~| ERROR expected trait, found constant `BAR` //~| ERROR type provided when a constant was expected - //~| WARN trait objects without an explicit `dyn` are deprecated - //~| WARN this is accepted in the current edition } fn c() { foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr index 380c17c8e62..d9bcc523b1f 100644 --- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr +++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr @@ -10,7 +10,7 @@ LL | foo::<{ BAR + 3 }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:19:11 + --> $DIR/const-expression-suggest-missing-braces.rs:17:11 | LL | foo::<3 + 3>(); | ^^^^^ @@ -21,7 +21,7 @@ LL | foo::<{ 3 + 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:22:15 + --> $DIR/const-expression-suggest-missing-braces.rs:20:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -32,7 +32,7 @@ LL | foo::<{ BAR - 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:25:15 + --> $DIR/const-expression-suggest-missing-braces.rs:23:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -43,7 +43,7 @@ LL | foo::<{ BAR - BAR }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:28:11 + --> $DIR/const-expression-suggest-missing-braces.rs:26:11 | LL | foo::<100 - BAR>(); | ^^^^^^^^^ @@ -54,7 +54,7 @@ LL | foo::<{ 100 - BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:31:19 + --> $DIR/const-expression-suggest-missing-braces.rs:29:19 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -65,7 +65,7 @@ LL | foo::<{ bar() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:34:21 + --> $DIR/const-expression-suggest-missing-braces.rs:32:21 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -76,7 +76,7 @@ LL | foo::<{ bar::() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:37:21 + --> $DIR/const-expression-suggest-missing-braces.rs:35:21 | LL | foo::() + BAR>(); | ^ expected one of `,` or `>` @@ -87,7 +87,7 @@ LL | foo::<{ bar::() + BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:40:21 + --> $DIR/const-expression-suggest-missing-braces.rs:38:21 | LL | foo::() - BAR>(); | ^ expected one of `,` or `>` @@ -98,7 +98,7 @@ LL | foo::<{ bar::() - BAR }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:43:15 + --> $DIR/const-expression-suggest-missing-braces.rs:41:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -109,7 +109,7 @@ LL | foo::<{ BAR - bar::() }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:46:15 + --> $DIR/const-expression-suggest-missing-braces.rs:44:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -131,23 +131,13 @@ error[E0404]: expected trait, found constant `BAR` LL | foo::(); | ^^^ not a trait -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/const-expression-suggest-missing-braces.rs:11:11 - | -LL | foo::(); - | ^^^^^^^^^ help: use `dyn`: `dyn BAR + BAR` - | - = note: `#[warn(bare_trait_objects)]` on by default - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - error[E0747]: type provided when a constant was expected --> $DIR/const-expression-suggest-missing-braces.rs:11:11 | LL | foo::(); | ^^^^^^^^^ -error: aborting due to 14 previous errors; 1 warning emitted +error: aborting due to 14 previous errors Some errors have detailed explanations: E0404, E0747. For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/consts/const-eval/issue-91827-extern-types.rs b/src/test/ui/consts/const-eval/issue-91827-extern-types.rs new file mode 100644 index 00000000000..d5576ebfd02 --- /dev/null +++ b/src/test/ui/consts/const-eval/issue-91827-extern-types.rs @@ -0,0 +1,58 @@ +// run-pass +// +// Test that we can handle unsized types with an extern type tail part. +// Regression test for issue #91827. + +#![feature(const_ptr_offset_from)] +#![feature(const_slice_from_raw_parts)] +#![feature(extern_types)] + +use std::ptr::addr_of; + +extern "C" { + type Opaque; +} + +unsafe impl Sync for Opaque {} + +#[repr(C)] +pub struct List { + len: usize, + data: [T; 0], + tail: Opaque, +} + +#[repr(C)] +pub struct ListImpl { + len: usize, + data: [T; N], +} + +impl List { + const fn as_slice(&self) -> &[T] { + unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) } + } +} + +impl ListImpl { + const fn as_list(&self) -> &List { + unsafe { std::mem::transmute(self) } + } +} + +pub static A: ListImpl = ListImpl { + len: 3, + data: [5, 6, 7], +}; +pub static A_REF: &'static List = A.as_list(); +pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list()); + +const fn tail_offset(list: &List) -> isize { + unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List as *const u8) } +} + +fn main() { + assert_eq!(A_REF.as_slice(), &[5, 6, 7]); + // Check that interpreter and code generation agree about the position of the tail field. + assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF)); +} diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.rs b/src/test/ui/did_you_mean/bad-assoc-ty.rs index 1b6bcfbb9fc..609a5b0de6b 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.rs +++ b/src/test/ui/did_you_mean/bad-assoc-ty.rs @@ -32,6 +32,8 @@ type G = dyn 'static + (Send)::AssocTy; // Recovery should not apply in this context. type H = Fn(u8) -> (u8)::Output; //~^ ERROR ambiguous associated type +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition macro_rules! ty { ($ty: ty) => ($ty::AssocTy); diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 0e2fdf9f6c2..11514a28b2c 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -41,13 +41,13 @@ LL | type G = dyn 'static + (Send)::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `::AssocTy` error: missing angle brackets in associated item path - --> $DIR/bad-assoc-ty.rs:44:10 + --> $DIR/bad-assoc-ty.rs:46:10 | LL | type I = ty!()::AssocTy; | ^^^^^^^^^^^^^^ help: try: `::AssocTy` error: missing angle brackets in associated item path - --> $DIR/bad-assoc-ty.rs:37:19 + --> $DIR/bad-assoc-ty.rs:39:19 | LL | ($ty: ty) => ($ty::AssocTy); | ^^^^^^^^^^^^ help: try: `<$ty>::AssocTy` @@ -99,6 +99,20 @@ error[E0223]: ambiguous associated type LL | type G = dyn 'static + (Send)::AssocTy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Send + 'static) as Trait>::AssocTy` +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/bad-assoc-ty.rs:33:10 + | +LL | type H = Fn(u8) -> (u8)::Output; + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(bare_trait_objects)]` on by default + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | type H = (u8)>::Output; + | ++++ + + error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:33:10 | @@ -106,7 +120,7 @@ LL | type H = Fn(u8) -> (u8)::Output; | ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Fn(u8) -> u8 + 'static) as Trait>::Output` error[E0223]: ambiguous associated type - --> $DIR/bad-assoc-ty.rs:37:19 + --> $DIR/bad-assoc-ty.rs:39:19 | LL | ($ty: ty) => ($ty::AssocTy); | ^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` @@ -117,13 +131,13 @@ LL | type J = ty!(u8); = note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0223]: ambiguous associated type - --> $DIR/bad-assoc-ty.rs:44:10 + --> $DIR/bad-assoc-ty.rs:46:10 | LL | type I = ty!()::AssocTy; | ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:49:13 + --> $DIR/bad-assoc-ty.rs:51:13 | LL | fn foo>(x: X) {} | ^ ^ not allowed in type signatures @@ -136,7 +150,7 @@ LL | fn foo, T>(x: X) {} | ~ ~ +++ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:52:34 + --> $DIR/bad-assoc-ty.rs:54:34 | LL | fn bar(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures @@ -147,7 +161,7 @@ LL | fn bar(_: F) where F: Fn() -> T {} | +++ ~ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:55:19 + --> $DIR/bad-assoc-ty.rs:57:19 | LL | fn baz _>(_: F) {} | ^ not allowed in type signatures @@ -158,7 +172,7 @@ LL | fn baz T, T>(_: F) {} | ~+++ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/bad-assoc-ty.rs:58:33 + --> $DIR/bad-assoc-ty.rs:60:33 | LL | struct L(F) where F: Fn() -> _; | ^ not allowed in type signatures @@ -169,7 +183,7 @@ LL | struct L(F) where F: Fn() -> T; | +++ ~ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/bad-assoc-ty.rs:60:30 + --> $DIR/bad-assoc-ty.rs:62:30 | LL | struct M where F: Fn() -> _ { | ^ not allowed in type signatures @@ -180,7 +194,7 @@ LL | struct M where F: Fn() -> T { | +++ ~ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for enums - --> $DIR/bad-assoc-ty.rs:64:28 + --> $DIR/bad-assoc-ty.rs:66:28 | LL | enum N where F: Fn() -> _ { | ^ not allowed in type signatures @@ -191,7 +205,7 @@ LL | enum N where F: Fn() -> T { | +++ ~ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for unions - --> $DIR/bad-assoc-ty.rs:69:29 + --> $DIR/bad-assoc-ty.rs:71:29 | LL | union O where F: Fn() -> _ { | ^ not allowed in type signatures @@ -202,7 +216,7 @@ LL | union O where F: Fn() -> T { | +++ ~ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for traits - --> $DIR/bad-assoc-ty.rs:74:29 + --> $DIR/bad-assoc-ty.rs:76:29 | LL | trait P where F: Fn() -> _ { | ^ not allowed in type signatures @@ -213,7 +227,7 @@ LL | trait P where F: Fn() -> T { | +++ ~ error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions - --> $DIR/bad-assoc-ty.rs:79:38 + --> $DIR/bad-assoc-ty.rs:81:38 | LL | fn foo(_: F) where F: Fn() -> _ {} | ^ not allowed in type signatures @@ -223,7 +237,7 @@ help: use type parameters instead LL | fn foo(_: F) where F: Fn() -> T {} | +++ ~ -error: aborting due to 28 previous errors +error: aborting due to 28 previous errors; 1 warning emitted Some errors have detailed explanations: E0121, E0223. For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs index 23ca36b71e0..a074b5fa5f7 100644 --- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs +++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs @@ -6,6 +6,14 @@ fn function(x: &SomeTrait, y: Box) { //~| WARN this is accepted in the current edition //~| ERROR trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition let _x: &SomeTrait = todo!(); //~^ ERROR trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr index c9bb08cf35c..b8e4942dfef 100644 --- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr +++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr @@ -2,7 +2,7 @@ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:4:17 | LL | fn function(x: &SomeTrait, y: Box) { - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | note: the lint level is defined here --> $DIR/dyn-2018-edition-lint.rs:2:8 @@ -11,24 +11,95 @@ LL | #[deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &dyn SomeTrait, y: Box) { + | error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:4:35 | LL | fn function(x: &SomeTrait, y: Box) { - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &SomeTrait, y: Box) { + | error: trait objects without an explicit `dyn` are deprecated - --> $DIR/dyn-2018-edition-lint.rs:9:14 + --> $DIR/dyn-2018-edition-lint.rs:17:14 | LL | let _x: &SomeTrait = todo!(); - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - let _x: &SomeTrait = todo!(); +LL + let _x: &dyn SomeTrait = todo!(); + | -error: aborting due to 3 previous errors +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-2018-edition-lint.rs:4:17 + | +LL | fn function(x: &SomeTrait, y: Box) { + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &dyn SomeTrait, y: Box) { + | + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-2018-edition-lint.rs:4:17 + | +LL | fn function(x: &SomeTrait, y: Box) { + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &dyn SomeTrait, y: Box) { + | + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-2018-edition-lint.rs:4:35 + | +LL | fn function(x: &SomeTrait, y: Box) { + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &SomeTrait, y: Box) { + | + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-2018-edition-lint.rs:4:35 + | +LL | fn function(x: &SomeTrait, y: Box) { + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &SomeTrait, y: Box) { + | + +error: aborting due to 7 previous errors diff --git a/src/test/ui/dyn-keyword/dyn-2021-edition-error.rs b/src/test/ui/dyn-keyword/dyn-2021-edition-error.rs index bc1bed8a9a4..0f05d8753ea 100644 --- a/src/test/ui/dyn-keyword/dyn-2021-edition-error.rs +++ b/src/test/ui/dyn-keyword/dyn-2021-edition-error.rs @@ -4,7 +4,6 @@ fn function(x: &SomeTrait, y: Box) { //~^ ERROR trait objects must include the `dyn` keyword //~| ERROR trait objects must include the `dyn` keyword let _x: &SomeTrait = todo!(); - //~^ ERROR trait objects must include the `dyn` keyword } trait SomeTrait {} diff --git a/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr b/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr index 730bc691bf8..b5bc359d716 100644 --- a/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr +++ b/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr @@ -1,14 +1,3 @@ -error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/dyn-2021-edition-error.rs:6:14 - | -LL | let _x: &SomeTrait = todo!(); - | ^^^^^^^^^ - | -help: add `dyn` keyword before this trait - | -LL | let _x: &dyn SomeTrait = todo!(); - | +++ - error[E0782]: trait objects must include the `dyn` keyword --> $DIR/dyn-2021-edition-error.rs:3:17 | @@ -17,8 +6,9 @@ LL | fn function(x: &SomeTrait, y: Box) { | help: add `dyn` keyword before this trait | -LL | fn function(x: &dyn SomeTrait, y: Box) { - | +++ +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &dyn SomeTrait, y: Box) { + | error[E0782]: trait objects must include the `dyn` keyword --> $DIR/dyn-2021-edition-error.rs:3:35 @@ -28,9 +18,10 @@ LL | fn function(x: &SomeTrait, y: Box) { | help: add `dyn` keyword before this trait | -LL | fn function(x: &SomeTrait, y: Box) { - | +++ +LL - fn function(x: &SomeTrait, y: Box) { +LL + fn function(x: &SomeTrait, y: Box) { + | -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0782`. diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed index 25caa6a8030..00069a3e7ad 100644 --- a/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed @@ -15,8 +15,6 @@ impl fmt::Display for Foo { ::fmt(self, f) //~^ ERROR trait objects without an explicit `dyn` are deprecated //~| WARNING this is accepted in the current edition - //~| ERROR trait objects without an explicit `dyn` are deprecated - //~| WARNING this is accepted in the current edition } } diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.rs b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs index cf72da2b61e..ee5fee4cfb8 100644 --- a/src/test/ui/dyn-keyword/dyn-angle-brackets.rs +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs @@ -15,8 +15,6 @@ impl fmt::Display for Foo { ::fmt(self, f) //~^ ERROR trait objects without an explicit `dyn` are deprecated //~| WARNING this is accepted in the current edition - //~| ERROR trait objects without an explicit `dyn` are deprecated - //~| WARNING this is accepted in the current edition } } diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr index ef0f5b7f59d..fd4030e9622 100644 --- a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr @@ -2,7 +2,7 @@ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-angle-brackets.rs:15:10 | LL | ::fmt(self, f) - | ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug` + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/dyn-angle-brackets.rs:4:9 @@ -11,15 +11,11 @@ LL | #![deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see - -error: trait objects without an explicit `dyn` are deprecated - --> $DIR/dyn-angle-brackets.rs:15:10 +help: use `dyn` | -LL | ::fmt(self, f) - | ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug` - | - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see +LL - ::fmt(self, f) +LL + ::fmt(self, f) + | -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/editions/dyn-trait-sugg-2021.rs b/src/test/ui/editions/dyn-trait-sugg-2021.rs index 47c48e7ec9e..de0444b63e2 100644 --- a/src/test/ui/editions/dyn-trait-sugg-2021.rs +++ b/src/test/ui/editions/dyn-trait-sugg-2021.rs @@ -3,10 +3,10 @@ trait Foo {} impl dyn Foo { - fn hi(_x: T) {} + fn hi(_x: T) {} } fn main() { Foo::hi(123); - //~^ ERROR trait objects without an explicit `dyn` are deprecated + //~^ ERROR trait objects must include the `dyn` keyword } diff --git a/src/test/ui/editions/dyn-trait-sugg-2021.stderr b/src/test/ui/editions/dyn-trait-sugg-2021.stderr index a7119b073ab..8c68dec1df7 100644 --- a/src/test/ui/editions/dyn-trait-sugg-2021.stderr +++ b/src/test/ui/editions/dyn-trait-sugg-2021.stderr @@ -1,8 +1,13 @@ -error[E0782]: trait objects without an explicit `dyn` are deprecated +error[E0782]: trait objects must include the `dyn` keyword --> $DIR/dyn-trait-sugg-2021.rs:10:5 | LL | Foo::hi(123); - | ^^^ help: use `dyn`: `` + | ^^^ + | +help: add `dyn` keyword before this trait + | +LL | ::hi(123); + | ++++ + error: aborting due to previous error diff --git a/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr b/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr index 53924e24e46..9db9cfc7ff0 100644 --- a/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr +++ b/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr @@ -23,8 +23,8 @@ LL | | }); note: required by a bound in `Option::::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL | -LL | pub fn and_then Option>(self, f: F) -> Option { - | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Option::::and_then` +LL | F: ~const FnOnce(T) -> Option, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Option::::and_then` error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs index 48b4a4fc393..f01da8c61ed 100644 --- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -9,7 +9,5 @@ fn foo<'a>(arg: Box>) {} //~| ERROR: parenthesized generic arguments cannot be used //~| ERROR this associated type takes 0 generic arguments but 1 generic argument //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments - //~| WARNING: trait objects without an explicit `dyn` are deprecated - //~| WARNING: this is accepted in the current edition fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index 5e0f98c0bbf..6014a02c4d9 100644 --- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -10,16 +10,6 @@ error: parenthesized generic arguments cannot be used in associated type constra LL | fn foo<'a>(arg: Box>) {} | ^^^^^ -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/gat-trait-path-parenthesised-args.rs:7:29 - | -LL | fn foo<'a>(arg: Box>) {} - | ^^ help: use `dyn`: `dyn 'a` - | - = note: `#[warn(bare_trait_objects)]` on by default - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/gat-trait-path-parenthesised-args.rs:7:27 | @@ -50,6 +40,6 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/issues/issue-28344.rs b/src/test/ui/issues/issue-28344.rs index 4da7ee21baa..1a6a7f46b27 100644 --- a/src/test/ui/issues/issue-28344.rs +++ b/src/test/ui/issues/issue-28344.rs @@ -4,8 +4,12 @@ fn main() { let x: u8 = BitXor::bitor(0 as u8, 0 as u8); //~^ ERROR must be specified //~| no function or associated item named + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition let g = BitXor::bitor; //~^ ERROR must be specified //~| no function or associated item named + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition } diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 4955dea564d..b1d1c01b27a 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -1,3 +1,17 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-28344.rs:4:17 + | +LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); + | ^^^^^^ + | + = note: `#[warn(bare_trait_objects)]` on by default + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let x: u8 = ::bitor(0 as u8, 0 as u8); + | ++++ + + error[E0191]: the value of the associated type `Output` (from trait `BitXor`) must be specified --> $DIR/issue-28344.rs:4:17 | @@ -13,14 +27,27 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | function or associated item not found in `dyn BitXor<_>` | help: there is an associated function with a similar name: `bitxor` +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-28344.rs:10:13 + | +LL | let g = BitXor::bitor; + | ^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let g = ::bitor; + | ++++ + + error[E0191]: the value of the associated type `Output` (from trait `BitXor`) must be specified - --> $DIR/issue-28344.rs:8:13 + --> $DIR/issue-28344.rs:10:13 | LL | let g = BitXor::bitor; | ^^^^^^ help: specify the associated type: `BitXor` error[E0599]: no function or associated item named `bitor` found for trait object `dyn BitXor<_>` in the current scope - --> $DIR/issue-28344.rs:8:21 + --> $DIR/issue-28344.rs:10:21 | LL | let g = BitXor::bitor; | ^^^^^ @@ -28,7 +55,7 @@ LL | let g = BitXor::bitor; | function or associated item not found in `dyn BitXor<_>` | help: there is an associated function with a similar name: `bitxor` -error: aborting due to 4 previous errors +error: aborting due to 4 previous errors; 2 warnings emitted Some errors have detailed explanations: E0191, E0599. For more information about an error, try `rustc --explain E0191`. diff --git a/src/test/ui/issues/issue-47706-trait.stderr b/src/test/ui/issues/issue-47706-trait.stderr index eb0c80f8f0d..d596b4a69f3 100644 --- a/src/test/ui/issues/issue-47706-trait.stderr +++ b/src/test/ui/issues/issue-47706-trait.stderr @@ -11,8 +11,8 @@ LL | None::<()>.map(Self::f); note: required by a bound in `Option::::map` --> $SRC_DIR/core/src/option.rs:LL:COL | -LL | pub fn map U>(self, f: F) -> Option { - | ^^^^^^^^^^^^^^ required by this bound in `Option::::map` +LL | F: ~const FnOnce(T) -> U, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Option::::map` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-47706.stderr b/src/test/ui/issues/issue-47706.stderr index 237b2b9e798..0b4f84a330a 100644 --- a/src/test/ui/issues/issue-47706.stderr +++ b/src/test/ui/issues/issue-47706.stderr @@ -12,8 +12,8 @@ LL | self.foo.map(Foo::new) note: required by a bound in `Option::::map` --> $SRC_DIR/core/src/option.rs:LL:COL | -LL | pub fn map U>(self, f: F) -> Option { - | ^^^^^^^^^^^^^^ required by this bound in `Option::::map` +LL | F: ~const FnOnce(T) -> U, + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Option::::map` error[E0593]: function is expected to take 0 arguments, but it takes 1 argument --> $DIR/issue-47706.rs:27:9 diff --git a/src/test/ui/issues/issue-58734.rs b/src/test/ui/issues/issue-58734.rs index b253c135b8c..c838fde5d73 100644 --- a/src/test/ui/issues/issue-58734.rs +++ b/src/test/ui/issues/issue-58734.rs @@ -19,4 +19,6 @@ fn main() { // no object safety error Trait::nonexistent(()); //~^ ERROR no function or associated item named `nonexistent` found + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition } diff --git a/src/test/ui/issues/issue-58734.stderr b/src/test/ui/issues/issue-58734.stderr index 5e98cfadf8a..a91a1b3778e 100644 --- a/src/test/ui/issues/issue-58734.stderr +++ b/src/test/ui/issues/issue-58734.stderr @@ -1,9 +1,23 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-58734.rs:20:5 + | +LL | Trait::nonexistent(()); + | ^^^^^ + | + = note: `#[warn(bare_trait_objects)]` on by default + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | ::nonexistent(()); + | ++++ + + error[E0599]: no function or associated item named `nonexistent` found for trait object `dyn Trait` in the current scope --> $DIR/issue-58734.rs:20:12 | LL | Trait::nonexistent(()); | ^^^^^^^^^^^ function or associated item not found in `dyn Trait` -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-86756.stderr b/src/test/ui/issues/issue-86756.stderr index 0d576909a35..5b2f04ffa83 100644 --- a/src/test/ui/issues/issue-86756.stderr +++ b/src/test/ui/issues/issue-86756.stderr @@ -18,11 +18,16 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-86756.rs:5:15 | LL | eq:: - | ^^^ help: use `dyn`: `dyn Foo` + | ^^^ | = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - eq:: +LL + eq:: + | error[E0107]: missing generics for trait `Foo` --> $DIR/issue-86756.rs:5:15 diff --git a/src/test/ui/lint/bare-trait-objects-path.rs b/src/test/ui/lint/bare-trait-objects-path.rs index 0a7c5a8dbd1..0e2294715cd 100644 --- a/src/test/ui/lint/bare-trait-objects-path.rs +++ b/src/test/ui/lint/bare-trait-objects-path.rs @@ -21,4 +21,6 @@ fn main() { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let _: Dyn::Ty; //~ ERROR ambiguous associated type + //~^ WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition } diff --git a/src/test/ui/lint/bare-trait-objects-path.stderr b/src/test/ui/lint/bare-trait-objects-path.stderr index 3477b01b6b5..4b8c2b539d5 100644 --- a/src/test/ui/lint/bare-trait-objects-path.stderr +++ b/src/test/ui/lint/bare-trait-objects-path.stderr @@ -1,3 +1,17 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/bare-trait-objects-path.rs:23:12 + | +LL | let _: Dyn::Ty; + | ^^^ + | + = note: `#[warn(bare_trait_objects)]` on by default + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let _: ::Ty; + | ++++ + + error[E0223]: ambiguous associated type --> $DIR/bare-trait-objects-path.rs:23:12 | @@ -8,30 +22,41 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bare-trait-objects-path.rs:14:5 | LL | Dyn::func(); - | ^^^ help: use `dyn`: `` + | ^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL | ::func(); + | ++++ + warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bare-trait-objects-path.rs:17:5 | LL | ::Dyn::func(); - | ^^^^^ help: use `dyn`: `` + | ^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL | ::func(); + | ++++++ ++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bare-trait-objects-path.rs:20:5 | LL | Dyn::CONST; - | ^^^ help: use `dyn`: `` + | ^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL | ::CONST; + | ++++ + -error: aborting due to previous error; 3 warnings emitted +error: aborting due to previous error; 4 warnings emitted For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs index 9b1edba41aa..631a8cb2f08 100644 --- a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs +++ b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs @@ -10,5 +10,9 @@ pub trait SomeTrait {} pub fn function(_x: Box) {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition fn main() {} diff --git a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr index d945cc3347a..99d97ba52a0 100644 --- a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr @@ -2,11 +2,44 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/allowed-group-warn-by-default-lint.rs:10:25 | LL | pub fn function(_x: Box) {} - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | = note: requested on the command line with `--force-warn bare-trait-objects` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | -warning: 1 warning emitted +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/allowed-group-warn-by-default-lint.rs:10:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/allowed-group-warn-by-default-lint.rs:10:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/cap-lints-allow.rs b/src/test/ui/lint/force-warn/cap-lints-allow.rs index 9609ea99431..fdba7f4105e 100644 --- a/src/test/ui/lint/force-warn/cap-lints-allow.rs +++ b/src/test/ui/lint/force-warn/cap-lints-allow.rs @@ -8,5 +8,9 @@ pub trait SomeTrait {} pub fn function(_x: Box) {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition fn main() {} diff --git a/src/test/ui/lint/force-warn/cap-lints-allow.stderr b/src/test/ui/lint/force-warn/cap-lints-allow.stderr index f3ae16b5657..90496ca7d20 100644 --- a/src/test/ui/lint/force-warn/cap-lints-allow.stderr +++ b/src/test/ui/lint/force-warn/cap-lints-allow.stderr @@ -2,11 +2,44 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/cap-lints-allow.rs:8:25 | LL | pub fn function(_x: Box) {} - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | = note: requested on the command line with `--force-warn bare-trait-objects` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | -warning: 1 warning emitted +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/cap-lints-allow.rs:8:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/cap-lints-allow.rs:8:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs index 9736027452a..7ad7462ddc5 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs +++ b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs @@ -8,5 +8,9 @@ pub trait SomeTrait {} pub fn function(_x: Box) {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition fn main() {} diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr index dc62521bf89..b6d36eaac44 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr @@ -2,11 +2,44 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25 | LL | pub fn function(_x: Box) {} - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | -warning: 1 warning emitted +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.rs b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.rs index 99cad614c25..ee5a18c3829 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.rs +++ b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.rs @@ -10,5 +10,9 @@ pub trait SomeTrait {} pub fn function(_x: Box) {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition fn main() {} diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr index fcbae024eb6..e8fdaa72cc0 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr @@ -2,11 +2,44 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-lint-group.rs:10:25 | LL | pub fn function(_x: Box) {} - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | -warning: 1 warning emitted +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/lint-group-allowed-lint-group.rs:10:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/lint-group-allowed-lint-group.rs:10:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs index f0aacd77340..248aece6fe7 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs +++ b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs @@ -10,5 +10,9 @@ pub trait SomeTrait {} pub fn function(_x: Box) {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition +//~| WARN trait objects without an explicit `dyn` are deprecated +//~| WARN this is accepted in the current edition fn main() {} diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr index 1212ae083c2..2de30d0c2f4 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr @@ -2,11 +2,44 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25 | LL | pub fn function(_x: Box) {} - | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait` + | ^^^^^^^^^ | = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | -warning: 1 warning emitted +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25 + | +LL | pub fn function(_x: Box) {} + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub fn function(_x: Box) {} +LL + pub fn function(_x: Box) {} + | + +warning: 3 warnings emitted diff --git a/src/test/ui/lint/unused/unused-result.rs b/src/test/ui/lint/unused/unused-result.rs index a65e98990dc..e283eaa88dd 100644 --- a/src/test/ui/lint/unused/unused-result.rs +++ b/src/test/ui/lint/unused/unused-result.rs @@ -31,7 +31,7 @@ fn test2() { } fn main() { - foo::(); //~ ERROR: unused result + foo::(); //~ ERROR: unused result of type `isize` foo::(); //~ ERROR: unused `MustUse` that must be used foo::(); //~ ERROR: unused `MustUseMsg` that must be used //~^ NOTE: some message diff --git a/src/test/ui/lint/unused/unused-result.stderr b/src/test/ui/lint/unused/unused-result.stderr index 1b1dcab3a1b..087e06341cd 100644 --- a/src/test/ui/lint/unused/unused-result.stderr +++ b/src/test/ui/lint/unused/unused-result.stderr @@ -18,7 +18,7 @@ LL | foo::(); | = note: some message -error: unused result +error: unused result of type `isize` --> $DIR/unused-result.rs:34:5 | LL | foo::(); diff --git a/src/test/ui/mir/remove-zsts-query-cycle.rs b/src/test/ui/mir/remove-zsts-query-cycle.rs index 8f93c6cadff..be4d68f2de7 100644 --- a/src/test/ui/mir/remove-zsts-query-cycle.rs +++ b/src/test/ui/mir/remove-zsts-query-cycle.rs @@ -2,7 +2,7 @@ // optimized mir -> remove zsts -> layout of a generator -> optimized mir. // // edition:2018 -// compile-flags: --crate-type=lib +// compile-flags: --crate-type=lib -Zinline-mir=yes // build-pass pub async fn listen() -> Result<(), std::io::Error> { diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs index 87ba230eab5..32aeee29472 100644 --- a/src/test/ui/parser/duplicate-visibility.rs +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -1,6 +1,9 @@ fn main() {} -extern "C" { +extern "C" { //~ NOTE while parsing this item list starting here pub pub fn foo(); //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` -} + //~| NOTE expected one of 9 possible tokens + //~| HELP there is already a visibility modifier, remove one + //~| NOTE explicit visibility first seen here +} //~ NOTE the item list ends here diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr index d9815fc7395..97144ac2f64 100644 --- a/src/test/ui/parser/duplicate-visibility.stderr +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -7,10 +7,16 @@ LL | pub pub fn foo(); | ^^^ | | | expected one of 9 possible tokens - | help: visibility `pub` must come before `pub pub`: `pub pub pub` -LL | + | help: there is already a visibility modifier, remove one +... LL | } | - the item list ends here + | +note: explicit visibility first seen here + --> $DIR/duplicate-visibility.rs:4:5 + | +LL | pub pub fn foo(); + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-87694-duplicated-pub.rs b/src/test/ui/parser/issue-87694-duplicated-pub.rs new file mode 100644 index 00000000000..e3ea61dc4ad --- /dev/null +++ b/src/test/ui/parser/issue-87694-duplicated-pub.rs @@ -0,0 +1,5 @@ +pub const pub fn test() {} +//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` +//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe` +//~| HELP there is already a visibility modifier, remove one +//~| NOTE explicit visibility first seen here diff --git a/src/test/ui/parser/issue-87694-duplicated-pub.stderr b/src/test/ui/parser/issue-87694-duplicated-pub.stderr new file mode 100644 index 00000000000..8d242bc9de5 --- /dev/null +++ b/src/test/ui/parser/issue-87694-duplicated-pub.stderr @@ -0,0 +1,17 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-87694-duplicated-pub.rs:1:11 + | +LL | pub const pub fn test() {} + | ^^^ + | | + | expected one of `async`, `extern`, `fn`, or `unsafe` + | help: there is already a visibility modifier, remove one + | +note: explicit visibility first seen here + --> $DIR/issue-87694-duplicated-pub.rs:1:1 + | +LL | pub const pub fn test() {} + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-87694-misplaced-pub.rs b/src/test/ui/parser/issue-87694-misplaced-pub.rs new file mode 100644 index 00000000000..3f824617cad --- /dev/null +++ b/src/test/ui/parser/issue-87694-misplaced-pub.rs @@ -0,0 +1,5 @@ +const pub fn test() {} +//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` +//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe` +//~| HELP visibility `pub` must come before `const` +//~| SUGGESTION pub const diff --git a/src/test/ui/parser/issue-87694-misplaced-pub.stderr b/src/test/ui/parser/issue-87694-misplaced-pub.stderr new file mode 100644 index 00000000000..94c6a29efcb --- /dev/null +++ b/src/test/ui/parser/issue-87694-misplaced-pub.stderr @@ -0,0 +1,11 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-87694-misplaced-pub.rs:1:7 + | +LL | const pub fn test() {} + | ------^^^ + | | | + | | expected one of `async`, `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const`: `pub const` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issues/issue-68890-2.rs b/src/test/ui/parser/issues/issue-68890-2.rs index 0a6e26acfc7..29c12352146 100644 --- a/src/test/ui/parser/issues/issue-68890-2.rs +++ b/src/test/ui/parser/issues/issue-68890-2.rs @@ -3,5 +3,3 @@ fn main() {} type X<'a> = (?'a) +; //~^ ERROR `?` may only modify trait bounds, not lifetime bounds //~| ERROR at least one trait is required for an object type -//~| WARN trait objects without an explicit `dyn` are deprecated -//~| WARN this is accepted in the current edition diff --git a/src/test/ui/parser/issues/issue-68890-2.stderr b/src/test/ui/parser/issues/issue-68890-2.stderr index 1a64b9a017d..d9fb7beebdb 100644 --- a/src/test/ui/parser/issues/issue-68890-2.stderr +++ b/src/test/ui/parser/issues/issue-68890-2.stderr @@ -4,22 +4,12 @@ error: `?` may only modify trait bounds, not lifetime bounds LL | type X<'a> = (?'a) +; | ^ -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/issue-68890-2.rs:3:14 - | -LL | type X<'a> = (?'a) +; - | ^^^^^^^ help: use `dyn`: `dyn (?'a) +` - | - = note: `#[warn(bare_trait_objects)]` on by default - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - error[E0224]: at least one trait is required for an object type --> $DIR/issue-68890-2.rs:3:14 | LL | type X<'a> = (?'a) +; | ^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs index e68ee747cfd..5f731f8db77 100644 --- a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs +++ b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs @@ -13,11 +13,7 @@ mac!('a); // avoid false positives fn y<'a>(y: &mut 'a + Send) { //~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a` - //~| WARNING trait objects without an explicit `dyn` are deprecated - //~| WARN this is accepted in the current edition //~| ERROR at least one trait is required for an object type let z = y as &mut 'a + Send; //~^ ERROR expected value, found trait `Send` - //~| WARNING trait objects without an explicit `dyn` are deprecated - //~| WARN this is accepted in the current edition } diff --git a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr index 48c2b2a19d4..799bc16bd6a 100644 --- a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr +++ b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr @@ -22,37 +22,18 @@ LL | mac!('a); = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0423]: expected value, found trait `Send` - --> $DIR/issue-73568-lifetime-after-mut.rs:19:28 + --> $DIR/issue-73568-lifetime-after-mut.rs:17:28 | LL | let z = y as &mut 'a + Send; | ^^^^ not a value -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/issue-73568-lifetime-after-mut.rs:14:18 - | -LL | fn y<'a>(y: &mut 'a + Send) { - | ^^ help: use `dyn`: `dyn 'a` - | - = note: `#[warn(bare_trait_objects)]` on by default - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/issue-73568-lifetime-after-mut.rs:19:23 - | -LL | let z = y as &mut 'a + Send; - | ^^ help: use `dyn`: `dyn 'a` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - error[E0224]: at least one trait is required for an object type --> $DIR/issue-73568-lifetime-after-mut.rs:14:18 | LL | fn y<'a>(y: &mut 'a + Send) { | ^^ -error: aborting due to 5 previous errors; 2 warnings emitted +error: aborting due to 5 previous errors Some errors have detailed explanations: E0178, E0224, E0423. For more information about an error, try `rustc --explain E0178`. diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs index 7c3d915a4c0..df0cd54399a 100644 --- a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs @@ -1,11 +1,9 @@ // edition:2018 -// Test that even when `const` is already present, the proposed fix is `const const async`, -// like for `pub pub`. +// Test that even when `const` is already present, the proposed fix is to remove the second `const` const async const fn test() {} //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const` //~| NOTE expected one of `extern`, `fn`, or `unsafe` -//~| HELP `const` must come before `async` -//~| SUGGESTION const async -//~| NOTE keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern` +//~| HELP `const` already used earlier, remove this one +//~| NOTE `const` first seen here diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr index 56280912540..977c6ebfef3 100644 --- a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr +++ b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr @@ -1,13 +1,17 @@ error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const` - --> $DIR/const-async-const.rs:6:13 + --> $DIR/const-async-const.rs:5:13 | LL | const async const fn test() {} - | ------^^^^^ - | | | - | | expected one of `extern`, `fn`, or `unsafe` - | help: `const` must come before `async`: `const async` + | ^^^^^ + | | + | expected one of `extern`, `fn`, or `unsafe` + | help: `const` already used earlier, remove this one | - = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern` +note: `const` first seen here + --> $DIR/const-async-const.rs:5:1 + | +LL | const async const fn test() {} + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.rs b/src/test/ui/parser/macro/trait-object-macro-matcher.rs index 663739f235a..560195977d0 100644 --- a/src/test/ui/parser/macro/trait-object-macro-matcher.rs +++ b/src/test/ui/parser/macro/trait-object-macro-matcher.rs @@ -11,6 +11,4 @@ fn main() { m!('static); //~^ ERROR lifetime in trait object type must be followed by `+` //~| ERROR at least one trait is required for an object type - //~| WARN trait objects without an explicit `dyn` are deprecated - //~| WARN this is accepted in the current edition } diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr index 876bfd389cb..40082564bad 100644 --- a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr +++ b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr @@ -4,22 +4,12 @@ error: lifetime in trait object type must be followed by `+` LL | m!('static); | ^^^^^^^ -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/trait-object-macro-matcher.rs:11:8 - | -LL | m!('static); - | ^^^^^^^ help: use `dyn`: `dyn 'static` - | - = note: `#[warn(bare_trait_objects)]` on by default - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - error[E0224]: at least one trait is required for an object type --> $DIR/trait-object-macro-matcher.rs:11:8 | LL | m!('static); | ^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr index 657288c70f3..a852337b6fe 100644 --- a/src/test/ui/parser/trait-object-trait-parens.stderr +++ b/src/test/ui/parser/trait-object-trait-parens.stderr @@ -20,29 +20,16 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/trait-object-trait-parens.rs:8:16 | LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/trait-object-trait-parens.rs:13:16 +help: use `dyn` | -LL | let _: Box Trait<'a>) + (Obj)>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn ?Sized + (for<'a> Trait<'a>) + (Obj)` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/trait-object-trait-parens.rs:18:16 - | -LL | let _: Box Trait<'a> + (Obj) + (?Sized)>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn for<'a> Trait<'a> + (Obj) + (?Sized)` - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see +LL - let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; +LL + let _: Box Trait<'a>)>; + | error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/trait-object-trait-parens.rs:8:35 @@ -55,6 +42,20 @@ LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + for<'a> Trait<'a> {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/trait-object-trait-parens.rs:13:16 + | +LL | let _: Box Trait<'a>) + (Obj)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - let _: Box Trait<'a>) + (Obj)>; +LL + let _: Box Trait<'a>) + (Obj)>; + | + error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/trait-object-trait-parens.rs:13:47 | @@ -66,6 +67,20 @@ LL | let _: Box Trait<'a>) + (Obj)>; = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: for<'a> Trait<'a> + Obj {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/trait-object-trait-parens.rs:18:16 + | +LL | let _: Box Trait<'a> + (Obj) + (?Sized)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - let _: Box Trait<'a> + (Obj) + (?Sized)>; +LL + let _: Box Trait<'a> + (Obj) + (?Sized)>; + | + error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/trait-object-trait-parens.rs:18:36 | diff --git a/src/test/ui/suggestions/as-ref-2.stderr b/src/test/ui/suggestions/as-ref-2.stderr index 86a175098c6..3c9d0f72abe 100644 --- a/src/test/ui/suggestions/as-ref-2.stderr +++ b/src/test/ui/suggestions/as-ref-2.stderr @@ -11,8 +11,8 @@ LL | let _y = foo; note: this function takes ownership of the receiver `self`, which moves `foo` --> $SRC_DIR/core/src/option.rs:LL:COL | -LL | pub fn map U>(self, f: F) -> Option { - | ^^^^ +LL | pub const fn map(self, f: F) -> Option + | ^^^^ help: consider calling `.as_ref()` to borrow the type's contents | LL | let _x: Option = foo.as_ref().map(|s| bar(&s)); diff --git a/src/test/ui/suggestions/issue-61963.rs b/src/test/ui/suggestions/issue-61963.rs index d31ed01b191..a27c3845253 100644 --- a/src/test/ui/suggestions/issue-61963.rs +++ b/src/test/ui/suggestions/issue-61963.rs @@ -18,10 +18,20 @@ pub struct Qux(T); pub struct Foo { //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition qux: Qux>, bar: Box, //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition } fn main() {} diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr index bb487920e3b..1eebd8d60ca 100644 --- a/src/test/ui/suggestions/issue-61963.stderr +++ b/src/test/ui/suggestions/issue-61963.stderr @@ -1,8 +1,8 @@ error: trait objects without an explicit `dyn` are deprecated - --> $DIR/issue-61963.rs:22:14 + --> $DIR/issue-61963.rs:28:14 | LL | bar: Box, - | ^^^ help: use `dyn`: `dyn Bar` + | ^^^ | note: the lint level is defined here --> $DIR/issue-61963.rs:3:9 @@ -11,15 +11,95 @@ LL | #![deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - bar: Box, +LL + bar: Box, + | error: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-61963.rs:18:1 | LL | pub struct Foo { - | ^^^ help: use `dyn`: `dyn pub` + | ^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - pub struct Foo { +LL + dyn pub struct Foo { + | -error: aborting due to 2 previous errors +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:28:14 + | +LL | bar: Box, + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - bar: Box, +LL + bar: Box, + | + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:28:14 + | +LL | bar: Box, + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - bar: Box, +LL + bar: Box, + | + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:18:1 + | +LL | pub struct Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub struct Foo { +LL + dyn pub struct Foo { + | + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:18:1 + | +LL | pub struct Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub struct Foo { +LL + dyn pub struct Foo { + | + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/issue-61963.rs:18:1 + | +LL | pub struct Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - pub struct Foo { +LL + dyn pub struct Foo { + | + +error: aborting due to 7 previous errors diff --git a/src/test/ui/traits/bound/not-on-bare-trait.stderr b/src/test/ui/traits/bound/not-on-bare-trait.stderr index 0bbf1bffda5..08f6d166d22 100644 --- a/src/test/ui/traits/bound/not-on-bare-trait.stderr +++ b/src/test/ui/traits/bound/not-on-bare-trait.stderr @@ -2,11 +2,16 @@ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/not-on-bare-trait.rs:7:12 | LL | fn foo(_x: Foo + Send) { - | ^^^^^^^^^^ help: use `dyn`: `dyn Foo + Send` + | ^^^^^^^^^^ | = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see +help: use `dyn` + | +LL - fn foo(_x: Foo + Send) { +LL + fn foo(_x: dyn Foo + Send) { + | error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time --> $DIR/not-on-bare-trait.rs:7:8 diff --git a/src/test/ui/unspecified-self-in-trait-ref.rs b/src/test/ui/unspecified-self-in-trait-ref.rs index 74a9af84cae..158b5a98557 100644 --- a/src/test/ui/unspecified-self-in-trait-ref.rs +++ b/src/test/ui/unspecified-self-in-trait-ref.rs @@ -9,12 +9,22 @@ pub trait Bar { fn main() { let a = Foo::lol(); //~^ ERROR no function or associated item named + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition let b = Foo::<_>::lol(); //~^ ERROR no function or associated item named + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition let c = Bar::lol(); //~^ ERROR no function or associated item named + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition let d = Bar::::lol(); //~^ ERROR no function or associated item named + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition let e = Bar::::lol(); //~^ ERROR must be explicitly specified + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition } diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/unspecified-self-in-trait-ref.stderr index c9518170222..2ba92187157 100644 --- a/src/test/ui/unspecified-self-in-trait-ref.stderr +++ b/src/test/ui/unspecified-self-in-trait-ref.stderr @@ -1,29 +1,95 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/unspecified-self-in-trait-ref.rs:10:13 + | +LL | let a = Foo::lol(); + | ^^^ + | + = note: `#[warn(bare_trait_objects)]` on by default + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let a = ::lol(); + | ++++ + + error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope --> $DIR/unspecified-self-in-trait-ref.rs:10:18 | LL | let a = Foo::lol(); | ^^^ function or associated item not found in `dyn Foo<_>` +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/unspecified-self-in-trait-ref.rs:14:13 + | +LL | let b = Foo::<_>::lol(); + | ^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let b = >::lol(); + | ++++ + + error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope - --> $DIR/unspecified-self-in-trait-ref.rs:12:23 + --> $DIR/unspecified-self-in-trait-ref.rs:14:23 | LL | let b = Foo::<_>::lol(); | ^^^ function or associated item not found in `dyn Foo<_>` +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/unspecified-self-in-trait-ref.rs:18:13 + | +LL | let c = Bar::lol(); + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let c = ::lol(); + | ++++ + + error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<_, _>` in the current scope - --> $DIR/unspecified-self-in-trait-ref.rs:14:18 + --> $DIR/unspecified-self-in-trait-ref.rs:18:18 | LL | let c = Bar::lol(); | ^^^ function or associated item not found in `dyn Bar<_, _>` +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/unspecified-self-in-trait-ref.rs:22:13 + | +LL | let d = Bar::::lol(); + | ^^^^^^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let d = >::lol(); + | ++++ + + error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar` in the current scope - --> $DIR/unspecified-self-in-trait-ref.rs:16:30 + --> $DIR/unspecified-self-in-trait-ref.rs:22:30 | LL | let d = Bar::::lol(); | ^^^ function or associated item not found in `dyn Bar` +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/unspecified-self-in-trait-ref.rs:26:13 + | +LL | let e = Bar::::lol(); + | ^^^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL | let e = >::lol(); + | ++++ + + error[E0393]: the type parameter `A` must be explicitly specified - --> $DIR/unspecified-self-in-trait-ref.rs:18:13 + --> $DIR/unspecified-self-in-trait-ref.rs:26:13 | LL | / pub trait Bar { LL | | fn foo(&self); @@ -35,7 +101,7 @@ LL | let e = Bar::::lol(); | = note: because of the default `Self` reference, type parameters must be specified on object types -error: aborting due to 5 previous errors +error: aborting due to 5 previous errors; 5 warnings emitted Some errors have detailed explanations: E0393, E0599. For more information about an error, try `rustc --explain E0393`.