diff --git a/compiler/rustc_error_codes/src/error_codes/E0632.md b/compiler/rustc_error_codes/src/error_codes/E0632.md index 40840e894d6..7e0a5c71f5f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0632.md +++ b/compiler/rustc_error_codes/src/error_codes/E0632.md @@ -1,9 +1,11 @@ +#### Note: this error code is no longer emitted by the compiler. + An explicit generic argument was provided when calling a function that uses `impl Trait` in argument position. Erroneous code example: -```compile_fail,E0632 +```ignore (no longer an error) fn foo(a: T, b: impl Clone) {} foo::(0i32, "abc".to_string()); diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl index 95b348ec613..c61735a57e1 100644 --- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl @@ -95,12 +95,6 @@ typeck-expected-return-type = expected `{$expected}` because of return type typeck-unconstrained-opaque-type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same module -typeck-explicit-generic-args-with-impl-trait = - cannot provide explicit generic arguments when `impl Trait` is used in argument position - .label = explicit generic argument not allowed - .note = see issue #83701 for more information - .help = add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable - typeck-missing-type-params = the type {$parameterCount -> [one] parameter diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 0abd45c621d..099c40b215d 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -142,6 +142,8 @@ declare_features! ( (accepted, dyn_trait, "1.27.0", Some(44662), None), /// Allows integer match exhaustiveness checking (RFC 2591). (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), + /// Allows explicit generic arguments specification with `impl Trait` present. + (accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701), None), /// Allows arbitrary expressions in key-value attributes at parse time. (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None), /// Allows resolving absolute paths as paths from other crates. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 1798bf8d428..35473b6e97a 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -383,8 +383,6 @@ declare_features! ( (active, exclusive_range_pattern, "1.11.0", Some(37854), None), /// Allows exhaustive pattern matching on types that contain uninhabited types. (active, exhaustive_patterns, "1.13.0", Some(51085), None), - /// Allows explicit generic arguments specification with `impl Trait` present. - (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None), /// Allows defining `extern type`s. (active, extern_types, "1.23.0", Some(43467), None), /// Allows the use of `#[ffi_const]` on foreign functions. diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 39f7d30e81a..ce2698ef44c 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -111,6 +111,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { } /// Makes `a <: b`, where `a` may or may not be expected. + /// + /// See [`At::trace_exp`] and [`Trace::sub`] for a version of + /// this method that only requires `T: Relate<'tcx>` pub fn sub_exp(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()> where T: ToTrace<'tcx>, @@ -122,6 +125,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// call like `foo(x)`, where `foo: fn(i32)`, you might have /// `sup(i32, x)`, since the "expected" type is the type that /// appears in the signature. + /// + /// See [`At::trace`] and [`Trace::sub`] for a version of + /// this method that only requires `T: Relate<'tcx>` pub fn sup(self, expected: T, actual: T) -> InferResult<'tcx, ()> where T: ToTrace<'tcx>, @@ -130,6 +136,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { } /// Makes `expected <: actual`. + /// + /// See [`At::trace`] and [`Trace::sub`] for a version of + /// this method that only requires `T: Relate<'tcx>` pub fn sub(self, expected: T, actual: T) -> InferResult<'tcx, ()> where T: ToTrace<'tcx>, @@ -138,6 +147,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { } /// Makes `expected <: actual`. + /// + /// See [`At::trace_exp`] and [`Trace::eq`] for a version of + /// this method that only requires `T: Relate<'tcx>` pub fn eq_exp(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()> where T: ToTrace<'tcx>, @@ -146,6 +158,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { } /// Makes `expected <: actual`. + /// + /// See [`At::trace`] and [`Trace::eq`] for a version of + /// this method that only requires `T: Relate<'tcx>` pub fn eq(self, expected: T, actual: T) -> InferResult<'tcx, ()> where T: ToTrace<'tcx>, @@ -176,6 +191,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// this can result in an error (e.g., if asked to compute LUB of /// u32 and i32), it is meaningful to call one of them the /// "expected type". + /// + /// See [`At::trace`] and [`Trace::lub`] for a version of + /// this method that only requires `T: Relate<'tcx>` pub fn lub(self, expected: T, actual: T) -> InferResult<'tcx, T> where T: ToTrace<'tcx>, @@ -186,6 +204,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// Computes the greatest-lower-bound, or mutual subtype, of two /// values. As with `lub` order doesn't matter, except for error /// cases. + /// + /// See [`At::trace`] and [`Trace::glb`] for a version of + /// this method that only requires `T: Relate<'tcx>` pub fn glb(self, expected: T, actual: T) -> InferResult<'tcx, T> where T: ToTrace<'tcx>, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 18fc1158b04..1181925dd96 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -67,10 +67,8 @@ use rustc_hir::{Item, ItemKind, Node}; use rustc_middle::dep_graph::DepContext; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, - error::TypeError, - subst::{GenericArgKind, Subst, SubstsRef}, - Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, + self, error::TypeError, Binder, List, Region, Subst, Ty, TyCtxt, TypeFoldable, + TypeSuperFoldable, }; use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; @@ -926,10 +924,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { mut t1_out: &mut DiagnosticStyledString, mut t2_out: &mut DiagnosticStyledString, path: String, - sub: ty::subst::SubstsRef<'tcx>, + sub: &'tcx [ty::GenericArg<'tcx>], other_path: String, other_ty: Ty<'tcx>, ) -> Option<()> { + // FIXME/HACK: Go back to `SubstsRef` to use its inherent methods, + // ideally that shouldn't be necessary. + let sub = self.tcx.intern_substs(sub); for (i, ta) in sub.types().enumerate() { if ta == other_ty { self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty); @@ -960,45 +961,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - /// For generic types with parameters with defaults, remove the parameters corresponding to - /// the defaults. This repeats a lot of the logic found in `ty::print::pretty`. - fn strip_generic_default_params( - &self, - def_id: DefId, - substs: ty::subst::SubstsRef<'tcx>, - ) -> SubstsRef<'tcx> { - let generics = self.tcx.generics_of(def_id); - let mut num_supplied_defaults = 0; - - let default_params = generics.params.iter().rev().filter_map(|param| match param.kind { - ty::GenericParamDefKind::Type { has_default: true, .. } => Some(param.def_id), - ty::GenericParamDefKind::Const { has_default: true } => Some(param.def_id), - _ => None, - }); - for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) { - match actual.unpack() { - GenericArgKind::Const(c) => { - if EarlyBinder(self.tcx.const_param_default(def_id)).subst(self.tcx, substs) - != c - { - break; - } - } - GenericArgKind::Type(ty) => { - if self.tcx.bound_type_of(def_id).subst(self.tcx, substs) != ty { - break; - } - } - _ => break, - } - num_supplied_defaults += 1; - } - let len = generics.params.len(); - let mut generics = generics.clone(); - generics.params.truncate(len - num_supplied_defaults); - substs.truncate_to(self.tcx, &generics) - } - /// Given two `fn` signatures highlight only sub-parts that are different. fn cmp_fn_sig( &self, @@ -1156,8 +1118,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => { let did1 = def1.did(); let did2 = def2.did(); - let sub_no_defaults_1 = self.strip_generic_default_params(did1, sub1); - let sub_no_defaults_2 = self.strip_generic_default_params(did2, sub2); + let sub_no_defaults_1 = + self.tcx.generics_of(did1).own_substs_no_defaults(self.tcx, sub1); + let sub_no_defaults_2 = + self.tcx.generics_of(did2).own_substs_no_defaults(self.tcx, sub2); let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); let path1 = self.tcx.def_path_str(did1); let path2 = self.tcx.def_path_str(did2); 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 7b5c377f7b4..207d2870c5c 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 @@ -2,6 +2,7 @@ use crate::infer::type_variable::TypeVariableOriginKind; use crate::infer::InferCtxt; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; +use rustc_hir::def::Res; use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; @@ -11,7 +12,7 @@ use rustc_middle::infer::unify_key::ConstVariableOriginKind; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; -use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, InferConst}; +use rustc_middle::ty::{self, DefIdTree, InferConst}; use rustc_middle::ty::{Ty, TyCtxt, TypeckResults}; use rustc_span::symbol::{kw, Ident}; use rustc_span::{BytePos, Span}; @@ -853,12 +854,23 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)), ) => { if tcx.res_generics_def_id(path.res) != Some(def.did()) { - bug!( - "unexpected path: def={:?} substs={:?} path={:?}", - def, - substs, - path, - ); + match path.res { + Res::Def(DefKind::TyAlias, _) => { + // FIXME: Ideally we should support this. For that + // we have to map back from the self type to the + // type alias though. That's difficult. + // + // See the `need_type_info/type-alias.rs` test for + // some examples. + } + // There cannot be inference variables in the self type, + // so there's nothing for us to do here. + Res::SelfTy { .. } => {} + _ => warn!( + "unexpected path: def={:?} substs={:?} path={:?}", + def, substs, path, + ), + } } else { return Box::new( self.resolved_path_inferred_subst_iter(path, substs) @@ -958,26 +970,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg)) { let substs = self.infcx.resolve_vars_if_possible(substs); - let num_args = generics - .params - .iter() - .rev() - .filter(|&p| !matches!(p.kind, GenericParamDefKind::Lifetime)) - .skip_while(|¶m| { - if let Some(default) = param.default_value(tcx) { - // FIXME: Using structural comparisions has a bunch of false negatives. - // - // We should instead try to replace inference variables with placeholders and - // then use `infcx.can_eq`. That probably should be a separate method - // generally used during error reporting. - default.subst(tcx, substs) == substs[param.index as usize] - } else { - false - } - }) - .count(); - let generic_args = - &generics.own_substs(substs)[generics.own_counts().lifetimes..][..num_args]; + let generic_args = &generics.own_substs_no_defaults(tcx, substs) + [generics.own_counts().lifetimes..]; let span = match expr.kind { ExprKind::MethodCall(path, _, _) => path.ident.span, _ => expr.span, diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 1feabb2d6b1..5fff840c39e 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -228,8 +228,47 @@ impl<'tcx> Generics { }) } + /// Returns the substs corresponding to the generic parameters + /// of this item, excluding `Self`. + /// + /// **This should only be used for diagnostics purposes.** + pub fn own_substs_no_defaults( + &'tcx self, + tcx: TyCtxt<'tcx>, + substs: &'tcx [ty::GenericArg<'tcx>], + ) -> &'tcx [ty::GenericArg<'tcx>] { + let mut own_params = self.parent_count..self.count(); + if self.has_self && self.parent.is_none() { + own_params.start = 1; + } + + // Filter the default arguments. + // + // This currently uses structural equality instead + // of semantic equivalance. While not ideal, that's + // good enough for now as this should only be used + // for diagnostics anyways. + own_params.end -= self + .params + .iter() + .rev() + .take_while(|param| { + param.default_value(tcx).map_or(false, |default| { + default.subst(tcx, substs) == substs[param.index as usize] + }) + }) + .count(); + + &substs[own_params] + } + /// Returns the substs corresponding to the generic parameters of this item, excluding `Self`. - pub fn own_substs(&'tcx self, substs: SubstsRef<'tcx>) -> &'tcx [ty::GenericArg<'tcx>] { + /// + /// **This should only be used for diagnostics purposes.** + pub fn own_substs( + &'tcx self, + substs: &'tcx [ty::GenericArg<'tcx>], + ) -> &'tcx [ty::GenericArg<'tcx>] { let own = &substs[self.parent_count..][..self.params.len()]; if self.has_self && self.parent.is_none() { &own[1..] } else { &own } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 48ac7ecdf05..7f0f3755c4b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -22,7 +22,6 @@ use crate::mir::{Body, GeneratorLayout}; use crate::traits::{self, Reveal}; use crate::ty; use crate::ty::fast_reject::SimplifiedType; -use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::util::Discr; pub use adt::*; pub use assoc::*; @@ -44,6 +43,7 @@ use rustc_session::cstore::CrateStoreDyn; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use rustc_target::abi::Align; +pub use subst::*; pub use vtable::*; use std::fmt::Debug; diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 9d8124eb25d..5ad93d77820 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -149,7 +149,7 @@ pub trait Printer<'tcx>: Sized { // on top of the same path, but without its own generics. _ => { if !generics.params.is_empty() && substs.len() >= generics.count() { - let args = self.generic_args_to_print(generics, substs); + let args = generics.own_substs_no_defaults(self.tcx(), substs); return self.path_generic_args( |cx| cx.print_def_path(def_id, parent_substs), args, @@ -184,43 +184,6 @@ pub trait Printer<'tcx>: Sized { } } - fn generic_args_to_print( - &self, - generics: &'tcx ty::Generics, - substs: &'tcx [GenericArg<'tcx>], - ) -> &'tcx [GenericArg<'tcx>] { - let mut own_params = generics.parent_count..generics.count(); - - // Don't print args for `Self` parameters (of traits). - if generics.has_self && own_params.start == 0 { - own_params.start = 1; - } - - // Don't print args that are the defaults of their respective parameters. - own_params.end -= generics - .params - .iter() - .rev() - .take_while(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => false, - ty::GenericParamDefKind::Type { has_default, .. } => { - has_default - && substs[param.index as usize] - == GenericArg::from( - self.tcx().bound_type_of(param.def_id).subst(self.tcx(), substs), - ) - } - ty::GenericParamDefKind::Const { has_default } => { - has_default - && substs[param.index as usize] - == GenericArg::from(self.tcx().const_param_default(param.def_id)) - } - }) - .count(); - - &substs[own_params] - } - fn default_print_impl_path( self, impl_def_id: DefId, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7328b18a328..53a97a46b2d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -825,12 +825,11 @@ pub trait PrettyPrinter<'tcx>: for (fn_once_trait_ref, entry) in fn_traits { // Get the (single) generic ty (the args) of this FnOnce trait ref. - let generics = self.generic_args_to_print( - self.tcx().generics_of(fn_once_trait_ref.def_id()), - fn_once_trait_ref.skip_binder().substs, - ); + let generics = self.tcx().generics_of(fn_once_trait_ref.def_id()); + let args = + generics.own_substs_no_defaults(self.tcx(), fn_once_trait_ref.skip_binder().substs); - match (entry.return_ty, generics[0].expect_ty()) { + match (entry.return_ty, args[0].expect_ty()) { // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded // a return type. (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => { @@ -892,15 +891,13 @@ pub trait PrettyPrinter<'tcx>: print(trait_ref.skip_binder().print_only_trait_name()) ); - let generics = self.generic_args_to_print( - self.tcx().generics_of(trait_ref.def_id()), - trait_ref.skip_binder().substs, - ); + let generics = self.tcx().generics_of(trait_ref.def_id()); + let args = generics.own_substs_no_defaults(self.tcx(), trait_ref.skip_binder().substs); - if !generics.is_empty() || !assoc_items.is_empty() { + if !args.is_empty() || !assoc_items.is_empty() { let mut first = true; - for ty in generics { + for ty in args { if first { p!("<"); first = false; @@ -1071,10 +1068,10 @@ pub trait PrettyPrinter<'tcx>: let dummy_cx = cx.tcx().mk_ty_infer(ty::FreshTy(0)); let principal = principal.with_self_ty(cx.tcx(), dummy_cx); - let args = cx.generic_args_to_print( - cx.tcx().generics_of(principal.def_id), - principal.substs, - ); + let args = cx + .tcx() + .generics_of(principal.def_id) + .own_substs_no_defaults(cx.tcx(), principal.substs); // Don't print `'_` if there's no unerased regions. let print_regions = args.iter().any(|arg| match arg.unpack() { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 45a5adb90cf..23c1767cb90 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -513,6 +513,9 @@ struct DiagnosticMetadata<'ast> { /// The current impl items (used to suggest). current_impl_items: Option<&'ast [P]>, + + /// When processing impl trait + currently_processing_impl_trait: Option<(TraitRef, Ty)>, } struct LateResolutionVisitor<'a, 'b, 'ast> { @@ -2087,18 +2090,22 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { fn with_optional_trait_ref( &mut self, opt_trait_ref: Option<&TraitRef>, + self_type: &'ast Ty, f: impl FnOnce(&mut Self, Option) -> T, ) -> T { let mut new_val = None; let mut new_id = None; if let Some(trait_ref) = opt_trait_ref { let path: Vec<_> = Segment::from_path(&trait_ref.path); + self.diagnostic_metadata.currently_processing_impl_trait = + Some((trait_ref.clone(), self_type.clone())); let res = self.smart_resolve_path_fragment( None, &path, PathSource::Trait(AliasPossibility::No), Finalize::new(trait_ref.ref_id, trait_ref.path.span), ); + self.diagnostic_metadata.currently_processing_impl_trait = None; if let Some(def_id) = res.base_res().opt_def_id() { new_id = Some(def_id); new_val = Some((self.r.expect_module(def_id), trait_ref.clone())); @@ -2139,7 +2146,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_self_rib(Res::SelfTy { trait_: None, alias_to: None }, |this| { this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter(item_id), |this| { // Resolve the trait reference, if necessary. - this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| { + this.with_optional_trait_ref(opt_trait_reference.as_ref(), self_type, |this, trait_id| { let item_def_id = this.r.local_def_id(item_id); // Register the trait definitions from here. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 5e52e9b40f0..68ddc37c3a8 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -146,6 +146,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let is_expected = &|res| source.is_expected(res); let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _)); + debug!(?res, ?source); + // Make the base error. struct BaseError<'a> { msg: String, @@ -250,6 +252,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let mut err = self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code); + self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); + if let Some(sugg) = base_error.suggestion { err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect); } @@ -692,6 +696,35 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } + fn suggest_swapping_misplaced_self_ty_and_trait( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + res: Option, + span: Span, + ) { + if let Some((trait_ref, self_ty)) = + self.diagnostic_metadata.currently_processing_impl_trait.clone() + && let TyKind::Path(_, self_ty_path) = &self_ty.kind + && let PathResult::Module(ModuleOrUniformRoot::Module(module)) = + self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None) + && let ModuleKind::Def(DefKind::Trait, ..) = module.kind + && trait_ref.path.span == span + && let PathSource::Trait(_) = source + && let Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) = res + && let Ok(self_ty_str) = + self.r.session.source_map().span_to_snippet(self_ty.span) + && let Ok(trait_ref_str) = + self.r.session.source_map().span_to_snippet(trait_ref.path.span) + { + err.multipart_suggestion( + "`impl` items mention the trait being implemented first and the type it is being implemented for second", + vec![(trait_ref.path.span, self_ty_str), (self_ty.span, trait_ref_str)], + Applicability::MaybeIncorrect, + ); + } + } + fn get_single_associated_item( &mut self, path: &[Segment], diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 7f227217e3c..d7e2f621065 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -333,7 +333,7 @@ impl<'a> FileNameDisplay<'a> { pub fn to_string_lossy(&self) -> Cow<'a, str> { match self.inner { FileName::Real(ref inner) => inner.to_string_lossy(self.display_pref), - _ => Cow::from(format!("{}", self)), + _ => Cow::from(self.to_string()), } } } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index dc4bc8fb55a..3fe4b5b46e0 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -3,7 +3,7 @@ use crate::astconv::{ AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, }; -use crate::errors::{AssocTypeBindingNotAllowed, ExplicitGenericArgsWithImplTrait}; +use crate::errors::AssocTypeBindingNotAllowed; use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; use rustc_ast::ast::ParamKindOrd; use rustc_errors::{struct_span_err, Applicability, Diagnostic, MultiSpan}; @@ -397,8 +397,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { is_method_call: IsMethodCall, ) -> GenericArgCountResult { let empty_args = hir::GenericArgs::none(); - let suppress_mismatch = Self::check_impl_trait(tcx, seg, generics); - let gen_args = seg.args.unwrap_or(&empty_args); let gen_pos = if is_method_call == IsMethodCall::Yes { GenericArgPosition::MethodCall @@ -406,10 +404,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericArgPosition::Value }; let has_self = generics.parent.is_none() && generics.has_self; - let infer_args = seg.infer_args || suppress_mismatch; Self::check_generic_arg_count( - tcx, span, def_id, seg, generics, gen_args, gen_pos, has_self, infer_args, + tcx, + span, + def_id, + seg, + generics, + gen_args, + gen_pos, + has_self, + seg.infer_args, ) } @@ -431,19 +436,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let param_counts = gen_params.own_counts(); // Subtracting from param count to ensure type params synthesized from `impl Trait` - // cannot be explicitly specified even with `explicit_generic_args_with_impl_trait` - // feature enabled. - let synth_type_param_count = if tcx.features().explicit_generic_args_with_impl_trait { - gen_params - .params - .iter() - .filter(|param| { - matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. }) - }) - .count() - } else { - 0 - }; + // cannot be explicitly specified. + let synth_type_param_count = gen_params + .params + .iter() + .filter(|param| { + matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. }) + }) + .count(); let named_type_param_count = param_counts.types - has_self as usize - synth_type_param_count; let infer_lifetimes = @@ -611,40 +611,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } - /// Report error if there is an explicit type parameter when using `impl Trait`. - pub(crate) fn check_impl_trait( - tcx: TyCtxt<'_>, - seg: &hir::PathSegment<'_>, - generics: &ty::Generics, - ) -> bool { - if seg.infer_args || tcx.features().explicit_generic_args_with_impl_trait { - return false; - } - - let impl_trait = generics.has_impl_trait(); - - if impl_trait { - let spans = seg - .args() - .args - .iter() - .filter_map(|arg| match arg { - GenericArg::Infer(_) | GenericArg::Type(_) | GenericArg::Const(_) => { - Some(arg.span()) - } - _ => None, - }) - .collect::>(); - - tcx.sess.emit_err(ExplicitGenericArgsWithImplTrait { - spans, - is_nightly_build: tcx.sess.is_nightly_build().then_some(()), - }); - } - - impl_trait - } - /// Emits an error regarding forbidden type binding associations pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span) { tcx.sess.emit_err(AssocTypeBindingNotAllowed { span }); diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index a7f736fed14..67a3d4a4d02 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -241,17 +241,6 @@ pub struct UnconstrainedOpaqueType { pub name: Symbol, } -#[derive(SessionDiagnostic)] -#[error(code = "E0632", slug = "typeck-explicit-generic-args-with-impl-trait")] -#[note] -pub struct ExplicitGenericArgsWithImplTrait { - #[primary_span] - #[label] - pub spans: Vec, - #[help] - pub is_nightly_build: Option<()>, -} - pub struct MissingTypeParams { pub span: Span, pub def_span: Span, diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 1def9fe0972..82cd3647040 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1417,13 +1417,13 @@ impl From for Stdio { /// For proper error reporting of failed processes, print the value of `ExitStatus` or /// `ExitStatusError` using their implementations of [`Display`](crate::fmt::Display). /// -/// # Differences from `ExitStatus` +/// # Differences from `ExitCode` /// -/// `ExitCode` is intended for terminating the currently running process, via -/// the `Termination` trait, in contrast to [`ExitStatus`], which represents the +/// [`ExitCode`] is intended for terminating the currently running process, via +/// the `Termination` trait, in contrast to `ExitStatus`, which represents the /// termination of a child process. These APIs are separate due to platform /// compatibility differences and their expected usage; it is not generally -/// possible to exactly reproduce an ExitStatus from a child for the current +/// possible to exactly reproduce an `ExitStatus` from a child for the current /// process after the fact. /// /// [`status`]: Command::status @@ -1684,7 +1684,7 @@ impl crate::error::Error for ExitStatusError {} /// the `Termination` trait, in contrast to [`ExitStatus`], which represents the /// termination of a child process. These APIs are separate due to platform /// compatibility differences and their expected usage; it is not generally -/// possible to exactly reproduce an ExitStatus from a child for the current +/// possible to exactly reproduce an `ExitStatus` from a child for the current /// process after the fact. /// /// # Examples diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md index 25ef8b5bb91..e3b08648999 100644 --- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md +++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md @@ -87,7 +87,9 @@ on your documentation examples make requests to. #![doc(html_playground_url = "https://playground.example.com/")] ``` -Now, when you press "run", the button will make a request to this domain. +Now, when you press "run", the button will make a request to this domain. The request +URL will contain 2 query parameters: `code` and `edition` for the code in the documentation +and the Rust edition respectively. If you don't use this attribute, there will be no run buttons. diff --git a/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md b/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md deleted file mode 100644 index 479571d85fe..00000000000 --- a/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md +++ /dev/null @@ -1,53 +0,0 @@ -# `explicit_generic_args_with_impl_trait` - -The tracking issue for this feature is: [#83701] - -[#83701]: https://github.com/rust-lang/rust/issues/83701 - ------------------------- - -The `explicit_generic_args_with_impl_trait` feature gate lets you specify generic arguments even -when `impl Trait` is used in argument position. - -A simple example is: - -```rust -#![feature(explicit_generic_args_with_impl_trait)] - -fn foo(_f: impl AsRef) {} - -fn main() { - foo::("".to_string()); -} -``` - -This is currently rejected: - -```text -error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position - --> src/main.rs:6:11 - | -6 | foo::("".to_string()); - | ^^^ explicit generic argument not allowed - -``` - -However it would compile if `explicit_generic_args_with_impl_trait` is enabled. - -Note that the synthetic type parameters from `impl Trait` are still implicit and you -cannot explicitly specify these: - -```rust,compile_fail -#![feature(explicit_generic_args_with_impl_trait)] - -fn foo(_f: impl AsRef) {} -fn bar>(_f: F) {} - -fn main() { - bar::("".to_string()); // Okay - bar::("".to_string()); // Okay - - foo::("".to_string()); // Okay - foo::("".to_string()); // Error, you cannot specify `impl Trait` explicitly -} -``` diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs index 308c121a941..f633e56b0ec 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs @@ -15,12 +15,12 @@ impl Traitor<1, 2> for u64 {} fn uwu() -> impl Traitor { - //~^ error: the trait bound `u32: Traitor` is not satisfied + //~^ error: the trait bound `u32: Traitor` is not satisfied 1_u32 } fn owo() -> impl Traitor { - //~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied + //~^ error: the trait bound `u64: Traitor` is not satisfied 1_u64 } diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr index 8031da28ca1..cbe4a4ac0d6 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -6,21 +6,21 @@ LL | fn rawr() -> impl Trait { | = help: the trait `Trait` is implemented for `Uwu` -error[E0277]: the trait bound `u32: Traitor` is not satisfied +error[E0277]: the trait bound `u32: Traitor` is not satisfied --> $DIR/rp_impl_trait_fail.rs:17:26 | LL | fn uwu() -> impl Traitor { - | ^^^^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u32` + | ^^^^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u32` | = help: the following other types implement trait `Traitor`: > > -error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied +error[E0277]: the trait bound `u64: Traitor` is not satisfied --> $DIR/rp_impl_trait_fail.rs:22:13 | LL | fn owo() -> impl Traitor { - | ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` + | ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64` | = help: the following other types implement trait `Traitor`: > diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.rs b/src/test/ui/const-generics/defaults/trait_objects_fail.rs index 7ba12d02b6e..5e779d2e8de 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.rs +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.rs @@ -26,5 +26,5 @@ fn main() { foo(&10_u32); //~^ error: the trait bound `u32: Trait` is not satisfied bar(&true); - //~^ error: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied + //~^ error: the trait bound `bool: Traitor<{_: u8}>` is not satisfied } diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr index 7f8a1f742d8..60dc96f675a 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr @@ -9,16 +9,16 @@ LL | foo(&10_u32); = help: the trait `Trait<2_u8>` is implemented for `u32` = note: required for the cast to the object type `dyn Trait` -error[E0277]: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied +error[E0277]: the trait bound `bool: Traitor<{_: u8}>` is not satisfied --> $DIR/trait_objects_fail.rs:28:9 | LL | bar(&true); - | --- ^^^^^ the trait `Traitor<{_: u8}, {_: u8}>` is not implemented for `bool` + | --- ^^^^^ the trait `Traitor<{_: u8}>` is not implemented for `bool` | | | required by a bound introduced by this call | = help: the trait `Traitor<2_u8, 3_u8>` is implemented for `bool` - = note: required for the cast to the object type `dyn Traitor<{_: u8}, {_: u8}>` + = note: required for the cast to the object type `dyn Traitor<{_: u8}>` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.stderr b/src/test/ui/const-generics/impl-trait-with-const-arguments.stderr deleted file mode 100644 index 87e4ad50040..00000000000 --- a/src/test/ui/const-generics/impl-trait-with-const-arguments.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position - --> $DIR/impl-trait-with-const-arguments.rs:18:20 - | -LL | assert_eq!(f::<4usize>(Usizable), 20usize); - | ^^^^^^ explicit generic argument not allowed - | - = note: see issue #83701 for more information - = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0632`. diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/const-args.rs similarity index 72% rename from src/test/ui/const-generics/impl-trait-with-const-arguments.rs rename to src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/const-args.rs index 24ba393c17f..1aa23c60823 100644 --- a/src/test/ui/const-generics/impl-trait-with-const-arguments.rs +++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/const-args.rs @@ -1,3 +1,5 @@ +// check-pass + trait Usizer { fn m(self) -> usize; } @@ -16,5 +18,4 @@ impl Usizer for Usizable { fn main() { assert_eq!(f::<4usize>(Usizable), 20usize); -//~^ ERROR cannot provide explicit generic arguments when `impl Trait` is used in argument position } diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs index 832a3e3b7b1..3b1024d6126 100644 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs +++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs @@ -1,5 +1,3 @@ -#![feature(explicit_generic_args_with_impl_trait)] - fn foo(_f: impl AsRef) {} fn main() { diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr index 2ae7745c725..c8b82783ea8 100644 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr +++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr @@ -1,5 +1,5 @@ error[E0107]: this function takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/explicit-generic-args-for-impl.rs:6:5 + --> $DIR/explicit-generic-args-for-impl.rs:4:5 | LL | foo::("".to_string()); | ^^^ ------ help: remove this generic argument @@ -7,7 +7,7 @@ LL | foo::("".to_string()); | expected 1 generic argument | note: function defined here, with 1 generic parameter: `T` - --> $DIR/explicit-generic-args-for-impl.rs:3:4 + --> $DIR/explicit-generic-args-for-impl.rs:1:4 | LL | fn foo(_f: impl AsRef) {} | ^^^ - diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs index a6585bcf848..99e0931ab95 100644 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs +++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(explicit_generic_args_with_impl_trait)] - fn foo(_f: impl AsRef) {} fn main() { diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs deleted file mode 100644 index 0e4d6986d46..00000000000 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs +++ /dev/null @@ -1,7 +0,0 @@ -// gate-test-explicit_generic_args_with_impl_trait - -fn foo(_f: impl AsRef) {} - -fn main() { - foo::("".to_string()); //~ ERROR E0632 -} diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr deleted file mode 100644 index a25c85faf4e..00000000000 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position - --> $DIR/feature-gate.rs:6:11 - | -LL | foo::("".to_string()); - | ^^^ explicit generic argument not allowed - | - = note: see issue #83701 for more information - = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0632`. diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs index e2ee63821ae..987df499734 100644 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs +++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(explicit_generic_args_with_impl_trait)] - fn f(_: impl AsRef, _: impl AsRef) {} fn main() { diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs index ffb0582fe8d..7249a36f5fe 100644 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs +++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs @@ -1,5 +1,3 @@ -#![feature(explicit_generic_args_with_impl_trait)] - fn f(_: impl AsRef, _: impl AsRef) {} fn main() { diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr index b6701b68fd6..9d6db88d364 100644 --- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr +++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr @@ -1,5 +1,5 @@ error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied - --> $DIR/not-enough-args.rs:6:5 + --> $DIR/not-enough-args.rs:4:5 | LL | f::<[u8]>("a", b"a"); | ^ ---- supplied 1 generic argument @@ -7,7 +7,7 @@ LL | f::<[u8]>("a", b"a"); | expected 2 generic arguments | note: function defined here, with 2 generic parameters: `T`, `U` - --> $DIR/not-enough-args.rs:3:4 + --> $DIR/not-enough-args.rs:1:4 | LL | fn f(_: impl AsRef, _: impl AsRef) {} | ^ - - diff --git a/src/test/ui/impl-trait/issues/universal-issue-48703.rs b/src/test/ui/impl-trait/issues/universal-issue-48703.rs deleted file mode 100644 index d1e5aa6c6b9..00000000000 --- a/src/test/ui/impl-trait/issues/universal-issue-48703.rs +++ /dev/null @@ -1,7 +0,0 @@ -use std::fmt::Debug; - -fn foo(x: impl Debug) { } - -fn main() { - foo::('a'); //~ ERROR cannot provide explicit generic arguments -} diff --git a/src/test/ui/impl-trait/issues/universal-issue-48703.stderr b/src/test/ui/impl-trait/issues/universal-issue-48703.stderr deleted file mode 100644 index 02c7fe8ff2c..00000000000 --- a/src/test/ui/impl-trait/issues/universal-issue-48703.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position - --> $DIR/universal-issue-48703.rs:6:11 - | -LL | foo::('a'); - | ^^^^^^ explicit generic argument not allowed - | - = note: see issue #83701 for more information - = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0632`. diff --git a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs b/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs deleted file mode 100644 index 4ac0a694cb1..00000000000 --- a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::any::Any; -pub struct EventHandler { -} - -impl EventHandler -{ - pub fn handle_event(&mut self, _efunc: impl FnMut(T)) {} -} - -struct TestEvent(i32); - -fn main() { - let mut evt = EventHandler {}; - evt.handle_event::(|_evt| { - //~^ ERROR cannot provide explicit generic arguments - }); -} diff --git a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr b/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr deleted file mode 100644 index 84b98f71f4f..00000000000 --- a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position - --> $DIR/universal-turbofish-in-method-issue-50950.rs:14:24 - | -LL | evt.handle_event::(|_evt| { - | ^^^^^^^^^ ^^^^^^^^^^^^^ explicit generic argument not allowed - | | - | explicit generic argument not allowed - | - = note: see issue #83701 for more information - = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0632`. diff --git a/src/test/ui/inference/issue-83606.rs b/src/test/ui/inference/issue-83606.rs index be56a3020cc..eaaef3463dd 100644 --- a/src/test/ui/inference/issue-83606.rs +++ b/src/test/ui/inference/issue-83606.rs @@ -5,6 +5,6 @@ fn foo(_: impl std::fmt::Display) -> [usize; N] { } fn main() { - let _ = foo("foo"); //<- Do not suggest `foo::("foo");`! + let _ = foo("foo"); //~^ ERROR: type annotations needed for `[usize; _]` } diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr index 4ffaf820b82..f5c84f96064 100644 --- a/src/test/ui/inference/issue-83606.stderr +++ b/src/test/ui/inference/issue-83606.stderr @@ -1,12 +1,12 @@ error[E0282]: type annotations needed for `[usize; _]` --> $DIR/issue-83606.rs:8:9 | -LL | let _ = foo("foo"); //<- Do not suggest `foo::("foo");`! +LL | let _ = foo("foo"); | ^ | help: consider giving this pattern a type, where the the value of const parameter `N` is specified | -LL | let _: [usize; _] = foo("foo"); //<- Do not suggest `foo::("foo");`! +LL | let _: [usize; _] = foo("foo"); | ++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/inference/need_type_info/concrete-impl.rs b/src/test/ui/inference/need_type_info/concrete-impl.rs new file mode 100644 index 00000000000..72e0e74f323 --- /dev/null +++ b/src/test/ui/inference/need_type_info/concrete-impl.rs @@ -0,0 +1,16 @@ +trait Ambiguous { + fn method() {} +} + +struct One; +struct Two; +struct Struct; + +impl Ambiguous for Struct {} +impl Ambiguous for Struct {} + +fn main() { + >::method(); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed +} diff --git a/src/test/ui/inference/need_type_info/concrete-impl.stderr b/src/test/ui/inference/need_type_info/concrete-impl.stderr new file mode 100644 index 00000000000..b79d34affa2 --- /dev/null +++ b/src/test/ui/inference/need_type_info/concrete-impl.stderr @@ -0,0 +1,33 @@ +error[E0282]: type annotations needed + --> $DIR/concrete-impl.rs:13:5 + | +LL | >::method(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous` + | +help: consider specifying the generic argument + | +LL | >::method(); + | ~~~~~ + +error[E0283]: type annotations needed + --> $DIR/concrete-impl.rs:13:5 + | +LL | >::method(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous` + | +note: multiple `impl`s satisfying `Struct: Ambiguous<_>` found + --> $DIR/concrete-impl.rs:9:1 + | +LL | impl Ambiguous for Struct {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Ambiguous for Struct {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying the generic argument + | +LL | >::method(); + | ~~~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/inference/need_type_info/self-ty-in-path.rs b/src/test/ui/inference/need_type_info/self-ty-in-path.rs new file mode 100644 index 00000000000..768a8cc3778 --- /dev/null +++ b/src/test/ui/inference/need_type_info/self-ty-in-path.rs @@ -0,0 +1,13 @@ +// Test that we don't ICE when encountering a `Self` in a path. +struct TestErr(T); + +impl TestErr { + fn func_a() {} + + fn func_b() { + Self::func_a(); + //~^ ERROR type annotations needed + } +} + +fn main() {} diff --git a/src/test/ui/inference/need_type_info/self-ty-in-path.stderr b/src/test/ui/inference/need_type_info/self-ty-in-path.stderr new file mode 100644 index 00000000000..04b521dbdb3 --- /dev/null +++ b/src/test/ui/inference/need_type_info/self-ty-in-path.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/self-ty-in-path.rs:8:9 + | +LL | Self::func_a(); + | ^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the associated function `func_a` + | +help: consider specifying the generic argument + | +LL | Self::func_a::(); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/inference/need_type_info/type-alias-indirect.rs b/src/test/ui/inference/need_type_info/type-alias-indirect.rs new file mode 100644 index 00000000000..0ed02ddc5f3 --- /dev/null +++ b/src/test/ui/inference/need_type_info/type-alias-indirect.rs @@ -0,0 +1,18 @@ +// An addition to the `type-alias.rs` test, +// see the FIXME in that file for why this test +// exists. +// +// If there is none, feel free to remove this test +// again. +struct Ty(T); +impl Ty { + fn new() {} +} + +type IndirectAlias = Ty>; +fn indirect_alias() { + IndirectAlias::new(); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/inference/need_type_info/type-alias-indirect.stderr b/src/test/ui/inference/need_type_info/type-alias-indirect.stderr new file mode 100644 index 00000000000..6161690df50 --- /dev/null +++ b/src/test/ui/inference/need_type_info/type-alias-indirect.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/type-alias-indirect.rs:14:5 + | +LL | IndirectAlias::new(); + | ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/inference/need_type_info/type-alias.rs b/src/test/ui/inference/need_type_info/type-alias.rs new file mode 100644 index 00000000000..f921b046b6c --- /dev/null +++ b/src/test/ui/inference/need_type_info/type-alias.rs @@ -0,0 +1,36 @@ +// Test the inference errors in case the relevant path +// uses a type alias. +// +// Regression test for #97698. +struct Ty(T); +impl Ty { + fn new() {} +} + +type DirectAlias = Ty; +fn direct_alias() { + DirectAlias::new() + //~^ ERROR type annotations needed +} + +type IndirectAlias = Ty>; +fn indirect_alias() { + IndirectAlias::new(); + // FIXME: This should also emit an error. + // + // Added it separately as `type-alias-indirect.rs` + // where it does error. +} + +struct TyDefault(T, U); +impl TyDefault { + fn new() {} +} + +type DirectButWithDefaultAlias = TyDefault; +fn direct_but_with_default_alias() { + DirectButWithDefaultAlias::new(); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/inference/need_type_info/type-alias.stderr b/src/test/ui/inference/need_type_info/type-alias.stderr new file mode 100644 index 00000000000..a33f49baf54 --- /dev/null +++ b/src/test/ui/inference/need_type_info/type-alias.stderr @@ -0,0 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/type-alias.rs:12:5 + | +LL | DirectAlias::new() + | ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + +error[E0282]: type annotations needed + --> $DIR/type-alias.rs:32:5 + | +LL | DirectButWithDefaultAlias::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs new file mode 100644 index 00000000000..03c7ed347bd --- /dev/null +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs @@ -0,0 +1,22 @@ +// edition:2021 + +pub trait Trait<'a, T> {} + +pub struct Struct; +pub enum Enum {} + +pub union Union { + f1: usize, +} + +impl<'a, T> Struct for Trait<'a, T> {} +//~^ ERROR expected trait, found struct `Struct` +//~| ERROR trait objects must include the `dyn` keyword + +impl<'a, T> Enum for Trait<'a, T> {} +//~^ ERROR expected trait, found enum `Enum` + +impl<'a, T> Union for Trait<'a, T> {} +//~^ ERROR expected trait, found union `Union` + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr new file mode 100644 index 00000000000..dd6951e0474 --- /dev/null +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr @@ -0,0 +1,49 @@ +error[E0404]: expected trait, found struct `Struct` + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:13 + | +LL | impl<'a, T> Struct for Trait<'a, T> {} + | ^^^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Struct {} + | ~~~~~~~~~~~~ ~~~~~~~~~ + +error[E0404]: expected trait, found enum `Enum` + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:16:13 + | +LL | impl<'a, T> Enum for Trait<'a, T> {} + | ^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Enum {} + | ~~~~~~~~~~~~ ~~~~~~~ + +error[E0404]: expected trait, found union `Union` + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:13 + | +LL | impl<'a, T> Union for Trait<'a, T> {} + | ^^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Union {} + | ~~~~~~~~~~~~ ~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:27 + | +LL | impl<'a, T> Struct for Trait<'a, T> {} + | ^^^^^^^^^^^^ + | +help: add `dyn` keyword before this trait + | +LL - impl<'a, T> Struct for Trait<'a, T> {} +LL + impl<'a, T> Struct for dyn Trait<'a, T> {} + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0404, E0782. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs new file mode 100644 index 00000000000..947bc2c7965 --- /dev/null +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs @@ -0,0 +1,21 @@ +pub trait Trait<'a, T> {} + +pub struct Struct; +pub enum Enum {} + +pub union Union { + f1: usize, +} + +impl<'a, T> Struct for Trait<'a, T> {} +//~^ ERROR expected trait, found struct `Struct` +//~| WARNING trait objects without an explicit `dyn` are deprecated +//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + +impl<'a, T> Enum for Trait<'a, T> {} +//~^ ERROR expected trait, found enum `Enum` + +impl<'a, T> Union for Trait<'a, T> {} +//~^ ERROR expected trait, found union `Union` + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr new file mode 100644 index 00000000000..86ab8474c42 --- /dev/null +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr @@ -0,0 +1,51 @@ +error[E0404]: expected trait, found struct `Struct` + --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:13 + | +LL | impl<'a, T> Struct for Trait<'a, T> {} + | ^^^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Struct {} + | ~~~~~~~~~~~~ ~~~~~~~~~ + +error[E0404]: expected trait, found enum `Enum` + --> $DIR/suggest-swapping-self-ty-and-trait.rs:15:13 + | +LL | impl<'a, T> Enum for Trait<'a, T> {} + | ^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Enum {} + | ~~~~~~~~~~~~ ~~~~~~~ + +error[E0404]: expected trait, found union `Union` + --> $DIR/suggest-swapping-self-ty-and-trait.rs:18:13 + | +LL | impl<'a, T> Union for Trait<'a, T> {} + | ^^^^^^^^ not a trait + | +help: `impl` items mention the trait being implemented first and the type it is being implemented for second + | +LL | impl<'a, T> Trait<'a, T> for Union {} + | ~~~~~~~~~~~~ ~~~~~~~~ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:27 + | +LL | impl<'a, T> Struct for Trait<'a, T> {} + | ^^^^^^^^^^^^ + | + = note: `#[warn(bare_trait_objects)]` on by default + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: use `dyn` + | +LL - impl<'a, T> Struct for Trait<'a, T> {} +LL + impl<'a, T> Struct for dyn Trait<'a, T> {} + | + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0404`.