From 24bd6a1b9b1190378589075a96181a4f65015949 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 18 Jul 2024 10:04:04 +0000 Subject: [PATCH 1/4] Remove a now-resolved hack --- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index d9c70c3cee655..ca6fa2710bfb9 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -74,20 +74,7 @@ fn enforce_impl_params_are_constrained( ) -> Result<(), ErrorGuaranteed> { // Every lifetime used in an associated type must be constrained. let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); - if impl_self_ty.references_error() { - // Don't complain about unconstrained type params when self ty isn't known due to errors. - // (#36836) - tcx.dcx().span_delayed_bug( - tcx.def_span(impl_def_id), - format!( - "potentially unconstrained type parameters weren't evaluated: {impl_self_ty:?}", - ), - ); - // This is super fishy, but our current `rustc_hir_analysis::check_crate` pipeline depends on - // `type_of` having been called much earlier, and thus this value being read from cache. - // Compilation must continue in order for other important diagnostics to keep showing up. - return Ok(()); - } + impl_self_ty.error_reported()?; let impl_generics = tcx.generics_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); From d8b0864dade968f8edb4e88331358e894e831781 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 19 Jul 2024 09:45:57 +0000 Subject: [PATCH 2/4] Reject unconstrained lifetimes in type_of(assoc_ty) instead of during wfcheck of the impl item --- compiler/rustc_hir_analysis/messages.ftl | 1 + compiler/rustc_hir_analysis/src/collect.rs | 95 +++++++++++++++++-- .../rustc_hir_analysis/src/collect/type_of.rs | 23 +++-- compiler/rustc_hir_analysis/src/errors.rs | 2 + .../rustc_hir_analysis/src/impl_wf_check.rs | 46 +-------- tests/ui/associated-types/issue-26262.stderr | 6 ++ .../in-trait/unconstrained-impl-region.rs | 3 +- .../in-trait/unconstrained-impl-region.stderr | 20 +++- tests/ui/delegation/unsupported.stderr | 16 ++-- ...-predicate-entailment-error.current.stderr | 42 ++++---- .../opaque-and-lifetime-mismatch.stderr | 18 ++-- .../in-trait/span-bug-issue-121457.stderr | 24 ++--- .../impl-trait/in-trait/unconstrained-lt.rs | 1 + .../in-trait/unconstrained-lt.stderr | 25 ++++- tests/ui/impl-unused-rps-in-assoc-type.stderr | 6 ++ tests/ui/issues/issue-22886.stderr | 6 ++ tests/ui/issues/issue-29861.rs | 7 +- tests/ui/issues/issue-29861.stderr | 18 ++-- tests/ui/issues/issue-35139.stderr | 6 ++ ...mpl-item-type-no-body-semantic-fail.stderr | 20 ++-- .../tilde-const-invalid-places.rs | 1 - .../tilde-const-invalid-places.stderr | 36 +++---- .../assoc-type-lifetime-unconstrained.rs | 1 - .../assoc-type-lifetime-unconstrained.stderr | 18 ++-- .../ui/type-alias-impl-trait/issue-74761-2.rs | 1 - .../issue-74761-2.stderr | 24 ++--- tests/ui/type-alias-impl-trait/issue-74761.rs | 1 - .../type-alias-impl-trait/issue-74761.stderr | 24 ++--- ...alias-impl-trait-unconstrained-lifetime.rs | 1 - ...s-impl-trait-unconstrained-lifetime.stderr | 18 ++-- .../unconstrained-impl-param.stderr | 6 ++ 31 files changed, 308 insertions(+), 208 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 070d63b48b7bd..ef4bbb2581ea6 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -552,6 +552,7 @@ hir_analysis_unconstrained_generic_parameter = the {$param_def_kind} `{$param_na .label = unconstrained {$param_def_kind} .const_param_note = expressions using a const parameter must map each value to a distinct output value .const_param_note2 = proving the result of expressions other than the parameter are unique is not supported + .help = this use of an otherwise unconstrained lifetime is not allowed hir_analysis_unconstrained_opaque_type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same {$what} diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 8d5824130d858..5835a743f3252 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -14,17 +14,18 @@ //! At present, however, we do run collection across all items in the //! crate as a kind of pass. This should eventually be factored away. -use std::cell::Cell; +use std::cell::{Cell, RefCell}; use std::iter; use std::ops::Bound; use rustc_abi::ExternAbi; use rustc_ast::Recovered; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey, struct_span_code_err, + Applicability, Diag, DiagCtxtHandle, E0207, E0228, ErrorGuaranteed, StashKey, + struct_span_code_err, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -36,7 +37,9 @@ use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode}; +use rustc_middle::ty::{ + self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt as _, TypingMode, +}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, Span}; @@ -46,7 +49,8 @@ use rustc_trait_selection::traits::ObligationCtxt; use tracing::{debug, instrument}; use crate::check::intrinsic::intrinsic_operation_unsafety; -use crate::errors; +use crate::constrained_generic_params::{self as cgp, Parameter}; +use crate::errors::{self, UnconstrainedGenericParameter}; use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason}; pub(crate) mod dump; @@ -127,6 +131,7 @@ pub struct ItemCtxt<'tcx> { tcx: TyCtxt<'tcx>, item_def_id: LocalDefId, tainted_by_errors: Cell>, + pub(crate) forbidden_params: RefCell>, } /////////////////////////////////////////////////////////////////////////// @@ -375,7 +380,12 @@ fn bad_placeholder<'cx, 'tcx>( impl<'tcx> ItemCtxt<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> { - ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) } + ItemCtxt { + tcx, + item_def_id, + tainted_by_errors: Cell::new(None), + forbidden_params: Default::default(), + } } pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { @@ -396,6 +406,58 @@ impl<'tcx> ItemCtxt<'tcx> { None => Ok(()), } } + + fn forbid_unconstrained_lifetime_params_from_parent_impl(&self) -> Result<(), ErrorGuaranteed> { + let tcx = self.tcx; + let impl_def_id = tcx.hir().get_parent_item(self.hir_id()); + let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); + impl_self_ty.error_reported()?; + let impl_generics = tcx.generics_of(impl_def_id); + let impl_predicates = tcx.predicates_of(impl_def_id); + let impl_trait_ref = + tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); + + impl_trait_ref.error_reported()?; + + let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref); + + cgp::identify_constrained_generic_params( + tcx, + impl_predicates, + impl_trait_ref, + &mut input_parameters, + ); + + for param in &impl_generics.own_params { + let p = match param.kind { + // This is a horrible concession to reality. It'd be + // better to just ban unconstrained lifetimes outright, but in + // practice people do non-hygienic macros like: + // + // ``` + // macro_rules! __impl_slice_eq1 { + // ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq { + // .... + // } + // } + // } + // ``` + // + // In a concession to backwards compatibility, we continue to + // permit those, so long as the lifetimes aren't used in + // associated types. This is sound, because lifetimes + // used elsewhere are not projected back out. + ty::GenericParamDefKind::Type { .. } => continue, + ty::GenericParamDefKind::Lifetime => param.to_early_bound_region_data().into(), + ty::GenericParamDefKind::Const { .. } => continue, + }; + if !input_parameters.contains(&p) { + self.forbidden_params.borrow_mut().insert(p, param.clone()); + } + } + Ok(()) + } } impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { @@ -538,8 +600,25 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { ty.ty_adt_def() } - fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) { - // There's no place to record types from signatures? + fn record_ty(&self, _hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) { + // There's no place to record types from signatures + + if !self.forbidden_params.borrow().is_empty() { + for param in cgp::parameters_for(self.tcx, ty, true) { + if let Some(param) = self.forbidden_params.borrow_mut().remove(¶m) { + let mut diag = self.dcx().create_err(UnconstrainedGenericParameter { + span: self.tcx.def_span(param.def_id), + param_name: param.name, + param_def_kind: self.tcx.def_descr(param.def_id), + const_param_note: false, + const_param_note2: false, + lifetime_help: Some(span), + }); + diag.code(E0207); + diag.emit(); + } + } + } } fn infcx(&self) -> Option<&InferCtxt<'tcx>> { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 7cf99bebd36a3..5b49106166488 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -388,6 +388,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ use rustc_hir::*; use rustc_middle::ty::Ty; + let hir_id = tcx.local_def_id_to_hir_id(def_id); + + let icx = ItemCtxt::new(tcx, def_id); + // 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. @@ -396,7 +400,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ 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()]; + let ty = map[&assoc_item.trait_item_def_id.unwrap()]; + match icx.forbid_unconstrained_lifetime_params_from_parent_impl() { + Ok(()) => { + // Ensure no unconstrained lifetimes are used in these impls. + icx.record_ty(hir_id, ty.instantiate_identity(), tcx.def_span(def_id)); + } + Err(guar) => return ty::EarlyBinder::bind(Ty::new_error(tcx, guar)), + } + return ty; } Err(_) => { return ty::EarlyBinder::bind(Ty::new_error_with_message( @@ -418,10 +430,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ None => {} } - let hir_id = tcx.local_def_id_to_hir_id(def_id); - - let icx = ItemCtxt::new(tcx, def_id); - let output = match tcx.hir_node(hir_id) { Node::TraitItem(item) => match item.kind { TraitItemKind::Fn(..) => { @@ -472,7 +480,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ check_feature_inherent_assoc_ty(tcx, item.span); } - icx.lower_ty(ty) + match icx.forbid_unconstrained_lifetime_params_from_parent_impl() { + Err(guar) => Ty::new_error(tcx, guar), + Ok(()) => icx.lower_ty(ty), + } } }, diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 4142dcff226bf..a555be4fefecb 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1617,6 +1617,8 @@ pub(crate) struct UnconstrainedGenericParameter { pub const_param_note: bool, #[note(hir_analysis_const_param_note2)] pub const_param_note2: bool, + #[help] + pub lifetime_help: Option, } #[derive(Diagnostic)] diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index ca6fa2710bfb9..f6968f9b3e2fc 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -11,7 +11,6 @@ use std::assert_matches::debug_assert_matches; use min_specialization::check_min_specialization; -use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; @@ -89,25 +88,6 @@ fn enforce_impl_params_are_constrained( &mut input_parameters, ); - // Disallow unconstrained lifetimes, but only if they appear in assoc types. - let lifetimes_in_associated_types: FxHashSet<_> = tcx - .associated_item_def_ids(impl_def_id) - .iter() - .flat_map(|def_id| { - let item = tcx.associated_item(def_id); - match item.kind { - ty::AssocKind::Type => { - if item.defaultness(tcx).has_value() { - cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true) - } else { - vec![] - } - } - ty::AssocKind::Fn | ty::AssocKind::Const => vec![], - } - }) - .collect(); - let mut res = Ok(()); for param in &impl_generics.own_params { let err = match param.kind { @@ -116,11 +96,7 @@ fn enforce_impl_params_are_constrained( let param_ty = ty::ParamTy::for_def(param); !input_parameters.contains(&cgp::Parameter::from(param_ty)) } - ty::GenericParamDefKind::Lifetime => { - let param_lt = cgp::Parameter::from(param.to_early_bound_region_data()); - lifetimes_in_associated_types.contains(¶m_lt) && // (*) - !input_parameters.contains(¶m_lt) - } + ty::GenericParamDefKind::Lifetime => false, ty::GenericParamDefKind::Const { .. } => { let param_ct = ty::ParamConst::for_def(param); !input_parameters.contains(&cgp::Parameter::from(param_ct)) @@ -134,29 +110,11 @@ fn enforce_impl_params_are_constrained( param_def_kind: tcx.def_descr(param.def_id), const_param_note, const_param_note2: const_param_note, + lifetime_help: None, }); diag.code(E0207); res = Err(diag.emit()); } } res - - // (*) This is a horrible concession to reality. I think it'd be - // better to just ban unconstrained lifetimes outright, but in - // practice people do non-hygienic macros like: - // - // ``` - // macro_rules! __impl_slice_eq1 { - // ($Lhs: ty, $Rhs: ty, $Bound: ident) => { - // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq { - // .... - // } - // } - // } - // ``` - // - // In a concession to backwards compatibility, we continue to - // permit those, so long as the lifetimes aren't used in - // associated types. I believe this is sound, because lifetimes - // used elsewhere are not projected back out. } diff --git a/tests/ui/associated-types/issue-26262.stderr b/tests/ui/associated-types/issue-26262.stderr index 90e2d0d930164..f6c9c45ff03aa 100644 --- a/tests/ui/associated-types/issue-26262.stderr +++ b/tests/ui/associated-types/issue-26262.stderr @@ -9,6 +9,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a,T: Trait2<'a>> Trait1<>::Foo> for T { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-26262.rs:19:16 + | +LL | type Bar = &'a (); + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.rs b/tests/ui/async-await/in-trait/unconstrained-impl-region.rs index 9382c2323643b..f0c80ccb0f611 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.rs +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.rs @@ -11,7 +11,8 @@ pub(crate) trait Actor: Sized { } impl<'a> Actor for () { -//~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + //~| ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates type Message = &'a (); async fn on_mount(self, _: impl Inbox<&'a ()>) {} } diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr index ef7e4ef0eb85f..faee7d0f77f9d 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr @@ -3,7 +3,25 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Actor for () { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/unconstrained-impl-region.rs:16:20 + | +LL | type Message = &'a (); + | ^^^^^^ + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-impl-region.rs:13:6 + | +LL | impl<'a> Actor for () { + | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/unconstrained-impl-region.rs:17:5 + | +LL | async fn on_mount(self, _: impl Inbox<&'a ()>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr index 2b0bcf9d84e82..a2d0a8298f3b7 100644 --- a/tests/ui/delegation/unsupported.stderr +++ b/tests/ui/delegation/unsupported.stderr @@ -10,11 +10,11 @@ note: ...which requires comparing an impl and trait method signature, inferring LL | reuse to_reuse::opaque_ret; | ^^^^^^^^^^ = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle -note: cycle used when checking that `opaque::` is well-formed - --> $DIR/unsupported.rs:21:5 +note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition + --> $DIR/unsupported.rs:22:25 | -LL | impl ToReuse for u8 { - | ^^^^^^^^^^^^^^^^^^^ +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error[E0391]: cycle detected when computing type of `opaque::::{synthetic#0}` @@ -29,11 +29,11 @@ note: ...which requires comparing an impl and trait method signature, inferring LL | reuse ToReuse::opaque_ret; | ^^^^^^^^^^ = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle -note: cycle used when checking that `opaque::` is well-formed - --> $DIR/unsupported.rs:24:5 +note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition + --> $DIR/unsupported.rs:25:24 | -LL | impl ToReuse for u16 { - | ^^^^^^^^^^^^^^^^^^^^ +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: recursive delegation is not supported yet diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr index 38c7a9ea16e64..b1c9d0baf1954 100644 --- a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr @@ -23,10 +23,16 @@ LL | F: Callback + MyFn, | +++++++++++ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:36:30 + --> $DIR/false-positive-predicate-entailment-error.rs:36:5 | -LL | fn autobatch(self) -> impl Trait - | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F` +LL | / fn autobatch(self) -> impl Trait +LL | | +LL | | +LL | | +... | +LL | | where +LL | | F: Callback, + | |_______________________________________^ the trait `MyFn` is not implemented for `F` | note: required for `F` to implement `Callback` --> $DIR/false-positive-predicate-entailment-error.rs:14:21 @@ -35,30 +41,17 @@ LL | impl> Callback for F { | ------- ^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here -note: required by a bound in `::autobatch` - --> $DIR/false-positive-predicate-entailment-error.rs:43:12 - | -LL | fn autobatch(self) -> impl Trait - | --------- required by a bound in this associated function -... -LL | F: Callback, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `::autobatch` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider further restricting this bound | LL | F: Callback + MyFn, | +++++++++++ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:36:5 + --> $DIR/false-positive-predicate-entailment-error.rs:36:30 | -LL | / fn autobatch(self) -> impl Trait -LL | | -LL | | -LL | | -... | -LL | | where -LL | | F: Callback, - | |_______________________________________^ the trait `MyFn` is not implemented for `F` +LL | fn autobatch(self) -> impl Trait + | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F` | note: required for `F` to implement `Callback` --> $DIR/false-positive-predicate-entailment-error.rs:14:21 @@ -67,7 +60,14 @@ LL | impl> Callback for F { | ------- ^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +note: required by a bound in `::autobatch` + --> $DIR/false-positive-predicate-entailment-error.rs:43:12 + | +LL | fn autobatch(self) -> impl Trait + | --------- required by a bound in this associated function +... +LL | F: Callback, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `::autobatch` help: consider further restricting this bound | LL | F: Callback + MyFn, diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr index 81570781b27da..0972dd3951428 100644 --- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr @@ -62,15 +62,6 @@ note: struct defined here, with 0 generic parameters LL | struct Wrapper<'rom>(&'rom ()); | ^^^^^^^ -error[E0053]: method `bar` has an incompatible return type for trait - --> $DIR/opaque-and-lifetime-mismatch.rs:10:17 - | -LL | fn bar() -> i32 { - | ^^^ - | | - | expected `Wrapper<'static>`, found `i32` - | return type in trait - error[E0053]: method `bar` has an incompatible type for trait --> $DIR/opaque-and-lifetime-mismatch.rs:10:17 | @@ -89,6 +80,15 @@ help: change the output type to match the trait LL | fn bar() -> Wrapper<'static> { | ~~~~~~~~~~~~~~~~ +error[E0053]: method `bar` has an incompatible return type for trait + --> $DIR/opaque-and-lifetime-mismatch.rs:10:17 + | +LL | fn bar() -> i32 { + | ^^^ + | | + | expected `Wrapper<'static>`, found `i32` + | return type in trait + error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/opaque-and-lifetime-mismatch.rs:24:17 | diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr index d8a2eef94a180..cbcb932e1dae9 100644 --- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr +++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr @@ -1,3 +1,15 @@ +error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration + --> $DIR/span-bug-issue-121457.rs:10:14 + | +LL | type Item<'a> + | ---- lifetimes in impl do not match this type in trait +LL | where +LL | Self: 'a; + | -- this bound might be missing in the impl +... +LL | type Item = u32; + | ^ lifetimes do not match type in trait + error[E0582]: binding for associated type `Item` references lifetime `'missing`, which does not appear in the trait input types --> $DIR/span-bug-issue-121457.rs:13:51 | @@ -12,18 +24,6 @@ LL | fn iter(&self) -> impl for<'missing> Iterator $DIR/span-bug-issue-121457.rs:10:14 - | -LL | type Item<'a> - | ---- lifetimes in impl do not match this type in trait -LL | where -LL | Self: 'a; - | -- this bound might be missing in the impl -... -LL | type Item = u32; - | ^ lifetimes do not match type in trait - error[E0277]: `()` is not an iterator --> $DIR/span-bug-issue-121457.rs:13:23 | diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.rs b/tests/ui/impl-trait/in-trait/unconstrained-lt.rs index ff3753de5a2e1..ec30a36e36592 100644 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.rs +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.rs @@ -6,6 +6,7 @@ impl<'a, T> Foo for T { //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates fn test() -> &'a () { + //~^ WARN: impl trait in impl method signature does not match trait method signature &() } } diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr index 4c5a42c0b4b47..8881b75af1654 100644 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr +++ b/tests/ui/impl-trait/in-trait/unconstrained-lt.stderr @@ -3,7 +3,30 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, T> Foo for T { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/unconstrained-lt.rs:8:18 + | +LL | fn test() -> &'a () { + | ^^^^^^ + +warning: impl trait in impl method signature does not match trait method signature + --> $DIR/unconstrained-lt.rs:8:18 + | +LL | fn test() -> impl Sized; + | ---------- return type from trait method defined here +... +LL | fn test() -> &'a () { + | ^^^^^^ + | + = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate + = note: we are soliciting feedback, see issue #121718 for more information + = note: `#[warn(refining_impl_trait_internal)]` on by default +help: replace the return type so that it matches the trait + | +LL | fn test() -> impl Sized { + | ~~~~~~~~~~ -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-unused-rps-in-assoc-type.stderr b/tests/ui/impl-unused-rps-in-assoc-type.stderr index ef61fa4be4830..a4e260e311076 100644 --- a/tests/ui/impl-unused-rps-in-assoc-type.stderr +++ b/tests/ui/impl-unused-rps-in-assoc-type.stderr @@ -3,6 +3,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Fun for Holder { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/impl-unused-rps-in-assoc-type.rs:12:19 + | +LL | type Output = &'a str; + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-22886.stderr b/tests/ui/issues/issue-22886.stderr index a04fa677f9ec5..563d8038926ff 100644 --- a/tests/ui/issues/issue-22886.stderr +++ b/tests/ui/issues/issue-22886.stderr @@ -3,6 +3,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Iterator for Newtype { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-22886.rs:14:17 + | +LL | type Item = &'a Box; + | ^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-29861.rs b/tests/ui/issues/issue-29861.rs index 875c168185feb..5aa8808d3f5a9 100644 --- a/tests/ui/issues/issue-29861.rs +++ b/tests/ui/issues/issue-29861.rs @@ -9,12 +9,13 @@ pub trait MakeRef2 { type Ref2; } impl<'a, T: 'a> MakeRef2 for T { -//~^ ERROR the lifetime parameter `'a` is not constrained + //~^ ERROR the lifetime parameter `'a` is not constrained type Ref2 = >::Ref; } -fn foo() -> ::Ref2 { &String::from("foo") } -//~^ ERROR temporary value dropped while borrowed +fn foo() -> ::Ref2 { + &String::from("foo") +} fn main() { println!("{}", foo()); diff --git a/tests/ui/issues/issue-29861.stderr b/tests/ui/issues/issue-29861.stderr index a25cbf0515d84..52f9a59959416 100644 --- a/tests/ui/issues/issue-29861.stderr +++ b/tests/ui/issues/issue-29861.stderr @@ -3,19 +3,13 @@ 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[E0716]: temporary value dropped while borrowed - --> $DIR/issue-29861.rs:16:43 | -LL | fn foo() -> ::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 +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-29861.rs:13:17 | - = note: consider using a `let` binding to create a longer lived value +LL | type Ref2 = >::Ref; + | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0716. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/issues/issue-35139.stderr b/tests/ui/issues/issue-35139.stderr index 875af70483224..ee30a6c42a507 100644 --- a/tests/ui/issues/issue-35139.stderr +++ b/tests/ui/issues/issue-35139.stderr @@ -3,6 +3,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> MethodType for MTFn { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-35139.rs:10:20 + | +LL | type GetProp = dyn fmt::Debug + 'a; + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error 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 9800420072be4..6cffa7c5073ee 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 @@ -72,16 +72,6 @@ LL | type W: Ord 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[E0658]: inherent associated types are unstable - --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5 - | -LL | type W where Self: Eq; - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 for more information - = 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[E0277]: the trait bound `X: Eq` is not satisfied --> $DIR/impl-item-type-no-body-semantic-fail.rs:13:23 | @@ -99,6 +89,16 @@ help: add `#![feature(trivial_bounds)]` to the crate attributes to enable LL + #![feature(trivial_bounds)] | +error[E0658]: inherent associated types are unstable + --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5 + | +LL | type W where Self: Eq; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 for more information + = 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[E0277]: the trait bound `X: Eq` is not satisfied --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:18 | diff --git a/tests/ui/traits/const-traits/tilde-const-invalid-places.rs b/tests/ui/traits/const-traits/tilde-const-invalid-places.rs index 9d220686771ec..7d77fdd055a36 100644 --- a/tests/ui/traits/const-traits/tilde-const-invalid-places.rs +++ b/tests/ui/traits/const-traits/tilde-const-invalid-places.rs @@ -42,7 +42,6 @@ struct Implementor; impl Implementor { type Type = (); //~ ERROR `~const` is not allowed - //~^ ERROR inherent associated types are unstable fn non_const_function() {} //~ ERROR `~const` is not allowed const CONSTANT: () = (); //~ ERROR `~const` is not allowed //~^ ERROR generic const items are experimental diff --git a/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr b/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr index 8151b9aaa23de..126c0849ab7a6 100644 --- a/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr +++ b/tests/ui/traits/const-traits/tilde-const-invalid-places.stderr @@ -155,19 +155,19 @@ LL | type Type = (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:46:30 + --> $DIR/tilde-const-invalid-places.rs:45:30 | LL | fn non_const_function() {} | ^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/tilde-const-invalid-places.rs:46:8 + --> $DIR/tilde-const-invalid-places.rs:45:8 | LL | fn non_const_function() {} | ^^^^^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:47:23 + --> $DIR/tilde-const-invalid-places.rs:46:23 | LL | const CONSTANT: () = (); | ^^^^^^ @@ -175,49 +175,49 @@ LL | const CONSTANT: () = (); = note: this item cannot have `~const` trait bounds error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:52:15 + --> $DIR/tilde-const-invalid-places.rs:51:15 | LL | trait Child0: ~const Trait {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/tilde-const-invalid-places.rs:52:1 + --> $DIR/tilde-const-invalid-places.rs:51:1 | LL | trait Child0: ~const Trait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:53:26 + --> $DIR/tilde-const-invalid-places.rs:52:26 | LL | trait Child1 where Self: ~const Trait {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/tilde-const-invalid-places.rs:53:1 + --> $DIR/tilde-const-invalid-places.rs:52:1 | LL | trait Child1 where Self: ~const Trait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:56:9 + --> $DIR/tilde-const-invalid-places.rs:55:9 | LL | impl Trait for T {} | ^^^^^^ | note: this impl is not `const`, so it cannot have `~const` trait bounds - --> $DIR/tilde-const-invalid-places.rs:56:1 + --> $DIR/tilde-const-invalid-places.rs:55:1 | LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:59:9 + --> $DIR/tilde-const-invalid-places.rs:58:9 | LL | impl Struct {} | ^^^^^^ | note: inherent impls cannot have `~const` trait bounds - --> $DIR/tilde-const-invalid-places.rs:59:1 + --> $DIR/tilde-const-invalid-places.rs:58:1 | LL | impl Struct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | const CONSTANT: () = (); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: generic const items are experimental - --> $DIR/tilde-const-invalid-places.rs:47:19 + --> $DIR/tilde-const-invalid-places.rs:46:19 | LL | const CONSTANT: () = (); | ^^^^^^^^^^^^^^^^^ @@ -294,17 +294,7 @@ note: required by a bound in `NonConstTrait::Type` LL | type Type: ~const Trait; | ^^^^^^^^^^^^ required by this bound in `NonConstTrait::Type` -error[E0658]: inherent associated types are unstable - --> $DIR/tilde-const-invalid-places.rs:44:5 - | -LL | type Type = (); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #8995 for more information - = 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: aborting due to 30 previous errors +error: aborting due to 29 previous errors Some errors have detailed explanations: E0275, E0392, E0658, E0740. For more information about an error, try `rustc --explain E0275`. 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 f62dccff58d0d..7c7c68ad60afe 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,7 +20,6 @@ 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 e6b94c525ff23..e31dcfcf7f489 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 @@ -3,17 +3,13 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, I> UnwrapItemsExt for I { | ^^ unconstrained lifetime parameter - -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 {} - | ^^^^^^^^^^^ +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/assoc-type-lifetime-unconstrained.rs:19:17 + | +LL | type Iter = impl MyTrait<'a>; + | ^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0792. -For more information about an error, try `rustc --explain E0207`. +For more information about this 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 e556025adee6e..f582592e9bcc8 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-74761-2.rs @@ -10,7 +10,6 @@ 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 26babc29000c0..31f4c05415866 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr @@ -3,23 +3,25 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-74761-2.rs:10:14 + | +LL | type B = impl core::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^ error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-74761-2.rs:7:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter - -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 {} - | ^^ +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-74761-2.rs:10:14 + | +LL | type B = impl core::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0207, E0792. -For more information about an error, try `rustc --explain E0207`. +For more information about this 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 e556025adee6e..f582592e9bcc8 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761.rs +++ b/tests/ui/type-alias-impl-trait/issue-74761.rs @@ -10,7 +10,6 @@ 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 a4826c293467e..6171cc9fefef1 100644 --- a/tests/ui/type-alias-impl-trait/issue-74761.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74761.stderr @@ -3,23 +3,25 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-74761.rs:10:14 + | +LL | type B = impl core::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^ error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-74761.rs:7:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter - -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 {} - | ^^ +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/issue-74761.rs:10:14 + | +LL | type B = impl core::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0207, E0792. -For more information about an error, try `rustc --explain E0207`. +For more information about this 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 b232097fdb332..296a3f3e30072 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,7 +12,6 @@ impl<'a, I: Iterator> Trait for (i32, I) { type Associated = (i32, impl Iterator); 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 5f9c56f1ca9d0..745214db531e8 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 @@ -3,17 +3,13 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a, I: Iterator> Trait for (i32, I) { | ^^ unconstrained lifetime parameter - -error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:14:9 | -LL | impl<'a, I: Iterator> Trait for (i32, I) { - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | (0_i32, [0_i32].iter().copied()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:12:29 + | +LL | type Associated = (i32, impl Iterator); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0792. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr index 6206f169c5b9e..c702814dbadcd 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr +++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr @@ -3,6 +3,12 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> Trait for Opaque<&'a str> { | ^^ unconstrained lifetime parameter + | +help: this use of an otherwise unconstrained lifetime is not allowed + --> $DIR/unconstrained-impl-param.rs:13:18 + | +LL | type Assoc = &'a str; + | ^^^^^^^ error: aborting due to 1 previous error From 074fff26ccde54e07d274816ea9a1864ef7a4827 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Sat, 20 Jul 2024 13:12:25 +0000 Subject: [PATCH 3/4] Perform unconstrained param detection in explicit_predicates_of and taint the query result --- .../src/collect/predicates_of.rs | 27 ++++++++--- compiler/rustc_hir_analysis/src/delegation.rs | 1 + .../rustc_hir_analysis/src/impl_wf_check.rs | 22 ++------- compiler/rustc_middle/src/ty/generics.rs | 5 +- compiler/rustc_smir/src/rustc_smir/context.rs | 6 ++- src/librustdoc/clean/auto_trait.rs | 7 ++- src/librustdoc/clean/mod.rs | 1 + ...d_in_impl_with_unconstrained_type_param.rs | 20 ++++++++ ..._impl_with_unconstrained_type_param.stderr | 9 ++++ .../unconstrained_const_param_on_drop.stderr | 18 +++---- tests/ui/impl-unused-tps.stderr | 48 +++++++++---------- 11 files changed, 103 insertions(+), 61 deletions(-) create mode 100644 tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.rs create mode 100644 tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ca2597e79fd14..da0daf55a9c93 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -6,7 +6,8 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::{ - self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast, + self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, + TypeVisitor, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; @@ -107,6 +108,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen return ty::GenericPredicates { parent: Some(tcx.parent(def_id.to_def_id())), predicates: tcx.arena.alloc_from_iter(predicates), + errored_due_to_unconstrained_params: Ok(()), }; } @@ -128,6 +130,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen return ty::GenericPredicates { parent: Some(impl_def_id), predicates: tcx.arena.alloc_from_iter(impl_predicates), + errored_due_to_unconstrained_params: trait_assoc_predicates + .errored_due_to_unconstrained_params, }; } @@ -153,6 +157,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // We use an `IndexSet` to preserve order of insertion. // Preserving the order of insertion is important here so as not to break UI tests. let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default(); + let mut errored_due_to_unconstrained_params = Ok(()); let hir_generics = node.generics().unwrap_or(NO_GENERICS); if let Node::Item(item) = node { @@ -319,11 +324,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { let self_ty = tcx.type_of(def_id).instantiate_identity(); let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::instantiate_identity); - cgp::setup_constraining_predicates( - tcx, - &mut predicates, - trait_ref, - &mut cgp::parameters_for_impl(tcx, self_ty, trait_ref), + let mut input_parameters = cgp::parameters_for_impl(tcx, self_ty, trait_ref); + cgp::setup_constraining_predicates(tcx, &mut predicates, trait_ref, &mut input_parameters); + errored_due_to_unconstrained_params = errored_due_to_unconstrained_params.and( + self_ty.error_reported().and(trait_ref.error_reported()).and_then(|()| { + crate::impl_wf_check::enforce_impl_params_are_constrained( + tcx, + def_id, + input_parameters, + ) + }), ); } @@ -338,6 +348,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ty::GenericPredicates { parent: generics.parent, predicates: tcx.arena.alloc_from_iter(predicates), + errored_due_to_unconstrained_params, } } @@ -507,6 +518,8 @@ pub(super) fn explicit_predicates_of<'tcx>( ty::GenericPredicates { parent: predicates_and_bounds.parent, predicates: tcx.arena.alloc_slice(&predicates), + errored_due_to_unconstrained_params: predicates_and_bounds + .errored_due_to_unconstrained_params, } } } else { @@ -558,6 +571,8 @@ pub(super) fn explicit_predicates_of<'tcx>( return GenericPredicates { parent: parent_preds.parent, predicates: { tcx.arena.alloc_from_iter(filtered_predicates) }, + errored_due_to_unconstrained_params: parent_preds + .errored_due_to_unconstrained_params, }; } gather_explicit_predicates_of(tcx, def_id) diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index e65420ea8bf44..b98732c872c3c 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -278,6 +278,7 @@ impl<'tcx> PredicatesBuilder<'tcx> { ty::GenericPredicates { parent: self.parent, predicates: self.tcx.arena.alloc_from_iter(preds), + errored_due_to_unconstrained_params: Ok(()), } } } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index f6968f9b3e2fc..178b96ccd5b45 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -11,10 +11,11 @@ use std::assert_matches::debug_assert_matches; use min_specialization::check_min_specialization; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::ErrorGuaranteed; use crate::constrained_generic_params as cgp; @@ -59,7 +60,7 @@ pub(crate) fn check_impl_wf( let min_specialization = tcx.features().min_specialization(); let mut res = Ok(()); debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }); - res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id)); + res = res.and(tcx.explicit_predicates_of(impl_def_id).errored_due_to_unconstrained_params); if min_specialization { res = res.and(check_min_specialization(tcx, impl_def_id)); } @@ -67,26 +68,13 @@ pub(crate) fn check_impl_wf( res } -fn enforce_impl_params_are_constrained( +pub(crate) fn enforce_impl_params_are_constrained( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, + input_parameters: FxHashSet, ) -> Result<(), ErrorGuaranteed> { // Every lifetime used in an associated type must be constrained. - let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); - impl_self_ty.error_reported()?; let impl_generics = tcx.generics_of(impl_def_id); - let impl_predicates = tcx.predicates_of(impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); - - impl_trait_ref.error_reported()?; - - let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref); - cgp::identify_constrained_generic_params( - tcx, - impl_predicates, - impl_trait_ref, - &mut input_parameters, - ); let mut res = Ok(()); for param in &impl_generics.own_params { diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index ce40ab182613c..6a2bb164b53b1 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -2,7 +2,7 @@ use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use rustc_span::symbol::{Symbol, kw}; use tracing::instrument; @@ -356,10 +356,11 @@ impl<'tcx> Generics { } /// Bounds on generics. -#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)] +#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub struct GenericPredicates<'tcx> { pub parent: Option, pub predicates: &'tcx [(Clause<'tcx>, Span)], + pub errored_due_to_unconstrained_params: Result<(), ErrorGuaranteed>, } impl<'tcx> GenericPredicates<'tcx> { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 9025b47c422dd..d055ed0bb2d9c 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -175,7 +175,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id); + let GenericPredicates { parent, predicates, errored_due_to_unconstrained_params: _ } = + tables.tcx.predicates_of(def_id); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), predicates: predicates @@ -196,7 +197,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ) -> stable_mir::ty::GenericPredicates { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.explicit_predicates_of(def_id); + let GenericPredicates { parent, predicates, errored_due_to_unconstrained_params: _ } = + tables.tcx.explicit_predicates_of(def_id); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), predicates: predicates diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 185898c31b75b..7f1a7873fc1e4 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -105,7 +105,12 @@ fn synthesize_auto_trait_impl<'tcx>( let mut generics = clean_ty_generics( cx, tcx.generics_of(item_def_id), - ty::GenericPredicates::default(), + ty::GenericPredicates { + parent: None, + predicates: &[], + effects_min_tys: ty::List::empty(), + errored_due_to_unconstrained_params: Ok(()), + }, ); generics.where_predicates.clear(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 34141c47cf3d4..9ea7d393af540 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1404,6 +1404,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), ty::GenericPredicates { parent: None, predicates, + errored_due_to_unconstrained_params: Ok(()), }); simplify::move_bounds_to_generic_parameters(&mut generics); diff --git a/tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.rs b/tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.rs new file mode 100644 index 0000000000000..0d2b89ea7ca3d --- /dev/null +++ b/tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.rs @@ -0,0 +1,20 @@ +//! This test used to ICE when trying to resolve the method call in the `test` function. + +mod foo { + pub trait Callable { + type Output; + fn call() -> Self::Output; + } + + impl<'a, V: ?Sized> Callable for &'a () { + //~^ ERROR: `V` is not constrained + type Output = (); + } +} +use foo::*; + +fn test<'a>() -> impl Sized { + <&'a () as Callable>::call() +} + +fn main() {} diff --git a/tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.stderr b/tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.stderr new file mode 100644 index 0000000000000..6998e1b1abc1c --- /dev/null +++ b/tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates + --> $DIR/missing_method_in_impl_with_unconstrained_type_param.rs:9:14 + | +LL | impl<'a, V: ?Sized> Callable for &'a () { + | ^ unconstrained type parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr index 851888534eeb2..a63539fd67579 100644 --- a/tests/ui/dropck/unconstrained_const_param_on_drop.stderr +++ b/tests/ui/dropck/unconstrained_const_param_on_drop.stderr @@ -1,3 +1,12 @@ +error[E0207]: the const parameter `UNUSED` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained_const_param_on_drop.rs:3:6 + | +LL | impl Drop for Foo {} + | ^^^^^^^^^^^^^^^^^^^ unconstrained const parameter + | + = 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[E0367]: `Drop` impl requires `the constant `_` has type `usize`` but the struct it is implemented for does not --> $DIR/unconstrained_const_param_on_drop.rs:3:6 | @@ -10,15 +19,6 @@ note: the implementor must specify the same requirement LL | struct Foo {} | ^^^^^^^^^^ -error[E0207]: the const parameter `UNUSED` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained_const_param_on_drop.rs:3:6 - | -LL | impl Drop for Foo {} - | ^^^^^^^^^^^^^^^^^^^ unconstrained const parameter - | - = 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 Some errors have detailed explanations: E0207, E0367. diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/impl-unused-tps.stderr index da4589dee8278..2c5414b360550 100644 --- a/tests/ui/impl-unused-tps.stderr +++ b/tests/ui/impl-unused-tps.stderr @@ -1,3 +1,27 @@ +error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/impl-unused-tps.rs:49:9 + | +LL | impl Foo for T + | ^ unconstrained type parameter + +error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates + --> $DIR/impl-unused-tps.rs:49:12 + | +LL | impl Foo for T + | ^ unconstrained type parameter + +error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/impl-unused-tps.rs:32:9 + | +LL | impl Bar for T { + | ^ unconstrained type parameter + +error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/impl-unused-tps.rs:40:9 + | +LL | impl Bar for T + | ^ unconstrained type parameter + error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]` --> $DIR/impl-unused-tps.rs:28:1 | @@ -46,30 +70,6 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self LL | impl Foo for [isize; 1] { | ^ unconstrained type parameter -error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:32:9 - | -LL | impl Bar for T { - | ^ unconstrained type parameter - -error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:40:9 - | -LL | impl Bar for T - | ^ unconstrained type parameter - -error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:49:9 - | -LL | impl Foo for T - | ^ unconstrained type parameter - -error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:49:12 - | -LL | impl Foo for T - | ^ unconstrained type parameter - error: aborting due to 9 previous errors Some errors have detailed explanations: E0119, E0207. From 5cffc1ea2bcabeb4a44c67fe836f68e9621d9196 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 24 Jul 2024 08:55:49 +0000 Subject: [PATCH 4/4] Taint obligations in confirmation --- .../rustc_hir_typeck/src/method/suggest.rs | 4 ++ compiler/rustc_middle/src/ty/generic_args.rs | 9 +++ .../src/traits/select/mod.rs | 12 ++++ tests/crashes/123141.rs | 23 ------- tests/crashes/125874.rs | 22 ------ tests/crashes/126942.rs | 11 --- .../unconstrained_impl_param.rs | 18 +++++ .../unconstrained_impl_param.stderr | 9 +++ .../post-analysis-user-facing-param-env.rs | 1 - ...post-analysis-user-facing-param-env.stderr | 19 +----- tests/ui/const-generics/kind_mismatch.rs | 1 + tests/ui/const-generics/kind_mismatch.stderr | 11 ++- tests/ui/const-generics/kind_mismatch2.rs | 14 ++++ tests/ui/const-generics/kind_mismatch2.stderr | 9 +++ .../bugs/issue-87735.stderr | 68 +------------------ .../in-trait/refine-resolution-errors.rs | 1 - .../in-trait/refine-resolution-errors.stderr | 11 +-- tests/ui/impl-trait/issues/issue-87340.rs | 2 - tests/ui/impl-trait/issues/issue-87340.stderr | 17 +---- ...e-failed-to-resolve-instance-for-110696.rs | 1 - ...iled-to-resolve-instance-for-110696.stderr | 15 +--- .../impl-with-unconstrained-param.rs | 2 - .../impl-with-unconstrained-param.stderr | 17 +---- tests/ui/type-alias-impl-trait/issue-74244.rs | 1 - .../type-alias-impl-trait/issue-74244.stderr | 11 +-- 25 files changed, 97 insertions(+), 212 deletions(-) delete mode 100644 tests/crashes/123141.rs delete mode 100644 tests/crashes/125874.rs delete mode 100644 tests/crashes/126942.rs create mode 100644 tests/ui/associated-item/unconstrained_impl_param.rs create mode 100644 tests/ui/associated-item/unconstrained_impl_param.stderr create mode 100644 tests/ui/const-generics/kind_mismatch2.rs create mode 100644 tests/ui/const-generics/kind_mismatch2.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 6b1a288510ac1..87cff28fc38f5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -598,6 +598,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let is_method = mode == Mode::MethodCall; let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; + if let Err(guar) = unsatisfied_predicates.error_reported() { + return guar; + } + let similar_candidate = no_match_data.similar_candidate; let item_kind = if is_method { "method" diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index fd84d75b53f3d..e99e206ecaf03 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -13,6 +13,7 @@ use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension}; use rustc_serialize::{Decodable, Encodable}; +use rustc_span::ErrorGuaranteed; use rustc_type_ir::WithCachedTypeInfo; use smallvec::SmallVec; @@ -300,6 +301,14 @@ impl<'tcx> GenericArg<'tcx> { GenericArgKind::Const(ct) => ct.is_ct_infer(), } } + + pub fn to_error(self, tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self { + match self.unpack() { + ty::GenericArgKind::Lifetime(_) => ty::Region::new_error(tcx, guar).into(), + ty::GenericArgKind::Type(_) => Ty::new_error(tcx, guar).into(), + ty::GenericArgKind::Const(_) => ty::Const::new_error(tcx, guar).into(), + } + } } impl<'a, 'tcx> Lift> for GenericArg<'a> { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 41a35c31fe432..e3008290d3fdd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2828,6 +2828,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // `$1: Copy`, so we must ensure the obligations are emitted in // that order. let predicates = tcx.predicates_of(def_id); + if let Err(guar) = predicates.errored_due_to_unconstrained_params { + self.infcx.set_tainted_by_errors(guar); + // Constrain any inference variables to their error variant to ensure unconstrained + // generic parameters don't leak as they'll never get constrained. + for arg in args { + let _ = self.infcx.at(cause, param_env).eq( + DefineOpaqueTypes::Yes, + arg, + arg.to_error(tcx, guar), + ); + } + } assert_eq!(predicates.parent, None); let predicates = predicates.instantiate_own(tcx, args); let mut obligations = PredicateObligations::with_capacity(predicates.len()); diff --git a/tests/crashes/123141.rs b/tests/crashes/123141.rs deleted file mode 100644 index 07181387e0450..0000000000000 --- a/tests/crashes/123141.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: #123141 - -trait Trait { - fn next(self) -> Self::Item; - type Item; -} - -struct Foo(T); - -impl Trait for Foo { - type Item = Foo; - fn next(self) -> Self::Item { - loop {} - } -} - -fn opaque() -> impl Trait { - Foo::<_>(10_u32) -} - -fn main() { - opaque().next(); -} diff --git a/tests/crashes/125874.rs b/tests/crashes/125874.rs deleted file mode 100644 index 6a2713cd7c896..0000000000000 --- a/tests/crashes/125874.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: rust-lang/rust#125874 -pub trait A {} - -pub trait Mirror { - type Assoc: ?Sized; -} -impl Mirror for dyn A { - type Assoc = T; -} - -struct Bar { - foo: ::Assoc, -} - -pub fn main() { - let strct = Bar { foo: 3 }; - - match strct { - Bar { foo: 1, .. } => {} - _ => (), - }; -} diff --git a/tests/crashes/126942.rs b/tests/crashes/126942.rs deleted file mode 100644 index e4adc8fab287e..0000000000000 --- a/tests/crashes/126942.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: rust-lang/rust#126942 -struct Thing; - -pub trait Every { - type Assoc; -} -impl Every for Thing { - type Assoc = T; -} - -static I: ::Assoc = 3; diff --git a/tests/ui/associated-item/unconstrained_impl_param.rs b/tests/ui/associated-item/unconstrained_impl_param.rs new file mode 100644 index 0000000000000..4a3cda6b4d6d4 --- /dev/null +++ b/tests/ui/associated-item/unconstrained_impl_param.rs @@ -0,0 +1,18 @@ +//! This test used to ICE during the normalization of +//! `I`'s type, because of the mismatch of generic parameters +//! on the impl with the generic parameters the projection can +//! fulfill. + +struct Thing; + +pub trait Every { + type Assoc; +} +impl Every for Thing { + //~^ ERROR: `T` is not constrained + type Assoc = T; +} + +static I: ::Assoc = 3; + +fn main() {} diff --git a/tests/ui/associated-item/unconstrained_impl_param.stderr b/tests/ui/associated-item/unconstrained_impl_param.stderr new file mode 100644 index 0000000000000..b7c76266cf237 --- /dev/null +++ b/tests/ui/associated-item/unconstrained_impl_param.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained_impl_param.rs:11:6 + | +LL | impl Every for Thing { + | ^ unconstrained type parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs index e5af632da7577..ee2fa8c810faa 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs @@ -10,7 +10,6 @@ where { fn unimplemented(self, _: &Foo) -> Self::Output { //~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add` - //~| ERROR type annotations needed loop {} } } diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr index ade18eb88b901..186d687b8d112 100644 --- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr +++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr @@ -3,7 +3,6 @@ error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add` | LL | / fn unimplemented(self, _: &Foo) -> Self::Output { LL | | -LL | | LL | | loop {} LL | | } | |_____^ not a member of trait `std::ops::Add` @@ -26,21 +25,7 @@ LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for 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[E0284]: type annotations needed - --> $DIR/post-analysis-user-facing-param-env.rs:11:40 - | -LL | fn unimplemented(self, _: &Foo) -> Self::Output { - | ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM` - | -note: required for `Foo` to implement `Add<&'a Foo>` - --> $DIR/post-analysis-user-facing-param-env.rs:6:28 - | -LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo - | ---------------- ^^^^^^^^^^^^^^^^^^^^^^ ^^^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284, E0407. +Some errors have detailed explanations: E0207, E0407. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/kind_mismatch.rs b/tests/ui/const-generics/kind_mismatch.rs index ecdc01a5ef901..d819dd462990a 100644 --- a/tests/ui/const-generics/kind_mismatch.rs +++ b/tests/ui/const-generics/kind_mismatch.rs @@ -20,4 +20,5 @@ pub fn remove_key>() -> S { fn main() { let map: KeyHolder<0> = remove_key::<_, _>(); + //~^ ERROR: type annotations needed } diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr index 1487b18961986..6649a4d9c80fd 100644 --- a/tests/ui/const-generics/kind_mismatch.stderr +++ b/tests/ui/const-generics/kind_mismatch.stderr @@ -14,6 +14,13 @@ LL | impl ContainsKey for KeyHolder {} | | | help: consider changing this type parameter to a const parameter: `const K: u8` -error: aborting due to 2 previous errors +error[E0282]: type annotations needed + --> $DIR/kind_mismatch.rs:22:29 + | +LL | let map: KeyHolder<0> = remove_key::<_, _>(); + | ^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `K` declared on the function `remove_key` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0282, E0747. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/const-generics/kind_mismatch2.rs b/tests/ui/const-generics/kind_mismatch2.rs new file mode 100644 index 0000000000000..9df9d15286e01 --- /dev/null +++ b/tests/ui/const-generics/kind_mismatch2.rs @@ -0,0 +1,14 @@ +struct Node {} + +impl Node<{ D }> +where + SmallVec:, //~ ERROR: constant provided when a type was expected +{ + fn new() {} +} + +struct SmallVec(T); + +fn main() { + Node::new(); +} diff --git a/tests/ui/const-generics/kind_mismatch2.stderr b/tests/ui/const-generics/kind_mismatch2.stderr new file mode 100644 index 0000000000000..6ad32f2763e83 --- /dev/null +++ b/tests/ui/const-generics/kind_mismatch2.stderr @@ -0,0 +1,9 @@ +error[E0747]: constant provided when a type was expected + --> $DIR/kind_mismatch2.rs:5:14 + | +LL | SmallVec:, + | ^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.stderr b/tests/ui/generic-associated-types/bugs/issue-87735.stderr index d80050652389d..1b95543136303 100644 --- a/tests/ui/generic-associated-types/bugs/issue-87735.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-87735.stderr @@ -22,73 +22,7 @@ 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 - | -- the parameter type `T` must be valid for the lifetime `'b` as defined here... -... -LL | T: AsRef2 = &'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 = &'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 - | -- 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 = &'b [U]> + 'b, - | ++++ - -error: lifetime may not live long enough - --> $DIR/issue-87735.rs:37:5 - | -LL | impl<'b, T, U> AsRef2 for Foo - | -- 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 - | -- 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 +error: aborting due to 2 previous errors 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/refine-resolution-errors.rs b/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs index a9936c7bc3fee..894f592d9e204 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs @@ -13,7 +13,6 @@ impl Mirror for () { pub trait First { async fn first() -> <() as Mirror>::Assoc; - //~^ ERROR type annotations needed } impl First for () { diff --git a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr index 0f5573dda04c1..10ebad2a7d5a1 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr @@ -4,13 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl Mirror for () { | ^ unconstrained type parameter -error[E0282]: type annotations needed - --> $DIR/refine-resolution-errors.rs:15:5 - | -LL | async fn first() -> <() as Mirror>::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0282. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/issues/issue-87340.rs b/tests/ui/impl-trait/issues/issue-87340.rs index b1baaaa6ba5c1..705a4addcb704 100644 --- a/tests/ui/impl-trait/issues/issue-87340.rs +++ b/tests/ui/impl-trait/issues/issue-87340.rs @@ -9,8 +9,6 @@ impl 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 1be4087be4242..8513cb2881e1f 100644 --- a/tests/ui/impl-trait/issues/issue-87340.stderr +++ b/tests/ui/impl-trait/issues/issue-87340.stderr @@ -4,19 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl X for () { | ^ unconstrained type parameter -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 +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0282. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs index 0ee188d825f0d..2bcb8f06f4fd6 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs @@ -42,7 +42,6 @@ impl>>, U> MyIndex> for Scope { //~^ ERROR the type parameter `T` is not constrained by the impl type O = T; fn my_index(self) -> Self::O { - //~^ ERROR item does not constrain MyFrom::my_from(self.0).ok().unwrap() } } diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr index eace96317dc1d..0ab4c34381a26 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr @@ -17,19 +17,6 @@ note: this opaque type is in the signature LL | type DummyT = impl F; | ^^^^^^ -error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature - --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:44:8 - | -LL | fn my_index(self) -> Self::O { - | ^^^^^^^^ - | - = note: consider moving the opaque type's declaration and defining uses into a separate module -note: this opaque type is in the signature - --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:20:18 - | -LL | type DummyT = impl F; - | ^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this 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 fcac83500ec4f..1824ff5e2fb82 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,8 +12,6 @@ impl 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 bb0e11d314c33..137a4db81b563 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,19 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl X for () { | ^ unconstrained type parameter -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 +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0282. -For more information about an error, try `rustc --explain E0207`. +For more information about this 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 ce8a38a3361f8..bb4104b3d2519 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.rs +++ b/tests/ui/type-alias-impl-trait/issue-74244.rs @@ -14,7 +14,6 @@ impl Allocator for DefaultAllocator { type A = impl Fn(::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 d2b50ffd86b59..f5ca56bacccf6 100644 --- a/tests/ui/type-alias-impl-trait/issue-74244.stderr +++ b/tests/ui/type-alias-impl-trait/issue-74244.stderr @@ -4,13 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self LL | impl Allocator for DefaultAllocator { | ^ unconstrained type parameter -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 +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0282. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0207`.