diff options
117 files changed, 1623 insertions, 285 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 71adf9b0091..d20f19e60e8 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -8,3 +8,5 @@ a06baa56b95674fc626b3c3fd680d6a65357fe60 283abbf0e7d20176f76006825b5c52e9a4234e4c # format libstd/sys c34fbfaad38cf5829ef5cfe780dc9d58480adeaa +# move tests +cf2dff2b1e3fa55fa5415d524200070d0d7aacfe diff --git a/Cargo.lock b/Cargo.lock index 4bea3af7f3b..9b3b3951888 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4273,6 +4273,7 @@ version = "0.0.0" dependencies = [ "rustc_span", "tracing", + "tracing-core", "tracing-subscriber", "tracing-tree", ] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 2e135aafb1e..41d4a5679f1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -416,8 +416,7 @@ fn compute_hir_hash( pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { let sess = tcx.sess; - let krate = tcx.untracked_crate.steal(); - let mut resolver = tcx.resolver_for_lowering(()).steal(); + let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal(); let ast_index = index_crate(&resolver.node_id_to_def_id, &krate); let mut owners = IndexVec::from_fn_n( diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 6658ee89ad6..968c1f49b95 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -6,6 +6,7 @@ use rustc_errors::{ struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, }; use rustc_hir as hir; +use rustc_hir::def::Res; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem}; use rustc_infer::infer::TyCtxtInferExt; @@ -20,7 +21,7 @@ use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; -use rustc_span::symbol::sym; +use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; @@ -29,6 +30,7 @@ use crate::borrowck_errors; use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead; use crate::diagnostics::find_all_local_uses; +use crate::diagnostics::mutability_errors::mut_borrow_of_mutable_ref; use crate::{ borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf, InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind, @@ -356,7 +358,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. - })) = hir.find(hir.local_def_id_to_hir_id(self.mir_def_id())) + })) = hir.find(self.mir_hir_id()) && let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id) { let place = &self.move_data.move_paths[mpi].place; @@ -948,7 +950,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } (BorrowKind::Mut { .. }, BorrowKind::Shared) => { first_borrow_desc = "immutable "; - self.cannot_reborrow_already_borrowed( + let mut err = self.cannot_reborrow_already_borrowed( span, &desc_place, &msg_place, @@ -958,7 +960,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "immutable", &msg_borrow, None, - ) + ); + self.suggest_binding_for_closure_capture_self( + &mut err, + issued_borrow.borrowed_place, + &issued_spans, + ); + err } (BorrowKind::Mut { .. }, BorrowKind::Mut { .. }) => { @@ -1240,6 +1248,138 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } + fn suggest_binding_for_closure_capture_self( + &self, + err: &mut Diagnostic, + borrowed_place: Place<'tcx>, + issued_spans: &UseSpans<'tcx>, + ) { + let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; + let hir = self.infcx.tcx.hir(); + + // check whether the borrowed place is capturing `self` by mut reference + let local = borrowed_place.local; + let Some(_) = self + .body + .local_decls + .get(local) + .map(|l| mut_borrow_of_mutable_ref(l, self.local_names[local])) else { return }; + + struct ExpressionFinder<'hir> { + capture_span: Span, + closure_change_spans: Vec<Span>, + closure_arg_span: Option<Span>, + in_closure: bool, + suggest_arg: String, + hir: rustc_middle::hir::map::Map<'hir>, + closure_local_id: Option<hir::HirId>, + closure_call_changes: Vec<(Span, String)>, + } + impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> { + fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { + if e.span.contains(self.capture_span) { + if let hir::ExprKind::Closure(&hir::Closure { + movability: None, + body, + fn_arg_span, + fn_decl: hir::FnDecl{ inputs, .. }, + .. + }) = e.kind && + let Some(hir::Node::Expr(body )) = self.hir.find(body.hir_id) { + self.suggest_arg = "this: &Self".to_string(); + if inputs.len() > 0 { + self.suggest_arg.push_str(", "); + } + self.in_closure = true; + self.closure_arg_span = fn_arg_span; + self.visit_expr(body); + self.in_closure = false; + } + } + if let hir::Expr { kind: hir::ExprKind::Path(path), .. } = e { + if let hir::QPath::Resolved(_, hir::Path { segments: [seg], ..}) = path && + seg.ident.name == kw::SelfLower && self.in_closure { + self.closure_change_spans.push(e.span); + } + } + hir::intravisit::walk_expr(self, e); + } + + fn visit_local(&mut self, local: &'hir hir::Local<'hir>) { + if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } = local.pat && + let Some(init) = local.init + { + if let hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { + movability: None, + .. + }), .. } = init && + init.span.contains(self.capture_span) { + self.closure_local_id = Some(*hir_id); + } + } + hir::intravisit::walk_local(self, local); + } + + fn visit_stmt(&mut self, s: &'hir hir::Stmt<'hir>) { + if let hir::StmtKind::Semi(e) = s.kind && + let hir::ExprKind::Call(hir::Expr { kind: hir::ExprKind::Path(path), ..}, args) = e.kind && + let hir::QPath::Resolved(_, hir::Path { segments: [seg], ..}) = path && + let Res::Local(hir_id) = seg.res && + Some(hir_id) == self.closure_local_id { + let (span, arg_str) = if args.len() > 0 { + (args[0].span.shrink_to_lo(), "self, ".to_string()) + } else { + let span = e.span.trim_start(seg.ident.span).unwrap_or(e.span); + (span, "(self)".to_string()) + }; + self.closure_call_changes.push((span, arg_str)); + } + hir::intravisit::walk_stmt(self, s); + } + } + + if let Some(hir::Node::ImplItem( + hir::ImplItem { kind: hir::ImplItemKind::Fn(_fn_sig, body_id), .. } + )) = hir.find(self.mir_hir_id()) && + let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id) { + let mut finder = ExpressionFinder { + capture_span: *capture_kind_span, + closure_change_spans: vec![], + closure_arg_span: None, + in_closure: false, + suggest_arg: String::new(), + closure_local_id: None, + closure_call_changes: vec![], + hir, + }; + finder.visit_expr(expr); + + if finder.closure_change_spans.is_empty() || finder.closure_call_changes.is_empty() { + return; + } + + let mut sugg = vec![]; + let sm = self.infcx.tcx.sess.source_map(); + + if let Some(span) = finder.closure_arg_span { + sugg.push((sm.next_point(span.shrink_to_lo()).shrink_to_hi(), finder.suggest_arg)); + } + for span in finder.closure_change_spans { + sugg.push((span, "this".to_string())); + } + + for (span, suggest) in finder.closure_call_changes { + sugg.push((span, suggest)); + } + + err.multipart_suggestion_verbose( + "try explicitly pass `&Self` into the Closure as an argument", + sugg, + Applicability::MachineApplicable, + ); + } + } + /// Returns the description of the root place for a conflicting borrow and the full /// descriptions of the places that caused the conflict. /// diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index b9cfc7e6961..45b15c2c5bd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1094,7 +1094,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } -fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool { +pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool { debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind()); match local_decl.local_info.as_deref() { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index e8a4d1c37c1..f3050a6ef3f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -79,7 +79,7 @@ impl<'tcx> RegionErrors<'tcx> { #[track_caller] pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) { let val = val.into(); - self.1.sess.delay_span_bug(DUMMY_SP, "{val:?}"); + self.1.sess.delay_span_bug(DUMMY_SP, format!("{val:?}")); self.0.push(val); } pub fn is_empty(&self) -> bool { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 8ca7103ed48..342abf81f6a 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1231,12 +1231,21 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { sess.emit_fatal(errors::LinkerFileStem); }); + // Remove any version postfix. + let stem = stem + .rsplit_once('-') + .and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs)) + .unwrap_or(stem); + + // GCC can have an optional target prefix. let flavor = if stem == "emcc" { LinkerFlavor::EmCc } else if stem == "gcc" || stem.ends_with("-gcc") + || stem == "g++" + || stem.ends_with("-g++") || stem == "clang" - || stem.ends_with("-clang") + || stem == "clang++" { LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target) } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") { diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 16f64235562..a62e5dec4b8 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -231,6 +231,10 @@ fn run_compiler( registry: diagnostics_registry(), }; + if !tracing::dispatcher::has_been_set() { + init_rustc_env_logger_with_backtrace_option(&config.opts.unstable_opts.log_backtrace); + } + match make_input(config.opts.error_format, &matches.free) { Err(reported) => return Err(reported), Ok(Some((input, input_file_path))) => { @@ -1300,7 +1304,14 @@ pub fn install_ice_hook() { /// This allows tools to enable rust logging without having to magically match rustc's /// tracing crate version. pub fn init_rustc_env_logger() { - if let Err(error) = rustc_log::init_rustc_env_logger() { + init_rustc_env_logger_with_backtrace_option(&None); +} + +/// This allows tools to enable rust logging without having to magically match rustc's +/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to +/// choose a target module you wish to show backtraces along with its logging. +pub fn init_rustc_env_logger_with_backtrace_option(backtrace_target: &Option<String>) { + if let Err(error) = rustc_log::init_rustc_env_logger_with_backtrace_option(backtrace_target) { early_error(ErrorOutputType::default(), &error.to_string()); } } @@ -1366,7 +1377,6 @@ mod signal_handler { pub fn main() -> ! { let start_time = Instant::now(); let start_rss = get_resident_set_size(); - init_rustc_env_logger(); signal_handler::install(); let mut callbacks = TimePassesCallbacks::default(); install_ice_hook(); diff --git a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl b/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl index 0612dbae0b6..ca72b7faa92 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl @@ -46,3 +46,14 @@ hir_typeck_add_missing_parentheses_in_range = you must surround the range in par hir_typeck_op_trait_generic_params = `{$method_name}` must not have any generic parameters + +hir_typeck_lang_start_incorrect_number_params = incorrect number of parameters for the `start` lang item +hir_typeck_lang_start_incorrect_number_params_note_expected_count = the `start` lang item should have four parameters, but found {$found_param_count} + +hir_typeck_lang_start_expected_sig_note = the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize` + +hir_typeck_lang_start_incorrect_param = parameter {$param_num} of the `start` lang item is incorrect + .suggestion = change the type from `{$found_ty}` to `{$expected_ty}` + +hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang item is incorrect + .suggestion = change the type from `{$found_ty}` to `{$expected_ty}` diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 001e53d1d0e..91857dd227d 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -4,6 +4,9 @@ -passes_see_issue = see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information +passes_incorrect_do_not_recommend_location = + `#[do_not_recommend]` can only be placed on trait implementations + passes_outer_crate_level_attr = crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 9fa0e6e8eaa..3521911b055 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -27,6 +27,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_generics, Visitor as _}; use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; @@ -1643,8 +1644,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn report_ambiguous_associated_type( &self, span: Span, - type_str: &str, - trait_str: &str, + types: &[String], + traits: &[String], name: Symbol, ) -> ErrorGuaranteed { let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type"); @@ -1655,19 +1656,92 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .keys() .any(|full_span| full_span.contains(span)) { - err.span_suggestion( + err.span_suggestion_verbose( span.shrink_to_lo(), "you are looking for the module in `std`, not the primitive type", "std::", Applicability::MachineApplicable, ); } else { - err.span_suggestion( - span, - "use fully-qualified syntax", - format!("<{} as {}>::{}", type_str, trait_str, name), - Applicability::HasPlaceholders, - ); + match (types, traits) { + ([], []) => { + err.span_suggestion_verbose( + span, + &format!( + "if there were a type named `Type` that implements a trait named \ + `Trait` with associated type `{name}`, you could use the \ + fully-qualified path", + ), + format!("<Type as Trait>::{name}"), + Applicability::HasPlaceholders, + ); + } + ([], [trait_str]) => { + err.span_suggestion_verbose( + span, + &format!( + "if there were a type named `Example` that implemented `{trait_str}`, \ + you could use the fully-qualified path", + ), + format!("<Example as {trait_str}>::{name}"), + Applicability::HasPlaceholders, + ); + } + ([], traits) => { + err.span_suggestions( + span, + &format!( + "if there were a type named `Example` that implemented one of the \ + traits with associated type `{name}`, you could use the \ + fully-qualified path", + ), + traits + .iter() + .map(|trait_str| format!("<Example as {trait_str}>::{name}")) + .collect::<Vec<_>>(), + Applicability::HasPlaceholders, + ); + } + ([type_str], []) => { + err.span_suggestion_verbose( + span, + &format!( + "if there were a trait named `Example` with associated type `{name}` \ + implemented for `{type_str}`, you could use the fully-qualified path", + ), + format!("<{type_str} as Example>::{name}"), + Applicability::HasPlaceholders, + ); + } + (types, []) => { + err.span_suggestions( + span, + &format!( + "if there were a trait named `Example` with associated type `{name}` \ + implemented for one of the types, you could use the fully-qualified \ + path", + ), + types + .into_iter() + .map(|type_str| format!("<{type_str} as Example>::{name}")), + Applicability::HasPlaceholders, + ); + } + (types, traits) => { + let mut suggestions = vec![]; + for type_str in types { + for trait_str in traits { + suggestions.push(format!("<{type_str} as {trait_str}>::{name}")); + } + } + err.span_suggestions( + span, + "use the fully-qualified path", + suggestions, + Applicability::MachineApplicable, + ); + } + } } err.emit() } @@ -2050,12 +2124,64 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.emit() } else if let Err(reported) = qself_ty.error_reported() { reported + } else if let ty::Alias(ty::Opaque, alias_ty) = qself_ty.kind() { + // `<impl Trait as OtherTrait>::Assoc` makes no sense. + struct_span_err!( + tcx.sess, + tcx.def_span(alias_ty.def_id), + E0667, + "`impl Trait` is not allowed in path parameters" + ) + .emit() // Already reported in an earlier stage. } else { + // Find all the `impl`s that `qself_ty` has for any trait that has the + // associated type, so that we suggest the right one. + let infcx = tcx.infer_ctxt().build(); + // We create a fresh `ty::ParamEnv` instead of the one for `self.item_def_id()` + // to avoid a cycle error in `src/test/ui/resolve/issue-102946.rs`. + let param_env = ty::ParamEnv::empty(); + let traits: Vec<_> = self + .tcx() + .all_traits() + .filter(|trait_def_id| { + // Consider only traits with the associated type + tcx.associated_items(*trait_def_id) + .in_definition_order() + .any(|i| { + i.kind.namespace() == Namespace::TypeNS + && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident + && matches!(i.kind, ty::AssocKind::Type) + }) + // Consider only accessible traits + && tcx.visibility(*trait_def_id) + .is_accessible_from(self.item_def_id(), tcx) + && tcx.all_impls(*trait_def_id) + .any(|impl_def_id| { + let trait_ref = tcx.bound_impl_trait_ref(impl_def_id); + trait_ref.map_or(false, |trait_ref| { + let impl_ = trait_ref.subst( + tcx, + infcx.fresh_substs_for_item(span, impl_def_id), + ); + infcx + .can_eq( + param_env, + tcx.erase_regions(impl_.self_ty()), + tcx.erase_regions(qself_ty), + ) + .is_ok() + }) + && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative + }) + }) + .map(|trait_def_id| tcx.def_path_str(trait_def_id)) + .collect(); + // Don't print `TyErr` to the user. self.report_ambiguous_associated_type( span, - &qself_ty.to_string(), - "Trait", + &[qself_ty.to_string()], + &traits, assoc_ident.name, ) }; @@ -2173,16 +2299,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let is_part_of_self_trait_constraints = def_id == trait_def_id; let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id); - let type_name = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait { - "Self" + let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait { + vec!["Self".to_string()] } else { - "Type" + // Find all the types that have an `impl` for the trait. + tcx.all_impls(trait_def_id) + .filter(|impl_def_id| { + // Consider only accessible traits + tcx.visibility(*impl_def_id).is_accessible_from(self.item_def_id(), tcx) + && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative + }) + .filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id)) + .map(|impl_| impl_.self_ty()) + // We don't care about blanket impls. + .filter(|self_ty| !self_ty.has_non_region_param()) + .map(|self_ty| tcx.erase_regions(self_ty).to_string()) + .collect() }; - + // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that + // references the trait. Relevant for the first case in + // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs` let reported = self.report_ambiguous_associated_type( span, - type_name, - &path_str, + &type_names, + &[path_str], item_segment.ident.name, ); return tcx.ty_error_with_guaranteed(reported) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 7af89934d14..2cdf7579471 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2,7 +2,9 @@ use super::potentially_plural_count; use crate::errors::LifetimesOrBoundsMismatchOnTrait; use hir::def_id::{DefId, LocalDefId}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed}; +use rustc_errors::{ + pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit; @@ -320,15 +322,6 @@ fn compare_method_predicate_entailment<'tcx>( ty::Binder::dummy(ty::PredicateKind::WellFormed(unnormalized_impl_fty.into())), )); } - let emit_implied_wf_lint = || { - infcx.tcx.struct_span_lint_hir( - rustc_session::lint::builtin::IMPLIED_BOUNDS_ENTAILMENT, - impl_m_hir_id, - infcx.tcx.def_span(impl_m.def_id), - "impl method assumes more implied bounds than the corresponding trait method", - |lint| lint, - ); - }; // Check that all obligations are satisfied by the implementation's // version. @@ -346,7 +339,7 @@ fn compare_method_predicate_entailment<'tcx>( ) .map(|()| { // If the skip-mode was successful, emit a lint. - emit_implied_wf_lint(); + emit_implied_wf_lint(infcx.tcx, impl_m, impl_m_hir_id, vec![]); }); } CheckImpliedWfMode::Skip => { @@ -382,8 +375,16 @@ fn compare_method_predicate_entailment<'tcx>( CheckImpliedWfMode::Skip, ) .map(|()| { + let bad_args = extract_bad_args_for_implies_lint( + tcx, + &errors, + (trait_m, trait_sig), + // Unnormalized impl sig corresponds to the HIR types written + (impl_m, unnormalized_impl_sig), + impl_m_hir_id, + ); // If the skip-mode was successful, emit a lint. - emit_implied_wf_lint(); + emit_implied_wf_lint(tcx, impl_m, impl_m_hir_id, bad_args); }); } CheckImpliedWfMode::Skip => { @@ -400,6 +401,141 @@ fn compare_method_predicate_entailment<'tcx>( Ok(()) } +fn extract_bad_args_for_implies_lint<'tcx>( + tcx: TyCtxt<'tcx>, + errors: &[infer::RegionResolutionError<'tcx>], + (trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>), + (impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>), + hir_id: hir::HirId, +) -> Vec<(Span, Option<String>)> { + let mut blame_generics = vec![]; + for error in errors { + // Look for the subregion origin that contains an input/output type + let origin = match error { + infer::RegionResolutionError::ConcreteFailure(o, ..) => o, + infer::RegionResolutionError::GenericBoundFailure(o, ..) => o, + infer::RegionResolutionError::SubSupConflict(_, _, o, ..) => o, + infer::RegionResolutionError::UpperBoundUniverseConflict(.., o, _) => o, + }; + // Extract (possible) input/output types from origin + match origin { + infer::SubregionOrigin::Subtype(trace) => { + if let Some((a, b)) = trace.values.ty() { + blame_generics.extend([a, b]); + } + } + infer::SubregionOrigin::RelateParamBound(_, ty, _) => blame_generics.push(*ty), + infer::SubregionOrigin::ReferenceOutlivesReferent(ty, _) => blame_generics.push(*ty), + _ => {} + } + } + + let fn_decl = tcx.hir().fn_decl_by_hir_id(hir_id).unwrap(); + let opt_ret_ty = match fn_decl.output { + hir::FnRetTy::DefaultReturn(_) => None, + hir::FnRetTy::Return(ty) => Some(ty), + }; + + // Map late-bound regions from trait to impl, so the names are right. + let mapping = std::iter::zip( + tcx.fn_sig(trait_m.def_id).bound_vars(), + tcx.fn_sig(impl_m.def_id).bound_vars(), + ) + .filter_map(|(impl_bv, trait_bv)| { + if let ty::BoundVariableKind::Region(impl_bv) = impl_bv + && let ty::BoundVariableKind::Region(trait_bv) = trait_bv + { + Some((impl_bv, trait_bv)) + } else { + None + } + }) + .collect(); + + // For each arg, see if it was in the "blame" of any of the region errors. + // If so, then try to produce a suggestion to replace the argument type with + // one from the trait. + let mut bad_args = vec![]; + for (idx, (ty, hir_ty)) in + std::iter::zip(impl_sig.inputs_and_output, fn_decl.inputs.iter().chain(opt_ret_ty)) + .enumerate() + { + let expected_ty = trait_sig.inputs_and_output[idx] + .fold_with(&mut RemapLateBound { tcx, mapping: &mapping }); + if blame_generics.iter().any(|blame| ty.contains(*blame)) { + let expected_ty_sugg = expected_ty.to_string(); + bad_args.push(( + hir_ty.span, + // Only suggest something if it actually changed. + (expected_ty_sugg != ty.to_string()).then_some(expected_ty_sugg), + )); + } + } + + bad_args +} + +struct RemapLateBound<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>, +} + +impl<'tcx> TypeFolder<'tcx> for RemapLateBound<'_, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + if let ty::ReFree(fr) = *r { + self.tcx.mk_region(ty::ReFree(ty::FreeRegion { + bound_region: self + .mapping + .get(&fr.bound_region) + .copied() + .unwrap_or(fr.bound_region), + ..fr + })) + } else { + r + } + } +} + +fn emit_implied_wf_lint<'tcx>( + tcx: TyCtxt<'tcx>, + impl_m: &ty::AssocItem, + hir_id: hir::HirId, + bad_args: Vec<(Span, Option<String>)>, +) { + let span: MultiSpan = if bad_args.is_empty() { + tcx.def_span(impl_m.def_id).into() + } else { + bad_args.iter().map(|(span, _)| *span).collect::<Vec<_>>().into() + }; + tcx.struct_span_lint_hir( + rustc_session::lint::builtin::IMPLIED_BOUNDS_ENTAILMENT, + hir_id, + span, + "impl method assumes more implied bounds than the corresponding trait method", + |lint| { + let bad_args: Vec<_> = + bad_args.into_iter().filter_map(|(span, sugg)| Some((span, sugg?))).collect(); + if !bad_args.is_empty() { + lint.multipart_suggestion( + format!( + "replace {} type{} to make the impl signature compatible", + pluralize!("this", bad_args.len()), + pluralize!(bad_args.len()) + ), + bad_args, + Applicability::MaybeIncorrect, + ); + } + lint + }, + ); +} + #[derive(Debug, PartialEq, Eq)] enum CheckImpliedWfMode { /// Checks implied well-formedness of the impl method. If it fails, we will diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d1f4dbc8d84..92fd4625ee8 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1254,7 +1254,11 @@ fn check_impl<'tcx>( // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap(); - let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref); + let trait_ref = wfcx.normalize( + ast_trait_ref.path.span, + Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), + trait_ref, + ); let trait_pred = ty::TraitPredicate { trait_ref, constness: match constness { @@ -1263,7 +1267,7 @@ fn check_impl<'tcx>( }, polarity: ty::ImplPolarity::Positive, }; - let obligations = traits::wf::trait_obligations( + let mut obligations = traits::wf::trait_obligations( wfcx.infcx, wfcx.param_env, wfcx.body_id, @@ -1271,6 +1275,13 @@ fn check_impl<'tcx>( ast_trait_ref.path.span, item, ); + for obligation in &mut obligations { + if let Some(pred) = obligation.predicate.to_opt_poly_trait_pred() + && pred.self_ty().skip_binder() == trait_ref.self_ty() + { + obligation.cause.span = ast_self_ty.span; + } + } debug!(?obligations); wfcx.register_obligations(obligations); } diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 4f9d5826583..2dbfc1bc9a2 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -114,34 +114,46 @@ fn diagnostic_hir_wf_check<'tcx>( // Get the starting `hir::Ty` using our `WellFormedLoc`. // We will walk 'into' this type to try to find // a more precise span for our predicate. - let ty = match loc { + let tys = match loc { WellFormedLoc::Ty(_) => match hir.get(hir_id) { hir::Node::ImplItem(item) => match item.kind { - hir::ImplItemKind::Type(ty) => Some(ty), - hir::ImplItemKind::Const(ty, _) => Some(ty), + hir::ImplItemKind::Type(ty) => vec![ty], + hir::ImplItemKind::Const(ty, _) => vec![ty], ref item => bug!("Unexpected ImplItem {:?}", item), }, hir::Node::TraitItem(item) => match item.kind { - hir::TraitItemKind::Type(_, ty) => ty, - hir::TraitItemKind::Const(ty, _) => Some(ty), + hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(), + hir::TraitItemKind::Const(ty, _) => vec![ty], ref item => bug!("Unexpected TraitItem {:?}", item), }, hir::Node::Item(item) => match item.kind { - hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty), - hir::ItemKind::Impl(ref impl_) => { - assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_); - Some(impl_.self_ty) - } + hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty], + hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait { + Some(t) => t + .path + .segments + .last() + .iter() + .flat_map(|seg| seg.args().args) + .filter_map(|arg| { + if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None } + }) + .chain([impl_.self_ty]) + .collect(), + None => { + vec![impl_.self_ty] + } + }, ref item => bug!("Unexpected item {:?}", item), }, - hir::Node::Field(field) => Some(field.ty), + hir::Node::Field(field) => vec![field.ty], hir::Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Static(ty, _), .. - }) => Some(*ty), + }) => vec![*ty], hir::Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Type { default: Some(ty), .. }, .. - }) => Some(*ty), + }) => vec![*ty], ref node => bug!("Unexpected node {:?}", node), }, WellFormedLoc::Param { function: _, param_idx } => { @@ -149,16 +161,16 @@ fn diagnostic_hir_wf_check<'tcx>( // Get return type if param_idx as usize == fn_decl.inputs.len() { match fn_decl.output { - hir::FnRetTy::Return(ty) => Some(ty), + hir::FnRetTy::Return(ty) => vec![ty], // The unit type `()` is always well-formed - hir::FnRetTy::DefaultReturn(_span) => None, + hir::FnRetTy::DefaultReturn(_span) => vec![], } } else { - Some(&fn_decl.inputs[param_idx as usize]) + vec![&fn_decl.inputs[param_idx as usize]] } } }; - if let Some(ty) = ty { + for ty in tys { visitor.visit_ty(ty); } visitor.cause diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 32f86b8042c..57feefbcab6 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -1,4 +1,7 @@ use crate::coercion::CoerceMany; +use crate::errors::{ + LangStartIncorrectNumberArgs, LangStartIncorrectParam, LangStartIncorrectRetTy, +}; use crate::gather_locals::GatherLocalsVisitor; use crate::FnCtxt; use crate::GeneratorTypes; @@ -9,8 +12,9 @@ use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::check::fn_maybe_err; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::RegionVariableOrigin; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Binder, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; +use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; use std::cell::RefCell; @@ -168,6 +172,10 @@ pub(super) fn check_fn<'a, 'tcx>( check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig, decl, declared_ret_ty); } + if let Some(lang_start_defid) = tcx.lang_items().start_fn() && lang_start_defid == hir.local_def_id(fn_id).to_def_id() { + check_lang_start_fn(tcx, fn_sig, decl, fn_def_id); + } + gen_ty } @@ -223,3 +231,126 @@ fn check_panic_info_fn( tcx.sess.span_err(span, "should have no const parameters"); } } + +fn check_lang_start_fn<'tcx>( + tcx: TyCtxt<'tcx>, + fn_sig: ty::FnSig<'tcx>, + decl: &'tcx hir::FnDecl<'tcx>, + def_id: LocalDefId, +) { + let inputs = fn_sig.inputs(); + + let arg_count = inputs.len(); + if arg_count != 4 { + tcx.sess.emit_err(LangStartIncorrectNumberArgs { + params_span: tcx.def_span(def_id), + found_param_count: arg_count, + }); + } + + // only check args if they should exist by checking the count + // note: this does not handle args being shifted or their order swapped very nicely + // but it's a lang item, users shouldn't frequently encounter this + + // first arg is `main: fn() -> T` + if let Some(&main_arg) = inputs.get(0) { + // make a Ty for the generic on the fn for diagnostics + // FIXME: make the lang item generic checks check for the right generic *kind* + // for example `start`'s generic should be a type parameter + let generics = tcx.generics_of(def_id); + let fn_generic = generics.param_at(0, tcx); + let generic_tykind = + ty::Param(ty::ParamTy { index: fn_generic.index, name: fn_generic.name }); + let generic_ty = tcx.mk_ty(generic_tykind); + let expected_fn_sig = + tcx.mk_fn_sig([].iter(), &generic_ty, false, hir::Unsafety::Normal, Abi::Rust); + let expected_ty = tcx.mk_fn_ptr(Binder::dummy(expected_fn_sig)); + + // we emit the same error to suggest changing the arg no matter what's wrong with the arg + let emit_main_fn_arg_err = || { + tcx.sess.emit_err(LangStartIncorrectParam { + param_span: decl.inputs[0].span, + param_num: 1, + expected_ty: expected_ty, + found_ty: main_arg, + }); + }; + + if let ty::FnPtr(main_fn_sig) = main_arg.kind() { + let main_fn_inputs = main_fn_sig.inputs(); + if main_fn_inputs.iter().count() != 0 { + emit_main_fn_arg_err(); + } + + let output = main_fn_sig.output(); + output.map_bound(|ret_ty| { + // if the output ty is a generic, it's probably the right one + if !matches!(ret_ty.kind(), ty::Param(_)) { + emit_main_fn_arg_err(); + } + }); + } else { + emit_main_fn_arg_err(); + } + } + + // second arg is isize + if let Some(&argc_arg) = inputs.get(1) { + if argc_arg != tcx.types.isize { + tcx.sess.emit_err(LangStartIncorrectParam { + param_span: decl.inputs[1].span, + param_num: 2, + expected_ty: tcx.types.isize, + found_ty: argc_arg, + }); + } + } + + // third arg is `*const *const u8` + if let Some(&argv_arg) = inputs.get(2) { + let mut argv_is_okay = false; + if let ty::RawPtr(outer_ptr) = argv_arg.kind() { + if outer_ptr.mutbl.is_not() { + if let ty::RawPtr(inner_ptr) = outer_ptr.ty.kind() { + if inner_ptr.mutbl.is_not() && inner_ptr.ty == tcx.types.u8 { + argv_is_okay = true; + } + } + } + } + + if !argv_is_okay { + let inner_ptr_ty = + tcx.mk_ptr(ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: tcx.types.u8 }); + let expected_ty = + tcx.mk_ptr(ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: inner_ptr_ty }); + tcx.sess.emit_err(LangStartIncorrectParam { + param_span: decl.inputs[2].span, + param_num: 3, + expected_ty, + found_ty: argv_arg, + }); + } + } + + // fourth arg is `sigpipe: u8` + if let Some(&sigpipe_arg) = inputs.get(3) { + if sigpipe_arg != tcx.types.u8 { + tcx.sess.emit_err(LangStartIncorrectParam { + param_span: decl.inputs[3].span, + param_num: 4, + expected_ty: tcx.types.u8, + found_ty: sigpipe_arg, + }); + } + } + + // output type is isize + if fn_sig.output() != tcx.types.isize { + tcx.sess.emit_err(LangStartIncorrectRetTy { + ret_span: decl.output.span(), + expected_ty: tcx.types.isize, + found_ty: fn_sig.output(), + }); + } +} diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 507272fdec5..5b4fd5e4a52 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -172,3 +172,36 @@ impl AddToDiagnostic for TypeMismatchFruTypo { ); } } + +#[derive(Diagnostic)] +#[diag(hir_typeck_lang_start_incorrect_number_params)] +#[note(hir_typeck_lang_start_incorrect_number_params_note_expected_count)] +#[note(hir_typeck_lang_start_expected_sig_note)] +pub struct LangStartIncorrectNumberArgs { + #[primary_span] + pub params_span: Span, + pub found_param_count: usize, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_lang_start_incorrect_param)] +pub struct LangStartIncorrectParam<'tcx> { + #[primary_span] + #[suggestion(style = "short", code = "{expected_ty}", applicability = "machine-applicable")] + pub param_span: Span, + + pub param_num: usize, + pub expected_ty: Ty<'tcx>, + pub found_ty: Ty<'tcx>, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_lang_start_incorrect_ret_ty)] +pub struct LangStartIncorrectRetTy<'tcx> { + #[primary_span] + #[suggestion(style = "short", code = "{expected_ty}", applicability = "machine-applicable")] + pub ret_span: Span, + + pub expected_ty: Ty<'tcx>, + pub found_ty: Ty<'tcx>, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 080ae6b9466..533a3c768eb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1782,9 +1782,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // like when you have two references but one is `usize` and the other // is `f32`. In those cases we still want to show the `note`. If the // value from `ef` is `Infer(_)`, then we ignore it. - if !ef.expected.is_ty_infer() { + if !ef.expected.is_ty_or_numeric_infer() { ef.expected != values.expected - } else if !ef.found.is_ty_infer() { + } else if !ef.found.is_ty_or_numeric_infer() { ef.found != values.found } else { false diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index a4c36b4c9cd..b8c843a8a5a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -78,7 +78,7 @@ impl InferenceDiagnosticsData { } fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str { - if in_type.is_ty_infer() { + if in_type.is_ty_or_numeric_infer() { "" } else if self.name == "_" { // FIXME: Consider specializing this message if there is a single `_` @@ -195,12 +195,12 @@ fn ty_to_string<'tcx>( // invalid pseudo-syntax, we want the `fn`-pointer output instead. (ty::FnDef(..), _) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(), (_, Some(def_id)) - if ty.is_ty_infer() + if ty.is_ty_or_numeric_infer() && infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) => { "Vec<_>".to_string() } - _ if ty.is_ty_infer() => "/* Type */".to_string(), + _ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(), // FIXME: The same thing for closures, but this only works when the closure // does not capture anything. // @@ -680,7 +680,7 @@ impl<'tcx> InferSourceKind<'tcx> { | InferSourceKind::ClosureReturn { ty, .. } => { if ty.is_closure() { ("closure", closure_as_fn_str(infcx, ty)) - } else if !ty.is_ty_infer() { + } else if !ty.is_ty_or_numeric_infer() { ("normal", ty_to_string(infcx, ty, None)) } else { ("other", String::new()) @@ -813,7 +813,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { self.attempt += 1; if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, ..}, .. }) = self.infer_source && let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..} = new_source.kind - && ty.is_ty_infer() + && ty.is_ty_or_numeric_infer() { // Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of // `let x: _ = iter.collect();`, as this is a very common case. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c8085e91dfa..50c40206d80 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -823,23 +823,26 @@ pub fn create_global_ctxt<'tcx>( lint_store, arena, hir_arena, - untracked_resolutions, untracked, - krate, dep_graph, queries.on_disk_cache.as_ref().map(OnDiskCache::as_dyn), queries.as_dyn(), rustc_query_impl::query_callbacks(arena), - crate_name, - outputs, ) }) }); let mut qcx = QueryContext { gcx }; qcx.enter(|tcx| { - tcx.feed_unit_query() - .resolver_for_lowering(tcx.arena.alloc(Steal::new(untracked_resolver_for_lowering))) + let feed = tcx.feed_unit_query(); + feed.resolver_for_lowering( + tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))), + ); + feed.resolutions(tcx.arena.alloc(untracked_resolutions)); + feed.output_filenames(tcx.arena.alloc(std::sync::Arc::new(outputs))); + feed.features_query(sess.features_untracked()); + let feed = tcx.feed_local_crate(); + feed.crate_name(crate_name); }); qcx } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index a3b9891ee64..07b28cc86ce 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -748,6 +748,7 @@ fn test_unstable_options_tracking_hash() { tracked!(link_only, true); tracked!(llvm_plugins, vec![String::from("plugin_name")]); tracked!(location_detail, LocationDetail { file: true, line: false, column: false }); + tracked!(log_backtrace, Some("filter".to_string())); tracked!(maximal_hir_to_mir_coverage, true); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 70c999811a5..e9eb14ea188 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -11,7 +11,7 @@ pub(crate) fn provide(providers: &mut Providers) { } fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) { - if !tcx.sess.features_untracked().enabled(sym::lint_reasons) { + if !tcx.features().enabled(sym::lint_reasons) { return; } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 28317d6cea0..6cdf5097083 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4033,10 +4033,10 @@ declare_lint! { /// /// This can be used to implement an unsound API if used incorrectly. pub IMPLIED_BOUNDS_ENTAILMENT, - Warn, + Deny, "impl method assumes more implied bounds than its corresponding trait method", @future_incompatible = FutureIncompatibleInfo { reference: "issue #105572 <https://github.com/rust-lang/rust/issues/105572>", - reason: FutureIncompatibilityReason::FutureReleaseError, + reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow, }; } diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 3c50827c1ab..7f955b0a750 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" tracing = "0.1.28" tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } tracing-tree = "0.2.0" +tracing-core = "0.1.28" [dev-dependencies] rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 4cac88aff64..fc1cabd2de9 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -45,16 +45,34 @@ use std::env::{self, VarError}; use std::fmt::{self, Display}; use std::io::{self, IsTerminal}; +use tracing_core::{Event, Subscriber}; use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter}; +use tracing_subscriber::fmt::{ + format::{self, FormatEvent, FormatFields}, + FmtContext, +}; use tracing_subscriber::layer::SubscriberExt; pub fn init_rustc_env_logger() -> Result<(), Error> { - init_env_logger("RUSTC_LOG") + init_rustc_env_logger_with_backtrace_option(&None) +} + +pub fn init_rustc_env_logger_with_backtrace_option( + backtrace_target: &Option<String>, +) -> Result<(), Error> { + init_env_logger_with_backtrace_option("RUSTC_LOG", backtrace_target) } /// In contrast to `init_rustc_env_logger` this allows you to choose an env var /// other than `RUSTC_LOG`. pub fn init_env_logger(env: &str) -> Result<(), Error> { + init_env_logger_with_backtrace_option(env, &None) +} + +pub fn init_env_logger_with_backtrace_option( + env: &str, + backtrace_target: &Option<String>, +) -> Result<(), Error> { let filter = match env::var(env) { Ok(env) => EnvFilter::new(env), _ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)), @@ -88,11 +106,47 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> { let layer = layer.with_thread_ids(true).with_thread_names(true); let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); - tracing::subscriber::set_global_default(subscriber).unwrap(); + match backtrace_target { + Some(str) => { + let fmt_layer = tracing_subscriber::fmt::layer() + .with_writer(io::stderr) + .without_time() + .event_format(BacktraceFormatter { backtrace_target: str.to_string() }); + let subscriber = subscriber.with(fmt_layer); + tracing::subscriber::set_global_default(subscriber).unwrap(); + } + None => { + tracing::subscriber::set_global_default(subscriber).unwrap(); + } + }; Ok(()) } +struct BacktraceFormatter { + backtrace_target: String, +} + +impl<S, N> FormatEvent<S, N> for BacktraceFormatter +where + S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>, + N: for<'a> FormatFields<'a> + 'static, +{ + fn format_event( + &self, + _ctx: &FmtContext<'_, S, N>, + mut writer: format::Writer<'_>, + event: &Event<'_>, + ) -> fmt::Result { + let target = event.metadata().target(); + if !target.contains(&self.backtrace_target) { + return Ok(()); + } + let backtrace = std::backtrace::Backtrace::capture(); + writeln!(writer, "stack backtrace: \n{:?}", backtrace) + } +} + pub fn stdout_isatty() -> bool { io::stdout().is_terminal() } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 75282f958b5..f816d614500 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -30,7 +30,12 @@ macro_rules! arena_types { [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, [decode] borrowck_result: rustc_middle::mir::BorrowCheckResult<'tcx>, - [] resolver: rustc_data_structures::steal::Steal<rustc_middle::ty::ResolverAstLowering>, + [] resolver: rustc_data_structures::steal::Steal<( + rustc_middle::ty::ResolverAstLowering, + rustc_data_structures::sync::Lrc<rustc_ast::Crate>, + )>, + [] output_filenames: std::sync::Arc<rustc_session::config::OutputFilenames>, + [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, [decode] code_region: rustc_middle::mir::coverage::CodeRegion, [] const_allocs: rustc_middle::mir::interpret::Allocation, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 076ce1bdb34..86655915736 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -27,12 +27,12 @@ rustc_queries! { } query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt { - eval_always + feedable no_hash desc { "getting the resolver outputs" } } - query resolver_for_lowering(_: ()) -> &'tcx Steal<ty::ResolverAstLowering> { + query resolver_for_lowering(_: ()) -> &'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)> { feedable no_hash desc { "getting the resolver for lowering" } @@ -1673,7 +1673,7 @@ rustc_queries! { /// Gets the name of the crate. query crate_name(_: CrateNum) -> Symbol { - eval_always + feedable desc { "fetching what a crate is named" } separate_provide_extern } @@ -1857,7 +1857,7 @@ rustc_queries! { /// This query returns an `&Arc` because codegen backends need the value even after the `TyCtxt` /// has been destroyed. query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> { - eval_always + feedable desc { "getting output filenames" } } @@ -2041,7 +2041,7 @@ rustc_queries! { } query features_query(_: ()) -> &'tcx rustc_feature::Features { - eval_always + feedable desc { "looking up enabled feature gates" } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5de414077a2..63f31e5a11f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -51,7 +51,7 @@ use rustc_macros::HashStable; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; -use rustc_session::config::{CrateType, OutputFilenames}; +use rustc_session::config::CrateType; use rustc_session::cstore::{CrateStoreDyn, Untracked}; use rustc_session::lint::Lint; use rustc_session::Limit; @@ -74,7 +74,6 @@ use std::hash::{Hash, Hasher}; use std::iter; use std::mem; use std::ops::{Bound, Deref}; -use std::sync::Arc; pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { /// Creates a new `OnDiskCache` instance from the serialized data in `data`. @@ -363,6 +362,9 @@ impl<'tcx> TyCtxt<'tcx> { pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> { TyCtxtFeed { tcx: self, key: () } } + pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> { + TyCtxtFeed { tcx: self, key: LOCAL_CRATE } + } } impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> { @@ -428,11 +430,6 @@ pub struct GlobalCtxt<'tcx> { pub consts: CommonConsts<'tcx>, untracked: Untracked, - /// Output of the resolver. - pub(crate) untracked_resolutions: ty::ResolverGlobalCtxt, - /// The entire crate as AST. This field serves as the input for the hir_crate query, - /// which lowers it from AST to HIR. It must not be read or used by anything else. - pub untracked_crate: Steal<Lrc<ast::Crate>>, /// This provides access to the incremental compilation on-disk cache for query results. /// Do not access this directly. It is only meant to be used by @@ -457,17 +454,11 @@ pub struct GlobalCtxt<'tcx> { /// Merge this with `selection_cache`? pub evaluation_cache: traits::EvaluationCache<'tcx>, - /// The definite name of the current crate after taking into account - /// attributes, commandline parameters, etc. - crate_name: Symbol, - /// Data layout specification for the current target. pub data_layout: TargetDataLayout, /// Stores memory for globals (statics/consts). pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>, - - output_filenames: Arc<OutputFilenames>, } impl<'tcx> TyCtxt<'tcx> { @@ -592,15 +583,11 @@ impl<'tcx> TyCtxt<'tcx> { lint_store: Lrc<dyn Any + sync::Send + sync::Sync>, arena: &'tcx WorkerLocal<Arena<'tcx>>, hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>, - untracked_resolutions: ty::ResolverGlobalCtxt, untracked: Untracked, - krate: Lrc<ast::Crate>, dep_graph: DepGraph, on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>, queries: &'tcx dyn query::QueryEngine<'tcx>, query_kinds: &'tcx [DepKindStruct<'tcx>], - crate_name: Symbol, - output_filenames: OutputFilenames, ) -> GlobalCtxt<'tcx> { let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| { s.emit_fatal(err); @@ -622,8 +609,6 @@ impl<'tcx> TyCtxt<'tcx> { lifetimes: common_lifetimes, consts: common_consts, untracked, - untracked_resolutions, - untracked_crate: Steal::new(krate), on_disk_cache, queries, query_caches: query::QueryCaches::default(), @@ -632,10 +617,8 @@ impl<'tcx> TyCtxt<'tcx> { pred_rcache: Default::default(), selection_cache: Default::default(), evaluation_cache: Default::default(), - crate_name, data_layout, alloc_map: Lock::new(interpret::AllocMap::new()), - output_filenames: Arc::new(output_filenames), } } @@ -810,7 +793,7 @@ impl<'tcx> TyCtxt<'tcx> { // statements within the query system and we'd run into endless // recursion otherwise. let (crate_name, stable_crate_id) = if def_id.is_local() { - (self.crate_name, self.sess.local_stable_crate_id()) + (self.crate_name(LOCAL_CRATE), self.sess.local_stable_crate_id()) } else { let cstore = &*self.untracked.cstore; (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate)) @@ -2407,13 +2390,8 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool { } pub fn provide(providers: &mut ty::query::Providers) { - providers.resolutions = |tcx, ()| &tcx.untracked_resolutions; providers.module_reexports = |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]); - providers.crate_name = |tcx, id| { - assert_eq!(id, LOCAL_CRATE); - tcx.crate_name - }; providers.maybe_unused_trait_imports = |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports; providers.maybe_unused_extern_crates = @@ -2424,8 +2402,6 @@ pub fn provide(providers: &mut ty::query::Providers) { providers.extern_mod_stmt_cnum = |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); - providers.output_filenames = |tcx, ()| &tcx.output_filenames; - providers.features_query = |tcx, ()| tcx.sess.features_untracked(); providers.is_panic_runtime = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f7e4c821569..bd5b04d5b2b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1686,7 +1686,7 @@ impl<'tcx> Ty<'tcx> { } #[inline] - pub fn is_ty_infer(self) -> bool { + pub fn is_ty_or_numeric_infer(self) -> bool { matches!(self.kind(), Infer(_)) } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 0c33e5bda1a..2dec58ea82a 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -202,7 +202,7 @@ impl<'tcx> GenericArg<'tcx> { pub fn is_non_region_infer(self) -> bool { match self.unpack() { GenericArgKind::Lifetime(_) => false, - GenericArgKind::Type(ty) => ty.is_ty_infer(), + GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(), GenericArgKind::Const(ct) => ct.is_ct_infer(), } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c59c06ac31e..f9f9799d3e4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -82,6 +82,7 @@ impl CheckAttrVisitor<'_> { let attrs = self.tcx.hir().attrs(hir_id); for attr in attrs { let attr_is_valid = match attr.name_or_empty() { + sym::do_not_recommend => self.check_do_not_recommend(attr.span, target), sym::inline => self.check_inline(hir_id, attr, span, target), sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target), sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target), @@ -241,6 +242,16 @@ impl CheckAttrVisitor<'_> { ); } + /// Checks if `#[do_not_recommend]` is applied on a trait impl. + fn check_do_not_recommend(&self, attr_span: Span, target: Target) -> bool { + if let Target::Impl = target { + true + } else { + self.tcx.sess.emit_err(errors::IncorrectDoNotRecommendLocation { span: attr_span }); + false + } + } + /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { match target { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index c6cd69add28..9c6519ea4bb 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -14,6 +14,13 @@ use rustc_span::{Span, Symbol, DUMMY_SP}; use crate::lang_items::Duplicate; +#[derive(Diagnostic)] +#[diag(passes_incorrect_do_not_recommend_location)] +pub struct IncorrectDoNotRecommendLocation { + #[primary_span] + pub span: Span, +} + #[derive(LintDiagnostic)] #[diag(passes_outer_crate_level_attr)] pub struct OuterCrateLevelAttr; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 1a852de8eed..fb2aebbd18a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -167,7 +167,7 @@ impl<'a> Resolver<'a> { ); err.emit(); } else if let Some((span, msg, sugg, appl)) = suggestion { - err.span_suggestion(span, msg, sugg, appl); + err.span_suggestion_verbose(span, msg, sugg, appl); err.emit(); } else if let [segment] = path.as_slice() && is_call { err.stash(segment.ident.span, rustc_errors::StashKey::CallIntoMethod); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d92f5a7c05e..d92b046d0b9 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2065,7 +2065,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { path: &[Segment], ) -> Option<(Span, &'static str, String, Applicability)> { let (ident, span) = match path { - [segment] if !segment.has_generic_args && segment.ident.name != kw::SelfUpper => { + [segment] + if !segment.has_generic_args + && segment.ident.name != kw::SelfUpper + && segment.ident.name != kw::Dyn => + { (segment.ident.to_string(), segment.ident.span) } _ => return None, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b062b43873b..7b5fd6cc2a8 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1411,6 +1411,8 @@ options! { "what location details should be tracked when using caller_location, either \ `none`, or a comma separated list of location details, for which \ valid options are `file`, `line`, and `column` (default: `file,line,column`)"), + log_backtrace: Option<String> = (None, parse_opt_string, [TRACKED], + "add a backtrace along with logging"), ls: bool = (false, parse_bool, [UNTRACKED], "list the symbols defined by a library crate (default: no)"), macro_backtrace: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 20bede22c34..0c7ffb056cc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2252,8 +2252,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { Ok(None) => { let ambiguities = ambiguity::recompute_applicable_impls(self.infcx, &obligation); - let has_non_region_infer = - trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer()); + let has_non_region_infer = trait_ref + .skip_binder() + .substs + .types() + .any(|t| !t.is_ty_or_numeric_infer()); // It doesn't make sense to talk about applicable impls if there are more // than a handful of them. if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 5f8c777f32a..d1b6d470e86 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1221,7 +1221,7 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { ) { let ast_attrs = self.tcx.hir().attrs(hir_id); if let Some(ref cfg) = ast_attrs.cfg(self.tcx, &FxHashSet::default()) { - if !cfg.matches(&self.sess.parse_sess, Some(self.sess.features_untracked())) { + if !cfg.matches(&self.sess.parse_sess, Some(self.tcx.features())) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs index 0710ac0bb0a..751c262673b 100644 --- a/src/tools/clippy/clippy_lints/src/attrs.rs +++ b/src/tools/clippy/clippy_lints/src/attrs.rs @@ -472,7 +472,7 @@ fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMe fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem], attr: &'_ Attribute) { // Check for the feature - if !cx.tcx.sess.features_untracked().lint_reasons { + if !cx.tcx.features().lint_reasons { return; } diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index 638e4a54849..efdd56dd47d 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -17,9 +17,12 @@ error[E0412]: cannot find type `VAL` in this scope --> $DIR/ice-6252.rs:10:63 | LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {} - | - ^^^ not found in this scope - | | - | help: you might be missing a type parameter: `, VAL` + | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {} + | +++++ error[E0046]: not all trait items implemented, missing: `VAL` --> $DIR/ice-6252.rs:10:1 diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs index a7da8f89aa3..1af77d1a25b 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.rs +++ b/src/tools/clippy/tests/ui/def_id_nocore.rs @@ -15,7 +15,7 @@ pub trait Copy {} pub unsafe trait Freeze {} #[lang = "start"] -fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { +fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { 0 } diff --git a/tests/run-make-fulldeps/target-specs/foo.rs b/tests/run-make-fulldeps/target-specs/foo.rs index d576a1dd281..22939e87912 100644 --- a/tests/run-make-fulldeps/target-specs/foo.rs +++ b/tests/run-make-fulldeps/target-specs/foo.rs @@ -11,7 +11,7 @@ trait Sized {} auto trait Freeze {} #[lang = "start"] -fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { +fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { 0 } diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout index 43f30f3d6e8..4bdecdc1b79 100644 --- a/tests/rustdoc-ui/z-help.stdout +++ b/tests/rustdoc-ui/z-help.stdout @@ -76,6 +76,7 @@ -Z llvm-plugins=val -- a list LLVM plugins to enable (space separated) -Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no) -Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`) + -Z log-backtrace=val -- add a backtrace along with logging -Z ls=val -- list the symbols defined by a library crate (default: no) -Z macro-backtrace=val -- show macro backtraces (default: no) -Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no) diff --git a/tests/ui/associated-item/ambiguous-associated-type-with-generics.fixed b/tests/ui/associated-item/ambiguous-associated-type-with-generics.fixed new file mode 100644 index 00000000000..23f71520040 --- /dev/null +++ b/tests/ui/associated-item/ambiguous-associated-type-with-generics.fixed @@ -0,0 +1,14 @@ +// run-rustfix +trait Trait<A> {} + +trait Assoc { + type Ty; +} + +impl<A> Assoc for dyn Trait<A> { + type Ty = i32; +} + +fn main() { + let _x: <dyn Trait<i32> as Assoc>::Ty; //~ ERROR ambiguous associated type +} diff --git a/tests/ui/associated-item/ambiguous-associated-type-with-generics.rs b/tests/ui/associated-item/ambiguous-associated-type-with-generics.rs new file mode 100644 index 00000000000..9c26e339a44 --- /dev/null +++ b/tests/ui/associated-item/ambiguous-associated-type-with-generics.rs @@ -0,0 +1,14 @@ +// run-rustfix +trait Trait<A> {} + +trait Assoc { + type Ty; +} + +impl<A> Assoc for dyn Trait<A> { + type Ty = i32; +} + +fn main() { + let _x: <dyn Trait<i32>>::Ty; //~ ERROR ambiguous associated type +} diff --git a/tests/ui/associated-item/ambiguous-associated-type-with-generics.stderr b/tests/ui/associated-item/ambiguous-associated-type-with-generics.stderr new file mode 100644 index 00000000000..97088b79fd6 --- /dev/null +++ b/tests/ui/associated-item/ambiguous-associated-type-with-generics.stderr @@ -0,0 +1,9 @@ +error[E0223]: ambiguous associated type + --> $DIR/ambiguous-associated-type-with-generics.rs:13:13 + | +LL | let _x: <dyn Trait<i32>>::Ty; + | ^^^^^^^^^^^^^^^^^^^^ help: use the fully-qualified path: `<dyn Trait<i32> as Assoc>::Ty` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0223`. diff --git a/tests/ui/associated-item/associated-item-duplicate-names-3.stderr b/tests/ui/associated-item/associated-item-duplicate-names-3.stderr index bf4bd634cf1..d0c17062076 100644 --- a/tests/ui/associated-item/associated-item-duplicate-names-3.stderr +++ b/tests/ui/associated-item/associated-item-duplicate-names-3.stderr @@ -13,7 +13,7 @@ error[E0223]: ambiguous associated type --> $DIR/associated-item-duplicate-names-3.rs:18:12 | LL | let x: Baz::Bar = 5; - | ^^^^^^^^ help: use fully-qualified syntax: `<Baz as Trait>::Bar` + | ^^^^^^^^ help: use the fully-qualified path: `<Baz as Foo>::Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr index 289911779ff..00856b55df5 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr @@ -2,31 +2,46 @@ error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:6:36 | LL | fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {} - | ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Get>::Value` + | ^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path + | +LL | fn get<T:Get,U:Get>(x: T, y: U) -> <Example as Get>::Value {} + | ~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:20:17 | LL | trait Foo where Foo::Assoc: Bar { - | ^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Foo>::Assoc` + | ^^^^^^^^^^ help: use the fully-qualified path: `<Self as Foo>::Assoc` error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:25:10 | LL | type X = std::ops::Deref::Target; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Deref>::Target` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Deref`, you could use the fully-qualified path + | +LL | type X = <Example as Deref>::Target; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:11:23 | LL | fn grab(&self) -> Grab::Value; - | ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value` + | ^^^^^^^^^^^ help: use the fully-qualified path: `<Self as Grab>::Value` error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:14:22 | LL | fn get(&self) -> Get::Value; - | ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Get>::Value` + | ^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path + | +LL | fn get(&self) -> <Example as Get>::Value; + | ~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 5 previous errors diff --git a/tests/ui/attributes/log-backtrace.rs b/tests/ui/attributes/log-backtrace.rs new file mode 100644 index 00000000000..3979d2001fc --- /dev/null +++ b/tests/ui/attributes/log-backtrace.rs @@ -0,0 +1,9 @@ +// run-pass +// +// This test makes sure that log-backtrace option doesn't give a compilation error. +// +// dont-check-compiler-stdout +// dont-check-compiler-stderr +// rustc-env:RUSTC_LOG=info +// compile-flags: -Zlog-backtrace=rustc_metadata::creader +fn main() {} diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr index 492316f0027..592aa4369ce 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr @@ -1,8 +1,8 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/builtin-superkinds-double-superkind.rs:6:24 + --> $DIR/builtin-superkinds-double-superkind.rs:6:32 | LL | impl <T: Sync+'static> Foo for (T,) { } - | ^^^ `T` cannot be sent between threads safely + | ^^^^ `T` cannot be sent between threads safely | = note: required because it appears within the type `(T,)` note: required by a bound in `Foo` @@ -16,10 +16,10 @@ LL | impl <T: Sync+'static + std::marker::Send> Foo for (T,) { } | +++++++++++++++++++ error[E0277]: `T` cannot be shared between threads safely - --> $DIR/builtin-superkinds-double-superkind.rs:9:16 + --> $DIR/builtin-superkinds-double-superkind.rs:9:24 | LL | impl <T: Send> Foo for (T,T) { } - | ^^^ `T` cannot be shared between threads safely + | ^^^^^ `T` cannot be shared between threads safely | = note: required because it appears within the type `(T, T)` note: required by a bound in `Foo` diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr index a46e4b2337c..f9d548bb8fb 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr @@ -1,8 +1,8 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/builtin-superkinds-in-metadata.rs:13:23 + --> $DIR/builtin-superkinds-in-metadata.rs:13:56 | LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely + | ^^^^ `T` cannot be sent between threads safely | note: required because it appears within the type `X<T>` --> $DIR/builtin-superkinds-in-metadata.rs:9:8 diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr index 9db9cbfdb91..8b19170b0f1 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr @@ -1,8 +1,8 @@ error[E0277]: `Rc<i8>` cannot be sent between threads safely - --> $DIR/builtin-superkinds-simple.rs:6:6 + --> $DIR/builtin-superkinds-simple.rs:6:14 | LL | impl Foo for std::rc::Rc<i8> { } - | ^^^ `Rc<i8>` cannot be sent between threads safely + | ^^^^^^^^^^^^^^^ `Rc<i8>` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `Rc<i8>` note: required by a bound in `Foo` diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr index 3ec0b907d0c..0cfea72d5f1 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr @@ -1,8 +1,8 @@ error[E0277]: `T` cannot be sent between threads safely - --> $DIR/builtin-superkinds-typaram-not-send.rs:5:24 + --> $DIR/builtin-superkinds-typaram-not-send.rs:5:32 | LL | impl <T: Sync+'static> Foo for T { } - | ^^^ `T` cannot be sent between threads safely + | ^ `T` cannot be sent between threads safely | note: required by a bound in `Foo` --> $DIR/builtin-superkinds-typaram-not-send.rs:3:13 diff --git a/tests/ui/chalkify/impl_wf.stderr b/tests/ui/chalkify/impl_wf.stderr index a142459bcb4..84c32fa3771 100644 --- a/tests/ui/chalkify/impl_wf.stderr +++ b/tests/ui/chalkify/impl_wf.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/impl_wf.rs:11:6 + --> $DIR/impl_wf.rs:11:14 | LL | impl Foo for str { } - | ^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` note: required by a bound in `Foo` @@ -12,10 +12,10 @@ LL | trait Foo: Sized { } | ^^^^^ required by this bound in `Foo` error[E0277]: the trait bound `f32: Foo` is not satisfied - --> $DIR/impl_wf.rs:22:6 + --> $DIR/impl_wf.rs:22:19 | LL | impl Baz<f32> for f32 { } - | ^^^^^^^^ the trait `Foo` is not implemented for `f32` + | ^^^ the trait `Foo` is not implemented for `f32` | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `Baz` diff --git a/tests/ui/coherence/coherence-overlap-trait-alias.stderr b/tests/ui/coherence/coherence-overlap-trait-alias.stderr index e324c1e799f..668b8319b38 100644 --- a/tests/ui/coherence/coherence-overlap-trait-alias.stderr +++ b/tests/ui/coherence/coherence-overlap-trait-alias.stderr @@ -1,8 +1,8 @@ error[E0283]: type annotations needed: cannot satisfy `u32: C` - --> $DIR/coherence-overlap-trait-alias.rs:15:6 + --> $DIR/coherence-overlap-trait-alias.rs:15:12 | LL | impl C for u32 {} - | ^ + | ^^^ | note: multiple `impl`s satisfying `u32: C` found --> $DIR/coherence-overlap-trait-alias.rs:14:1 diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr index 21f957ab549..55096e95df7 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.stderr +++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr @@ -61,25 +61,45 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:1:10 | LL | type A = [u8; 4]::AssocTy; - | ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8; 4] as Trait>::AssocTy` + | ^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `[u8; 4]`, you could use the fully-qualified path + | +LL | type A = <[u8; 4] as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:5:10 | LL | type B = [u8]::AssocTy; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8] as Trait>::AssocTy` + | ^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `[u8]`, you could use the fully-qualified path + | +LL | type B = <[u8] as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:9:10 | LL | type C = (u8)::AssocTy; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy` + | ^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | type C = <u8 as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:13:10 | LL | type D = (u8, u8)::AssocTy; - | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(u8, u8) as Trait>::AssocTy` + | ^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `(u8, u8)`, you could use the fully-qualified path + | +LL | type D = <(u8, u8) as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases --> $DIR/bad-assoc-ty.rs:17:10 @@ -91,13 +111,23 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:21:19 | LL | type F = &'static (u8)::AssocTy; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy` + | ^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | type F = &'static <u8 as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:27:10 | LL | type G = dyn 'static + (Send)::AssocTy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Send + 'static) as Trait>::AssocTy` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `(dyn Send + 'static)`, you could use the fully-qualified path + | +LL | type G = <(dyn Send + 'static) as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bad-assoc-ty.rs:33:10 @@ -117,24 +147,33 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:33:10 | LL | type H = Fn(u8) -> (u8)::Output; - | ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Fn(u8) -> u8 + 'static) as Trait>::Output` + | ^^^^^^^^^^^^^^^^^^^^^^ help: use the fully-qualified path: `<(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output` error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:39:19 | LL | ($ty: ty) => ($ty::AssocTy); - | ^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy` + | ^^^^^^^^^^^^ ... LL | type J = ty!(u8); | ------- in this macro invocation | = note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info) +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | ($ty: ty) => (<u8 as Example>::AssocTy); + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:46:10 | LL | type I = ty!()::AssocTy; - | ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy` + | ^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | type I = <u8 as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/bad-assoc-ty.rs:51:13 diff --git a/tests/ui/dst/dst-sized-trait-param.stderr b/tests/ui/dst/dst-sized-trait-param.stderr index 8ec94f5a3c0..60e9de90332 100644 --- a/tests/ui/dst/dst-sized-trait-param.stderr +++ b/tests/ui/dst/dst-sized-trait-param.stderr @@ -16,10 +16,10 @@ LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is siz | ++++++++ error[E0277]: the size for values of type `[usize]` cannot be known at compilation time - --> $DIR/dst-sized-trait-param.rs:10:6 + --> $DIR/dst-sized-trait-param.rs:10:21 | LL | impl Foo<isize> for [usize] { } - | ^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[usize]` note: required by a bound in `Foo` diff --git a/tests/ui/error-codes/E0223.rs b/tests/ui/error-codes/E0223.rs index 6031b682d72..2fe252de256 100644 --- a/tests/ui/error-codes/E0223.rs +++ b/tests/ui/error-codes/E0223.rs @@ -1,4 +1,8 @@ trait MyTrait { type X; } +struct MyStruct; +impl MyTrait for MyStruct { + type X = (); +} fn main() { let foo: MyTrait::X; diff --git a/tests/ui/error-codes/E0223.stderr b/tests/ui/error-codes/E0223.stderr index 726f39e11f1..42945e42f6e 100644 --- a/tests/ui/error-codes/E0223.stderr +++ b/tests/ui/error-codes/E0223.stderr @@ -1,8 +1,8 @@ error[E0223]: ambiguous associated type - --> $DIR/E0223.rs:4:14 + --> $DIR/E0223.rs:8:14 | LL | let foo: MyTrait::X; - | ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as MyTrait>::X` + | ^^^^^^^^^^ help: use the fully-qualified path: `<MyStruct as MyTrait>::X` error: aborting due to previous error diff --git a/tests/ui/error-codes/E0308-2.stderr b/tests/ui/error-codes/E0308-2.stderr index de54a417253..3a8a81a73a6 100644 --- a/tests/ui/error-codes/E0308-2.stderr +++ b/tests/ui/error-codes/E0308-2.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/E0308-2.rs:9:6 + --> $DIR/E0308-2.rs:9:13 | LL | impl Eq for &dyn DynEq {} - | ^^ lifetime mismatch + | ^^^^^^^^^^ lifetime mismatch | = note: expected trait `<&dyn DynEq as PartialEq>` found trait `<&(dyn DynEq + 'static) as PartialEq>` diff --git a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr index 26bdf460f5e..9d4ea01152c 100644 --- a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr +++ b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr @@ -2,9 +2,12 @@ error[E0412]: cannot find type `T` in this scope --> $DIR/fn-help-with-err-generic-is-not-function.rs:2:13 | LL | impl Struct<T> - | - ^ not found in this scope - | | - | help: you might be missing a type parameter: `<T>` + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<T> Struct<T> + | +++ error[E0412]: cannot find type `T` in this scope --> $DIR/fn-help-with-err-generic-is-not-function.rs:7:5 diff --git a/tests/ui/impl-trait/impl_trait_projections.rs b/tests/ui/impl-trait/impl_trait_projections.rs index fd0986d7c0a..b3ff2ce5a7b 100644 --- a/tests/ui/impl-trait/impl_trait_projections.rs +++ b/tests/ui/impl-trait/impl_trait_projections.rs @@ -11,7 +11,7 @@ fn path_parametrized_type_is_allowed() -> option::Option<impl Debug> { fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item { //~^ ERROR `impl Trait` is not allowed in path parameters -//~^^ ERROR ambiguous associated type +//~| ERROR `impl Trait` is not allowed in path parameters x.next().unwrap() } diff --git a/tests/ui/impl-trait/impl_trait_projections.stderr b/tests/ui/impl-trait/impl_trait_projections.stderr index 82d2422c407..4deb24731bc 100644 --- a/tests/ui/impl-trait/impl_trait_projections.stderr +++ b/tests/ui/impl-trait/impl_trait_projections.stderr @@ -22,13 +22,12 @@ error[E0667]: `impl Trait` is not allowed in path parameters LL | -> <dyn Iterator<Item = impl Debug> as Iterator>::Item | ^^^^^^^^^^ -error[E0223]: ambiguous associated type - --> $DIR/impl_trait_projections.rs:12:50 +error[E0667]: `impl Trait` is not allowed in path parameters + --> $DIR/impl_trait_projections.rs:12:51 | LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item { - | ^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<impl Iterator as Trait>::Item` + | ^^^^^^^^^^^^^ error: aborting due to 5 previous errors -Some errors have detailed explanations: E0223, E0667. -For more information about an error, try `rustc --explain E0223`. +For more information about this error, try `rustc --explain E0667`. diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr index 0ac31c642eb..ebe07027d2f 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr @@ -1,8 +1,8 @@ error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:5 + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31 | LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> @@ -14,3 +14,18 @@ LL | #![deny(implied_bounds_entailment)] error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: impl method assumes more implied bounds than the corresponding trait method + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31 + | +LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> +note: the lint level is defined here + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9 + | +LL | #![deny(implied_bounds_entailment)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr index 0dfa8167a99..43d3e058ffe 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr @@ -1,8 +1,8 @@ error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility.rs:14:5 + --> $DIR/impl-implied-bounds-compatibility.rs:14:35 | LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> @@ -14,3 +14,18 @@ LL | #![deny(implied_bounds_entailment)] error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: impl method assumes more implied bounds than the corresponding trait method + --> $DIR/impl-implied-bounds-compatibility.rs:14:35 + | +LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> +note: the lint level is defined here + --> $DIR/impl-implied-bounds-compatibility.rs:1:9 + | +LL | #![deny(implied_bounds_entailment)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/issues/issue-23073.stderr b/tests/ui/issues/issue-23073.stderr index 3a10a1ab11a..3a9f49ef167 100644 --- a/tests/ui/issues/issue-23073.stderr +++ b/tests/ui/issues/issue-23073.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/issue-23073.rs:6:17 | LL | type FooT = <<Self as Bar>::Foo>::T; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<Self as Bar>::Foo as Trait>::T` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `T` implemented for `<Self as Bar>::Foo`, you could use the fully-qualified path + | +LL | type FooT = <<Self as Bar>::Foo as Example>::T; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/issues/issue-58712.stderr b/tests/ui/issues/issue-58712.stderr index 87c16aa993b..f4bd4d1e826 100644 --- a/tests/ui/issues/issue-58712.stderr +++ b/tests/ui/issues/issue-58712.stderr @@ -2,9 +2,12 @@ error[E0412]: cannot find type `DeviceId` in this scope --> $DIR/issue-58712.rs:6:20 | LL | impl<H> AddrVec<H, DeviceId> { - | - ^^^^^^^^ not found in this scope - | | - | help: you might be missing a type parameter: `, DeviceId` + | ^^^^^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<H, DeviceId> AddrVec<H, DeviceId> { + | ++++++++++ error[E0412]: cannot find type `DeviceId` in this scope --> $DIR/issue-58712.rs:8:29 diff --git a/tests/ui/issues/issue-65230.stderr b/tests/ui/issues/issue-65230.stderr index fcabcdea74f..7ccab889483 100644 --- a/tests/ui/issues/issue-65230.stderr +++ b/tests/ui/issues/issue-65230.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/issue-65230.rs:8:6 + --> $DIR/issue-65230.rs:8:13 | LL | impl T1 for &dyn T2 {} - | ^^ lifetime mismatch + | ^^^^^^^ lifetime mismatch | = note: expected trait `<&dyn T2 as T0>` found trait `<&(dyn T2 + 'static) as T0>` diff --git a/tests/ui/issues/issue-77919.stderr b/tests/ui/issues/issue-77919.stderr index ca256847b1f..d154bfe0cb5 100644 --- a/tests/ui/issues/issue-77919.stderr +++ b/tests/ui/issues/issue-77919.stderr @@ -13,9 +13,12 @@ error[E0412]: cannot find type `VAL` in this scope --> $DIR/issue-77919.rs:11:63 | LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {} - | - ^^^ not found in this scope - | | - | help: you might be missing a type parameter: `, VAL` + | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {} + | +++++ error[E0046]: not all trait items implemented, missing: `VAL` --> $DIR/issue-77919.rs:11:1 diff --git a/tests/ui/issues/issue-78622.stderr b/tests/ui/issues/issue-78622.stderr index f7d44f21d3b..70daf8a2f1a 100644 --- a/tests/ui/issues/issue-78622.stderr +++ b/tests/ui/issues/issue-78622.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/issue-78622.rs:5:5 | LL | S::A::<f> {} - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::A` + | ^^^^ + | +help: if there were a trait named `Example` with associated type `A` implemented for `S`, you could use the fully-qualified path + | +LL | <S as Example>::A::<f> {} + | ~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/issues/issue-86756.stderr b/tests/ui/issues/issue-86756.stderr index 6c5917bdf6e..bfa7459ab4a 100644 --- a/tests/ui/issues/issue-86756.stderr +++ b/tests/ui/issues/issue-86756.stderr @@ -9,8 +9,6 @@ LL | trait Foo<T, T = T> {} error[E0412]: cannot find type `dyn` in this scope --> $DIR/issue-86756.rs:5:10 | -LL | fn eq<A, B>() { - | - help: you might be missing a type parameter: `, dyn` LL | eq::<dyn, Foo> | ^^^ not found in this scope diff --git a/tests/ui/lang-items/start_lang_item_args.argc.stderr b/tests/ui/lang-items/start_lang_item_args.argc.stderr new file mode 100644 index 00000000000..65c99a93c75 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.argc.stderr @@ -0,0 +1,8 @@ +error: parameter 2 of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:75:38 + | +LL | fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize { + | ^^ help: change the type from `i8` to `isize` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.argv.stderr b/tests/ui/lang-items/start_lang_item_args.argv.stderr new file mode 100644 index 00000000000..f0947a9b3e9 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.argv.stderr @@ -0,0 +1,8 @@ +error: parameter 3 of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:89:52 + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize { + | ^^ help: change the type from `u8` to `*const *const u8` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr new file mode 100644 index 00000000000..08efd5088f9 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr @@ -0,0 +1,13 @@ +error: parameter 3 of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:82:52 + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize { + | ^^^^^^^^^^^^^^^^^^^ + | +help: change the type from `*const *const usize` to `*const *const u8` + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + | ~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.main_args.stderr b/tests/ui/lang-items/start_lang_item_args.main_args.stderr new file mode 100644 index 00000000000..c20a744661d --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.main_args.stderr @@ -0,0 +1,13 @@ +error: parameter 1 of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:61:20 + | +LL | fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + | ^^^^^^^^^^^^ + | +help: change the type from `fn(i32) -> T` to `fn() -> T` + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + | ~~~~~~~~~ + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr new file mode 100644 index 00000000000..8f967252f49 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr @@ -0,0 +1,13 @@ +error: parameter 1 of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:68:20 + | +LL | fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + | ^^^^^^^^^^^ + | +help: change the type from `fn() -> u16` to `fn() -> T` + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + | ~~~~~~~~~ + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr new file mode 100644 index 00000000000..deb37b868ea --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr @@ -0,0 +1,8 @@ +error: parameter 1 of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:54:20 + | +LL | fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + | ^^^ help: change the type from `u64` to `fn() -> T` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr new file mode 100644 index 00000000000..004c2a67f62 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr @@ -0,0 +1,11 @@ +error: incorrect number of parameters for the `start` lang item + --> $DIR/start_lang_item_args.rs:15:1 + | +LL | fn start<T>() -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the `start` lang item should have four parameters, but found 0 + = note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr new file mode 100644 index 00000000000..1d8285b5900 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr @@ -0,0 +1,8 @@ +error: the return type of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:29:84 + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {} + | ^ help: change the type from `()` to `isize` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr new file mode 100644 index 00000000000..e545a750f24 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr @@ -0,0 +1,11 @@ +error: incorrect number of parameters for the `start` lang item + --> $DIR/start_lang_item_args.rs:22:1 + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the `start` lang item should have four parameters, but found 3 + = note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.rs b/tests/ui/lang-items/start_lang_item_args.rs new file mode 100644 index 00000000000..0dbfba39cb6 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.rs @@ -0,0 +1,101 @@ +// check-fail +// revisions: missing_all_args missing_sigpipe_arg missing_ret start_ret too_many_args +// revisions: main_ty main_args main_ret argc argv_inner_ptr argv sigpipe + +#![feature(lang_items, no_core)] +#![no_core] + +#[lang = "copy"] +pub trait Copy {} +#[lang = "sized"] +pub trait Sized {} + +#[cfg(missing_all_args)] +#[lang = "start"] +fn start<T>() -> isize { + //[missing_all_args]~^ ERROR incorrect number of parameters + 100 +} + +#[cfg(missing_sigpipe_arg)] +#[lang = "start"] +fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { + //[missing_sigpipe_arg]~^ ERROR incorrect number of parameters + 100 +} + +#[cfg(missing_ret)] +#[lang = "start"] +fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {} +//[missing_ret]~^ ERROR the return type of the `start` lang item is incorrect + +#[cfg(start_ret)] +#[lang = "start"] +fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 { + //[start_ret]~^ ERROR the return type of the `start` lang item is incorrect + 100 +} + +#[cfg(too_many_args)] +#[lang = "start"] +fn start<T>( + //[too_many_args]~^ ERROR incorrect number of parameters + _main: fn() -> T, + _argc: isize, + _argv: *const *const u8, + _sigpipe: u8, + _extra_arg: (), +) -> isize { + 100 +} + +#[cfg(main_ty)] +#[lang = "start"] +fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + //[main_ty]~^ ERROR parameter 1 of the `start` lang item is incorrect + 100 +} + +#[cfg(main_args)] +#[lang = "start"] +fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + //[main_args]~^ ERROR parameter 1 of the `start` lang item is incorrect + 100 +} + +#[cfg(main_ret)] +#[lang = "start"] +fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + //[main_ret]~^ ERROR parameter 1 of the `start` lang item is incorrect + 100 +} + +#[cfg(argc)] +#[lang = "start"] +fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize { + //[argc]~^ ERROR parameter 2 of the `start` lang item is incorrect + 100 +} + +#[cfg(argv_inner_ptr)] +#[lang = "start"] +fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize { + //[argv_inner_ptr]~^ ERROR parameter 3 of the `start` lang item is incorrect + 100 +} + +#[cfg(argv)] +#[lang = "start"] +fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize { + //[argv]~^ ERROR parameter 3 of the `start` lang item is incorrect + 100 +} + +#[cfg(sigpipe)] +#[lang = "start"] +fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize { + //[sigpipe]~^ ERROR parameter 4 of the `start` lang item is incorrect + 100 +} + +fn main() {} diff --git a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr new file mode 100644 index 00000000000..b20ae312801 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr @@ -0,0 +1,8 @@ +error: parameter 4 of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:96:80 + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize { + | ^^^ help: change the type from `i64` to `u8` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr new file mode 100644 index 00000000000..935d5f3c8b4 --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr @@ -0,0 +1,8 @@ +error: the return type of the `start` lang item is incorrect + --> $DIR/start_lang_item_args.rs:34:87 + | +LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 { + | ^^ help: change the type from `u8` to `isize` + +error: aborting due to previous error + diff --git a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr new file mode 100644 index 00000000000..30a7ed18a3d --- /dev/null +++ b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr @@ -0,0 +1,17 @@ +error: incorrect number of parameters for the `start` lang item + --> $DIR/start_lang_item_args.rs:41:1 + | +LL | / fn start<T>( +LL | | +LL | | _main: fn() -> T, +LL | | _argc: isize, +... | +LL | | _extra_arg: (), +LL | | ) -> isize { + | |__________^ + | + = note: the `start` lang item should have four parameters, but found 5 + = note: the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize` + +error: aborting due to previous error + diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr index 8ed303ca606..a19f4963c23 100644 --- a/tests/ui/lint/bare-trait-objects-path.stderr +++ b/tests/ui/lint/bare-trait-objects-path.stderr @@ -16,7 +16,7 @@ error[E0223]: ambiguous associated type --> $DIR/bare-trait-objects-path.rs:23:12 | LL | let _: Dyn::Ty; - | ^^^^^^^ help: use fully-qualified syntax: `<dyn Dyn as Trait>::Ty` + | ^^^^^^^ help: use the fully-qualified path: `<dyn Dyn as Assoc>::Ty` warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bare-trait-objects-path.rs:14:5 diff --git a/tests/ui/marker_trait_attr/overlap-marker-trait-with-underscore-lifetime.stderr b/tests/ui/marker_trait_attr/overlap-marker-trait-with-underscore-lifetime.stderr index 235c89e200a..3cd59d6926e 100644 --- a/tests/ui/marker_trait_attr/overlap-marker-trait-with-underscore-lifetime.stderr +++ b/tests/ui/marker_trait_attr/overlap-marker-trait-with-underscore-lifetime.stderr @@ -1,8 +1,8 @@ error[E0283]: type annotations needed: cannot satisfy `&(): Marker` - --> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:6 + --> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:17 | LL | impl Marker for &'_ () {} - | ^^^^^^ + | ^^^^^^ | note: multiple `impl`s satisfying `&(): Marker` found --> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:1 @@ -13,10 +13,10 @@ LL | impl Marker for &'_ () {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed: cannot satisfy `&(): Marker` - --> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:7:6 + --> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:7:17 | LL | impl Marker for &'_ () {} - | ^^^^^^ + | ^^^^^^ | note: multiple `impl`s satisfying `&(): Marker` found --> $DIR/overlap-marker-trait-with-underscore-lifetime.rs:6:1 diff --git a/tests/ui/marker_trait_attr/region-overlap.stderr b/tests/ui/marker_trait_attr/region-overlap.stderr index 6631fe987e2..c6497b4669d 100644 --- a/tests/ui/marker_trait_attr/region-overlap.stderr +++ b/tests/ui/marker_trait_attr/region-overlap.stderr @@ -1,8 +1,8 @@ error[E0283]: type annotations needed: cannot satisfy `(&'static (), &'a ()): A` - --> $DIR/region-overlap.rs:5:10 + --> $DIR/region-overlap.rs:5:16 | LL | impl<'a> A for (&'static (), &'a ()) {} - | ^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found --> $DIR/region-overlap.rs:5:1 @@ -13,10 +13,10 @@ LL | impl<'a> A for (&'a (), &'static ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed: cannot satisfy `(&'a (), &'static ()): A` - --> $DIR/region-overlap.rs:6:10 + --> $DIR/region-overlap.rs:6:16 | LL | impl<'a> A for (&'a (), &'static ()) {} - | ^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found --> $DIR/region-overlap.rs:5:1 diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr index 9218ae9d5da..0cae01bd1e3 100644 --- a/tests/ui/parser/dyn-trait-compatibility.stderr +++ b/tests/ui/parser/dyn-trait-compatibility.stderr @@ -26,17 +26,13 @@ error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:5:15 | LL | type A2 = dyn<dyn, dyn>; - | - ^^^ not found in this scope - | | - | help: you might be missing a type parameter: `<dyn>` + | ^^^ not found in this scope error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:5:20 | LL | type A2 = dyn<dyn, dyn>; - | - ^^^ not found in this scope - | | - | help: you might be missing a type parameter: `<dyn>` + | ^^^ not found in this scope error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:9:11 @@ -48,9 +44,7 @@ error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:9:16 | LL | type A3 = dyn<<dyn as dyn>::dyn>; - | - ^^^ not found in this scope - | | - | help: you might be missing a type parameter: `<dyn>` + | ^^^ not found in this scope error: aborting due to 8 previous errors diff --git a/tests/ui/qualified/qualified-path-params-2.stderr b/tests/ui/qualified/qualified-path-params-2.stderr index 948f21fce4b..b6cf19b8286 100644 --- a/tests/ui/qualified/qualified-path-params-2.stderr +++ b/tests/ui/qualified/qualified-path-params-2.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/qualified-path-params-2.rs:18:10 | LL | type A = <S as Tr>::A::f<u8>; - | ^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<S as Tr>::A as Trait>::f` + | ^^^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `f` implemented for `<S as Tr>::A`, you could use the fully-qualified path + | +LL | type A = <<S as Tr>::A as Example>::f; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/resolve/issue-103202.stderr b/tests/ui/resolve/issue-103202.stderr index 880389371ef..d4d141fb06f 100644 --- a/tests/ui/resolve/issue-103202.stderr +++ b/tests/ui/resolve/issue-103202.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/issue-103202.rs:4:17 | LL | fn f(self: &S::x) {} - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::x` + | ^^^^ + | +help: if there were a trait named `Example` with associated type `x` implemented for `S`, you could use the fully-qualified path + | +LL | fn f(self: &<S as Example>::x) {} + | ~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/rfc-2397-do-not-recommend/incorrect-locations.rs b/tests/ui/rfc-2397-do-not-recommend/incorrect-locations.rs new file mode 100644 index 00000000000..91863f5e497 --- /dev/null +++ b/tests/ui/rfc-2397-do-not-recommend/incorrect-locations.rs @@ -0,0 +1,45 @@ +#![feature(do_not_recommend)] + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +const CONST: () = (); + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +static Static: () = (); + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +type Type = (); + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +enum Enum { +} + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +extern { +} + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +fn fun() { +} + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +struct Struct { +} + +#[do_not_recommend] +//~^ `#[do_not_recommend]` can only be placed +trait Trait { +} + +#[do_not_recommend] +impl Trait for i32 { +} + +fn main() { +} diff --git a/tests/ui/rfc-2397-do-not-recommend/incorrect-locations.stderr b/tests/ui/rfc-2397-do-not-recommend/incorrect-locations.stderr new file mode 100644 index 00000000000..01ebc23c86e --- /dev/null +++ b/tests/ui/rfc-2397-do-not-recommend/incorrect-locations.stderr @@ -0,0 +1,50 @@ +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:3:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:7:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:11:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:15:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:20:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:25:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:30:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: `#[do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:35:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/ui/rfc-2397-do-not-recommend/unstable-feature.rs b/tests/ui/rfc-2397-do-not-recommend/unstable-feature.rs index b816c4a19da..f0c5c222e78 100644 --- a/tests/ui/rfc-2397-do-not-recommend/unstable-feature.rs +++ b/tests/ui/rfc-2397-do-not-recommend/unstable-feature.rs @@ -1,6 +1,9 @@ +trait Foo { +} + #[do_not_recommend] //~^ ERROR the `#[do_not_recommend]` attribute is an experimental feature -trait Foo { +impl Foo for i32 { } fn main() { diff --git a/tests/ui/rfc-2397-do-not-recommend/unstable-feature.stderr b/tests/ui/rfc-2397-do-not-recommend/unstable-feature.stderr index 425d7e4bca0..1597e5be45f 100644 --- a/tests/ui/rfc-2397-do-not-recommend/unstable-feature.stderr +++ b/tests/ui/rfc-2397-do-not-recommend/unstable-feature.stderr @@ -1,5 +1,5 @@ error[E0658]: the `#[do_not_recommend]` attribute is an experimental feature - --> $DIR/unstable-feature.rs:1:1 + --> $DIR/unstable-feature.rs:4:1 | LL | #[do_not_recommend] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr index 1f8f312df01..bf12ef1ca77 100644 --- a/tests/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/super-traits-fail.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `S: ~const Foo` is not satisfied - --> $DIR/super-traits-fail.rs:15:12 + --> $DIR/super-traits-fail.rs:15:20 | LL | impl const Bar for S {} - | ^^^ the trait `~const Foo` is not implemented for `S` + | ^ the trait `~const Foo` is not implemented for `S` | note: the trait `Foo` is implemented for `S`, but that implementation is not `const` - --> $DIR/super-traits-fail.rs:15:12 + --> $DIR/super-traits-fail.rs:15:20 | LL | impl const Bar for S {} - | ^^^ + | ^ note: required by a bound in `Bar` --> $DIR/super-traits-fail.rs:8:12 | diff --git a/tests/ui/self/self-impl.stderr b/tests/ui/self/self-impl.stderr index fb47f27e022..36372b644d6 100644 --- a/tests/ui/self/self-impl.stderr +++ b/tests/ui/self/self-impl.stderr @@ -2,13 +2,13 @@ error[E0223]: ambiguous associated type --> $DIR/self-impl.rs:23:16 | LL | let _: <Self>::Baz = true; - | ^^^^^^^^^^^ help: use fully-qualified syntax: `<Bar as Trait>::Baz` + | ^^^^^^^^^^^ help: use the fully-qualified path: `<Bar as Foo>::Baz` error[E0223]: ambiguous associated type --> $DIR/self-impl.rs:25:16 | LL | let _: Self::Baz = true; - | ^^^^^^^^^ help: use fully-qualified syntax: `<Bar as Trait>::Baz` + | ^^^^^^^^^ help: use the fully-qualified path: `<Bar as Foo>::Baz` error: aborting due to 2 previous errors diff --git a/tests/ui/span/issue-71363.stderr b/tests/ui/span/issue-71363.stderr index 6c7ea007ee0..cb5cc320276 100644 --- a/tests/ui/span/issue-71363.stderr +++ b/tests/ui/span/issue-71363.stderr @@ -1,8 +1,8 @@ error[E0277]: `MyError` doesn't implement `std::fmt::Display` - --> $DIR/issue-71363.rs:4:6 + --> $DIR/issue-71363.rs:4:28 | 4 | impl std::error::Error for MyError {} - | ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted with the default formatter + | ^^^^^^^ `MyError` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `MyError` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead @@ -10,10 +10,10 @@ note: required by a bound in `std::error::Error` --> $SRC_DIR/core/src/error.rs:LL:COL error[E0277]: `MyError` doesn't implement `Debug` - --> $DIR/issue-71363.rs:4:6 + --> $DIR/issue-71363.rs:4:28 | 4 | impl std::error::Error for MyError {} - | ^^^^^^^^^^^^^^^^^ `MyError` cannot be formatted using `{:?}` + | ^^^^^^^ `MyError` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `MyError` = note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError` diff --git a/tests/ui/specialization/min_specialization/issue-79224.stderr b/tests/ui/specialization/min_specialization/issue-79224.stderr index be6f04ae62a..505baa23ca3 100644 --- a/tests/ui/specialization/min_specialization/issue-79224.stderr +++ b/tests/ui/specialization/min_specialization/issue-79224.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:18:17 + --> $DIR/issue-79224.rs:18:29 | LL | impl<B: ?Sized> Display for Cow<'_, B> { - | ^^^^^^^ the trait `Clone` is not implemented for `B` + | ^^^^^^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound diff --git a/tests/ui/structs/struct-path-associated-type.stderr b/tests/ui/structs/struct-path-associated-type.stderr index abb445214f3..ca5f0b7e21e 100644 --- a/tests/ui/structs/struct-path-associated-type.stderr +++ b/tests/ui/structs/struct-path-associated-type.stderr @@ -48,19 +48,19 @@ error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:32:13 | LL | let s = S::A {}; - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::A` + | ^^^^ help: use the fully-qualified path: `<S as Tr>::A` error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:33:13 | LL | let z = S::A::<u8> {}; - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::A` + | ^^^^ help: use the fully-qualified path: `<S as Tr>::A` error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:35:9 | LL | S::A {} => {} - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::A` + | ^^^^ help: use the fully-qualified path: `<S as Tr>::A` error: aborting due to 8 previous errors diff --git a/tests/ui/suggestions/issue-105761-suggest-self-for-closure.fixed b/tests/ui/suggestions/issue-105761-suggest-self-for-closure.fixed new file mode 100644 index 00000000000..78e48364bba --- /dev/null +++ b/tests/ui/suggestions/issue-105761-suggest-self-for-closure.fixed @@ -0,0 +1,28 @@ +//run-rustfix +#![allow(unused)] + +struct S; +impl S { + fn foo(&mut self) { + let x = |this: &Self, v: i32| { + this.bar(); + this.hel(); + }; + self.qux(); //~ ERROR cannot borrow `*self` as mutable because it is also borrowed as immutable + x(self, 1); + x(self, 3); + } + fn bar(&self) {} + fn hel(&self) {} + fn qux(&mut self) {} + + fn hello(&mut self) { + let y = |this: &Self| { + this.bar(); + }; + self.qux(); //~ ERROR cannot borrow `*self` as mutable because it is also borrowed as immutable + y(self); + } +} + +fn main() {} diff --git a/tests/ui/suggestions/issue-105761-suggest-self-for-closure.rs b/tests/ui/suggestions/issue-105761-suggest-self-for-closure.rs new file mode 100644 index 00000000000..6d8a9ffc12d --- /dev/null +++ b/tests/ui/suggestions/issue-105761-suggest-self-for-closure.rs @@ -0,0 +1,28 @@ +//run-rustfix +#![allow(unused)] + +struct S; +impl S { + fn foo(&mut self) { + let x = |v: i32| { + self.bar(); + self.hel(); + }; + self.qux(); //~ ERROR cannot borrow `*self` as mutable because it is also borrowed as immutable + x(1); + x(3); + } + fn bar(&self) {} + fn hel(&self) {} + fn qux(&mut self) {} + + fn hello(&mut self) { + let y = || { + self.bar(); + }; + self.qux(); //~ ERROR cannot borrow `*self` as mutable because it is also borrowed as immutable + y(); + } +} + +fn main() {} diff --git a/tests/ui/suggestions/issue-105761-suggest-self-for-closure.stderr b/tests/ui/suggestions/issue-105761-suggest-self-for-closure.stderr new file mode 100644 index 00000000000..bc97d32ebb6 --- /dev/null +++ b/tests/ui/suggestions/issue-105761-suggest-self-for-closure.stderr @@ -0,0 +1,49 @@ +error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable + --> $DIR/issue-105761-suggest-self-for-closure.rs:11:9 + | +LL | let x = |v: i32| { + | -------- immutable borrow occurs here +LL | self.bar(); + | ---- first borrow occurs due to use of `self` in closure +... +LL | self.qux(); + | ^^^^^^^^^^ mutable borrow occurs here +LL | x(1); + | - immutable borrow later used here + | +help: try explicitly pass `&Self` into the Closure as an argument + | +LL ~ let x = |this: &Self, v: i32| { +LL ~ this.bar(); +LL ~ this.hel(); +LL | }; +LL | self.qux(); +LL ~ x(self, 1); +LL ~ x(self, 3); + | + +error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable + --> $DIR/issue-105761-suggest-self-for-closure.rs:23:9 + | +LL | let y = || { + | -- immutable borrow occurs here +LL | self.bar(); + | ---- first borrow occurs due to use of `self` in closure +LL | }; +LL | self.qux(); + | ^^^^^^^^^^ mutable borrow occurs here +LL | y(); + | - immutable borrow later used here + | +help: try explicitly pass `&Self` into the Closure as an argument + | +LL ~ let y = |this: &Self| { +LL ~ this.bar(); +LL | }; +LL | self.qux(); +LL ~ y(self); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0502`. diff --git a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr index 2bf072ef521..b90ae051fb7 100644 --- a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr +++ b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr @@ -21,7 +21,12 @@ error[E0223]: ambiguous associated type --> $DIR/let-binding-init-expr-as-ty.rs:2:14 | LL | let foo: i32::from_be(num); - | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<i32 as Trait>::from_be` + | ^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `from_be` implemented for `i32`, you could use the fully-qualified path + | +LL | let foo: <i32 as Example>::from_be; + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/type-not-found-in-adt-field.stderr b/tests/ui/suggestions/type-not-found-in-adt-field.stderr index e990fb5ba12..934ba87bbaa 100644 --- a/tests/ui/suggestions/type-not-found-in-adt-field.stderr +++ b/tests/ui/suggestions/type-not-found-in-adt-field.stderr @@ -7,10 +7,13 @@ LL | m: Vec<Someunknownname<String, ()>>, error[E0412]: cannot find type `K` in this scope --> $DIR/type-not-found-in-adt-field.rs:6:8 | -LL | struct OtherStruct { - | - help: you might be missing a type parameter: `<K>` LL | m: K, | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct OtherStruct<K> { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/trait-bounds/unsized-bound.stderr b/tests/ui/trait-bounds/unsized-bound.stderr index ec85ada7a8d..da27ba1c58d 100644 --- a/tests/ui/trait-bounds/unsized-bound.stderr +++ b/tests/ui/trait-bounds/unsized-bound.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `B` cannot be known at compilation time - --> $DIR/unsized-bound.rs:2:12 + --> $DIR/unsized-bound.rs:2:30 | LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} - | - ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | @@ -38,10 +38,10 @@ LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {} | error[E0277]: the size for values of type `C` cannot be known at compilation time - --> $DIR/unsized-bound.rs:5:31 + --> $DIR/unsized-bound.rs:5:52 | LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} - | - ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^^^^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | @@ -92,10 +92,10 @@ LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} | error[E0277]: the size for values of type `B` cannot be known at compilation time - --> $DIR/unsized-bound.rs:10:28 + --> $DIR/unsized-bound.rs:10:47 | LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {} - | - ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^^^^^^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | @@ -131,10 +131,10 @@ LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {} | error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/unsized-bound.rs:14:9 + --> $DIR/unsized-bound.rs:14:23 | LL | impl<A> Trait3<A> for A where A: ?Sized {} - | - ^^^^^^^^^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | @@ -154,10 +154,10 @@ LL | trait Trait3<A: ?Sized> {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/unsized-bound.rs:17:17 + --> $DIR/unsized-bound.rs:17:31 | LL | impl<A: ?Sized> Trait4<A> for A {} - | - ^^^^^^^^^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | @@ -177,10 +177,10 @@ LL | trait Trait4<A: ?Sized> {} | ++++++++ error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized-bound.rs:20:12 + --> $DIR/unsized-bound.rs:20:29 | LL | impl<X, Y> Trait5<X, Y> for X where X: ?Sized {} - | - ^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | @@ -200,10 +200,10 @@ LL | trait Trait5<A: ?Sized, B> {} | ++++++++ error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized-bound.rs:23:20 + --> $DIR/unsized-bound.rs:23:37 | LL | impl<X: ?Sized, Y> Trait6<X, Y> for X {} - | - ^^^^^^^^^^^^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `std::marker::Sized` | diff --git a/tests/ui/traits/ignore-err-impls.stderr b/tests/ui/traits/ignore-err-impls.stderr index 1390106a291..45bd533b5c6 100644 --- a/tests/ui/traits/ignore-err-impls.stderr +++ b/tests/ui/traits/ignore-err-impls.stderr @@ -2,9 +2,12 @@ error[E0412]: cannot find type `Type` in this scope --> $DIR/ignore-err-impls.rs:6:14 | LL | impl Generic<Type> for S {} - | - ^^^^ not found in this scope - | | - | help: you might be missing a type parameter: `<Type>` + | ^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<Type> Generic<Type> for S {} + | ++++++ error: aborting due to previous error diff --git a/tests/ui/traits/impl-bounds-checking.stderr b/tests/ui/traits/impl-bounds-checking.stderr index b01bacdb87d..1f969efe114 100644 --- a/tests/ui/traits/impl-bounds-checking.stderr +++ b/tests/ui/traits/impl-bounds-checking.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `isize: Clone2` is not satisfied - --> $DIR/impl-bounds-checking.rs:10:6 + --> $DIR/impl-bounds-checking.rs:10:24 | LL | impl Getter<isize> for isize { - | ^^^^^^^^^^^^^ the trait `Clone2` is not implemented for `isize` + | ^^^^^ the trait `Clone2` is not implemented for `isize` | note: required by a bound in `Getter` --> $DIR/impl-bounds-checking.rs:6:17 diff --git a/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr b/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr index 5572c6515ff..1bace8ab286 100644 --- a/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr +++ b/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr @@ -1,8 +1,8 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements - --> $DIR/impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:13 + --> $DIR/impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:28 | LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { - | ^^^^^^^^^^ + | ^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... --> $DIR/impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:6 @@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'b` as defined he LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { | ^^ note: ...so that the types are compatible - --> $DIR/impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:13 + --> $DIR/impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:28 | LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { - | ^^^^^^^^^^ + | ^^^^^^^^^ = note: expected `T1<'a>` found `T1<'_>` diff --git a/tests/ui/traits/issue-43784-supertrait.stderr b/tests/ui/traits/issue-43784-supertrait.stderr index bb890cb99ee..4fe12731475 100644 --- a/tests/ui/traits/issue-43784-supertrait.stderr +++ b/tests/ui/traits/issue-43784-supertrait.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/issue-43784-supertrait.rs:8:9 + --> $DIR/issue-43784-supertrait.rs:8:22 | LL | impl<T> Complete for T {} - | ^^^^^^^^ the trait `Copy` is not implemented for `T` + | ^ the trait `Copy` is not implemented for `T` | note: required by a bound in `Complete` --> $DIR/issue-43784-supertrait.rs:4:21 diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 0bb1f9ae035..aa8384e9805 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -2,9 +2,12 @@ error[E0412]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:3:12 | LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); - | -^ not found in this scope - | | - | help: you might be missing a type parameter: `<N>` + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct Foo<N>(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); + | +++ error[E0412]: cannot find type `NotDefined` in this scope --> $DIR/issue-50480.rs:3:15 @@ -16,17 +19,23 @@ error[E0412]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:3:12 | LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); - | -^ not found in this scope - | | - | help: you might be missing a type parameter: `<N>` + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct Foo<N>(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); + | +++ error[E0412]: cannot find type `NotDefined` in this scope --> $DIR/issue-50480.rs:3:15 | LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); - | - ^^^^^^^^^^ not found in this scope - | | - | help: you might be missing a type parameter: `<NotDefined>` + | ^^^^^^^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct Foo<NotDefined>(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); + | ++++++++++++ error[E0412]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:12:18 diff --git a/tests/ui/traits/issue-75627.stderr b/tests/ui/traits/issue-75627.stderr index 432ddf2dcdb..1675edc9ff0 100644 --- a/tests/ui/traits/issue-75627.stderr +++ b/tests/ui/traits/issue-75627.stderr @@ -2,9 +2,12 @@ error[E0412]: cannot find type `T` in this scope --> $DIR/issue-75627.rs:3:26 | LL | unsafe impl Send for Foo<T> {} - | - ^ not found in this scope - | | - | help: you might be missing a type parameter: `<T>` + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | unsafe impl<T> Send for Foo<T> {} + | +++ error: aborting due to previous error diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 7e781016e1f..8e7fd5f2557 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -30,9 +30,12 @@ error[E0412]: cannot find type `MISC` in this scope --> $DIR/issue-78372.rs:3:34 | LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} - | - ^^^^ not found in this scope - | | - | help: you might be missing a type parameter: `, MISC` + | ^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<T, MISC> DispatchFromDyn<Smaht<U, MISC>> for T {} + | ++++++ error[E0658]: use of unstable library feature 'dispatch_from_dyn' --> $DIR/issue-78372.rs:1:5 diff --git a/tests/ui/traits/issue-91594.stderr b/tests/ui/traits/issue-91594.stderr index 6b314fa586d..85d903fadd1 100644 --- a/tests/ui/traits/issue-91594.stderr +++ b/tests/ui/traits/issue-91594.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied - --> $DIR/issue-91594.rs:10:6 + --> $DIR/issue-91594.rs:10:19 | LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo` | = help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo` note: required for `Foo` to implement `Component<Foo>` diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index f137a298a7f..293cfbda86c 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -148,19 +148,24 @@ error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:115:12 | LL | let _: S::A; - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::A` + | ^^^^ + | +help: if there were a trait named `Example` with associated type `A` implemented for `S`, you could use the fully-qualified path + | +LL | let _: <S as Example>::A; + | ~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:116:12 | LL | let _: S::B; - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::B` + | ^^^^ help: use the fully-qualified path: `<S as assoc_ty::B>::B` error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:117:12 | LL | let _: S::C; - | ^^^^ help: use fully-qualified syntax: `<S as Trait>::C` + | ^^^^ help: use the fully-qualified path: `<S as assoc_ty::C>::C` error[E0624]: associated type `A` is private --> $DIR/item-privacy.rs:119:12 diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr index 85087282d3a..b4591778f8e 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr @@ -1,11 +1,13 @@ error[E0412]: cannot find type `Dst` in this scope --> $DIR/unknown_dst.rs:20:36 | -LL | fn should_gracefully_handle_unknown_dst() { - | - help: you might be missing a type parameter: `<Dst>` -... LL | assert::is_transmutable::<Src, Dst, Context>(); | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn should_gracefully_handle_unknown_dst<Dst>() { + | +++++ error: aborting due to previous error diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr index 9bedbe87c3f..a55d71d8068 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr @@ -1,11 +1,13 @@ error[E0412]: cannot find type `Src` in this scope --> $DIR/unknown_src.rs:20:31 | -LL | fn should_gracefully_handle_unknown_src() { - | - help: you might be missing a type parameter: `<Src>` -... LL | assert::is_transmutable::<Src, Dst, Context>(); | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn should_gracefully_handle_unknown_src<Src>() { + | +++++ error: aborting due to previous error diff --git a/tests/ui/typeck/autoderef-with-param-env-error.stderr b/tests/ui/typeck/autoderef-with-param-env-error.stderr index cde800336dd..182612d5ee7 100644 --- a/tests/ui/typeck/autoderef-with-param-env-error.stderr +++ b/tests/ui/typeck/autoderef-with-param-env-error.stderr @@ -1,11 +1,13 @@ error[E0412]: cannot find type `T` in this scope --> $DIR/autoderef-with-param-env-error.rs:3:5 | -LL | fn foo() - | - help: you might be missing a type parameter: `<T>` -LL | where LL | T: Send, | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn foo<T>() + | +++ error: aborting due to previous error diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr index 2b3b1b9efdf..5561673f3c6 100644 --- a/tests/ui/typeck/issue-104513-ice.stderr +++ b/tests/ui/typeck/issue-104513-ice.stderr @@ -1,10 +1,13 @@ error[E0405]: cannot find trait `Oops` in this scope --> $DIR/issue-104513-ice.rs:3:19 | -LL | fn f() { - | - help: you might be missing a type parameter: `<Oops>` LL | let _: S<impl Oops> = S; | ^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn f<Oops>() { + | ++++++ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding --> $DIR/issue-104513-ice.rs:3:14 diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index 5f7f6aa9f6e..72fccea8ae3 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr @@ -205,7 +205,12 @@ error[E0223]: ambiguous associated type --> $DIR/ufcs-partially-resolved.rs:36:12 | LL | let _: <u8 as Tr>::Y::NN; - | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<u8 as Tr>::Y as Trait>::NN` + | ^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `NN` implemented for `<u8 as Tr>::Y`, you could use the fully-qualified path + | +LL | let _: <<u8 as Tr>::Y as Example>::NN; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0599]: no associated item named `NN` found for type `u16` in the current scope --> $DIR/ufcs-partially-resolved.rs:38:20 |
