diff options
152 files changed, 1693 insertions, 740 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index b8cf72c2c73..325342d653d 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1612,10 +1612,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .any(|impl_def_id| { let impl_header = tcx.impl_trait_header(impl_def_id); impl_header.is_some_and(|header| { - let header = header.instantiate( + let trait_ref = header.trait_ref.instantiate( tcx, infcx.fresh_args_for_item(DUMMY_SP, impl_def_id), ); + let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased); // FIXME: Don't bother dealing with non-lifetime binders here... if value.has_escaping_bound_vars() { @@ -1624,7 +1625,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { infcx .can_eq( ty::ParamEnv::empty(), - header.trait_ref.self_ty(), + trait_ref.self_ty(), value, ) && header.polarity != ty::ImplPolarity::Negative }) @@ -1677,9 +1678,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .filter(|header| { // Consider only accessible traits tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx) - && header.skip_binder().polarity != ty::ImplPolarity::Negative + && header.polarity != ty::ImplPolarity::Negative }) - .map(|header| header.instantiate_identity().trait_ref.self_ty()) + .map(|header| header.trait_ref.instantiate_identity().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()) diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index 7705445ffaa..b9543c7a29b 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -45,10 +45,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { dummy_self, &mut bounds, false, - // FIXME: This should be `true`, but we don't really handle - // associated type bounds or type aliases in objects in a way - // that makes this meaningful, I think. - OnlySelfBounds(false), + // True so we don't populate `bounds` with associated type bounds, even + // though they're disallowed from object types. + OnlySelfBounds(true), ) { potential_assoc_types.extend(cur_potential_assoc_types); } @@ -83,9 +82,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let expanded_traits = traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b))); - let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits - .filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self) - .partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); + let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = + expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); if regular_traits.len() > 1 { let first_trait = ®ular_traits[0]; let additional_trait = ®ular_traits[1]; @@ -158,7 +156,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { for (base_trait_ref, span) in regular_traits_refs_spans { let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx); - for pred in traits::elaborate(tcx, [base_pred]) { + for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() { debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred); let bound_predicate = pred.kind(); @@ -312,45 +310,39 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) }); - let existential_projections = projection_bounds - .iter() - // We filter out traits that don't have `Self` as their self type above, - // we need to do the same for projections. - .filter(|(bound, _)| bound.skip_binder().self_ty() == dummy_self) - .map(|(bound, _)| { - bound.map_bound(|mut b| { - assert_eq!(b.projection_ty.self_ty(), dummy_self); + let existential_projections = projection_bounds.iter().map(|(bound, _)| { + bound.map_bound(|mut b| { + assert_eq!(b.projection_ty.self_ty(), dummy_self); - // Like for trait refs, verify that `dummy_self` did not leak inside default type - // parameters. - let references_self = b.projection_ty.args.iter().skip(1).any(|arg| { - if arg.walk().any(|arg| arg == dummy_self.into()) { - return true; - } - false - }); - if references_self { - let guar = tcx.dcx().span_delayed_bug( - span, - "trait object projection bounds reference `Self`", - ); - let args: Vec<_> = b - .projection_ty - .args - .iter() - .map(|arg| { - if arg.walk().any(|arg| arg == dummy_self.into()) { - return Ty::new_error(tcx, guar).into(); - } - arg - }) - .collect(); - b.projection_ty.args = tcx.mk_args(&args); + // Like for trait refs, verify that `dummy_self` did not leak inside default type + // parameters. + let references_self = b.projection_ty.args.iter().skip(1).any(|arg| { + if arg.walk().any(|arg| arg == dummy_self.into()) { + return true; } + false + }); + if references_self { + let guar = tcx + .dcx() + .span_delayed_bug(span, "trait object projection bounds reference `Self`"); + let args: Vec<_> = b + .projection_ty + .args + .iter() + .map(|arg| { + if arg.walk().any(|arg| arg == dummy_self.into()) { + return Ty::new_error(tcx, guar).into(); + } + arg + }) + .collect(); + b.projection_ty.args = tcx.mk_args(&args); + } - ty::ExistentialProjection::erase_self_ty(tcx, b) - }) - }); + ty::ExistentialProjection::erase_self_ty(tcx, b) + }) + }); let regular_trait_predicates = existential_trait_refs .map(|trait_ref| trait_ref.map_bound(ty::ExistentialPredicate::Trait)); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 845bbdca96a..748571c12b3 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -530,11 +530,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } DefKind::Impl { of_trait } => { if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { - check_impl_items_against_trait( - tcx, - def_id, - impl_trait_header.instantiate_identity(), - ); + check_impl_items_against_trait(tcx, def_id, impl_trait_header); check_on_unimplemented(tcx, def_id); } } @@ -725,10 +721,11 @@ fn check_impl_items_against_trait<'tcx>( impl_id: LocalDefId, impl_trait_header: ty::ImplTraitHeader<'tcx>, ) { + let trait_ref = impl_trait_header.trait_ref.instantiate_identity(); // If the trait reference itself is erroneous (so the compilation is going // to fail), skip checking the items here -- the `impl_item` table in `tcx` // isn't populated for such impls. - if impl_trait_header.references_error() { + if trait_ref.references_error() { return; } @@ -752,7 +749,7 @@ fn check_impl_items_against_trait<'tcx>( } } - let trait_def = tcx.trait_def(impl_trait_header.trait_ref.def_id); + let trait_def = tcx.trait_def(trait_ref.def_id); for &impl_item in impl_item_refs { let ty_impl_item = tcx.associated_item(impl_item); @@ -771,10 +768,10 @@ fn check_impl_items_against_trait<'tcx>( )); } ty::AssocKind::Fn => { - compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref); + compare_impl_method(tcx, ty_impl_item, ty_trait_item, trait_ref); } ty::AssocKind::Type => { - compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref); + compare_impl_ty(tcx, ty_impl_item, ty_trait_item, trait_ref); } } @@ -794,7 +791,7 @@ fn check_impl_items_against_trait<'tcx>( let mut must_implement_one_of: Option<&[Ident]> = trait_def.must_implement_one_of.as_deref(); - for &trait_item_id in tcx.associated_item_def_ids(impl_trait_header.trait_ref.def_id) { + for &trait_item_id in tcx.associated_item_def_ids(trait_ref.def_id) { let leaf_def = ancestors.leaf_def(tcx, trait_item_id); let is_implemented = leaf_def @@ -872,7 +869,7 @@ fn check_impl_items_against_trait<'tcx>( if let Some(missing_items) = must_implement_one_of { let attr_span = tcx - .get_attr(impl_trait_header.trait_ref.def_id, sym::rustc_must_implement_one_of) + .get_attr(trait_ref.def_id, sym::rustc_must_implement_one_of) .map(|attr| attr.span); missing_items_must_implement_one_of_err( diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index bec7b7bd974..ae7ea271c56 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -247,7 +247,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() hir::ItemKind::Impl(impl_) => { let header = tcx.impl_trait_header(def_id); let is_auto = header - .is_some_and(|header| tcx.trait_is_auto(header.skip_binder().trait_ref.def_id)); + .is_some_and(|header| tcx.trait_is_auto(header.trait_ref.skip_binder().def_id)); + + crate::impl_wf_check::check_impl_wf(tcx, def_id)?; let mut res = Ok(()); if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) { let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span); @@ -259,7 +261,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() .emit()); } // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. - match header.map(|h| h.skip_binder().polarity) { + match header.map(|h| h.polarity) { // `None` means this is an inherent impl Some(ty::ImplPolarity::Positive) | None => { res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait)); @@ -296,31 +298,31 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() hir::ItemKind::Const(ty, ..) => { check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid) } - hir::ItemKind::Struct(_, ast_generics) => { + hir::ItemKind::Struct(_, hir_generics) => { let res = check_type_defn(tcx, item, false); - check_variances_for_type_defn(tcx, item, ast_generics); + check_variances_for_type_defn(tcx, item, hir_generics); res } - hir::ItemKind::Union(_, ast_generics) => { + hir::ItemKind::Union(_, hir_generics) => { let res = check_type_defn(tcx, item, true); - check_variances_for_type_defn(tcx, item, ast_generics); + check_variances_for_type_defn(tcx, item, hir_generics); res } - hir::ItemKind::Enum(_, ast_generics) => { + hir::ItemKind::Enum(_, hir_generics) => { let res = check_type_defn(tcx, item, true); - check_variances_for_type_defn(tcx, item, ast_generics); + check_variances_for_type_defn(tcx, item, hir_generics); res } hir::ItemKind::Trait(..) => check_trait(tcx, item), hir::ItemKind::TraitAlias(..) => check_trait(tcx, item), // `ForeignItem`s are handled separately. hir::ItemKind::ForeignMod { .. } => Ok(()), - hir::ItemKind::TyAlias(hir_ty, ast_generics) => { + hir::ItemKind::TyAlias(hir_ty, hir_generics) => { if tcx.type_alias_is_lazy(item.owner_id) { // Bounds of lazy type aliases and of eager ones that contain opaque types are respected. // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`. let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow); - check_variances_for_type_defn(tcx, item, ast_generics); + check_variances_for_type_defn(tcx, item, hir_generics); res } else { Ok(()) @@ -1275,16 +1277,16 @@ fn check_item_type( }) } -#[instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))] +#[instrument(level = "debug", skip(tcx, hir_self_ty, hir_trait_ref))] fn check_impl<'tcx>( tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>, - ast_self_ty: &hir::Ty<'_>, - ast_trait_ref: &Option<hir::TraitRef<'_>>, + hir_self_ty: &hir::Ty<'_>, + hir_trait_ref: &Option<hir::TraitRef<'_>>, ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| { - match ast_trait_ref { - Some(ast_trait_ref) => { + match hir_trait_ref { + Some(hir_trait_ref) => { // `#[rustc_reservation_impl]` impls are not real impls and // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). @@ -1292,8 +1294,9 @@ fn check_impl<'tcx>( // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. tcx.ensure().coherent_trait(trait_ref.def_id)?; + let trait_span = hir_trait_ref.path.span; let trait_ref = wfcx.normalize( - ast_trait_ref.path.span, + trait_span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), trait_ref, ); @@ -1304,14 +1307,23 @@ fn check_impl<'tcx>( wfcx.param_env, wfcx.body_def_id, trait_pred, - ast_trait_ref.path.span, + trait_span, item, ); for obligation in &mut obligations { + if obligation.cause.span != trait_span { + // We already have a better span. + continue; + } if let Some(pred) = obligation.predicate.to_opt_poly_trait_pred() - && pred.self_ty().skip_binder() == trait_ref.self_ty() + && pred.skip_binder().self_ty() == trait_ref.self_ty() + { + obligation.cause.span = hir_self_ty.span; + } + if let Some(pred) = obligation.predicate.to_opt_poly_projection_pred() + && pred.skip_binder().self_ty() == trait_ref.self_ty() { - obligation.cause.span = ast_self_ty.span; + obligation.cause.span = hir_self_ty.span; } } debug!(?obligations); @@ -1325,7 +1337,7 @@ fn check_impl<'tcx>( self_ty, ); wfcx.register_wf_obligation( - ast_self_ty.span, + hir_self_ty.span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), self_ty.into(), ); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 6c3a9b747ef..8d8b13d6cb3 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -25,7 +25,7 @@ use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCause}; use std::collections::BTreeMap; -pub fn check_trait<'tcx>( +pub(super) fn check_trait<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, impl_def_id: LocalDefId, @@ -66,10 +66,9 @@ impl<'tcx> Checker<'tcx> { fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; - let header = checker.impl_header; let impl_did = checker.impl_def_id; // Destructors only work on local ADT types. - match header.trait_ref.self_ty().kind() { + match checker.impl_header.trait_ref.instantiate_identity().self_ty().kind() { ty::Adt(def, _) if def.did().is_local() => return Ok(()), ty::Error(_) => return Ok(()), _ => {} @@ -86,7 +85,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran let impl_did = checker.impl_def_id; debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); - let self_type = impl_header.trait_ref.self_ty(); + let self_type = impl_header.trait_ref.instantiate_identity().self_ty(); debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); let param_env = tcx.param_env(impl_did); @@ -120,7 +119,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E let tcx = checker.tcx; let header = checker.impl_header; let impl_did = checker.impl_def_id; - let self_type = header.trait_ref.self_ty(); + let self_type = header.trait_ref.instantiate_identity().self_ty(); assert!(!self_type.has_escaping_bound_vars()); let param_env = tcx.param_env(impl_did); @@ -157,9 +156,8 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; - let header = checker.impl_header; let impl_did = checker.impl_def_id; - let trait_ref = header.trait_ref; + let trait_ref = checker.impl_header.trait_ref.instantiate_identity(); debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); let span = tcx.def_span(impl_did); diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index d6281fa08f7..fc7a73e12be 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -134,11 +134,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let mut res = tcx.ensure().specialization_graph_of(def_id); for &impl_def_id in impls { - let trait_header = tcx.impl_trait_header(impl_def_id).unwrap().instantiate_identity(); - let trait_def = tcx.trait_def(trait_header.trait_ref.def_id); + let trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); + let trait_ref = trait_header.trait_ref.instantiate_identity(); + let trait_def = tcx.trait_def(trait_ref.def_id); - res = res.and(check_impl(tcx, impl_def_id, trait_header.trait_ref, trait_def)); - res = res.and(check_object_overlap(tcx, impl_def_id, trait_header.trait_ref)); + res = res.and(check_impl(tcx, impl_def_id, trait_ref, trait_def)); + res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref)); res = res.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)); res = res.and(tcx.ensure().orphan_check_impl(impl_def_id)); diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 53a5ada4105..13ce4f07593 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -13,9 +13,10 @@ pub(super) fn check_item( trait_header: ImplTraitHeader<'_>, trait_def: &TraitDef, ) -> Result<(), ErrorGuaranteed> { - let trait_ref = trait_header.trait_ref; let unsafe_attr = tcx.generics_of(def_id).params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); + let trait_ref = trait_header.trait_ref.instantiate_identity(); + match (trait_def.unsafety, unsafe_attr, trait_header.unsafety, trait_header.polarity) { (Unsafety::Normal, None, Unsafety::Unsafe, Positive | Reservation) => { let span = tcx.def_span(def_id); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 2cc37651ef5..e1704ffc8bf 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1519,10 +1519,7 @@ fn suggest_impl_trait<'tcx>( None } -fn impl_trait_header( - tcx: TyCtxt<'_>, - def_id: LocalDefId, -) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> { +fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTraitHeader<'_>> { let icx = ItemCtxt::new(tcx, def_id); let item = tcx.hir().expect_item(def_id); let impl_ = item.expect_impl(); @@ -1558,11 +1555,11 @@ fn impl_trait_header( } else { icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty) }; - ty::EarlyBinder::bind(ty::ImplTraitHeader { - trait_ref, + ty::ImplTraitHeader { + trait_ref: ty::EarlyBinder::bind(trait_ref), unsafety: impl_.unsafety, polarity: polarity_of_impl(tcx, def_id, impl_, item.span) - }) + } }) } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 9cc6c16c126..c86788db988 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -14,6 +14,43 @@ use rustc_span::Span; pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { use rustc_hir::*; + // For an RPITIT, synthesize generics which are equal to the opaque's generics + // and parent fn's generics compressed into one list. + if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) = + tcx.opt_rpitit_info(def_id.to_def_id()) + { + let trait_def_id = tcx.parent(fn_def_id); + let opaque_ty_generics = tcx.generics_of(opaque_def_id); + let opaque_ty_parent_count = opaque_ty_generics.parent_count; + let mut params = opaque_ty_generics.params.clone(); + + let parent_generics = tcx.generics_of(trait_def_id); + let parent_count = parent_generics.parent_count + parent_generics.params.len(); + + let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone(); + + for param in &mut params { + param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32 + - opaque_ty_parent_count as u32; + } + + trait_fn_params.extend(params); + params = trait_fn_params; + + let param_def_id_to_index = + params.iter().map(|param| (param.def_id, param.index)).collect(); + + return ty::Generics { + parent: Some(trait_def_id), + parent_count, + params, + param_def_id_to_index, + has_self: opaque_ty_generics.has_self, + has_late_bound_regions: opaque_ty_generics.has_late_bound_regions, + host_effect_index: parent_generics.host_effect_index, + }; + } + let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 417f0fceaa8..2217e5280a7 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -5,7 +5,7 @@ use rustc_hir::HirId; use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; @@ -350,22 +350,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty // If we are computing `type_of` the synthesized associated type for an RPITIT in the impl // side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the // associated type in the impl. - if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) = - tcx.opt_rpitit_info(def_id.to_def_id()) - { - match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) { - Ok(map) => { - let assoc_item = tcx.associated_item(def_id); - return map[&assoc_item.trait_item_def_id.unwrap()]; - } - Err(_) => { - return ty::EarlyBinder::bind(Ty::new_error_with_message( - tcx, - DUMMY_SP, - "Could not collect return position impl trait in trait tys", - )); + match tcx.opt_rpitit_info(def_id.to_def_id()) { + Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => { + match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) { + Ok(map) => { + let assoc_item = tcx.associated_item(def_id); + return map[&assoc_item.trait_item_def_id.unwrap()]; + } + Err(_) => { + return ty::EarlyBinder::bind(Ty::new_error_with_message( + tcx, + DUMMY_SP, + "Could not collect return position impl trait in trait tys", + )); + } } } + // For an RPITIT in a trait, just return the corresponding opaque. + Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { + return ty::EarlyBinder::bind(Ty::new_opaque( + tcx, + opaque_def_id, + ty::GenericArgs::identity_for_item(tcx, opaque_def_id), + )); + } + None => {} } let hir_id = tcx.local_def_id_to_hir_id(def_id); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 9d7866fe3e0..caa85092415 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -14,8 +14,7 @@ use min_specialization::check_min_specialization; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{LocalDefId, LocalModDefId}; -use rustc_middle::query::Providers; +use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; @@ -51,23 +50,16 @@ mod min_specialization; /// impl<'a> Trait<Foo> for Bar { type X = &'a i32; } /// // ^ 'a is unused and appears in assoc type, error /// ``` -fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) -> Result<(), ErrorGuaranteed> { +pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let min_specialization = tcx.features().min_specialization; - let module = tcx.hir_module_items(module_def_id); let mut res = Ok(()); - for id in module.items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) { - res = res.and(enforce_impl_params_are_constrained(tcx, id.owner_id.def_id)); - if min_specialization { - res = res.and(check_min_specialization(tcx, id.owner_id.def_id)); - } - } + debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. })); + res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id)); + if min_specialization { + res = res.and(check_min_specialization(tcx, impl_def_id)); } - res -} -pub fn provide(providers: &mut Providers) { - *providers = Providers { check_mod_impl_wf, ..*providers }; + res } fn enforce_impl_params_are_constrained( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 7cb103626da..77c4ff382b9 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -153,7 +153,6 @@ pub fn provide(providers: &mut Providers) { check_unused::provide(providers); variance::provide(providers); outlives::provide(providers); - impl_wf_check::provide(providers); hir_wf_check::provide(providers); } @@ -171,9 +170,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { } tcx.sess.time("coherence_checking", || { - // Check impls constrain their parameters - let res = - tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module)); + tcx.hir().par_for_each_module(|module| { + let _ = tcx.ensure().check_mod_type_wf(module); + }); for &trait_def_id in tcx.all_local_trait_impls(()).keys() { let _ = tcx.ensure().coherent_trait(trait_def_id); @@ -181,19 +180,12 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { // these queries are executed for side-effects (error reporting): let _ = tcx.ensure().crate_inherent_impls(()); let _ = tcx.ensure().crate_inherent_impls_overlap_check(()); - res - })?; + }); if tcx.features().rustc_attrs { tcx.sess.time("variance_testing", || variance::test::test_variance(tcx))?; } - tcx.sess.time("wf_checking", || { - tcx.hir().par_for_each_module(|module| { - let _ = tcx.ensure().check_mod_type_wf(module); - }) - }); - if tcx.features().rustc_attrs { collect::test_opaque_hidden_types(tcx)?; } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 893b3f9534d..7012f40e349 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3368,11 +3368,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "inherent impls can't be candidates, only trait impls can be", ) }) - .filter(|header| { - header.skip_binder().polarity == ty::ImplPolarity::Negative - }) + .filter(|header| header.polarity == ty::ImplPolarity::Negative) .any(|header| { - let imp = header.instantiate_identity().trait_ref; + let imp = header.trait_ref.instantiate_identity(); let imp_simp = simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup); imp_simp.is_some_and(|s| s == simp_rcvr_ty) diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs index f30e366c198..cc0f00254ff 100644 --- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs +++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs @@ -77,7 +77,7 @@ impl<'tcx> InferCtxt<'tcx> { // that name placeholders created in this function. Nested goals from type relations can // also contain placeholders created by this function. let value = self.enter_forall_and_leak_universe(forall); - debug!("?value"); + debug!(?value); f(value) } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 085e9026051..61f0ab14e8c 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -686,6 +686,11 @@ pub fn create_global_ctxt<'tcx>( /// Runs the type-checking, region checking and other miscellaneous analysis /// passes on the crate. fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { + if tcx.sess.opts.unstable_opts.hir_stats { + rustc_passes::hir_stats::print_hir_stats(tcx); + } + + #[cfg(debug_assertions)] rustc_passes::hir_id_validator::check_crate(tcx); let sess = tcx.sess; diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index a58a37bf3ac..a0be1c09c9a 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -143,7 +143,11 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di BuiltinLintDiag::RedundantImport(spans, ident) => { for (span, is_imported) in spans { let introduced = if is_imported { "imported" } else { "defined" }; - diag.span_label(span, format!("the item `{ident}` is already {introduced} here")); + let span_msg = if span.is_dummy() { "by prelude" } else { "here" }; + diag.span_label( + span, + format!("the item `{ident}` is already {introduced} {span_msg}"), + ); } } BuiltinLintDiag::DeprecatedMacro(suggestion, span) => { diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 90e68a6b5b9..dcccace12b0 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -1077,7 +1077,7 @@ impl CrateError { crate_rejections, }); } else { - dcx.emit_err(errors::CannotFindCrate { + let error = errors::CannotFindCrate { span, crate_name, add_info, @@ -1091,11 +1091,18 @@ impl CrateError { profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime), locator_triple: locator.triple, is_ui_testing: sess.opts.unstable_opts.ui_testing, - }); + }; + // The diagnostic for missing core is very good, but it is followed by a lot of + // other diagnostics that do not add information. + if missing_core { + dcx.emit_fatal(error); + } else { + dcx.emit_err(error); + } } } CrateError::NotFound(crate_name) => { - dcx.emit_err(errors::CannotFindCrate { + let error = errors::CannotFindCrate { span, crate_name, add_info: String::new(), @@ -1105,7 +1112,14 @@ impl CrateError { profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime), locator_triple: sess.opts.target_triple.clone(), is_ui_testing: sess.opts.unstable_opts.ui_testing, - }); + }; + // The diagnostic for missing core is very good, but it is followed by a lot of + // other diagnostics that do not add information. + if missing_core { + dcx.emit_fatal(error); + } else { + dcx.emit_err(error); + } } } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 3866d6fec2d..6e9cbfdcfee 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1993,9 +1993,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if of_trait && let Some(header) = tcx.impl_trait_header(def_id) { record!(self.tables.impl_trait_header[def_id] <- header); - let trait_ref = header.map_bound(|h| h.trait_ref); - let trait_ref = trait_ref.instantiate_identity(); + let trait_ref = header.trait_ref.instantiate_identity(); let simplified_self_ty = fast_reject::simplify_type( self.tcx, trait_ref.self_ty(), diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 28166687606..8aa31ef564f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -423,7 +423,7 @@ define_tables! { variances_of: Table<DefIndex, LazyArray<ty::Variance>>, fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::PolyFnSig<'static>>>>, codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>, - impl_trait_header: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::ImplTraitHeader<'static>>>>, + impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>, const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<rustc_middle::ty::Const<'static>>>>, object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>, optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>, diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index d0711baa181..33ee3371605 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -177,8 +177,8 @@ impl EraseType for Option<mir::DestructuredConstant<'_>> { type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()]; } -impl EraseType for Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> { - type Result = [u8; size_of::<Option<ty::EarlyBinder<ty::ImplTraitHeader<'static>>>>()]; +impl EraseType for Option<ty::ImplTraitHeader<'_>> { + type Result = [u8; size_of::<Option<ty::ImplTraitHeader<'static>>>()]; } impl EraseType for Option<ty::EarlyBinder<Ty<'_>>> { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b0431ae05d3..0268c530c9e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -826,7 +826,7 @@ rustc_queries! { /// creates and returns the associated items that correspond to each impl trait in return position /// of the implemented trait. query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] { - desc { |tcx| "creating associated items for impl trait in trait returned by `{}`", tcx.def_path_str(fn_def_id) } + desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) } cache_on_disk_if { fn_def_id.is_local() } separate_provide_extern } @@ -834,13 +834,13 @@ rustc_queries! { /// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding /// associated item. query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId { - desc { |tcx| "creates the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) } + desc { |tcx| "creating the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) } cache_on_disk_if { true } } /// Given an `impl_id`, return the trait it implements along with some header information. /// Return `None` if this is an inherent impl. - query impl_trait_header(impl_id: DefId) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'tcx>>> { + query impl_trait_header(impl_id: DefId) -> Option<ty::ImplTraitHeader<'tcx>> { desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } cache_on_disk_if { impl_id.is_local() } separate_provide_extern @@ -955,11 +955,6 @@ rustc_queries! { desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) } } - query check_mod_impl_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) } - ensure_forwards_result_if_red - } - query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) } ensure_forwards_result_if_red diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4eec93532a2..da81b9dd375 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2310,12 +2310,11 @@ impl<'tcx> TyCtxt<'tcx> { self, def_id: impl IntoQueryParam<DefId>, ) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> { - Some(self.impl_trait_header(def_id)?.map_bound(|h| h.trait_ref)) + Some(self.impl_trait_header(def_id)?.trait_ref) } pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity { - self.impl_trait_header(def_id) - .map_or(ty::ImplPolarity::Positive, |h| h.skip_binder().polarity) + self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0a38d379a52..d9f7ece83e0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -250,9 +250,9 @@ pub struct ImplHeader<'tcx> { pub predicates: Vec<Predicate<'tcx>>, } -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, TyEncodable, TyDecodable, HashStable)] +#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub struct ImplTraitHeader<'tcx> { - pub trait_ref: ty::TraitRef<'tcx>, + pub trait_ref: ty::EarlyBinder<ty::TraitRef<'tcx>>, pub polarity: ImplPolarity, pub unsafety: hir::Unsafety, } @@ -1624,12 +1624,15 @@ impl<'tcx> TyCtxt<'tcx> { def_id1: DefId, def_id2: DefId, ) -> Option<ImplOverlapKind> { - let impl1 = self.impl_trait_header(def_id1).unwrap().instantiate_identity(); - let impl2 = self.impl_trait_header(def_id2).unwrap().instantiate_identity(); + let impl1 = self.impl_trait_header(def_id1).unwrap(); + let impl2 = self.impl_trait_header(def_id2).unwrap(); + + let trait_ref1 = impl1.trait_ref.skip_binder(); + let trait_ref2 = impl2.trait_ref.skip_binder(); // If either trait impl references an error, they're allowed to overlap, // as one of them essentially doesn't exist. - if impl1.references_error() || impl2.references_error() { + if trait_ref1.references_error() || trait_ref2.references_error() { return Some(ImplOverlapKind::Permitted { marker: false }); } @@ -1650,7 +1653,7 @@ impl<'tcx> TyCtxt<'tcx> { let is_marker_overlap = { let is_marker_impl = |trait_ref: TraitRef<'_>| -> bool { self.trait_def(trait_ref.def_id).is_marker }; - is_marker_impl(impl1.trait_ref) && is_marker_impl(impl2.trait_ref) + is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2) }; if is_marker_overlap { diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 9a6d4498352..69f3d3101fa 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -58,52 +58,61 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.thir[scrutinee].span, ), ExprKind::If { cond, then, else_opt, if_then_scope } => { - let then_blk; let then_span = this.thir[then].span; let then_source_info = this.source_info(then_span); let condition_scope = this.local_scope(); - let mut else_blk = unpack!( - then_blk = this.in_scope( - (if_then_scope, then_source_info), - LintLevel::Inherited, - |this| { - let source_info = if this.is_let(cond) { - let variable_scope = - this.new_source_scope(then_span, LintLevel::Inherited, None); - this.source_scope = variable_scope; - SourceInfo { span: then_span, scope: variable_scope } - } else { - this.source_info(then_span) - }; - let (then_block, else_block) = - this.in_if_then_scope(condition_scope, then_span, |this| { - let then_blk = unpack!(this.then_else_break( - block, - cond, - Some(condition_scope), // Temp scope - condition_scope, - source_info, - true, // Declare `let` bindings normally - )); - - this.expr_into_dest(destination, then_blk, then) - }); - then_block.and(else_block) - }, - ) + let then_and_else_blocks = this.in_scope( + (if_then_scope, then_source_info), + LintLevel::Inherited, + |this| { + // FIXME: Does this need extra logic to handle let-chains? + let source_info = if this.is_let(cond) { + let variable_scope = + this.new_source_scope(then_span, LintLevel::Inherited, None); + this.source_scope = variable_scope; + SourceInfo { span: then_span, scope: variable_scope } + } else { + this.source_info(then_span) + }; + + // Lower the condition, and have it branch into `then` and `else` blocks. + let (then_block, else_block) = + this.in_if_then_scope(condition_scope, then_span, |this| { + let then_blk = unpack!(this.then_else_break( + block, + cond, + Some(condition_scope), // Temp scope + condition_scope, + source_info, + true, // Declare `let` bindings normally + )); + + // Lower the `then` arm into its block. + this.expr_into_dest(destination, then_blk, then) + }); + + // Pack `(then_block, else_block)` into `BlockAnd<BasicBlock>`. + then_block.and(else_block) + }, ); - else_blk = if let Some(else_opt) = else_opt { - unpack!(this.expr_into_dest(destination, else_blk, else_opt)) + // Unpack `BlockAnd<BasicBlock>` into `(then_blk, else_blk)`. + let (then_blk, mut else_blk); + else_blk = unpack!(then_blk = then_and_else_blocks); + + // If there is an `else` arm, lower it into `else_blk`. + if let Some(else_expr) = else_opt { + unpack!(else_blk = this.expr_into_dest(destination, else_blk, else_expr)); } else { - // Body of the `if` expression without an `else` clause must return `()`, thus - // we implicitly generate an `else {}` if it is not specified. + // There is no `else` arm, so we know both arms have type `()`. + // Generate the implicit `else {}` by assigning unit. let correct_si = this.source_info(expr_span.shrink_to_hi()); this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx); - else_blk - }; + } + // The `then` and `else` arms have been lowered into their respective + // blocks, so make both of them meet up in a new block. let join_block = this.cfg.start_new_block(); this.cfg.goto(then_blk, source_info, join_block); this.cfg.goto(else_blk, source_info, join_block); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index b0cb9fa517f..37cce625c8e 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1361,7 +1361,7 @@ fn create_mono_items_for_default_impls<'tcx>( return; }; - if matches!(impl_.skip_binder().polarity, ty::ImplPolarity::Negative) { + if matches!(impl_.polarity, ty::ImplPolarity::Negative) { return; } @@ -1385,7 +1385,7 @@ fn create_mono_items_for_default_impls<'tcx>( } }; let impl_args = GenericArgs::for_item(tcx, item.owner_id.to_def_id(), only_region_params); - let trait_ref = impl_.instantiate(tcx, impl_args).trait_ref; + let trait_ref = impl_.trait_ref.instantiate(tcx, impl_args); // Unlike 'lazy' monomorphization that begins by collecting items transitively // called by `main` or other global items, when eagerly monomorphizing impl diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 54854cd2da9..ea9c78ca34c 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -787,13 +787,17 @@ impl<'a> Parser<'a> { let suggest_eq = if self.token.kind == token::Dot && let _ = self.bump() && let mut snapshot = self.create_snapshot_for_diagnostic() - && let Ok(_) = snapshot.parse_dot_suffix_expr( - colon_sp, - self.mk_expr_err( + && let Ok(_) = snapshot + .parse_dot_suffix_expr( colon_sp, - self.dcx().delayed_bug("error during `:` -> `=` recovery"), - ), - ) { + self.mk_expr_err( + colon_sp, + self.dcx() + .delayed_bug("error during `:` -> `=` recovery"), + ), + ) + .map_err(Diag::cancel) + { true } else if let Some(op) = self.check_assoc_op() && op.node.can_continue_expr_unambiguously() diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 02f56ecb10b..dd6c1166957 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -1,38 +1,26 @@ use rustc_data_structures::sync::Lock; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_hir::intravisit; -use rustc_hir::{HirId, ItemLocalId}; +use rustc_hir::{intravisit, HirId, ItemLocalId}; use rustc_index::bit_set::GrowableBitSet; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; pub fn check_crate(tcx: TyCtxt<'_>) { - if tcx.sess.opts.unstable_opts.hir_stats { - crate::hir_stats::print_hir_stats(tcx); - } - - #[cfg(debug_assertions)] - { - let errors = Lock::new(Vec::new()); + let errors = Lock::new(Vec::new()); - tcx.hir().par_for_each_module(|module_id| { - let mut v = HirIdValidator { - tcx, - owner: None, - hir_ids_seen: Default::default(), - errors: &errors, - }; + tcx.hir().par_for_each_module(|module_id| { + let mut v = + HirIdValidator { tcx, owner: None, hir_ids_seen: Default::default(), errors: &errors }; - tcx.hir().visit_item_likes_in_module(module_id, &mut v); - }); + tcx.hir().visit_item_likes_in_module(module_id, &mut v); + }); - let errors = errors.into_inner(); + let errors = errors.into_inner(); - if !errors.is_empty() { - let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2); - tcx.dcx().delayed_bug(message); - } + if !errors.is_empty() { + let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2); + tcx.dcx().delayed_bug(message); } } @@ -90,7 +78,7 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> { self.error(|| { format!( "ItemLocalIds not assigned densely in {pretty_owner}. \ - Max ItemLocalId = {max}, missing IDs = {missing_items:#?}; seen IDs = {seen_items:#?}" + Max ItemLocalId = {max}, missing IDs = {missing_items:#?}; seen IDs = {seen_items:#?}" ) }); } diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 7227b185f4d..e03052bcfed 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -28,6 +28,7 @@ mod debugger_visualizer; mod diagnostic_items; pub mod entry; mod errors; +#[cfg(debug_assertions)] pub mod hir_id_validator; pub mod hir_stats; mod lang_items; diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 13fec70e0a7..bf1ea2e2709 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -137,6 +137,81 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { self.check_import_as_underscore(item, *id); } } + + fn report_unused_extern_crate_items( + &mut self, + maybe_unused_extern_crates: FxHashMap<ast::NodeId, Span>, + ) { + let tcx = self.r.tcx(); + for extern_crate in &self.extern_crate_items { + let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_'); + + // If the crate is fully unused, we suggest removing it altogether. + // We do this in any edition. + if warn_if_unused { + if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) { + self.r.lint_buffer.buffer_lint_with_diagnostic( + UNUSED_EXTERN_CRATES, + extern_crate.id, + span, + "unused extern crate", + BuiltinLintDiag::UnusedExternCrate { + removal_span: extern_crate.span_with_attributes, + }, + ); + continue; + } + } + + // If we are not in Rust 2018 edition, then we don't make any further + // suggestions. + if !tcx.sess.at_least_rust_2018() { + continue; + } + + // If the extern crate has any attributes, they may have funky + // semantics we can't faithfully represent using `use` (most + // notably `#[macro_use]`). Ignore it. + if extern_crate.has_attrs { + continue; + } + + // If the extern crate is renamed, then we cannot suggest replacing it with a use as this + // would not insert the new name into the prelude, where other imports in the crate may be + // expecting it. + if extern_crate.renames { + continue; + } + + // If the extern crate isn't in the extern prelude, + // there is no way it can be written as a `use`. + if !self + .r + .extern_prelude + .get(&extern_crate.ident) + .is_some_and(|entry| !entry.introduced_by_item) + { + continue; + } + + let vis_span = extern_crate + .vis_span + .find_ancestor_inside(extern_crate.span) + .unwrap_or(extern_crate.vis_span); + let ident_span = extern_crate + .ident + .span + .find_ancestor_inside(extern_crate.span) + .unwrap_or(extern_crate.ident.span); + self.r.lint_buffer.buffer_lint_with_diagnostic( + UNUSED_EXTERN_CRATES, + extern_crate.id, + extern_crate.span, + "`extern crate` is not idiomatic in the new edition", + BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span }, + ); + } + } } impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { @@ -335,6 +410,8 @@ impl Resolver<'_, '_> { }; visit::walk_crate(&mut visitor, krate); + visitor.report_unused_extern_crate_items(maybe_unused_extern_crates); + for unused in visitor.unused_imports.values() { let mut fixes = Vec::new(); let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) { @@ -416,75 +493,6 @@ impl Resolver<'_, '_> { ); } - for extern_crate in visitor.extern_crate_items { - let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_'); - - // If the crate is fully unused, we suggest removing it altogether. - // We do this in any edition. - if warn_if_unused { - if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) { - visitor.r.lint_buffer.buffer_lint_with_diagnostic( - UNUSED_EXTERN_CRATES, - extern_crate.id, - span, - "unused extern crate", - BuiltinLintDiag::UnusedExternCrate { - removal_span: extern_crate.span_with_attributes, - }, - ); - continue; - } - } - - // If we are not in Rust 2018 edition, then we don't make any further - // suggestions. - if !tcx.sess.at_least_rust_2018() { - continue; - } - - // If the extern crate has any attributes, they may have funky - // semantics we can't faithfully represent using `use` (most - // notably `#[macro_use]`). Ignore it. - if extern_crate.has_attrs { - continue; - } - - // If the extern crate is renamed, then we cannot suggest replacing it with a use as this - // would not insert the new name into the prelude, where other imports in the crate may be - // expecting it. - if extern_crate.renames { - continue; - } - - // If the extern crate isn't in the extern prelude, - // there is no way it can be written as a `use`. - if !visitor - .r - .extern_prelude - .get(&extern_crate.ident) - .is_some_and(|entry| !entry.introduced_by_item) - { - continue; - } - - let vis_span = extern_crate - .vis_span - .find_ancestor_inside(extern_crate.span) - .unwrap_or(extern_crate.vis_span); - let ident_span = extern_crate - .ident - .span - .find_ancestor_inside(extern_crate.span) - .unwrap_or(extern_crate.ident.span); - visitor.r.lint_buffer.buffer_lint_with_diagnostic( - UNUSED_EXTERN_CRATES, - extern_crate.id, - extern_crate.span, - "`extern crate` is not idiomatic in the new edition", - BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span }, - ); - } - let unused_imports = visitor.unused_imports; let mut check_redundant_imports = FxIndexSet::default(); for module in self.arenas.local_modules().iter() { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 9e5b2fe094f..ea08041f2aa 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1336,9 +1336,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let mut is_redundant = true; - let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None }; - self.per_ns(|this, ns| { if is_redundant && let Ok(binding) = source_bindings[ns].get() { if binding.res() == Res::Err { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 83ee1d8bdcb..18abc5d22b7 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2593,10 +2593,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let span = *entry.get(); let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); self.report_error(param.ident.span, err); - if let GenericParamKind::Lifetime = param.kind { - // Record lifetime res, so lowering knows there is something fishy. - self.record_lifetime_param(param.id, LifetimeRes::Error); - } + let rib = match param.kind { + GenericParamKind::Lifetime => { + // Record lifetime res, so lowering knows there is something fishy. + self.record_lifetime_param(param.id, LifetimeRes::Error); + continue; + } + GenericParamKind::Type { .. } => &mut function_type_rib, + GenericParamKind::Const { .. } => &mut function_value_rib, + }; + + // Taint the resolution in case of errors to prevent follow up errors in typeck + self.r.record_partial_res(param.id, PartialRes::new(Res::Err)); + rib.bindings.insert(ident, Res::Err); continue; } Entry::Vacant(entry) => { diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 2b7ac68c21d..b5cee4f34f5 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -377,10 +377,12 @@ const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[ // tidy-alphabetical-start ("d", Unstable(sym::loongarch_target_feature)), ("f", Unstable(sym::loongarch_target_feature)), + ("frecipe", Unstable(sym::loongarch_target_feature)), ("lasx", Unstable(sym::loongarch_target_feature)), ("lbt", Unstable(sym::loongarch_target_feature)), ("lsx", Unstable(sym::loongarch_target_feature)), ("lvz", Unstable(sym::loongarch_target_feature)), + ("relax", Unstable(sym::loongarch_target_feature)), ("ual", Unstable(sym::loongarch_target_feature)), // tidy-alphabetical-end ]; diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 248985715c2..ed839d14dc7 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -166,13 +166,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; if !drcx.args_may_unify( goal.predicate.trait_ref(tcx).args, - impl_trait_header.skip_binder().trait_ref.args, + impl_trait_header.trait_ref.skip_binder().args, ) { return Err(NoSolution); } // We have to ignore negative impls when projecting. - let impl_polarity = impl_trait_header.skip_binder().polarity; + let impl_polarity = impl_trait_header.polarity; match impl_polarity { ty::ImplPolarity::Negative => return Err(NoSolution), ty::ImplPolarity::Reservation => { @@ -183,7 +183,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id); - let impl_trait_ref = impl_trait_header.instantiate(tcx, impl_args).trait_ref; + let impl_trait_ref = impl_trait_header.trait_ref.instantiate(tcx, impl_args); ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 80198ba39f9..281f5cc5685 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -47,14 +47,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; if !drcx.args_may_unify( goal.predicate.trait_ref.args, - impl_trait_header.skip_binder().trait_ref.args, + impl_trait_header.trait_ref.skip_binder().args, ) { return Err(NoSolution); } // An upper bound of the certainty of this goal, used to lower the certainty // of reservation impl to ambiguous during coherence. - let impl_polarity = impl_trait_header.skip_binder().polarity; + let impl_polarity = impl_trait_header.polarity; let maximal_certainty = match impl_polarity { ty::ImplPolarity::Positive | ty::ImplPolarity::Negative => { match impl_polarity == goal.predicate.polarity { @@ -70,7 +70,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id); - let impl_trait_ref = impl_trait_header.instantiate(tcx, impl_args).trait_ref; + let impl_trait_ref = impl_trait_header.trait_ref.instantiate(tcx, impl_args); ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; let where_clause_bounds = tcx @@ -102,7 +102,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { if trait_clause.def_id() == goal.predicate.def_id() && trait_clause.polarity() == goal.predicate.polarity { - // FIXME: Constness ecx.probe_misc_candidate("assumption").enter(|ecx| { let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); ecx.eq( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 7a930937255..ac2b738d3b6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1431,45 +1431,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #[extension(pub(super) trait InferCtxtPrivExt<'tcx>)] impl<'tcx> TypeErrCtxt<'_, 'tcx> { + fn can_match_trait( + &self, + goal: ty::TraitPredicate<'tcx>, + assumption: ty::PolyTraitPredicate<'tcx>, + ) -> bool { + if goal.polarity != assumption.polarity() { + return false; + } + + let trait_goal = goal.trait_ref; + let trait_assumption = self.instantiate_binder_with_fresh_vars( + DUMMY_SP, + infer::BoundRegionConversionTime::HigherRankedType, + assumption.to_poly_trait_ref(), + ); + + self.can_eq(ty::ParamEnv::empty(), trait_goal, trait_assumption) + } + + fn can_match_projection( + &self, + goal: ty::ProjectionPredicate<'tcx>, + assumption: ty::PolyProjectionPredicate<'tcx>, + ) -> bool { + let assumption = self.instantiate_binder_with_fresh_vars( + DUMMY_SP, + infer::BoundRegionConversionTime::HigherRankedType, + assumption, + ); + + let param_env = ty::ParamEnv::empty(); + self.can_eq(param_env, goal.projection_ty, assumption.projection_ty) + && self.can_eq(param_env, goal.term, assumption.term) + } + // returns if `cond` not occurring implies that `error` does not occur - i.e., that // `error` occurring implies that `cond` occurs. + #[instrument(level = "debug", skip(self), ret)] fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool { if cond == error { return true; } - // FIXME: It should be possible to deal with `ForAll` in a cleaner way. - let bound_error = error.kind(); - let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) { - ( - ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)), - ty::PredicateKind::Clause(ty::ClauseKind::Trait(error)), - ) => (cond, bound_error.rebind(error)), - _ => { - // FIXME: make this work in other cases too. - return false; - } - }; - - for pred in elaborate(self.tcx, std::iter::once(cond)) { - let bound_predicate = pred.kind(); - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(implication)) = - bound_predicate.skip_binder() - { - let error = error.to_poly_trait_ref(); - let implication = bound_predicate.rebind(implication.trait_ref); - // FIXME: I'm just not taking associated types at all here. - // Eventually I'll need to implement param-env-aware - // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. - let param_env = ty::ParamEnv::empty(); - if self.can_sub(param_env, error, implication) { - debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); - return true; - } - } + if let Some(error) = error.to_opt_poly_trait_pred() { + self.enter_forall(error, |error| { + elaborate(self.tcx, std::iter::once(cond)) + .filter_map(|implied| implied.to_opt_poly_trait_pred()) + .any(|implied| self.can_match_trait(error, implied)) + }) + } else if let Some(error) = error.to_opt_poly_projection_pred() { + self.enter_forall(error, |error| { + elaborate(self.tcx, std::iter::once(cond)) + .filter_map(|implied| implied.to_opt_poly_projection_pred()) + .any(|implied| self.can_match_projection(error, implied)) + }) + } else { + false } - - false } #[instrument(skip(self), level = "debug")] @@ -1888,13 +1907,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .tcx .all_impls(trait_pred.def_id()) .filter_map(|def_id| { - let imp = self.tcx.impl_trait_header(def_id).unwrap().skip_binder(); + let imp = self.tcx.impl_trait_header(def_id).unwrap(); if imp.polarity == ty::ImplPolarity::Negative || !self.tcx.is_user_visible_dep(def_id.krate) { return None; } - let imp = imp.trait_ref; + let imp = imp.trait_ref.skip_binder(); self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false).map( |similarity| ImplCandidate { trait_ref: imp, similarity, impl_def_id: def_id }, @@ -2078,12 +2097,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .all_impls(def_id) // Ignore automatically derived impls and `!Trait` impls. .filter_map(|def_id| self.tcx.impl_trait_header(def_id)) - .map(ty::EarlyBinder::instantiate_identity) - .filter(|header| { - header.polarity != ty::ImplPolarity::Negative - || self.tcx.is_automatically_derived(def_id) + .filter_map(|header| { + (header.polarity != ty::ImplPolarity::Negative + || self.tcx.is_automatically_derived(def_id)) + .then(|| header.trait_ref.instantiate_identity()) }) - .map(|header| header.trait_ref) .filter(|trait_ref| { let self_ty = trait_ref.self_ty(); // Avoid mentioning type parameters. diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 39f4ceda9f1..66f740b761d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -562,7 +562,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // and so forth that we need to. let impl_trait_header = self.tcx().impl_trait_header(impl_def_id).unwrap(); if !drcx - .args_may_unify(obligation_args, impl_trait_header.skip_binder().trait_ref.args) + .args_may_unify(obligation_args, impl_trait_header.trait_ref.skip_binder().args) { return; } @@ -577,7 +577,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if self.reject_fn_ptr_impls( impl_def_id, obligation, - impl_trait_header.skip_binder().trait_ref.self_ty(), + impl_trait_header.trait_ref.skip_binder().self_ty(), ) { return; } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7dbea0cdb90..a6bd1ba9c3f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -42,7 +42,7 @@ use rustc_middle::ty::_match::MatchAgainstFreshVars; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::GenericArgsRef; -use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; +use rustc_middle::ty::{self, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_span::symbol::sym; use rustc_span::Symbol; @@ -2441,7 +2441,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { fn match_impl( &mut self, impl_def_id: DefId, - impl_trait_header: EarlyBinder<ty::ImplTraitHeader<'tcx>>, + impl_trait_header: ty::ImplTraitHeader<'tcx>, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Normalized<'tcx, GenericArgsRef<'tcx>>, ()> { let placeholder_obligation = @@ -2450,8 +2450,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id); - let impl_trait_header = impl_trait_header.instantiate(self.tcx(), impl_args); - if impl_trait_header.references_error() { + let trait_ref = impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args); + if trait_ref.references_error() { return Err(()); } @@ -2464,7 +2464,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - impl_trait_header.trait_ref, + trait_ref, ) }); diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index f5bc6c3ad2c..27dd8f26489 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -169,7 +169,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, } } - let impl1_trait_header = tcx.impl_trait_header(impl1_def_id).unwrap().instantiate_identity(); + let impl1_trait_header = tcx.impl_trait_header(impl1_def_id).unwrap(); // We determine whether there's a subset relationship by: // @@ -198,7 +198,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, fulfill_implication( &infcx, penv, - impl1_trait_header.trait_ref, + impl1_trait_header.trait_ref.instantiate_identity(), impl1_def_id, impl2_def_id, |_, _| ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 6e01e0b76aa..3f433a9e919 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -127,7 +127,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { } // Get components of trait alias. - let predicates = tcx.implied_predicates_of(trait_ref.def_id()); + let predicates = tcx.super_predicates_of(trait_ref.def_id()); debug!(?predicates); let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 15059bc6613..b09a803e856 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -223,60 +223,87 @@ enum Elaborate { None, } +/// Points the cause span of a super predicate at the relevant associated type. +/// +/// Given a trait impl item: +/// +/// ```ignore (incomplete) +/// impl TargetTrait for TargetType { +/// type Assoc = SomeType; +/// } +/// ``` +/// +/// And a super predicate of `TargetTrait` that has any of the following forms: +/// +/// 1. `<OtherType as OtherTrait>::Assoc == <TargetType as TargetTrait>::Assoc` +/// 2. `<<TargetType as TargetTrait>::Assoc as OtherTrait>::Assoc == OtherType` +/// 3. `<TargetType as TargetTrait>::Assoc: OtherTrait` +/// +/// Replace the span of the cause with the span of the associated item: +/// +/// ```ignore (incomplete) +/// impl TargetTrait for TargetType { +/// type Assoc = SomeType; +/// // ^^^^^^^^ this span +/// } +/// ``` +/// +/// Note that bounds that can be expressed as associated item bounds are **not** +/// super predicates. This means that form 2 and 3 from above are only relevant if +/// the [`GenericArgsRef`] of the projection type are not its identity arguments. fn extend_cause_with_original_assoc_item_obligation<'tcx>( tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, item: Option<&hir::Item<'tcx>>, cause: &mut traits::ObligationCause<'tcx>, pred: ty::Predicate<'tcx>, ) { - debug!( - "extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}", - trait_ref, item, cause, pred - ); + debug!(?item, ?cause, ?pred, "extended_cause_with_original_assoc_item_obligation"); let (items, impl_def_id) = match item { Some(hir::Item { kind: hir::ItemKind::Impl(impl_), owner_id, .. }) => { (impl_.items, *owner_id) } _ => return, }; - let fix_span = - |impl_item_ref: &hir::ImplItemRef| match tcx.hir().impl_item(impl_item_ref.id).kind { - hir::ImplItemKind::Const(ty, _) | hir::ImplItemKind::Type(ty) => ty.span, - _ => impl_item_ref.span, - }; + + let ty_to_impl_span = |ty: Ty<'_>| { + if let ty::Alias(ty::Projection, projection_ty) = ty.kind() + && let Some(&impl_item_id) = + tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id) + && let Some(impl_item) = + items.iter().find(|item| item.id.owner_id.to_def_id() == impl_item_id) + { + Some(tcx.hir().impl_item(impl_item.id).expect_type().span) + } else { + None + } + }; // It is fine to skip the binder as we don't care about regions here. match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) => { - // The obligation comes not from the current `impl` nor the `trait` being implemented, - // but rather from a "second order" obligation, where an associated type has a - // projection coming from another associated type. See - // `tests/ui/associated-types/point-at-type-on-obligation-failure.rs` and - // `traits-assoc-type-in-supertrait-bad.rs`. - if let Some(ty::Alias(ty::Projection, projection_ty)) = - proj.term.ty().map(|ty| ty.kind()) - && let Some(&impl_item_id) = - tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id) - && let Some(impl_item_span) = items - .iter() - .find(|item| item.id.owner_id.to_def_id() == impl_item_id) - .map(fix_span) + // Form 1: The obligation comes not from the current `impl` nor the `trait` being + // implemented, but rather from a "second order" obligation, where an associated + // type has a projection coming from another associated type. + // See `tests/ui/traits/assoc-type-in-superbad.rs` for an example. + if let Some(term_ty) = proj.term.ty() + && let Some(impl_item_span) = ty_to_impl_span(term_ty) { cause.span = impl_item_span; } + + // Form 2: A projection obligation for an associated item failed to be met. + // We overwrite the span from above to ensure that a bound like + // `Self::Assoc1: Trait<OtherAssoc = Self::Assoc2>` gets the same + // span for both obligations that it is lowered to. + if let Some(impl_item_span) = ty_to_impl_span(proj.self_ty()) { + cause.span = impl_item_span; + } } + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { - // An associated item obligation born out of the `trait` failed to be met. An example - // can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`. + // Form 3: A trait obligation for an associated item failed to be met. debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred); - if let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = *pred.self_ty().kind() - && let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&def_id) - && let Some(impl_item_span) = items - .iter() - .find(|item| item.id.owner_id.to_def_id() == impl_item_id) - .map(fix_span) - { + if let Some(impl_item_span) = ty_to_impl_span(pred.self_ty()) { cause.span = impl_item_span; } } @@ -355,9 +382,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { traits::ObligationCauseCode::DerivedObligation, ); } - extend_cause_with_original_assoc_item_obligation( - tcx, trait_ref, item, &mut cause, predicate, - ); + extend_cause_with_original_assoc_item_obligation(tcx, item, &mut cause, predicate); traits::Obligation::with_depth(tcx, cause, depth, param_env, predicate) }; diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index f3fae63ecc7..b2b5c6cd909 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -6,7 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _}; use rustc_middle::traits::CodegenObligationError; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt, @@ -72,6 +72,13 @@ pub fn codegen_select_candidate<'tcx>( let impl_source = infcx.resolve_vars_if_possible(impl_source); let impl_source = infcx.tcx.erase_regions(impl_source); + if impl_source.has_infer() { + // Unused lifetimes on an impl get replaced with inference vars, but never resolved, + // causing the return value of a query to contain inference vars. We do not have a concept + // for this and will in fact ICE in stable hashing of the return value. So bail out instead. + infcx.tcx.dcx().has_errors().unwrap(); + return Err(CodegenObligationError::FulfillmentError); + } Ok(&*tcx.arena.alloc(impl_source)) } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index db37bec4b82..26d3370469a 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -4,7 +4,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, GenericArgs, ImplTraitInTraitData, Ty, TyCtxt}; +use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { @@ -284,48 +284,8 @@ fn associated_type_for_impl_trait_in_trait( // Copy defaultness of the containing function. trait_assoc_ty.defaultness(tcx.defaultness(fn_def_id)); - // Copy type_of of the opaque. - trait_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_opaque( - tcx, - opaque_ty_def_id.to_def_id(), - GenericArgs::identity_for_item(tcx, opaque_ty_def_id), - ))); - trait_assoc_ty.is_type_alias_impl_trait(false); - // Copy generics_of of the opaque type item but the trait is the parent. - trait_assoc_ty.generics_of({ - let opaque_ty_generics = tcx.generics_of(opaque_ty_def_id); - let opaque_ty_parent_count = opaque_ty_generics.parent_count; - let mut params = opaque_ty_generics.params.clone(); - - let parent_generics = tcx.generics_of(trait_def_id); - let parent_count = parent_generics.parent_count + parent_generics.params.len(); - - let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone(); - - for param in &mut params { - param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32 - - opaque_ty_parent_count as u32; - } - - trait_fn_params.extend(params); - params = trait_fn_params; - - let param_def_id_to_index = - params.iter().map(|param| (param.def_id, param.index)).collect(); - - ty::Generics { - parent: Some(trait_def_id.to_def_id()), - parent_count, - params, - param_def_id_to_index, - has_self: opaque_ty_generics.has_self, - has_late_bound_regions: opaque_ty_generics.has_late_bound_regions, - host_effect_index: parent_generics.host_effect_index, - } - }); - // There are no inferred outlives for the synthesized associated type. trait_assoc_ty.inferred_outlives_of(&[]); @@ -382,8 +342,9 @@ fn associated_type_for_impl_trait_in_impl( impl_assoc_ty.defaultness(tcx.defaultness(impl_fn_def_id)); // Copy generics_of the trait's associated item but the impl as the parent. - // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) resolves to the trait instead of the impl - // generics. + // FIXME: This may be detrimental to diagnostics, as we resolve the early-bound vars + // here to paramswhose parent are items in the trait. We could synthesize new params + // here, but it seems overkill. impl_assoc_ty.generics_of({ let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id); let trait_assoc_parent_count = trait_assoc_generics.parent_count; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 48d9a5e27b7..2b6b91672c3 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -255,10 +255,9 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<' let impl_ = tcx .impl_trait_header(def_id) - .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)) - .skip_binder(); + .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)); - let trait_ref = impl_.trait_ref; + let trait_ref = impl_.trait_ref.skip_binder(); debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); let is_marker_like = impl_.polarity == ty::ImplPolarity::Positive diff --git a/config.example.toml b/config.example.toml index d12ed052fe4..c1939933850 100644 --- a/config.example.toml +++ b/config.example.toml @@ -300,6 +300,10 @@ # This is only useful for verifying that rustc generates reproducible builds. #full-bootstrap = false +# Set the bootstrap/download cache path. It is useful when building rust +# repeatedly in a CI invironment. +# bootstrap-cache-path = /shared/cache + # Enable a build of the extended Rust tool set which is not only the compiler # but also tools such as Cargo. This will also produce "combined installers" # which are used to install Rust and Cargo together. diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index dd8d6f6c7e6..4d9694d4beb 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -259,7 +259,7 @@ impl<T, A: Allocator> RawVec<T, A> { } else { // We could use Layout::array here which ensures the absence of isize and usize overflows // and could hypothetically handle differences between stride and size, but this memory - // has already been allocated so we know it can't overflow and currently rust does not + // has already been allocated so we know it can't overflow and currently Rust does not // support such types. So we can do better by skipping some checks and avoid an unwrap. const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) }; unsafe { diff --git a/library/core/src/arch.rs b/library/core/src/arch.rs index 8817ec0777b..31d6bc36fc8 100644 --- a/library/core/src/arch.rs +++ b/library/core/src/arch.rs @@ -6,10 +6,10 @@ pub use crate::core_arch::arch::*; /// Inline assembly. /// -/// Refer to [rust by example] for a usage guide and the [reference] for +/// Refer to [Rust By Example] for a usage guide and the [reference] for /// detailed information about the syntax and available options. /// -/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html +/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html /// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html #[stable(feature = "asm", since = "1.59.0")] #[rustc_builtin_macro] @@ -19,10 +19,10 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) { /// Module-level inline assembly. /// -/// Refer to [rust by example] for a usage guide and the [reference] for +/// Refer to [Rust By Example] for a usage guide and the [reference] for /// detailed information about the syntax and available options. /// -/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html +/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html /// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html #[stable(feature = "global_asm", since = "1.59.0")] #[rustc_builtin_macro] diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 42663ff2b53..8b5b48c59c2 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -360,6 +360,7 @@ where } } +/// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl<T: PartialOrd, const N: usize> PartialOrd for [T; N] { #[inline] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 643968c35e8..0ee7e190e3d 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1481,7 +1481,7 @@ pub(crate) mod builtin { /// script](https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script). /// /// When using the `include` macro to include stretches of documentation, remember that the - /// included file still needs to be a valid rust syntax. It is also possible to + /// included file still needs to be a valid Rust syntax. It is also possible to /// use the [`include_str`] macro as `#![doc = include_str!("...")]` (at the module level) or /// `#[doc = include_str!("...")]` (at the item level) to include documentation from a plain /// text or markdown file. diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 3eea065eef6..3508b0c7f23 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -3,7 +3,7 @@ use crate::num::NonZero; use crate::{cmp, fmt, hash, mem, num}; /// A type storing a `usize` which is a power of two, and thus -/// represents a possible alignment in the rust abstract machine. +/// represents a possible alignment in the Rust abstract machine. /// /// Note that particularly large alignments, while representable in this type, /// are likely not to be supported by actual allocators and linkers. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index aaedbed0d55..643b7971a66 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -23,7 +23,7 @@ use crate::slice; issue = "none", reason = "exposed from core to be reused in std; use the memchr crate" )] -/// Pure rust memchr implementation, taken from rust-memchr +/// Pure Rust memchr implementation, taken from rust-memchr pub mod memchr; #[unstable( diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs index fa02dd52e00..e8170c13ed2 100644 --- a/library/core/src/sync/exclusive.rs +++ b/library/core/src/sync/exclusive.rs @@ -19,7 +19,7 @@ use core::task::{Context, Poll}; /// /// Certain constructs like [`Future`]s can only be used with _exclusive_ access, /// and are often `Send` but not `Sync`, so `Exclusive` can be used as hint to the -/// rust compiler that something is `Sync` in practice. +/// Rust compiler that something is `Sync` in practice. /// /// ## Examples /// Using a non-`Sync` future prevents the wrapping struct from being `Sync` diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index e44da8e637e..8927e9a47fa 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -157,7 +157,7 @@ impl OsString { /// # Safety /// /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of - /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version + /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same Rust version /// built for the same target platform. For example, reconstructing an `OsString` from bytes sent /// over the network or stored in a file will likely violate these safety rules. /// @@ -213,7 +213,7 @@ impl OsString { /// ASCII. /// /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should - /// be treated as opaque and only comparable within the same rust version built for the same + /// be treated as opaque and only comparable within the same Rust version built for the same /// target platform. For example, sending the bytes over the network or storing it in a file /// will likely result in incompatible data. See [`OsString`] for more encoding details /// and [`std::ffi`] for platform-specific, specified conversions. @@ -747,7 +747,7 @@ impl OsStr { /// # Safety /// /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of - /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version + /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same Rust version /// built for the same target platform. For example, reconstructing an `OsStr` from bytes sent /// over the network or stored in a file will likely violate these safety rules. /// @@ -955,7 +955,7 @@ impl OsStr { /// ASCII. /// /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should - /// be treated as opaque and only comparable within the same rust version built for the same + /// be treated as opaque and only comparable within the same Rust version built for the same /// target platform. For example, sending the slice over the network or storing it in a file /// will likely result in incompatible byte slices. See [`OsString`] for more encoding details /// and [`std::ffi`] for platform-specific, specified conversions. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 288cce3aa08..55a5292a4a4 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -84,7 +84,7 @@ //! //! # Contributing changes to the documentation //! -//! Check out the rust contribution guidelines [here]( +//! Check out the Rust contribution guidelines [here]( //! https://rustc-dev-guide.rust-lang.org/contributing.html#writing-documentation). //! The source for this documentation can be found on //! [GitHub](https://github.com/rust-lang/rust). diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs index f289dafd8bc..319b835a768 100644 --- a/library/std/src/sys/pal/hermit/time.rs +++ b/library/std/src/sys/pal/hermit/time.rs @@ -179,7 +179,7 @@ impl Sub<Instant> for Instant { /// /// # Panics /// - /// Previous rust versions panicked when `other` was later than `self`. Currently this + /// Previous Rust versions panicked when `other` was later than `self`. Currently this /// method saturates. Future versions may reintroduce the panic in some circumstances. /// See [Monotonicity]. /// diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index b81efac6761..589a5fdad1d 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -80,6 +80,7 @@ fn test_named_thread_truncation() { #[test] fn test_get_os_named_thread() { use crate::sys::thread::Thread; + // Spawn a new thread to avoid interfering with other tests running on this thread. let handler = thread::spawn(|| { let name = c"test me please"; Thread::set_name(name); diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 91c010ef2b5..6f1a354d28a 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -59,7 +59,7 @@ pub use core::time::TryFromFloatSecsError; /// experience time dilation (slow down or speed up), but it will never go /// backwards. /// As part of this non-guarantee it is also not specified whether system suspends count as -/// elapsed time or not. The behavior varies across platforms and rust versions. +/// elapsed time or not. The behavior varies across platforms and Rust versions. /// /// Instants are opaque types that can only be compared to one another. There is /// no method to get "the number of seconds" from an instant. Instead, it only @@ -142,7 +142,7 @@ pub use core::time::TryFromFloatSecsError; /// where monotonicity is violated, or `Instant`s are subtracted in the wrong order. /// /// This workaround obscures programming errors where earlier and later instants are accidentally -/// swapped. For this reason future rust versions may reintroduce panics. +/// swapped. For this reason future Rust versions may reintroduce panics. /// /// [tier 1]: https://doc.rust-lang.org/rustc/platform-support.html /// [`duration_since`]: Instant::duration_since @@ -290,7 +290,7 @@ impl Instant { /// /// # Panics /// - /// Previous rust versions panicked when `earlier` was later than `self`. Currently this + /// Previous Rust versions panicked when `earlier` was later than `self`. Currently this /// method saturates. Future versions may reintroduce the panic in some circumstances. /// See [Monotonicity]. /// @@ -365,7 +365,7 @@ impl Instant { /// /// # Panics /// - /// Previous rust versions panicked when the current time was earlier than self. Currently this + /// Previous Rust versions panicked when the current time was earlier than self. Currently this /// method returns a Duration of zero in that case. Future versions may reintroduce the panic. /// See [Monotonicity]. /// @@ -450,7 +450,7 @@ impl Sub<Instant> for Instant { /// /// # Panics /// - /// Previous rust versions panicked when `other` was later than `self`. Currently this + /// Previous Rust versions panicked when `other` was later than `self`. Currently this /// method saturates. Future versions may reintroduce the panic in some circumstances. /// See [Monotonicity]. /// diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs index 22c28e4954e..875c66e5fa3 100644 --- a/library/test/src/formatters/terse.rs +++ b/library/test/src/formatters/terse.rs @@ -84,7 +84,7 @@ impl<T: Write> TerseFormatter<T> { if self.test_column % QUIET_MODE_MAX_COLUMN == QUIET_MODE_MAX_COLUMN - 1 { // We insert a new line regularly in order to flush the // screen when dealing with line-buffered output (e.g., piping to - // `stamp` in the rust CI). + // `stamp` in the Rust CI). self.write_progress()?; } diff --git a/library/test/src/types.rs b/library/test/src/types.rs index 1a8ae889c8c..6a7035a8e29 100644 --- a/library/test/src/types.rs +++ b/library/test/src/types.rs @@ -13,7 +13,7 @@ pub use NamePadding::*; pub use TestFn::*; pub use TestName::*; -/// Type of the test according to the [rust book](https://doc.rust-lang.org/cargo/guide/tests.html) +/// Type of the test according to the [Rust book](https://doc.rust-lang.org/cargo/guide/tests.html) /// conventions. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum TestType { diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 0d604c0d3e5..6e49bcc9744 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -557,7 +557,9 @@ class RustBuild(object): shutil.rmtree(bin_root) key = self.stage0_compiler.date - cache_dst = os.path.join(self.build_dir, "cache") + cache_dst = (self.get_toml('bootstrap-cache-path', 'build') or + os.path.join(self.build_dir, "cache")) + rustc_cache = os.path.join(cache_dst, key) if not os.path.exists(rustc_cache): os.makedirs(rustc_cache) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 8b65e8ff9c3..4257c0f7991 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -149,6 +149,7 @@ v("default-linker", "rust.default-linker", "the default linker") # (others are conditionally saved). o("manage-submodules", "build.submodules", "let the build manage the git submodules") o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two (not recommended except for testing reproducible builds)") +o("bootstrap-cache-path", "build.bootstrap-cache-path", "use provided path for the bootstrap cache") o("extended", "build.extended", "build an extended rust tool set") v("tools", None, "List of extended tools will be installed") diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index a4903ce2353..c4235755ba8 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -797,7 +797,10 @@ impl Step for Rustc { cargo.rustdocflag("-Zunstable-options"); cargo.rustdocflag("-Znormalize-docs"); cargo.rustdocflag("--show-type-layout"); - cargo.rustdocflag("--generate-link-to-definition"); + // FIXME: `--generate-link-to-definition` tries to resolve cfged out code + // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 + // cargo.rustdocflag("--generate-link-to-definition"); + compile::rustc_cargo(builder, &mut cargo, target, compiler.stage); cargo.arg("-Zunstable-options"); cargo.arg("-Zskip-rustdoc-fingerprint"); @@ -953,8 +956,10 @@ macro_rules! tool_doc { cargo.rustdocflag("-Arustdoc::private-intra-doc-links"); cargo.rustdocflag("--enable-index-page"); cargo.rustdocflag("--show-type-layout"); - cargo.rustdocflag("--generate-link-to-definition"); cargo.rustdocflag("-Zunstable-options"); + // FIXME: `--generate-link-to-definition` tries to resolve cfged out code + // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 + // cargo.rustdocflag("--generate-link-to-definition"); let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc"); $(for krate in $crates { diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 700c3ee4fda..fc9f9789bd6 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -81,7 +81,7 @@ fn update_rustfmt_version(build: &Builder<'_>) { } /// Returns the Rust files modified between the `merge-base` of HEAD and -/// rust-lang/master and what is now on the disk. +/// rust-lang/master and what is now on the disk. Does not include removed files. /// /// Returns `None` if all files should be formatted. fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, String> { diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 875a4efae02..326f8f57173 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -161,6 +161,7 @@ pub struct Config { pub vendor: bool, pub target_config: HashMap<TargetSelection, Target>, pub full_bootstrap: bool, + pub bootstrap_cache_path: Option<PathBuf>, pub extended: bool, pub tools: Option<HashSet<String>>, pub sanitizers: bool, @@ -827,6 +828,7 @@ define_config! { locked_deps: Option<bool> = "locked-deps", vendor: Option<bool> = "vendor", full_bootstrap: Option<bool> = "full-bootstrap", + bootstrap_cache_path: Option<PathBuf> = "bootstrap-cache-path", extended: Option<bool> = "extended", tools: Option<HashSet<String>> = "tools", verbose: Option<usize> = "verbose", @@ -1389,6 +1391,7 @@ impl Config { locked_deps, vendor, full_bootstrap, + bootstrap_cache_path, extended, tools, verbose, @@ -1477,6 +1480,7 @@ impl Config { config.reuse = reuse.map(PathBuf::from); config.submodules = submodules; config.android_ndk = android_ndk; + config.bootstrap_cache_path = bootstrap_cache_path; set(&mut config.low_priority, low_priority); set(&mut config.compiler_docs, compiler_docs); set(&mut config.library_docs_private_items, library_docs_private_items); diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 185089a646b..27829eab937 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -578,7 +578,9 @@ impl Config { return; } - let cache_dst = self.out.join("cache"); + let cache_dst = + self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache")); + let cache_dir = cache_dst.join(key); if !cache_dir.exists() { t!(fs::create_dir_all(&cache_dir)); @@ -705,7 +707,9 @@ download-rustc = false let llvm_assertions = self.llvm_assertions; let cache_prefix = format!("llvm-{llvm_sha}-{llvm_assertions}"); - let cache_dst = self.out.join("cache"); + let cache_dst = + self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache")); + let rustc_cache = cache_dst.join(cache_prefix); if !rustc_cache.exists() { t!(fs::create_dir_all(&rustc_cache)); diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 9a50ad4437e..d166b84e51f 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -136,4 +136,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`x install` now skips providing tarball sources (under 'build/dist' path) to speed up the installation process.", }, + ChangeInfo { + change_id: 121976, + severity: ChangeSeverity::Info, + summary: "A new `boostrap-cache-path` option has been introduced which can be utilized to modify the cache path for bootstrap.", + }, ]; diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs index b91dc38e924..a3c857b0268 100644 --- a/src/tools/build_helper/src/git.rs +++ b/src/tools/build_helper/src/git.rs @@ -113,6 +113,7 @@ pub fn get_git_merge_base( /// Returns the files that have been modified in the current branch compared to the master branch. /// The `extensions` parameter can be used to filter the files by their extension. +/// Does not include removed files. /// If `extensions` is empty, all files will be returned. pub fn get_git_modified_files( config: &GitConfig<'_>, @@ -125,13 +126,19 @@ pub fn get_git_modified_files( if let Some(git_dir) = git_dir { git.current_dir(git_dir); } - let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))? + let files = output_result(git.args(["diff-index", "--name-status", merge_base.trim()]))? .lines() - .map(|s| s.trim().to_owned()) - .filter(|f| { - Path::new(f).extension().map_or(false, |ext| { + .filter_map(|f| { + let (status, name) = f.trim().split_once(char::is_whitespace).unwrap(); + if status == "D" { + None + } else if Path::new(name).extension().map_or(false, |ext| { extensions.is_empty() || extensions.contains(&ext.to_str().unwrap()) - }) + }) { + Some(name.to_owned()) + } else { + None + } }) .collect(); Ok(Some(files)) diff --git a/src/tools/cargo b/src/tools/cargo -Subproject f772ec0224d3755ce52ac5128a80319fb2eb45d +Subproject a4c63fe5388beaa09e5f91196c86addab0a0358 diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs index 9f467724565..db0768848fd 100644 --- a/src/tools/miri/tests/compiletest.rs +++ b/src/tools/miri/tests/compiletest.rs @@ -81,8 +81,10 @@ fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> // Add a test env var to do environment communication tests. program.envs.push(("MIRI_ENV_VAR_TEST".into(), Some("0".into()))); + // Let the tests know where to store temp files (they might run for a different target, which can make this hard to find). - program.envs.push(("MIRI_TEMP".into(), Some(env::temp_dir().into()))); + let miri_temp = env::var_os("MIRI_TEMP").unwrap_or_else(|| env::temp_dir().into()); + program.envs.push(("MIRI_TEMP".into(), Some(miri_temp))); let mut config = Config { target: Some(target.to_owned()), diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 6ba39c1f563..304a178dc34 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -1,6 +1,10 @@ //@ignore-target-windows: File handling is not implemented yet //@compile-flags: -Zmiri-disable-isolation +// If this test is failing for you locally, you can try +// 1. Deleting the files `/tmp/miri_*` +// 2. Setting `MIRI_TEMP` or `TMPDIR` to a different directory, without the `miri_*` files + #![feature(io_error_more)] #![feature(io_error_uncategorized)] diff --git a/src/tools/opt-dist/src/utils/artifact_size.rs b/src/tools/opt-dist/src/utils/artifact_size.rs index eb1f6bcf21d..757f6d49709 100644 --- a/src/tools/opt-dist/src/utils/artifact_size.rs +++ b/src/tools/opt-dist/src/utils/artifact_size.rs @@ -15,8 +15,21 @@ pub fn print_binary_sizes(env: &Environment) -> anyhow::Result<()> { let root = env.build_artifacts().join("stage2"); + let all_lib_files = get_files_from_dir(&root.join("lib"), None)?; + let mut files = get_files_from_dir(&root.join("bin"), None)?; files.extend(get_files_from_dir(&root.join("lib"), Some(".so"))?); + + // libLLVM.so can be named libLLVM.so.<suffix>, so we try to explicitly add it here if it + // wasn't found by the above call. + if !files.iter().any(|f| f.file_name().unwrap_or_default().starts_with("libLLVM")) { + if let Some(llvm_lib) = + all_lib_files.iter().find(|f| f.file_name().unwrap_or_default().starts_with("libLLVM")) + { + files.push(llvm_lib.clone()); + } + } + files.sort_unstable(); let items: Vec<_> = files diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs index 16e2c7d60b8..9f7d6db5d26 100644 --- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs @@ -12,7 +12,7 @@ struct DefaultAllocator; // `<DefaultAllocator as Allocator>::Buffer` to be ambiguous, // which caused an ICE with `-Znormalize-docs`. impl<T> Allocator for DefaultAllocator { - //~^ ERROR: type annotations needed + //~^ ERROR: the type parameter `T` is not constrained type Buffer = (); } diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr index 01034018e22..55ab144b924 100644 --- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr @@ -1,9 +1,9 @@ -error[E0282]: type annotations needed - --> $DIR/not-wf-ambiguous-normalization.rs:14:23 +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/not-wf-ambiguous-normalization.rs:14:6 | LL | impl<T> Allocator for DefaultAllocator { - | ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + | ^ unconstrained type parameter error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index a4f60ea2684..3ee4542810c 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -39,7 +39,7 @@ //@ revisions: loongarch64 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@[loongarch64] needs-llvm-components: loongarch -//@[loongarch64] min-llvm-version: 17 +//@[loongarch64] min-llvm-version: 18 //@ revisions: wasm //@[wasm] compile-flags: --target wasm32-unknown-unknown //@[wasm] needs-llvm-components: webassembly diff --git a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr index 2a308f83731..03d72f2ae2c 100644 --- a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr +++ b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr @@ -1,11 +1,8 @@ -error[E0191]: the value of the associated types `Item`, `Item`, `IntoIter` and `IntoIter` in `IntoIterator` must be specified +error[E0191]: the value of the associated types `Item` and `IntoIter` in `IntoIterator` must be specified --> $DIR/overlaping-bound-suggestion.rs:7:13 | LL | inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | associated types `Item`, `IntoIter` must be specified - | associated types `Item`, `IntoIter` must be specified + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated types: `IntoIterator<Item: IntoIterator<Item: >, Item = Type, IntoIter = Type>` error[E0223]: ambiguous associated type --> $DIR/overlaping-bound-suggestion.rs:7:13 diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.rs b/tests/ui/associated-types/hr-associated-type-projection-1.rs index 3df3f68ab1e..d7fc5d122c3 100644 --- a/tests/ui/associated-types/hr-associated-type-projection-1.rs +++ b/tests/ui/associated-types/hr-associated-type-projection-1.rs @@ -11,8 +11,8 @@ where } impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T { - //~^ type mismatch resolving `<T as Deref>::Target == T` type Item = T; + //~^ type mismatch resolving `<T as Deref>::Target == T` } pub fn main() { diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.stderr b/tests/ui/associated-types/hr-associated-type-projection-1.stderr index 65221718ee6..b871bb51ae3 100644 --- a/tests/ui/associated-types/hr-associated-type-projection-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-projection-1.stderr @@ -1,10 +1,10 @@ error[E0271]: type mismatch resolving `<T as Deref>::Target == T` - --> $DIR/hr-associated-type-projection-1.rs:13:33 + --> $DIR/hr-associated-type-projection-1.rs:14:17 | LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T { - | - ^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type - | | - | expected this type parameter + | - expected this type parameter +LL | type Item = T; + | ^ expected type parameter `T`, found associated type | = note: expected type parameter `T` found associated type `<T as Deref>::Target` diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index acf6bb2810c..f1c8f83e30c 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -1,23 +1,4 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:23:17 - | -LL | #[derive(Debug, Copy, Clone)] - | ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable` - | -note: required for `<Col as Expression>::SqlType` to implement `IntoNullable` - --> $DIR/issue-38821.rs:9:18 - | -LL | impl<T: NotNull> IntoNullable for T { - | ------- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider further restricting the associated type - | -LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull, - | +++++++++++++++++++++++++++++++++++++++ - -error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied --> $DIR/issue-38821.rs:40:1 | LL | pub enum ColumnInsertValue<Col, Expr> where @@ -142,6 +123,25 @@ LL | impl<T: NotNull> IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here + = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider further restricting the associated type + | +LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull, + | +++++++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied + --> $DIR/issue-38821.rs:23:17 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable` + | +note: required for `<Col as Expression>::SqlType` to implement `IntoNullable` + --> $DIR/issue-38821.rs:9:18 + | +LL | impl<T: NotNull> IntoNullable for T { + | ------- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting the associated type diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 93333e5ef2a..007f9de0331 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra` LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 186 more + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 187 more = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 86df829fe72..49674daac26 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -154,7 +154,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt` = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr index b1bb75bfe51..48843f7cd18 100644 --- a/tests/ui/coherence/coherence-orphan.stderr +++ b/tests/ui/coherence/coherence-orphan.stderr @@ -10,17 +10,6 @@ LL | impl TheTrait<usize> for isize {} | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate - --> $DIR/coherence-orphan.rs:20:1 - | -LL | impl !Send for Vec<isize> {} - | ^^^^^^^^^^^^^^^---------- - | | | - | | `Vec` is not defined in the current crate - | impl doesn't use only types from inside the current crate - | - = note: define and implement a trait or new type instead - error[E0046]: not all trait items implemented, missing: `the_fn` --> $DIR/coherence-orphan.rs:10:1 | @@ -45,6 +34,17 @@ LL | impl TheTrait<isize> for TheType {} | = help: implement the missing item: `fn the_fn(&self) { todo!() }` +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-orphan.rs:20:1 + | +LL | impl !Send for Vec<isize> {} + | ^^^^^^^^^^^^^^^---------- + | | | + | | `Vec` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + error: aborting due to 5 previous errors Some errors have detailed explanations: E0046, E0117. diff --git a/tests/ui/const-generics/issues/issue-68366.full.stderr b/tests/ui/const-generics/issues/issue-68366.full.stderr index ca9eb801dfc..dc20af77310 100644 --- a/tests/ui/const-generics/issues/issue-68366.full.stderr +++ b/tests/ui/const-generics/issues/issue-68366.full.stderr @@ -1,5 +1,14 @@ +error: `Option<usize>` is forbidden as the type of a const generic parameter + --> $DIR/issue-68366.rs:9:25 + | +LL | struct Collatz<const N: Option<usize>>; + | ^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-68366.rs:11:7 + --> $DIR/issue-68366.rs:12:7 | LL | impl <const N: usize> Collatz<{Some(N)}> {} | ^^^^^^^^^^^^^^ unconstrained const parameter @@ -8,7 +17,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {} = note: proving the result of expressions other than the parameter are unique is not supported error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-68366.rs:17:6 + --> $DIR/issue-68366.rs:19:6 | LL | impl<const N: usize> Foo {} | ^^^^^^^^^^^^^^ unconstrained const parameter @@ -16,6 +25,17 @@ LL | impl<const N: usize> Foo {} = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 2 previous errors +error: overly complex generic constant + --> $DIR/issue-68366.rs:12:31 + | +LL | impl <const N: usize> Collatz<{Some(N)}> {} + | ^-------^ + | | + | struct/enum construction is not supported in generic constants + | + = help: consider moving this anonymous constant into a `const` function + = note: this operation may be supported in the future + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index ecf24a356de..78e49f46e1a 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/issue-68366.rs:11:37 + --> $DIR/issue-68366.rs:12:37 | LL | impl <const N: usize> Collatz<{Some(N)}> {} | ^ cannot perform const operation using `N` @@ -7,8 +7,17 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {} = help: const parameters may only be used as standalone arguments, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions +error: `Option<usize>` is forbidden as the type of a const generic parameter + --> $DIR/issue-68366.rs:9:25 + | +LL | struct Collatz<const N: Option<usize>>; + | ^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-68366.rs:11:7 + --> $DIR/issue-68366.rs:12:7 | LL | impl <const N: usize> Collatz<{Some(N)}> {} | ^^^^^^^^^^^^^^ unconstrained const parameter @@ -17,7 +26,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {} = note: proving the result of expressions other than the parameter are unique is not supported error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-68366.rs:17:6 + --> $DIR/issue-68366.rs:19:6 | LL | impl<const N: usize> Foo {} | ^^^^^^^^^^^^^^ unconstrained const parameter @@ -25,6 +34,6 @@ LL | impl<const N: usize> Foo {} = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/issues/issue-68366.rs b/tests/ui/const-generics/issues/issue-68366.rs index d3e57a021a6..d9d5e21857b 100644 --- a/tests/ui/const-generics/issues/issue-68366.rs +++ b/tests/ui/const-generics/issues/issue-68366.rs @@ -7,10 +7,12 @@ #![cfg_attr(full, allow(incomplete_features))] struct Collatz<const N: Option<usize>>; +//~^ ERROR: `Option<usize>` is forbidden impl <const N: usize> Collatz<{Some(N)}> {} //~^ ERROR the const parameter //[min]~^^ generic parameters may not be used in const operations +//[full]~^^^ ERROR overly complex struct Foo; diff --git a/tests/ui/crate-loading/missing-std.stderr b/tests/ui/crate-loading/missing-std.stderr index 70bcae1e0ed..3eb6c2946d3 100644 --- a/tests/ui/crate-loading/missing-std.stderr +++ b/tests/ui/crate-loading/missing-std.stderr @@ -8,8 +8,6 @@ LL | extern crate core; = help: consider downloading the target with `rustup target add x86_64-unknown-uefi` = help: consider building the standard library from source with `cargo build -Zbuild-std` -error: requires `sized` lang_item - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0463`. diff --git a/tests/ui/duplicate/duplicate-type-parameter.rs b/tests/ui/duplicate/duplicate-type-parameter.rs index 2751b3c8dc0..c2064b423f1 100644 --- a/tests/ui/duplicate/duplicate-type-parameter.rs +++ b/tests/ui/duplicate/duplicate-type-parameter.rs @@ -23,7 +23,6 @@ trait Qux<T,T> {} impl<T,T> Qux<T,T> for Option<T> {} //~^ ERROR the name `T` is already used -//~^^ ERROR the type parameter `T` is not constrained fn main() { } diff --git a/tests/ui/duplicate/duplicate-type-parameter.stderr b/tests/ui/duplicate/duplicate-type-parameter.stderr index 628f898d5c8..f23f2460a8a 100644 --- a/tests/ui/duplicate/duplicate-type-parameter.stderr +++ b/tests/ui/duplicate/duplicate-type-parameter.stderr @@ -54,13 +54,6 @@ LL | impl<T,T> Qux<T,T> for Option<T> {} | | | first use of `T` -error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/duplicate-type-parameter.rs:24:8 - | -LL | impl<T,T> Qux<T,T> for Option<T> {} - | ^ unconstrained type parameter - -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0207, E0403. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0403`. diff --git a/tests/ui/error-codes/E0374.stderr b/tests/ui/error-codes/E0374.stderr index 77f351b28ef..71eec4c16fd 100644 --- a/tests/ui/error-codes/E0374.stderr +++ b/tests/ui/error-codes/E0374.stderr @@ -1,3 +1,11 @@ +error[E0392]: type parameter `T` is never used + --> $DIR/E0374.rs:4:12 + | +LL | struct Foo<T: ?Sized> { + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures --> $DIR/E0374.rs:8:1 | @@ -7,14 +15,6 @@ LL | | where T: CoerceUnsized<U> {} | = note: expected a single field to be coerced, none found -error[E0392]: type parameter `T` is never used - --> $DIR/E0374.rs:4:12 - | -LL | struct Foo<T: ?Sized> { - | ^ unused type parameter - | - = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - error: aborting due to 2 previous errors Some errors have detailed explanations: E0374, E0392. diff --git a/tests/ui/error-codes/E0375.stderr b/tests/ui/error-codes/E0375.stderr index d5340022d68..af720bd40e7 100644 --- a/tests/ui/error-codes/E0375.stderr +++ b/tests/ui/error-codes/E0375.stderr @@ -1,12 +1,3 @@ -error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions - --> $DIR/E0375.rs:10:12 - | -LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions - | - = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced - = note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`) - error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/E0375.rs:6:8 | @@ -32,6 +23,15 @@ help: the `Box` type always has a statically known size and allocates its conten LL | b: Box<T>, | ++++ + +error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions + --> $DIR/E0375.rs:10:12 + | +LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions + | + = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced + = note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`) + error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0375. diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.stderr b/tests/ui/generic-associated-types/bugs/issue-87735.stderr index b80e3e798bd..d8005065238 100644 --- a/tests/ui/generic-associated-types/bugs/issue-87735.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-87735.stderr @@ -4,6 +4,91 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self LL | impl<'b, T, U> AsRef2 for Foo<T> | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0309]: the parameter type `U` may not live long enough + --> $DIR/issue-87735.rs:34:21 + | +LL | type Output<'a> = FooRef<'a, U> where Self: 'a; + | -- ^^^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds... + | | + | the parameter type `U` must be valid for the lifetime `'a` as defined here... + | +note: ...that is required by this bound + --> $DIR/issue-87735.rs:23:22 + | +LL | struct FooRef<'a, U>(&'a [U]); + | ^^^^^^^ +help: consider adding an explicit lifetime bound + | +LL | type Output<'a> = FooRef<'a, U> where Self: 'a, U: 'a; + | +++++++ + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/issue-87735.rs:31:15 + | +LL | impl<'b, T, U> AsRef2 for Foo<T> + | -- the parameter type `T` must be valid for the lifetime `'b` as defined here... +... +LL | T: AsRef2<Output<'b> = &'b [U]>, + | ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/issue-87735.rs:7:31 + | +LL | type Output<'a> where Self: 'a; + | ^^ +help: consider adding an explicit lifetime bound + | +LL | T: AsRef2<Output<'b> = &'b [U]> + 'b, + | ++++ + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/issue-87735.rs:36:31 + | +LL | impl<'b, T, U> AsRef2 for Foo<T> + | -- the parameter type `T` must be valid for the lifetime `'b` as defined here... +... +LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> { + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/issue-87735.rs:7:31 + | +LL | type Output<'a> where Self: 'a; + | ^^ +help: consider adding an explicit lifetime bound + | +LL | T: AsRef2<Output<'b> = &'b [U]> + 'b, + | ++++ + +error: lifetime may not live long enough + --> $DIR/issue-87735.rs:37:5 + | +LL | impl<'b, T, U> AsRef2 for Foo<T> + | -- lifetime `'b` defined here +... +LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> { + | -- lifetime `'a` defined here +LL | FooRef(self.0.as_ref2()) + | ^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + +error: lifetime may not live long enough + --> $DIR/issue-87735.rs:37:12 + | +LL | impl<'b, T, U> AsRef2 for Foo<T> + | -- lifetime `'b` defined here +... +LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> { + | -- lifetime `'a` defined here +LL | FooRef(self.0.as_ref2()) + | ^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + +help: `'b` and `'a` must be the same: replace one with the other + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0309. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/generic-associated-types/bugs/issue-88526.stderr b/tests/ui/generic-associated-types/bugs/issue-88526.stderr index ba87ac9185d..5da3e3ff64a 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88526.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88526.stderr @@ -4,6 +4,20 @@ error[E0207]: the type parameter `I` is not constrained by the impl trait, self LL | impl<'q, Q, I, F> A for TestB<Q, F> | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0309]: the parameter type `F` may not live long enough + --> $DIR/issue-88526.rs:16:18 + | +LL | type I<'a> = &'a F; + | -- ^^^^^ ...so that the reference type `&'a F` does not outlive the data it points at + | | + | the parameter type `F` must be valid for the lifetime `'a` as defined here... + | +help: consider adding an explicit lifetime bound + | +LL | type I<'a> = &'a F where F: 'a; + | +++++++++++ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0309. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs b/tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs new file mode 100644 index 00000000000..882497d1015 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// Check that we don't hit a query cycle when: +// 1. Computing generics_of, which requires... +// 2. Calling resolve_bound_vars, which requires... +// 3. Calling associated_items, which requires... +// 4. Calling associated_type_for_impl_trait_in_trait, which requires... +// 5. Computing generics_of, which cycles. + +pub trait Foo<'a> { + type Assoc; + + fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc> + where + T: Foo<'a, Assoc = ()>; +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-87340.rs b/tests/ui/impl-trait/issues/issue-87340.rs index 705a4addcb7..b1baaaa6ba5 100644 --- a/tests/ui/impl-trait/issues/issue-87340.rs +++ b/tests/ui/impl-trait/issues/issue-87340.rs @@ -9,6 +9,8 @@ impl<T> X for () { //~^ ERROR `T` is not constrained by the impl trait, self type, or predicates type I = impl Sized; fn f() -> Self::I {} + //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-87340.stderr b/tests/ui/impl-trait/issues/issue-87340.stderr index 8513cb2881e..1be4087be42 100644 --- a/tests/ui/impl-trait/issues/issue-87340.stderr +++ b/tests/ui/impl-trait/issues/issue-87340.stderr @@ -4,6 +4,19 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl<T> X for () { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/issue-87340.rs:11:23 + | +LL | fn f() -> Self::I {} + | ^^ cannot infer type for type parameter `T` + +error[E0282]: type annotations needed + --> $DIR/issue-87340.rs:11:15 + | +LL | fn f() -> Self::I {} + | ^^^^^^^ cannot infer type for type parameter `T` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index c4bdd484fdb..e82f33ad6bc 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -361,14 +361,6 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} = 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 #36887 <https://github.com/rust-lang/rust/issues/36887> -error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:239:1 - | -LL | impl <T = impl Debug> T {} - | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type - | - = note: either implement a trait on it or create a newtype to wrap it instead - error[E0283]: type annotations needed --> $DIR/where-allowed.rs:46:57 | @@ -389,6 +381,14 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani - impl<Args, F, A> Fn<Args> for Box<F, A> where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized; +error[E0118]: no nominal type found for inherent implementation + --> $DIR/where-allowed.rs:239:1 + | +LL | impl <T = impl Debug> T {} + | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | + = note: either implement a trait on it or create a newtype to wrap it instead + error[E0599]: no function or associated item named `into_vec` found for slice `[_]` in the current scope --> $DIR/where-allowed.rs:81:5 | diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/impl-unused-tps.stderr index 93215326c2f..af427cb5f3e 100644 --- a/tests/ui/impl-unused-tps.stderr +++ b/tests/ui/impl-unused-tps.stderr @@ -1,3 +1,25 @@ +error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]` + --> $DIR/impl-unused-tps.rs:27:1 + | +LL | impl<T> Foo<T> for [isize;0] { + | ---------------------------- first implementation here +... +LL | impl<T,U> Foo<T> for U { + | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` + +error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`) +note: required for `([isize; 0], _)` to implement `Bar` + --> $DIR/impl-unused-tps.rs:31:11 + | +LL | impl<T,U> Bar for T { + | - ^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 126 redundant requirements hidden + = note: required for `([isize; 0], _)` to implement `Bar` + error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/impl-unused-tps.rs:15:8 | @@ -28,28 +50,6 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self LL | impl<T,U,V> Foo<T> for T | ^ unconstrained type parameter -error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]` - --> $DIR/impl-unused-tps.rs:27:1 - | -LL | impl<T> Foo<T> for [isize;0] { - | ---------------------------- first implementation here -... -LL | impl<T,U> Foo<T> for U { - | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` - -error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`) -note: required for `([isize; 0], _)` to implement `Bar` - --> $DIR/impl-unused-tps.rs:31:11 - | -LL | impl<T,U> Bar for T { - | - ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: 126 redundant requirements hidden - = note: required for `([isize; 0], _)` to implement `Bar` - error: aborting due to 7 previous errors Some errors have detailed explanations: E0119, E0207, E0275. diff --git a/tests/ui/imports/auxiliary/aux-issue-121915.rs b/tests/ui/imports/auxiliary/aux-issue-121915.rs new file mode 100644 index 00000000000..7f9f5bda79f --- /dev/null +++ b/tests/ui/imports/auxiliary/aux-issue-121915.rs @@ -0,0 +1 @@ +pub fn item() {} diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.rs b/tests/ui/imports/redundant-import-issue-121915-2015.rs new file mode 100644 index 00000000000..d41d190bb58 --- /dev/null +++ b/tests/ui/imports/redundant-import-issue-121915-2015.rs @@ -0,0 +1,11 @@ +//@ compile-flags: --extern aux_issue_121915 --edition 2015 +//@ aux-build: aux-issue-121915.rs + +extern crate aux_issue_121915; + +#[deny(unused_imports)] +fn main() { + use aux_issue_121915; + //~^ ERROR the item `aux_issue_121915` is imported redundantly + aux_issue_121915::item(); +} diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.stderr b/tests/ui/imports/redundant-import-issue-121915-2015.stderr new file mode 100644 index 00000000000..174ed4fb96b --- /dev/null +++ b/tests/ui/imports/redundant-import-issue-121915-2015.stderr @@ -0,0 +1,17 @@ +error: the item `aux_issue_121915` is imported redundantly + --> $DIR/redundant-import-issue-121915-2015.rs:8:9 + | +LL | extern crate aux_issue_121915; + | ------------------------------ the item `aux_issue_121915` is already imported here +... +LL | use aux_issue_121915; + | ^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/redundant-import-issue-121915-2015.rs:6:8 + | +LL | #[deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/redundant-import-issue-121915.rs b/tests/ui/imports/redundant-import-issue-121915.rs new file mode 100644 index 00000000000..237acc4af25 --- /dev/null +++ b/tests/ui/imports/redundant-import-issue-121915.rs @@ -0,0 +1,9 @@ +//@ compile-flags: --extern aux_issue_121915 --edition 2018 +//@ aux-build: aux-issue-121915.rs + +#[deny(unused_imports)] +fn main() { + use aux_issue_121915; + //~^ ERROR the item `aux_issue_121915` is imported redundantly + aux_issue_121915::item(); +} diff --git a/tests/ui/imports/redundant-import-issue-121915.stderr b/tests/ui/imports/redundant-import-issue-121915.stderr new file mode 100644 index 00000000000..0047d7c3420 --- /dev/null +++ b/tests/ui/imports/redundant-import-issue-121915.stderr @@ -0,0 +1,14 @@ +error: the item `aux_issue_121915` is imported redundantly + --> $DIR/redundant-import-issue-121915.rs:6:9 + | +LL | use aux_issue_121915; + | ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by prelude + | +note: the lint level is defined here + --> $DIR/redundant-import-issue-121915.rs:4:8 + | +LL | #[deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/suggest-remove-issue-121315.rs b/tests/ui/imports/suggest-remove-issue-121315.rs new file mode 100644 index 00000000000..63533480ec1 --- /dev/null +++ b/tests/ui/imports/suggest-remove-issue-121315.rs @@ -0,0 +1,40 @@ +//@ compile-flags: --edition 2021 +#![deny(unused_imports)] +#![allow(dead_code)] + +fn test0() { + // Test remove FlatUnused + use std::convert::TryFrom; + //~^ ERROR the item `TryFrom` is imported redundantly + let _ = u32::try_from(5i32); +} + +fn test1() { + // FIXME(yukang) Test remove NestedFullUnused + use std::convert::{TryFrom, TryInto}; + //~^ ERROR the item `TryFrom` is imported redundantly + //~| ERROR the item `TryInto` is imported redundantly + + let _ = u32::try_from(5i32); + let _a: i32 = u32::try_into(5u32).unwrap(); +} + +fn test2() { + // FIXME(yukang): Test remove both redundant and unused + use std::convert::{AsMut, Into}; + //~^ ERROR unused import: `AsMut` + //~| ERROR the item `Into` is imported redundantly + + let _a: u32 = (5u8).into(); +} + +fn test3() { + // Test remove NestedPartialUnused + use std::convert::{From, Infallible}; + //~^ ERROR unused import: `From` + + trait MyTrait {} + impl MyTrait for fn() -> Infallible {} +} + +fn main() {} diff --git a/tests/ui/imports/suggest-remove-issue-121315.stderr b/tests/ui/imports/suggest-remove-issue-121315.stderr new file mode 100644 index 00000000000..dbd742f6c78 --- /dev/null +++ b/tests/ui/imports/suggest-remove-issue-121315.stderr @@ -0,0 +1,56 @@ +error: the item `TryFrom` is imported redundantly + --> $DIR/suggest-remove-issue-121315.rs:7:9 + | +LL | use std::convert::TryFrom; + | ^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `TryFrom` is already defined here + | +note: the lint level is defined here + --> $DIR/suggest-remove-issue-121315.rs:2:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: the item `TryFrom` is imported redundantly + --> $DIR/suggest-remove-issue-121315.rs:14:24 + | +LL | use std::convert::{TryFrom, TryInto}; + | ^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `TryFrom` is already defined here + +error: the item `TryInto` is imported redundantly + --> $DIR/suggest-remove-issue-121315.rs:14:33 + | +LL | use std::convert::{TryFrom, TryInto}; + | ^^^^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `TryInto` is already defined here + +error: unused import: `AsMut` + --> $DIR/suggest-remove-issue-121315.rs:24:24 + | +LL | use std::convert::{AsMut, Into}; + | ^^^^^ + +error: the item `Into` is imported redundantly + --> $DIR/suggest-remove-issue-121315.rs:24:31 + | +LL | use std::convert::{AsMut, Into}; + | ^^^^ + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the item `Into` is already defined here + +error: unused import: `From` + --> $DIR/suggest-remove-issue-121315.rs:33:24 + | +LL | use std::convert::{From, Infallible}; + | ^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/issues/issue-29861.rs b/tests/ui/issues/issue-29861.rs index 58f8eb5362c..875c168185f 100644 --- a/tests/ui/issues/issue-29861.rs +++ b/tests/ui/issues/issue-29861.rs @@ -14,6 +14,7 @@ impl<'a, T: 'a> MakeRef2 for T { } fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") } +//~^ ERROR temporary value dropped while borrowed fn main() { println!("{}", foo()); diff --git a/tests/ui/issues/issue-29861.stderr b/tests/ui/issues/issue-29861.stderr index e7860c19eaa..a25cbf0515d 100644 --- a/tests/ui/issues/issue-29861.stderr +++ b/tests/ui/issues/issue-29861.stderr @@ -4,6 +4,18 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, LL | impl<'a, T: 'a> MakeRef2 for T { | ^^ unconstrained lifetime parameter -error: aborting due to 1 previous error +error[E0716]: temporary value dropped while borrowed + --> $DIR/issue-29861.rs:16:43 + | +LL | fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") } + | ^^^^^^^^^^^^^^^^^^^ -- borrow later used here + | | | + | | temporary value is freed at the end of this statement + | creates a temporary value which is freed while still in use + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0716. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/issues/issue-33941.rs b/tests/ui/issues/issue-33941.rs index 0ad7cbe8efc..7b5be30834b 100644 --- a/tests/ui/issues/issue-33941.rs +++ b/tests/ui/issues/issue-33941.rs @@ -5,5 +5,4 @@ use std::collections::HashMap; fn main() { for _ in HashMap::new().iter().cloned() {} //~ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` //~^ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - //~| ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` } diff --git a/tests/ui/issues/issue-33941.stderr b/tests/ui/issues/issue-33941.stderr index e7f4a4fa004..f1b6b6ba17e 100644 --- a/tests/ui/issues/issue-33941.stderr +++ b/tests/ui/issues/issue-33941.stderr @@ -27,16 +27,6 @@ LL | for _ in HashMap::new().iter().cloned() {} = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator` = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator` -error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` - --> $DIR/issue-33941.rs:6:14 - | -LL | for _ in HashMap::new().iter().cloned() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(&_, &_)`, found `&_` - | - = note: expected tuple `(&_, &_)` - found reference `&_` - = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/issues/issue-37131.stderr b/tests/ui/issues/issue-37131.stderr index 9ecae3e7a2b..588696f3541 100644 --- a/tests/ui/issues/issue-37131.stderr +++ b/tests/ui/issues/issue-37131.stderr @@ -4,8 +4,6 @@ error[E0463]: can't find crate for `std` = help: consider downloading the target with `rustup target add thumbv6m-none-eabi` = help: consider building the standard library from source with `cargo build -Zbuild-std` -error: requires `sized` lang_item - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0463`. diff --git a/tests/ui/issues/issue-49851/compiler-builtins-error.rs b/tests/ui/issues/issue-49851/compiler-builtins-error.rs index 3b62cc73f93..db45d040f79 100644 --- a/tests/ui/issues/issue-49851/compiler-builtins-error.rs +++ b/tests/ui/issues/issue-49851/compiler-builtins-error.rs @@ -1,5 +1,4 @@ //~ ERROR can't find crate for `core` -//~^ ERROR can't find crate for `compiler_builtins` //@ compile-flags: --target thumbv7em-none-eabihf //@ needs-llvm-components: arm @@ -8,6 +7,5 @@ #![no_std] extern crate cortex_m; -//~^ ERROR can't find crate for `cortex_m` fn main() {} diff --git a/tests/ui/issues/issue-49851/compiler-builtins-error.stderr b/tests/ui/issues/issue-49851/compiler-builtins-error.stderr index fcfa2bf119c..1cd65a1b68c 100644 --- a/tests/ui/issues/issue-49851/compiler-builtins-error.stderr +++ b/tests/ui/issues/issue-49851/compiler-builtins-error.stderr @@ -4,16 +4,6 @@ error[E0463]: can't find crate for `core` = help: consider downloading the target with `rustup target add thumbv7em-none-eabihf` = help: consider building the standard library from source with `cargo build -Zbuild-std` -error[E0463]: can't find crate for `compiler_builtins` - -error[E0463]: can't find crate for `cortex_m` - --> $DIR/compiler-builtins-error.rs:10:1 - | -LL | extern crate cortex_m; - | ^^^^^^^^^^^^^^^^^^^^^^ can't find crate - -error: requires `sized` lang_item - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0463`. diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs index eceefa719ec..7bc91ef426b 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs @@ -3,6 +3,6 @@ impl<T> Loop<T> {} //~ ERROR the type parameter `T` is not constrained -type Loop<T> = Loop<T>; +type Loop<T> = Loop<T>; //~ ERROR overflow fn main() {} diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr index b65c84226ce..bcffa02ddd4 100644 --- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr +++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr @@ -4,6 +4,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl<T> Loop<T> {} | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0275]: overflow normalizing the type alias `Loop<T>` + --> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:16 + | +LL | type Loop<T> = Loop<T>; + | ^^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0275. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr b/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr index 92a54cff7f5..ab86df9c8a5 100644 --- a/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr +++ b/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr @@ -1,15 +1,3 @@ -error[E0715]: impls for marker traits cannot contain items - --> $DIR/override-item-on-marker-trait.rs:12:1 - | -LL | impl Marker for OverrideConst { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0715]: impls for marker traits cannot contain items - --> $DIR/override-item-on-marker-trait.rs:18:1 - | -LL | impl Marker for OverrideFn { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0714]: marker traits cannot have associated items --> $DIR/override-item-on-marker-trait.rs:5:5 | @@ -22,6 +10,18 @@ error[E0714]: marker traits cannot have associated items LL | fn do_something() {} | ^^^^^^^^^^^^^^^^^ +error[E0715]: impls for marker traits cannot contain items + --> $DIR/override-item-on-marker-trait.rs:12:1 + | +LL | impl Marker for OverrideConst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0715]: impls for marker traits cannot contain items + --> $DIR/override-item-on-marker-trait.rs:18:1 + | +LL | impl Marker for OverrideFn { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 4 previous errors Some errors have detailed explanations: E0714, E0715. diff --git a/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr index 1c71cdacd89..29b0b25a564 100644 --- a/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr +++ b/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr @@ -82,15 +82,6 @@ LL | type W where Self: Eq; = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0592]: duplicate definitions with name `W` - --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5 - | -LL | type W: Ord where Self: Eq; - | ------ other definition for `W` -... -LL | type W where Self: Eq; - | ^^^^^^ duplicate definitions for `W` - error[E0277]: the trait bound `X: Eq` is not satisfied --> $DIR/impl-item-type-no-body-semantic-fail.rs:13:23 | @@ -119,6 +110,15 @@ LL + #[derive(Eq)] LL | struct X; | +error[E0592]: duplicate definitions with name `W` + --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5 + | +LL | type W: Ord where Self: Eq; + | ------ other definition for `W` +... +LL | type W where Self: Eq; + | ^^^^^^ duplicate definitions for `W` + error: aborting due to 13 previous errors Some errors have detailed explanations: E0277, E0592, E0658. diff --git a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs index ed4de58cd23..521eb6a818b 100644 --- a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs +++ b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs @@ -1,3 +1,10 @@ +#![allow(unused)] + +fn test_122112() { + // Make sure we don't ICE if parsing in recovery fails + let _: std::env::temp_dir().join(&self, push: Box<usize>); //~ ERROR expected one of +} + fn main() { let _: std::env::temp_dir().join("foo"); //~ ERROR expected one of } diff --git a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr index d03f3ae0283..15c27bb9451 100644 --- a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr +++ b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr @@ -1,5 +1,13 @@ error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.` - --> $DIR/recover-colon-instead-of-eq-in-local.rs:2:32 + --> $DIR/recover-colon-instead-of-eq-in-local.rs:5:32 + | +LL | let _: std::env::temp_dir().join(&self, push: Box<usize>); + | - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=` + | | + | while parsing the type for `_` + +error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.` + --> $DIR/recover-colon-instead-of-eq-in-local.rs:9:32 | LL | let _: std::env::temp_dir().join("foo"); | - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=` @@ -7,5 +15,5 @@ LL | let _: std::env::temp_dir().join("foo"); | while parsing the type for `_` | help: use `=` if you meant to assign -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index 8f374bc4d8f..9ca7b574b13 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -37,7 +37,19 @@ error[E0207]: the const parameter `host` is not constrained by the impl trait, s = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 5 previous errors +error[E0308]: mismatched types + --> $DIR/derive-const-use.rs:16:14 + | +LL | #[derive_const(Default, PartialEq)] + | --------- in this derive macro expansion +LL | pub struct S((), A); + | ^^ expected `host`, found `true` + | + = note: expected constant `host` + found constant `true` + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0207, E0635. +Some errors have detailed explanations: E0207, E0308, E0635. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs index 97e89f96fe1..7bead45b35a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs @@ -8,6 +8,8 @@ impl const dyn T { //~^ ERROR inherent impls cannot be `const` //~| ERROR the const parameter `host` is not constrained by the impl trait, self type, or pub const fn new() -> std::sync::Mutex<dyn T> {} + //~^ ERROR mismatched types + //~| ERROR cannot be known at compilation time } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr index 11577d9ec1d..3ff1efb5988 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr @@ -17,6 +17,29 @@ LL | impl const dyn T { = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/span-bug-issue-121418.rs:10:27 + | +LL | pub const fn new() -> std::sync::Mutex<dyn T> {} + | --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex<dyn T>`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected struct `Mutex<(dyn T + 'static)>` + found unit type `()` + +error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time + --> $DIR/span-bug-issue-121418.rs:10:27 + | +LL | pub const fn new() -> std::sync::Mutex<dyn T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `Mutex<(dyn T + 'static)>`, the trait `Sized` is not implemented for `(dyn T + 'static)`, which is required by `Mutex<(dyn T + 'static)>: Sized` +note: required because it appears within the type `Mutex<(dyn T + 'static)>` + --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL + = note: the return type of a function must have a statically known size + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0277, E0308. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/trait-bounds/super-assoc-mismatch.rs b/tests/ui/trait-bounds/super-assoc-mismatch.rs new file mode 100644 index 00000000000..97dfec80e31 --- /dev/null +++ b/tests/ui/trait-bounds/super-assoc-mismatch.rs @@ -0,0 +1,60 @@ +trait Super { + type Assoc; +} +impl Super for () { + type Assoc = u8; +} +trait Sub: Super<Assoc = u16> {} + +trait BoundOnSelf: Sub {} +impl BoundOnSelf for () {} +//~^ ERROR the trait bound `(): Sub` is not satisfied + +trait BoundOnParam<T: Sub> {} +impl BoundOnParam<()> for () {} +//~^ ERROR the trait bound `(): Sub` is not satisfied + +trait BoundOnAssoc { + type Assoc: Sub; +} +impl BoundOnAssoc for () { + type Assoc = (); + //~^ ERROR the trait bound `(): Sub` is not satisfied +} + +trait BoundOnGat where Self::Assoc<u8>: Sub { + type Assoc<T>; +} +impl BoundOnGat for u8 { + type Assoc<T> = (); + //~^ ERROR the trait bound `(): Sub` is not satisfied +} + +fn trivial_bound() where (): Sub {} +//~^ ERROR the trait bound `(): Sub` is not satisfied + +// The following is an edge case where the unsatisfied projection predicate +// `<<u8 as MultiAssoc>::Assoc1<()> as SuperGeneric<u16>>::Assoc == <u8 as MultiAssoc>::Assoc2` +// contains both associated types of `MultiAssoc`. To suppress the error about the unsatisfied +// super projection, the error's span must be equal to the span of the unsatisfied trait error. +trait SuperGeneric<T> { + type Assoc; +} +trait SubGeneric<T>: SuperGeneric<T, Assoc = T> {} +trait MultiAssoc +where + Self::Assoc1<()>: SubGeneric<Self::Assoc2> +{ + type Assoc1<T>; + type Assoc2; +} +impl SuperGeneric<u16> for () { + type Assoc = u8; +} +impl MultiAssoc for u8 { + type Assoc1<T> = (); + //~^ ERROR the trait bound `(): SubGeneric<u16>` is not satisfied + type Assoc2 = u16; +} + +fn main() {} diff --git a/tests/ui/trait-bounds/super-assoc-mismatch.stderr b/tests/ui/trait-bounds/super-assoc-mismatch.stderr new file mode 100644 index 00000000000..47535776348 --- /dev/null +++ b/tests/ui/trait-bounds/super-assoc-mismatch.stderr @@ -0,0 +1,105 @@ +error[E0277]: the trait bound `(): Sub` is not satisfied + --> $DIR/super-assoc-mismatch.rs:10:22 + | +LL | impl BoundOnSelf for () {} + | ^^ the trait `Sub` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/super-assoc-mismatch.rs:7:1 + | +LL | trait Sub: Super<Assoc = u16> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `BoundOnSelf` + --> $DIR/super-assoc-mismatch.rs:9:20 + | +LL | trait BoundOnSelf: Sub {} + | ^^^ required by this bound in `BoundOnSelf` + +error[E0277]: the trait bound `(): Sub` is not satisfied + --> $DIR/super-assoc-mismatch.rs:14:27 + | +LL | impl BoundOnParam<()> for () {} + | ^^ the trait `Sub` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/super-assoc-mismatch.rs:7:1 + | +LL | trait Sub: Super<Assoc = u16> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `BoundOnParam` + --> $DIR/super-assoc-mismatch.rs:13:23 + | +LL | trait BoundOnParam<T: Sub> {} + | ^^^ required by this bound in `BoundOnParam` + +error[E0277]: the trait bound `(): Sub` is not satisfied + --> $DIR/super-assoc-mismatch.rs:21:18 + | +LL | type Assoc = (); + | ^^ the trait `Sub` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/super-assoc-mismatch.rs:7:1 + | +LL | trait Sub: Super<Assoc = u16> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `BoundOnAssoc::Assoc` + --> $DIR/super-assoc-mismatch.rs:18:17 + | +LL | type Assoc: Sub; + | ^^^ required by this bound in `BoundOnAssoc::Assoc` + +error[E0277]: the trait bound `(): Sub` is not satisfied + --> $DIR/super-assoc-mismatch.rs:29:21 + | +LL | type Assoc<T> = (); + | ^^ the trait `Sub` is not implemented for `()`, which is required by `<u8 as BoundOnGat>::Assoc<u8>: Sub` + | +help: this trait has no implementations, consider adding one + --> $DIR/super-assoc-mismatch.rs:7:1 + | +LL | trait Sub: Super<Assoc = u16> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `BoundOnGat` + --> $DIR/super-assoc-mismatch.rs:25:41 + | +LL | trait BoundOnGat where Self::Assoc<u8>: Sub { + | ^^^ required by this bound in `BoundOnGat` + +error[E0277]: the trait bound `(): Sub` is not satisfied + --> $DIR/super-assoc-mismatch.rs:33:26 + | +LL | fn trivial_bound() where (): Sub {} + | ^^^^^^^ the trait `Sub` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/super-assoc-mismatch.rs:7:1 + | +LL | trait Sub: Super<Assoc = u16> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: see issue #48214 + = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable + +error[E0277]: the trait bound `(): SubGeneric<u16>` is not satisfied + --> $DIR/super-assoc-mismatch.rs:55:22 + | +LL | type Assoc1<T> = (); + | ^^ the trait `SubGeneric<u16>` is not implemented for `()`, which is required by `<u8 as MultiAssoc>::Assoc1<()>: SubGeneric<<u8 as MultiAssoc>::Assoc2>` + | +help: this trait has no implementations, consider adding one + --> $DIR/super-assoc-mismatch.rs:43:1 + | +LL | trait SubGeneric<T>: SuperGeneric<T, Assoc = T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `MultiAssoc` + --> $DIR/super-assoc-mismatch.rs:46:23 + | +LL | trait MultiAssoc + | ---------- required by a bound in this trait +LL | where +LL | Self::Assoc1<()>: SubGeneric<Self::Assoc2> + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MultiAssoc` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/alias/only-require-assocs-from-supertraits.rs b/tests/ui/traits/alias/only-require-assocs-from-supertraits.rs new file mode 100644 index 00000000000..35149fdfba0 --- /dev/null +++ b/tests/ui/traits/alias/only-require-assocs-from-supertraits.rs @@ -0,0 +1,16 @@ +//@ check-pass + +#![feature(trait_alias)] + +trait Foo<T> {} +trait Bar { type Assoc; } + +trait Alias<T: Bar> = Foo<T>; + +// Check that an alias only requires us to specify the associated types +// of the principal's supertraits. For example, we shouldn't require +// specifying the type `Assoc` on trait `Bar` just because we have some +// `T: Bar` where clause on the alias... because that makes no sense. +fn use_alias<T: Bar>(x: &dyn Alias<T>) {} + +fn main() {} diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs index 52ecbcc9e2c..7d71fcdd158 100644 --- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs +++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs @@ -20,6 +20,7 @@ impl<T, S> Trait<T, S> for () {} fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> { //~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied //~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied +//~| ERROR type annotations needed 3 } diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr index e7ceb7372bf..5062d17033e 100644 --- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr +++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr @@ -43,7 +43,7 @@ LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> { | +++++++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:18 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:27:18 | LL | struct Struct<T: Trait<u32, String>> { | ^^^^^ expected 1 generic argument @@ -59,7 +59,7 @@ LL | struct Struct<T: Trait<u32, Assoc = String>> { | +++++++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:31:23 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:32:23 | LL | trait AnotherTrait<T: Trait<T, i32>> {} | ^^^^^ expected 1 generic argument @@ -75,7 +75,7 @@ LL | trait AnotherTrait<T: Trait<T, Assoc = i32>> {} | +++++++ error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:34:9 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:35:9 | LL | impl<T: Trait<u32, String>> Struct<T> {} | ^^^^^ expected 1 generic argument @@ -91,7 +91,7 @@ LL | impl<T: Trait<u32, Assoc = String>> Struct<T> {} | +++++++ error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:40:58 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:41:58 | LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {} | ^^^^^^ - help: remove this generic argument @@ -99,7 +99,7 @@ LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {} | expected 1 generic argument | note: struct defined here, with 1 generic parameter: `T` - --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:8 + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:27:8 | LL | struct Struct<T: Trait<u32, String>> { | ^^^^^^ - @@ -116,7 +116,13 @@ error[E0207]: the type parameter `S` is not constrained by the impl trait, self LL | impl<T, S> Trait<T, S> for () {} | ^ unconstrained type parameter -error: aborting due to 9 previous errors +error[E0282]: type annotations needed + --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:41 + | +LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> { + | ^^^^^^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to 10 previous errors -Some errors have detailed explanations: E0107, E0207. +Some errors have detailed explanations: E0107, E0207, E0282. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs index 74c7afd6b9e..89b2da4452a 100644 --- a/tests/ui/traits/issue-105231.rs +++ b/tests/ui/traits/issue-105231.rs @@ -1,7 +1,9 @@ //~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send` struct A<T>(B<T>); //~^ ERROR recursive types `A` and `B` have infinite size +//~| ERROR `T` is never used struct B<T>(A<A<T>>); +//~^ ERROR `T` is never used trait Foo {} impl<T> Foo for T where T: Send {} impl Foo for B<u8> {} diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr index fe20c47c57a..6467a438375 100644 --- a/tests/ui/traits/issue-105231.stderr +++ b/tests/ui/traits/issue-105231.stderr @@ -3,7 +3,7 @@ error[E0072]: recursive types `A` and `B` have infinite size | LL | struct A<T>(B<T>); | ^^^^^^^^^^^ ---- recursive without indirection -LL | +... LL | struct B<T>(A<A<T>>); | ^^^^^^^^^^^ ------- recursive without indirection | @@ -11,19 +11,38 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL ~ struct A<T>(Box<B<T>>); LL | +LL | LL ~ struct B<T>(Box<A<A<T>>>); | +error[E0392]: type parameter `T` is never used + --> $DIR/issue-105231.rs:2:10 + | +LL | struct A<T>(B<T>); + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead + +error[E0392]: type parameter `T` is never used + --> $DIR/issue-105231.rs:5:10 + | +LL | struct B<T>(A<A<T>>); + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead + error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`) note: required because it appears within the type `B<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<u8>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-105231.rs:4:8 + --> $DIR/issue-105231.rs:5:8 | LL | struct B<T>(A<A<T>>); | ^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0072, E0275. +Some errors have detailed explanations: E0072, E0275, E0392. For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 5bc79d9cee8..330b23b5755 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -60,6 +60,14 @@ error[E0412]: cannot find type `NotDefined` in this scope LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | ^^^^^^^^^^ not found in this scope +error[E0277]: `i32` is not an iterator + --> $DIR/issue-50480.rs:3:27 + | +LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); + | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator + | + = help: the trait `Iterator` is not implemented for `i32` + error[E0204]: the trait `Copy` cannot be implemented for this type --> $DIR/issue-50480.rs:1:17 | @@ -87,14 +95,6 @@ LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:3:27 - | -LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); - | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator - | - = help: the trait `Iterator` is not implemented for `i32` - -error[E0277]: `i32` is not an iterator --> $DIR/issue-50480.rs:14:33 | LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr index a04fa1ab8a1..39d453e8035 100644 --- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr @@ -1,15 +1,3 @@ -error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1 - | -LL | impl<T: Copy> Trait for T {} - | ------------------------- first implementation here -LL | struct LocalTy; -LL | impl Trait for <LocalTy as Overflow>::Assoc {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation - | - = note: overflow evaluating the requirement `_ == <LocalTy as Overflow>::Assoc` - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`) - error[E0275]: overflow evaluating the requirement `<T as Overflow>::Assoc: Sized` --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18 | @@ -27,6 +15,18 @@ help: consider relaxing the implicit `Sized` restriction LL | type Assoc: ?Sized; | ++++++++ +error[E0119]: conflicting implementations of trait `Trait` + --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1 + | +LL | impl<T: Copy> Trait for T {} + | ------------------------- first implementation here +LL | struct LocalTy; +LL | impl Trait for <LocalTy as Overflow>::Assoc {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + | + = note: overflow evaluating the requirement `_ == <LocalTy as Overflow>::Assoc` + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`) + error: aborting due to 2 previous errors Some errors have detailed explanations: E0119, E0275. diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 931c46c6887..45ff9f763cd 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -13,6 +13,12 @@ LL | #![feature(lazy_type_alias)] = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information = note: `#[warn(incomplete_features)]` on by default +error: the type `<*const T as ToUnit<'a>>::Unit` is not well-formed + --> $DIR/issue-118950-root-region.rs:14:21 + | +LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } @@ -26,12 +32,6 @@ LL | LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)` -error: the type `<*const T as ToUnit<'a>>::Unit` is not well-formed - --> $DIR/issue-118950-root-region.rs:14:21 - | -LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0119, E0412. diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs index 7c7c68ad60a..f62dccff58d 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs +++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs @@ -20,6 +20,7 @@ impl<'a, I> UnwrapItemsExt for I { fn unwrap_items(self) -> Self::Iter { MyStruct {} + //~^ ERROR expected generic lifetime parameter } } diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr index 089c3e4fd8a..e6b94c525ff 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr +++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr @@ -4,6 +4,16 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, LL | impl<'a, I> UnwrapItemsExt for I { | ^^ unconstrained lifetime parameter -error: aborting due to 1 previous error +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/assoc-type-lifetime-unconstrained.rs:22:9 + | +LL | impl<'a, I> UnwrapItemsExt for I { + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | MyStruct {} + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0792. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs index 1824ff5e2fb..fcac83500ec 100644 --- a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs +++ b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs @@ -12,6 +12,8 @@ impl<T> X for () { //~^ ERROR the type parameter `T` is not constrained type I = impl Sized; fn f() -> Self::I {} + //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr index 137a4db81b5..bb0e11d314c 100644 --- a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr +++ b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr @@ -4,6 +4,19 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl<T> X for () { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/impl-with-unconstrained-param.rs:14:23 + | +LL | fn f() -> Self::I {} + | ^^ cannot infer type for type parameter `T` + +error[E0282]: type annotations needed + --> $DIR/impl-with-unconstrained-param.rs:14:15 + | +LL | fn f() -> Self::I {} + | ^^^^^^^ cannot infer type for type parameter `T` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/issue-74244.rs b/tests/ui/type-alias-impl-trait/issue-74244.rs index bb4104b3d25..ce8a38a3361 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.rs +++ b/tests/ui/type-alias-impl-trait/issue-74244.rs @@ -14,6 +14,7 @@ impl<T> Allocator for DefaultAllocator { type A = impl Fn(<DefaultAllocator as Allocator>::Buffer); fn foo() -> A { + //~^ ERROR: type annotations needed |_| () } diff --git a/tests/ui/type-alias-impl-trait/issue-74244.stderr b/tests/ui/type-alias-impl-trait/issue-74244.stderr index f5ca56baccc..d2b50ffd86b 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74244.stderr @@ -4,6 +4,13 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl<T> Allocator for DefaultAllocator { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/issue-74244.rs:16:13 + | +LL | fn foo() -> A { + | ^ cannot infer type for type parameter `T` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/issue-74761-2.rs b/tests/ui/type-alias-impl-trait/issue-74761-2.rs index f582592e9bc..e556025adee 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-74761-2.rs @@ -10,6 +10,7 @@ impl<'a, 'b> A for () { type B = impl core::fmt::Debug; fn f(&self) -> Self::B {} + //~^ ERROR expected generic lifetime parameter } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr index f15d0a069ca..26babc29000 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr @@ -10,6 +10,16 @@ error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter -error: aborting due to 2 previous errors +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/issue-74761-2.rs:12:28 + | +LL | impl<'a, 'b> A for () { + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | fn f(&self) -> Self::B {} + | ^^ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0792. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/issue-74761.rs b/tests/ui/type-alias-impl-trait/issue-74761.rs index f582592e9bc..e556025adee 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761.rs +++ b/tests/ui/type-alias-impl-trait/issue-74761.rs @@ -10,6 +10,7 @@ impl<'a, 'b> A for () { type B = impl core::fmt::Debug; fn f(&self) -> Self::B {} + //~^ ERROR expected generic lifetime parameter } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-74761.stderr b/tests/ui/type-alias-impl-trait/issue-74761.stderr index 1d016fe070f..a4826c29346 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761.stderr @@ -10,6 +10,16 @@ error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter -error: aborting due to 2 previous errors +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/issue-74761.rs:12:28 + | +LL | impl<'a, 'b> A for () { + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | fn f(&self) -> Self::B {} + | ^^ + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0792. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs index 296a3f3e300..b232097fdb3 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs @@ -12,6 +12,7 @@ impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) { type Associated = (i32, impl Iterator<Item = i32>); fn into(self) -> Self::Associated { (0_i32, [0_i32].iter().copied()) + //~^ ERROR: expected generic lifetime parameter, found `'_` } } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr index cff2695304a..5f9c56f1ca9 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr @@ -4,6 +4,16 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, LL | impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) { | ^^ unconstrained lifetime parameter -error: aborting due to 1 previous error +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:14:9 + | +LL | impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) { + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | (0_i32, [0_i32].iter().copied()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0792. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs index e92cf2513e7..eae5e5fdde2 100644 --- a/tests/ui/type-alias-impl-trait/variance.rs +++ b/tests/ui/type-alias-impl-trait/variance.rs @@ -6,16 +6,21 @@ trait Captures<'a> {} impl<T> Captures<'_> for T {} type NotCapturedEarly<'a> = impl Sized; //~ [o] +//~^ ERROR: unconstrained opaque type type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o] +//~^ ERROR: unconstrained opaque type // TAIT does *not* capture `'b` type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o] +//~^ ERROR: unconstrained opaque type // TAIT does *not* capture `'b` type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o] +//~^ ERROR: unconstrained opaque type type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o] +//~^ ERROR: unconstrained opaque type trait Foo<'i> { type ImplicitCapture<'a>; @@ -27,18 +32,24 @@ trait Foo<'i> { impl<'i> Foo<'i> for &'i () { type ImplicitCapture<'a> = impl Sized; //~ [o, o] + //~^ ERROR: unconstrained opaque type type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o] + //~^ ERROR: unconstrained opaque type type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o] + //~^ ERROR: unconstrained opaque type } impl<'i> Foo<'i> for () { type ImplicitCapture<'a> = impl Sized; //~ [o, o] + //~^ ERROR: unconstrained opaque type type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o] + //~^ ERROR: unconstrained opaque type type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o] + //~^ ERROR: unconstrained opaque type } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr index 1794447c89a..914541fcf66 100644 --- a/tests/ui/type-alias-impl-trait/variance.stderr +++ b/tests/ui/type-alias-impl-trait/variance.stderr @@ -1,3 +1,91 @@ +error: unconstrained opaque type + --> $DIR/variance.rs:8:29 + | +LL | type NotCapturedEarly<'a> = impl Sized; + | ^^^^^^^^^^ + | + = note: `NotCapturedEarly` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/variance.rs:11:26 + | +LL | type CapturedEarly<'a> = impl Sized + Captures<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `CapturedEarly` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/variance.rs:15:56 + | +LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; + | ^^^^^^^^^^ + | + = note: `NotCapturedLate` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/variance.rs:19:49 + | +LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Captured` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/variance.rs:22:27 + | +LL | type Bar<'a, 'b: 'b, T> = impl Sized; + | ^^^^^^^^^^ + | + = note: `Bar` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/variance.rs:34:32 + | +LL | type ImplicitCapture<'a> = impl Sized; + | ^^^^^^^^^^ + | + = note: `ImplicitCapture` must be used in combination with a concrete type within the same impl + +error: unconstrained opaque type + --> $DIR/variance.rs:37:42 + | +LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `ExplicitCaptureFromHeader` must be used in combination with a concrete type within the same impl + +error: unconstrained opaque type + --> $DIR/variance.rs:40:39 + | +LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl + +error: unconstrained opaque type + --> $DIR/variance.rs:45:32 + | +LL | type ImplicitCapture<'a> = impl Sized; + | ^^^^^^^^^^ + | + = note: `ImplicitCapture` must be used in combination with a concrete type within the same impl + +error: unconstrained opaque type + --> $DIR/variance.rs:48:42 + | +LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `ExplicitCaptureFromHeader` must be used in combination with a concrete type within the same impl + +error: unconstrained opaque type + --> $DIR/variance.rs:51:39 + | +LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl + error: [o] --> $DIR/variance.rs:8:29 | @@ -5,64 +93,64 @@ LL | type NotCapturedEarly<'a> = impl Sized; | ^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:10:26 + --> $DIR/variance.rs:11:26 | LL | type CapturedEarly<'a> = impl Sized + Captures<'a>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:13:56 + --> $DIR/variance.rs:15:56 | LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; | ^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:16:49 + --> $DIR/variance.rs:19:49 | LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o, o] - --> $DIR/variance.rs:18:27 + --> $DIR/variance.rs:22:27 | LL | type Bar<'a, 'b: 'b, T> = impl Sized; | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:29:32 + --> $DIR/variance.rs:34:32 | LL | type ImplicitCapture<'a> = impl Sized; | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:31:42 + --> $DIR/variance.rs:37:42 | LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:33:39 + --> $DIR/variance.rs:40:39 | LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:37:32 + --> $DIR/variance.rs:45:32 | LL | type ImplicitCapture<'a> = impl Sized; | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:39:42 + --> $DIR/variance.rs:48:42 | LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:41:39 + --> $DIR/variance.rs:51:39 | LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 22 previous errors diff --git a/tests/ui/typeck/issue-13853-5.rs b/tests/ui/typeck/issue-13853-5.rs index 2afdf95aacf..fc97c6c67d6 100644 --- a/tests/ui/typeck/issue-13853-5.rs +++ b/tests/ui/typeck/issue-13853-5.rs @@ -7,6 +7,7 @@ trait Deserializable { impl<'a, T: Deserializable> Deserializable for &'a str { //~^ ERROR type parameter `T` is not constrained fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str { + //~^ ERROR mismatched types } } diff --git a/tests/ui/typeck/issue-13853-5.stderr b/tests/ui/typeck/issue-13853-5.stderr index 1eead956328..388d5ec746c 100644 --- a/tests/ui/typeck/issue-13853-5.stderr +++ b/tests/ui/typeck/issue-13853-5.stderr @@ -4,6 +4,22 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl<'a, T: Deserializable> Deserializable for &'a str { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/issue-13853-5.rs:9:70 + | +LL | fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str { + | ----------------- ^^^^^^^ expected `&str`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | +help: consider returning the local binding `_y` + | +LL ~ fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str { +LL + _y +LL ~ + | + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0308. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/variance/variance-associated-consts.rs b/tests/ui/variance/variance-associated-consts.rs index da55bc96244..6a44a94df3f 100644 --- a/tests/ui/variance/variance-associated-consts.rs +++ b/tests/ui/variance/variance-associated-consts.rs @@ -12,6 +12,7 @@ trait Trait { #[rustc_variance] struct Foo<T: Trait> { //~ ERROR [o] field: [u8; <T as Trait>::Const] + //~^ ERROR: unconstrained generic constant } fn main() { } diff --git a/tests/ui/variance/variance-associated-consts.stderr b/tests/ui/variance/variance-associated-consts.stderr index e25f0879add..f41574ca3a3 100644 --- a/tests/ui/variance/variance-associated-consts.stderr +++ b/tests/ui/variance/variance-associated-consts.stderr @@ -1,8 +1,16 @@ +error: unconstrained generic constant + --> $DIR/variance-associated-consts.rs:14:12 + | +LL | field: [u8; <T as Trait>::Const] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); <T as Trait>::Const]:` + error: [o] --> $DIR/variance-associated-consts.rs:13:1 | LL | struct Foo<T: Trait> { | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/variance/variance-regions-direct.rs b/tests/ui/variance/variance-regions-direct.rs index 39ea77a8aa2..f1763c403f1 100644 --- a/tests/ui/variance/variance-regions-direct.rs +++ b/tests/ui/variance/variance-regions-direct.rs @@ -50,6 +50,7 @@ struct Test6<'a, 'b:'a> { //~ ERROR [+, o] #[rustc_variance] struct Test7<'a> { //~ ERROR [*] + //~^ ERROR: `'a` is never used x: isize } diff --git a/tests/ui/variance/variance-regions-direct.stderr b/tests/ui/variance/variance-regions-direct.stderr index c55730296f1..edfc888f656 100644 --- a/tests/ui/variance/variance-regions-direct.stderr +++ b/tests/ui/variance/variance-regions-direct.stderr @@ -1,3 +1,11 @@ +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/variance-regions-direct.rs:52:14 + | +LL | struct Test7<'a> { + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + error: [+, +, +] --> $DIR/variance-regions-direct.rs:9:1 | @@ -35,10 +43,11 @@ LL | struct Test7<'a> { | ^^^^^^^^^^^^^^^^ error: [-, +, o] - --> $DIR/variance-regions-direct.rs:59:1 + --> $DIR/variance-regions-direct.rs:60:1 | LL | enum Test8<'a, 'b, 'c:'b> { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0392`. diff --git a/tests/ui/variance/variance-regions-indirect.rs b/tests/ui/variance/variance-regions-indirect.rs index 0d00535fef1..31e25641d8c 100644 --- a/tests/ui/variance/variance-regions-indirect.rs +++ b/tests/ui/variance/variance-regions-indirect.rs @@ -6,6 +6,7 @@ #[rustc_variance] enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *] + //~^ ERROR: `'d` is never used Test8A(extern "Rust" fn(&'a isize)), Test8B(&'b [isize]), Test8C(&'b mut &'c str), @@ -13,16 +14,19 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *] #[rustc_variance] struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, +, -] + //~^ ERROR: `'w` is never used f: Base<'z, 'y, 'x, 'w> } #[rustc_variance] // Combine - and + to yield o struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *] + //~^ ERROR: `'c` is never used f: Base<'a, 'a, 'b, 'c> } #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, +, *] + //~^ ERROR: `'c` is never used f: Base<'a, 'b, 'a, 'c> } diff --git a/tests/ui/variance/variance-regions-indirect.stderr b/tests/ui/variance/variance-regions-indirect.stderr index edf2626d598..901ec0c6a76 100644 --- a/tests/ui/variance/variance-regions-indirect.stderr +++ b/tests/ui/variance/variance-regions-indirect.stderr @@ -1,3 +1,35 @@ +error[E0392]: lifetime parameter `'d` is never used + --> $DIR/variance-regions-indirect.rs:8:26 + | +LL | enum Base<'a, 'b, 'c:'b, 'd> { + | ^^ unused lifetime parameter + | + = help: consider removing `'d`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0392]: lifetime parameter `'w` is never used + --> $DIR/variance-regions-indirect.rs:16:17 + | +LL | struct Derived1<'w, 'x:'y, 'y, 'z> { + | ^^ unused lifetime parameter + | + = help: consider removing `'w`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0392]: lifetime parameter `'c` is never used + --> $DIR/variance-regions-indirect.rs:22:28 + | +LL | struct Derived2<'a, 'b:'a, 'c> { + | ^^ unused lifetime parameter + | + = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0392]: lifetime parameter `'c` is never used + --> $DIR/variance-regions-indirect.rs:28:28 + | +LL | struct Derived3<'a:'b, 'b, 'c> { + | ^^ unused lifetime parameter + | + = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData` + error: [-, +, o, *] --> $DIR/variance-regions-indirect.rs:8:1 | @@ -5,28 +37,29 @@ LL | enum Base<'a, 'b, 'c:'b, 'd> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: [*, o, +, -] - --> $DIR/variance-regions-indirect.rs:15:1 + --> $DIR/variance-regions-indirect.rs:16:1 | LL | struct Derived1<'w, 'x:'y, 'y, 'z> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o, *] - --> $DIR/variance-regions-indirect.rs:20:1 + --> $DIR/variance-regions-indirect.rs:22:1 | LL | struct Derived2<'a, 'b:'a, 'c> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, +, *] - --> $DIR/variance-regions-indirect.rs:25:1 + --> $DIR/variance-regions-indirect.rs:28:1 | LL | struct Derived3<'a:'b, 'b, 'c> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: [-, +, o] - --> $DIR/variance-regions-indirect.rs:30:1 + --> $DIR/variance-regions-indirect.rs:34:1 | LL | struct Derived4<'a, 'b, 'c:'b> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 9 previous errors +For more information about this error, try `rustc --explain E0392`. diff --git a/tests/ui/variance/variance-trait-bounds.rs b/tests/ui/variance/variance-trait-bounds.rs index ad5334602a2..25a01b160dd 100644 --- a/tests/ui/variance/variance-trait-bounds.rs +++ b/tests/ui/variance/variance-trait-bounds.rs @@ -19,16 +19,19 @@ struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +] #[rustc_variance] enum TestEnum<U,T:Setter<U>> { //~ ERROR [*, +] + //~^ ERROR: `U` is never used Foo(T) } #[rustc_variance] struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +] + //~^ ERROR: `U` is never used t: T } #[rustc_variance] struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [*, +] + //~^ ERROR: `U` is never used t: T } diff --git a/tests/ui/variance/variance-trait-bounds.stderr b/tests/ui/variance/variance-trait-bounds.stderr index 5a73e541c3a..95ed18c1ad2 100644 --- a/tests/ui/variance/variance-trait-bounds.stderr +++ b/tests/ui/variance/variance-trait-bounds.stderr @@ -1,3 +1,30 @@ +error[E0392]: type parameter `U` is never used + --> $DIR/variance-trait-bounds.rs:21:15 + | +LL | enum TestEnum<U,T:Setter<U>> { + | ^ unused type parameter + | + = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead + +error[E0392]: type parameter `U` is never used + --> $DIR/variance-trait-bounds.rs:27:25 + | +LL | struct TestContraStruct<U,T:Setter<U>> { + | ^ unused type parameter + | + = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead + +error[E0392]: type parameter `U` is never used + --> $DIR/variance-trait-bounds.rs:33:16 + | +LL | struct TestBox<U,T:Getter<U>+Setter<U>> { + | ^ unused type parameter + | + = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead + error: [+, +] --> $DIR/variance-trait-bounds.rs:16:1 | @@ -11,16 +38,17 @@ LL | enum TestEnum<U,T:Setter<U>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: [*, +] - --> $DIR/variance-trait-bounds.rs:26:1 + --> $DIR/variance-trait-bounds.rs:27:1 | LL | struct TestContraStruct<U,T:Setter<U>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: [*, +] - --> $DIR/variance-trait-bounds.rs:31:1 + --> $DIR/variance-trait-bounds.rs:33:1 | LL | struct TestBox<U,T:Getter<U>+Setter<U>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0392`. |
