From abc838be131d0ac1be3ce8a694a6056473f89619 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 2 Apr 2025 14:17:13 +0200 Subject: [PATCH 1/3] rm RpitConstraintChecker we already collect opaque types from nested items during `mir_borrowck` of the root, checking that they are consistent this way. --- .../src/collect/type_of/opaque.rs | 72 ------------------- 1 file changed, 72 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 3dec1e286b4ef..8a3a6a8be1104 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -318,20 +318,6 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied(); if let Some(mir_opaque_ty) = mir_opaque_ty { - if mir_opaque_ty.references_error() { - return mir_opaque_ty.ty; - } - - debug!(?owner_def_id); - let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty }; - - match tcx.hir_node_by_def_id(owner_def_id) { - Node::Item(it) => intravisit::walk_item(&mut locator, it), - Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it), - Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it), - other => bug!("{:?} is not a valid scope for an opaque type item", other), - } - mir_opaque_ty.ty } else if let Some(guar) = tables.tainted_by_errors { // Some error in the owner fn prevented us from populating @@ -352,61 +338,3 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( } } } - -struct RpitConstraintChecker<'tcx> { - tcx: TyCtxt<'tcx>, - - /// def_id of the opaque type whose defining uses are being checked - def_id: LocalDefId, - - found: ty::OpaqueHiddenType<'tcx>, -} - -impl RpitConstraintChecker<'_> { - #[instrument(skip(self), level = "debug")] - fn check(&self, def_id: LocalDefId) { - // Use borrowck to get the type with unerased regions. - let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types; - debug!(?concrete_opaque_types); - if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) { - debug!(?concrete_type, "found constraint"); - if concrete_type.ty != self.found.ty { - if let Ok(d) = self.found.build_mismatch_error(&concrete_type, self.tcx) { - d.emit(); - } - } - } - } -} - -impl<'tcx> intravisit::Visitor<'tcx> for RpitConstraintChecker<'tcx> { - type NestedFilter = nested_filter::OnlyBodies; - - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { - self.tcx - } - fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { - intravisit::walk_expr(self, ex); - } - fn visit_item(&mut self, it: &'tcx Item<'tcx>) { - trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_item(self, it); - } - } - fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) { - trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_impl_item(self, it); - } - } - fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) { - trace!(?it.owner_id); - self.check(it.owner_id.def_id); - intravisit::walk_trait_item(self, it); - } -} From 990201cb78a77ec0c148a880e6ab46bafa3468df Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 1 Apr 2025 23:34:00 +0200 Subject: [PATCH 2/3] move `check_opaque_type_parameter_valid` --- compiler/rustc_borrowck/messages.ftl | 7 - .../src/region_infer/opaque_types.rs | 167 +----------------- .../rustc_borrowck/src/session_diagnostics.rs | 11 -- compiler/rustc_trait_selection/messages.ftl | 7 + compiler/rustc_trait_selection/src/errors.rs | 13 +- compiler/rustc_trait_selection/src/lib.rs | 1 + .../rustc_trait_selection/src/opaque_types.rs | 165 +++++++++++++++++ 7 files changed, 189 insertions(+), 182 deletions(-) create mode 100644 compiler/rustc_trait_selection/src/opaque_types.rs diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index ada20e5c614f8..33b80c4b03d6f 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -162,13 +162,6 @@ borrowck_opaque_type_lifetime_mismatch = .prev_lifetime_label = lifetime `{$prev}` previously used here .note = if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types -borrowck_opaque_type_non_generic_param = - expected generic {$kind} parameter, found `{$ty}` - .label = {STREQ($ty, "'static") -> - [true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type - *[other] this generic parameter must be used with a generic {$kind} parameter - } - borrowck_partial_var_move_by_use_in_closure = variable {$is_partial -> [true] partially moved diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index ca8b9fb4e9d82..2f15c2bc46447 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,22 +1,16 @@ use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::ErrorGuaranteed; -use rustc_hir::OpaqueTyOrigin; -use rustc_hir::def_id::LocalDefId; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _}; +use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_macros::extension; use rustc_middle::ty::{ - self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, - TypeVisitableExt, TypingMode, fold_regions, + self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions, }; use rustc_span::Span; -use rustc_trait_selection::regions::OutlivesEnvironmentBuildExt; -use rustc_trait_selection::traits::ObligationCtxt; +use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid; use tracing::{debug, instrument}; use super::RegionInferenceContext; use crate::opaque_types::ConcreteOpaqueTypes; -use crate::session_diagnostics::{LifetimeMismatchOpaqueParam, NonGenericOpaqueTypeParam}; +use crate::session_diagnostics::LifetimeMismatchOpaqueParam; use crate::universal_regions::RegionClassification; impl<'tcx> RegionInferenceContext<'tcx> { @@ -289,156 +283,3 @@ impl<'tcx> InferCtxt<'tcx> { definition_ty } } - -/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter]. -/// -/// [rustc-dev-guide chapter]: -/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html -fn check_opaque_type_parameter_valid<'tcx>( - infcx: &InferCtxt<'tcx>, - opaque_type_key: OpaqueTypeKey<'tcx>, - span: Span, -) -> Result<(), ErrorGuaranteed> { - let tcx = infcx.tcx; - let opaque_generics = tcx.generics_of(opaque_type_key.def_id); - let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); - let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); - - for (i, arg) in opaque_type_key.iter_captured_args(tcx) { - let arg_is_param = match arg.unpack() { - GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), - GenericArgKind::Lifetime(lt) => { - matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) - || (lt.is_static() && opaque_env.param_equal_static(i)) - } - GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), - }; - - if arg_is_param { - // Register if the same lifetime appears multiple times in the generic args. - // There is an exception when the opaque type *requires* the lifetimes to be equal. - // See [rustc-dev-guide chapter] § "An exception to uniqueness rule". - let seen_where = seen_params.entry(arg).or_default(); - if !seen_where.first().is_some_and(|&prev_i| opaque_env.params_equal(i, prev_i)) { - seen_where.push(i); - } - } else { - // Prevent `fn foo() -> Foo` from being defining. - let opaque_param = opaque_generics.param_at(i, tcx); - let kind = opaque_param.kind.descr(); - - opaque_env.param_is_error(i)?; - - return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam { - ty: arg, - kind, - span, - param_span: tcx.def_span(opaque_param.def_id), - })); - } - } - - for (_, indices) in seen_params { - if indices.len() > 1 { - let descr = opaque_generics.param_at(indices[0], tcx).kind.descr(); - let spans: Vec<_> = indices - .into_iter() - .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) - .collect(); - #[allow(rustc::diagnostic_outside_of_impl)] - #[allow(rustc::untranslatable_diagnostic)] - return Err(infcx - .dcx() - .struct_span_err(span, "non-defining opaque type use in defining scope") - .with_span_note(spans, format!("{descr} used multiple times")) - .emit()); - } - } - - Ok(()) -} - -/// Computes if an opaque type requires a lifetime parameter to be equal to -/// another one or to the `'static` lifetime. -/// These requirements are derived from the explicit and implied bounds. -struct LazyOpaqueTyEnv<'tcx> { - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, - - /// Equal parameters will have the same name. Computed Lazily. - /// Example: - /// `type Opaque<'a: 'static, 'b: 'c, 'c: 'b> = impl Sized;` - /// Identity args: `['a, 'b, 'c]` - /// Canonical args: `['static, 'b, 'b]` - canonical_args: std::cell::OnceCell>, -} - -impl<'tcx> LazyOpaqueTyEnv<'tcx> { - fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { - Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() } - } - - fn param_equal_static(&self, param_index: usize) -> bool { - self.get_canonical_args()[param_index].expect_region().is_static() - } - - fn params_equal(&self, param1: usize, param2: usize) -> bool { - let canonical_args = self.get_canonical_args(); - canonical_args[param1] == canonical_args[param2] - } - - fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> { - self.get_canonical_args()[param_index].error_reported() - } - - fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> { - if let Some(&canonical_args) = self.canonical_args.get() { - return canonical_args; - } - - let &Self { tcx, def_id, .. } = self; - let origin = tcx.local_opaque_ty_origin(def_id); - let parent = match origin { - OpaqueTyOrigin::FnReturn { parent, .. } - | OpaqueTyOrigin::AsyncFn { parent, .. } - | OpaqueTyOrigin::TyAlias { parent, .. } => parent, - }; - let param_env = tcx.param_env(parent); - let args = GenericArgs::identity_for_item(tcx, parent).extend_to( - tcx, - def_id.to_def_id(), - |param, _| { - tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into() - }, - ); - - // FIXME(#132279): It feels wrong to use `non_body_analysis` here given that we're - // in a body here. - let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); - let ocx = ObligationCtxt::new(&infcx); - - let wf_tys = ocx.assumed_wf_types(param_env, parent).unwrap_or_else(|_| { - tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds"); - Default::default() - }); - let outlives_env = OutlivesEnvironment::new(&infcx, parent, param_env, wf_tys); - - let mut seen = vec![tcx.lifetimes.re_static]; - let canonical_args = fold_regions(tcx, args, |r1, _| { - if r1.is_error() { - r1 - } else if let Some(&r2) = seen.iter().find(|&&r2| { - let free_regions = outlives_env.free_region_map(); - free_regions.sub_free_regions(tcx, r1, r2) - && free_regions.sub_free_regions(tcx, r2, r1) - }) { - r2 - } else { - seen.push(r1); - r1 - } - }); - self.canonical_args.set(canonical_args).unwrap(); - canonical_args - } -} diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 4be5d0dbf4284..5143b2fa20598 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -294,17 +294,6 @@ pub(crate) struct MoveBorrow<'a> { pub borrow_span: Span, } -#[derive(Diagnostic)] -#[diag(borrowck_opaque_type_non_generic_param, code = E0792)] -pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> { - pub ty: GenericArg<'tcx>, - pub kind: &'a str, - #[primary_span] - pub span: Span, - #[label] - pub param_span: Span, -} - #[derive(Diagnostic)] #[diag(borrowck_opaque_type_lifetime_mismatch)] pub(crate) struct LifetimeMismatchOpaqueParam<'tcx> { diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 4db9d9915b139..05bbb42fb7c63 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -264,8 +264,15 @@ trait_selection_oc_no_diverge = `else` clause of `let...else` does not diverge trait_selection_oc_no_else = `if` may be missing an `else` clause trait_selection_oc_try_compat = `?` operator has incompatible types trait_selection_oc_type_compat = type not compatible with trait + trait_selection_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds .label = opaque type defined here +trait_selection_opaque_type_non_generic_param = + expected generic {$kind} parameter, found `{$ty}` + .label = {STREQ($ty, "'static") -> + [true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type + *[other] this generic parameter must be used with a generic {$kind} parameter + } trait_selection_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type trait_selection_outlives_content = lifetime of reference outlives lifetime of borrowed content... diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index b30390a9330eb..9f7bfe5101ab2 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -12,7 +12,7 @@ use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty}; use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, IsAnonInPath, Node}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath}; -use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, Region, Ty, TyCtxt}; +use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, GenericArg, Region, Ty, TyCtxt}; use rustc_span::{BytePos, Ident, Span, Symbol, kw}; use crate::error_reporting::infer::ObligationCauseAsDiagArg; @@ -1922,3 +1922,14 @@ impl Subdiagnostic for AddPreciseCapturingForOvercapture { } } } + +#[derive(Diagnostic)] +#[diag(trait_selection_opaque_type_non_generic_param, code = E0792)] +pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> { + pub ty: GenericArg<'tcx>, + pub kind: &'a str, + #[primary_span] + pub span: Span, + #[label] + pub param_span: Span, +} diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index b18fb0fb8fd31..93c1180530452 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -36,6 +36,7 @@ pub mod error_reporting; pub mod errors; pub mod infer; +pub mod opaque_types; pub mod regions; pub mod solve; pub mod traits; diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs new file mode 100644 index 0000000000000..5af912fee5492 --- /dev/null +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -0,0 +1,165 @@ +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::OpaqueTyOrigin; +use rustc_hir::def_id::LocalDefId; +use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_middle::ty::{ + self, GenericArgKind, GenericArgs, OpaqueTypeKey, TyCtxt, TypeVisitableExt, + TypingMode, fold_regions, +}; +use rustc_span::{ErrorGuaranteed, Span}; + +use crate::errors::NonGenericOpaqueTypeParam; +use crate::regions::OutlivesEnvironmentBuildExt; +use crate::traits::ObligationCtxt; + +/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter]. +/// +/// [rustc-dev-guide chapter]: +/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html +pub fn check_opaque_type_parameter_valid<'tcx>( + infcx: &InferCtxt<'tcx>, + opaque_type_key: OpaqueTypeKey<'tcx>, + span: Span, +) -> Result<(), ErrorGuaranteed> { + let tcx = infcx.tcx; + let opaque_generics = tcx.generics_of(opaque_type_key.def_id); + let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); + let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); + + for (i, arg) in opaque_type_key.iter_captured_args(tcx) { + let arg_is_param = match arg.unpack() { + GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), + GenericArgKind::Lifetime(lt) => { + matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) + || (lt.is_static() && opaque_env.param_equal_static(i)) + } + GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), + }; + + if arg_is_param { + // Register if the same lifetime appears multiple times in the generic args. + // There is an exception when the opaque type *requires* the lifetimes to be equal. + // See [rustc-dev-guide chapter] § "An exception to uniqueness rule". + let seen_where = seen_params.entry(arg).or_default(); + if !seen_where.first().is_some_and(|&prev_i| opaque_env.params_equal(i, prev_i)) { + seen_where.push(i); + } + } else { + // Prevent `fn foo() -> Foo` from being defining. + let opaque_param = opaque_generics.param_at(i, tcx); + let kind = opaque_param.kind.descr(); + + opaque_env.param_is_error(i)?; + + return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam { + ty: arg, + kind, + span, + param_span: tcx.def_span(opaque_param.def_id), + })); + } + } + + for (_, indices) in seen_params { + if indices.len() > 1 { + let descr = opaque_generics.param_at(indices[0], tcx).kind.descr(); + let spans: Vec<_> = indices + .into_iter() + .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) + .collect(); + return Err(infcx + .dcx() + .struct_span_err(span, "non-defining opaque type use in defining scope") + .with_span_note(spans, format!("{descr} used multiple times")) + .emit()); + } + } + + Ok(()) +} + +/// Computes if an opaque type requires a lifetime parameter to be equal to +/// another one or to the `'static` lifetime. +/// These requirements are derived from the explicit and implied bounds. +struct LazyOpaqueTyEnv<'tcx> { + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + + /// Equal parameters will have the same name. Computed Lazily. + /// Example: + /// `type Opaque<'a: 'static, 'b: 'c, 'c: 'b> = impl Sized;` + /// Identity args: `['a, 'b, 'c]` + /// Canonical args: `['static, 'b, 'b]` + canonical_args: std::cell::OnceCell>, +} + +impl<'tcx> LazyOpaqueTyEnv<'tcx> { + fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() } + } + + fn param_equal_static(&self, param_index: usize) -> bool { + self.get_canonical_args()[param_index].expect_region().is_static() + } + + fn params_equal(&self, param1: usize, param2: usize) -> bool { + let canonical_args = self.get_canonical_args(); + canonical_args[param1] == canonical_args[param2] + } + + fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> { + self.get_canonical_args()[param_index].error_reported() + } + + fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> { + if let Some(&canonical_args) = self.canonical_args.get() { + return canonical_args; + } + + let &Self { tcx, def_id, .. } = self; + let origin = tcx.local_opaque_ty_origin(def_id); + let parent = match origin { + OpaqueTyOrigin::FnReturn { parent, .. } + | OpaqueTyOrigin::AsyncFn { parent, .. } + | OpaqueTyOrigin::TyAlias { parent, .. } => parent, + }; + let param_env = tcx.param_env(parent); + let args = GenericArgs::identity_for_item(tcx, parent).extend_to( + tcx, + def_id.to_def_id(), + |param, _| { + tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into() + }, + ); + + // FIXME(#132279): It feels wrong to use `non_body_analysis` here given that we're + // in a body here. + let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); + let ocx = ObligationCtxt::new(&infcx); + + let wf_tys = ocx.assumed_wf_types(param_env, parent).unwrap_or_else(|_| { + tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds"); + Default::default() + }); + let outlives_env = OutlivesEnvironment::new(&infcx, parent, param_env, wf_tys); + + let mut seen = vec![tcx.lifetimes.re_static]; + let canonical_args = fold_regions(tcx, args, |r1, _| { + if r1.is_error() { + r1 + } else if let Some(&r2) = seen.iter().find(|&&r2| { + let free_regions = outlives_env.free_region_map(); + free_regions.sub_free_regions(tcx, r1, r2) + && free_regions.sub_free_regions(tcx, r2, r1) + }) { + r2 + } else { + seen.push(r1); + r1 + } + }); + self.canonical_args.set(canonical_args).unwrap(); + canonical_args + } +} From 509a144eed84e6ccd1227cd0d90f877a774aae70 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 1 Apr 2025 23:48:41 +0200 Subject: [PATCH 3/3] add `TypingMode::Borrowck` --- compiler/rustc_borrowck/src/lib.rs | 38 +-- .../src/region_infer/opaque_types.rs | 18 +- compiler/rustc_hir_analysis/src/collect.rs | 1 + .../rustc_hir_analysis/src/collect/type_of.rs | 59 +++- .../src/collect/type_of/opaque.rs | 261 +++++++----------- compiler/rustc_hir_typeck/src/writeback.rs | 51 +++- compiler/rustc_infer/src/infer/mod.rs | 6 +- .../rustc_infer/src/infer/opaque_types/mod.rs | 35 ++- compiler/rustc_middle/src/query/mod.rs | 8 + compiler/rustc_middle/src/ty/context.rs | 8 + compiler/rustc_middle/src/ty/mod.rs | 37 ++- compiler/rustc_middle/src/ty/opaque_types.rs | 36 +-- .../rustc_middle/src/ty/typeck_results.rs | 2 +- .../rustc_next_trait_solver/src/solve/mod.rs | 1 + .../src/solve/normalizes_to/opaque_types.rs | 36 +++ .../src/solve/search_graph.rs | 1 + .../src/solve/trait_goals.rs | 1 + compiler/rustc_pattern_analysis/src/rustc.rs | 5 +- compiler/rustc_session/src/options.rs | 3 + .../rustc_trait_selection/src/opaque_types.rs | 27 +- .../src/solve/delegate.rs | 1 + .../src/traits/normalize.rs | 2 + .../src/traits/project.rs | 1 + .../src/traits/query/normalize.rs | 1 + .../src/traits/select/mod.rs | 4 +- compiler/rustc_ty_utils/src/instance.rs | 1 + compiler/rustc_type_ir/src/infer_ctxt.rs | 12 + compiler/rustc_type_ir/src/interner.rs | 2 + compiler/rustc_type_ir/src/relate/combine.rs | 1 + tests/crashes/112201.rs | 19 -- tests/crashes/137751.rs | 6 - tests/ui/coroutine/clone-rpit.next.stderr | 6 +- .../generic-associated-types/issue-87258_a.rs | 2 +- .../issue-87258_a.stderr | 11 +- .../generic-associated-types/issue-87258_b.rs | 2 +- .../issue-87258_b.stderr | 11 +- ...e-method-resolution-opaque-type.old.stderr | 17 +- ...rm-before-method-resolution-opaque-type.rs | 1 - tests/ui/impl-trait/issue-55872-1.rs | 1 + tests/ui/impl-trait/issue-55872-1.stderr | 8 +- tests/ui/impl-trait/issue-55872-2.rs | 2 +- tests/ui/impl-trait/issue-55872-2.stderr | 12 +- tests/ui/impl-trait/issue-55872-3.rs | 1 + tests/ui/impl-trait/issue-55872-3.stderr | 16 +- tests/ui/impl-trait/issue-55872.rs | 2 +- tests/ui/impl-trait/issue-55872.stderr | 6 +- tests/ui/impl-trait/issue-99073-2.rs | 3 +- tests/ui/impl-trait/issue-99073-2.stderr | 14 +- tests/ui/impl-trait/issue-99073.rs | 3 +- tests/ui/impl-trait/issue-99073.stderr | 18 +- .../issues/fuzzer-ice-issue-112201.rs | 17 ++ .../issues/fuzzer-ice-issue-112201.stderr | 18 ++ tests/ui/impl-trait/issues/issue-86800.rs | 2 - tests/ui/impl-trait/issues/issue-86800.stderr | 29 +- .../as-projection-term.next.stderr | 12 + .../non-defining-uses/as-projection-term.rs | 17 ++ .../ui/impl-trait/recursive-ice-101862.stderr | 18 +- tests/ui/impl-trait/rpit/early_bound.rs | 3 +- tests/ui/impl-trait/rpit/early_bound.stderr | 22 +- tests/ui/impl-trait/rpit/non-defining-use.rs | 3 +- .../impl-trait/rpit/non-defining-use.stderr | 22 +- .../transmute/in-defining-scope.stderr | 25 ++ ...o_tait_defining_each_other2.current.stderr | 17 +- .../two_tait_defining_each_other2.rs | 3 +- .../opaques/ambig-in-mir-typeck.rs} | 5 +- .../no-define-in-wf-check.current.stderr | 44 ++- .../opaques/no-define-in-wf-check.rs | 8 +- .../opaques/revealing-use-in-nested-body.rs | 11 + .../bad-tait-no-substs.rs | 1 - .../bad-tait-no-substs.stderr | 17 +- .../type-alias-impl-trait/bound_reduction2.rs | 2 +- .../bound_reduction2.stderr | 6 +- .../different_args_considered_equal.rs | 2 +- .../different_defining_uses.rs | 2 +- .../different_defining_uses.stderr | 12 +- .../different_defining_uses_never_type-2.rs | 1 - ...ifferent_defining_uses_never_type-2.stderr | 20 +- ...ifferent_defining_uses_never_type-3.stderr | 6 +- .../different_defining_uses_never_type.stderr | 8 +- ...different_defining_uses_never_type3.stderr | 4 +- .../failed-to-normalize-ice-99945.rs | 1 - .../failed-to-normalize-ice-99945.stderr | 16 +- .../generic_different_defining_uses.rs | 2 +- .../generic_different_defining_uses.stderr | 12 +- .../generic_duplicate_param_use.rs | 4 +- .../generic_duplicate_param_use.stderr | 12 +- .../generic_duplicate_param_use3.rs | 2 +- .../generic_duplicate_param_use3.stderr | 12 +- .../generic_duplicate_param_use5.rs | 2 +- .../generic_duplicate_param_use5.stderr | 12 +- .../generic_duplicate_param_use6.rs | 2 +- .../generic_duplicate_param_use6.stderr | 12 +- .../generic_duplicate_param_use8.rs | 2 +- .../generic_duplicate_param_use8.stderr | 12 +- .../generic_duplicate_param_use9.rs | 2 +- .../generic_duplicate_param_use9.stderr | 12 +- .../generic_nondefining_use.rs | 4 +- .../generic_nondefining_use.stderr | 12 +- .../type-alias-impl-trait/generic_not_used.rs | 2 +- .../generic_not_used.stderr | 6 +- .../type-alias-impl-trait/hkl_forbidden4.rs | 9 +- .../hkl_forbidden4.stderr | 35 +-- .../in-where-clause.stderr | 35 +++ .../ui/type-alias-impl-trait/issue-109054.rs | 2 +- .../type-alias-impl-trait/issue-109054.stderr | 12 +- .../issue-53092-2.stderr | 25 ++ tests/ui/type-alias-impl-trait/issue-53598.rs | 2 +- .../type-alias-impl-trait/issue-53598.stderr | 6 +- tests/ui/type-alias-impl-trait/issue-60564.rs | 2 +- .../type-alias-impl-trait/issue-60564.stderr | 6 +- .../issue-68368-non-defining-use-2.stderr | 4 +- .../issue-68368-non-defining-use.stderr | 4 +- tests/ui/type-alias-impl-trait/issue-77179.rs | 6 +- .../type-alias-impl-trait/issue-77179.stderr | 18 +- tests/ui/type-alias-impl-trait/multi-error.rs | 2 +- .../type-alias-impl-trait/multi-error.stderr | 8 +- .../multiple-def-uses-in-one-fn-infer.rs | 3 +- .../multiple-def-uses-in-one-fn-infer.stderr | 12 +- .../multiple-def-uses-in-one-fn2.rs | 2 +- .../multiple-def-uses-in-one-fn2.stderr | 12 +- .../nested_type_alias_impl_trait.rs | 2 +- .../non-defining-method.stderr | 4 +- .../normalize-hidden-types.current.stderr | 34 +-- .../not_a_defining_use.rs | 2 +- .../not_a_defining_use.stderr | 12 +- .../recursive-fn-tait.rs | 3 +- .../recursive-fn-tait.stderr | 12 +- .../recursive-tait-conflicting-defn-2.rs | 2 +- .../recursive-tait-conflicting-defn-2.stderr | 12 +- .../recursive-tait-conflicting-defn.rs | 3 +- .../recursive-tait-conflicting-defn.stderr | 12 +- 131 files changed, 881 insertions(+), 740 deletions(-) delete mode 100644 tests/crashes/112201.rs delete mode 100644 tests/crashes/137751.rs create mode 100644 tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs create mode 100644 tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr create mode 100644 tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr create mode 100644 tests/ui/impl-trait/non-defining-uses/as-projection-term.rs rename tests/{crashes/132335.rs => ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs} (74%) create mode 100644 tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 7f0ee28531cfa..240bd20053b15 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -35,7 +35,7 @@ use rustc_infer::infer::{ }; use rustc_middle::mir::*; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode, fold_regions}; +use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode}; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::{ EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces, @@ -171,12 +171,6 @@ fn do_mir_borrowck<'tcx>( let free_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes - // FIXME(-Znext-solver): A bit dubious that we're only registering - // predefined opaques in the typeck root. - if infcx.next_trait_solver() && !infcx.tcx.is_typeck_child(body.source.def_id()) { - infcx.register_predefined_opaques_for_next_solver(def); - } - let location_table = PoloniusLocationTable::new(body); let move_data = MoveData::gather_moves(body, tcx, |_| true); @@ -431,7 +425,12 @@ pub(crate) struct BorrowckInferCtxt<'tcx> { impl<'tcx> BorrowckInferCtxt<'tcx> { pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { - let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, def_id)); + let typing_mode = if tcx.use_typing_mode_borrowck() { + TypingMode::borrowck(tcx, def_id) + } else { + TypingMode::analysis_in_body(tcx, def_id) + }; + let infcx = tcx.infer_ctxt().build(typing_mode); let param_env = tcx.param_env(def_id); BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()), param_env } } @@ -478,29 +477,6 @@ impl<'tcx> BorrowckInferCtxt<'tcx> { next_region } - - /// With the new solver we prepopulate the opaque type storage during - /// MIR borrowck with the hidden types from HIR typeck. This is necessary - /// to avoid ambiguities as earlier goals can rely on the hidden type - /// of an opaque which is only constrained by a later goal. - fn register_predefined_opaques_for_next_solver(&self, def_id: LocalDefId) { - let tcx = self.tcx; - // OK to use the identity arguments for each opaque type key, since - // we remap opaques from HIR typeck back to their definition params. - for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) { - // HIR typeck did not infer the regions of the opaque, so we instantiate - // them with fresh inference variables. - let (key, hidden_ty) = fold_regions(tcx, data, |_, _| { - self.next_nll_region_var_in_universe( - NllRegionVariableOrigin::Existential { from_forall: false }, - ty::UniverseIndex::ROOT, - ) - }); - - let prev = self.register_hidden_type_in_storage(key, hidden_ty); - assert_eq!(prev, None); - } - } } impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 2f15c2bc46447..a098450352ff9 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -2,7 +2,8 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_macros::extension; use rustc_middle::ty::{ - self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions, + self, DefiningScopeKind, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, + TypeVisitableExt, fold_regions, }; use rustc_span::Span; use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid; @@ -266,14 +267,21 @@ impl<'tcx> InferCtxt<'tcx> { return Ty::new_error(self.tcx, e); } - if let Err(guar) = - check_opaque_type_parameter_valid(self, opaque_type_key, instantiated_ty.span) - { + if let Err(guar) = check_opaque_type_parameter_valid( + self, + opaque_type_key, + instantiated_ty.span, + DefiningScopeKind::MirBorrowck, + ) { return Ty::new_error(self.tcx, guar); } let definition_ty = instantiated_ty - .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) + .remap_generic_params_to_declaration_params( + opaque_type_key, + self.tcx, + DefiningScopeKind::MirBorrowck, + ) .ty; if let Err(e) = definition_ty.error_reported() { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 075abc3259449..625f51dd29eac 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -61,6 +61,7 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { type_of: type_of::type_of, type_of_opaque: type_of::type_of_opaque, + type_of_opaque_hir_typeck: type_of::type_of_opaque_hir_typeck, type_alias_is_lazy: type_of::type_alias_is_lazy, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index afda2c142e228..694c12288596f 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -7,7 +7,9 @@ use rustc_hir::{self as hir, AmbigArg, 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, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, fold_regions}; +use rustc_middle::ty::{ + self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, fold_regions, +}; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; @@ -324,10 +326,18 @@ pub(super) fn type_of_opaque( if let Some(def_id) = def_id.as_local() { Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { - opaque::find_opaque_ty_constraints_for_tait(tcx, def_id) + opaque::find_opaque_ty_constraints_for_tait( + tcx, + def_id, + DefiningScopeKind::MirBorrowck, + ) } hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => { - opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id) + opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type( + tcx, + def_id, + DefiningScopeKind::MirBorrowck, + ) } // Opaque types desugared from `impl Trait`. hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl } @@ -340,7 +350,12 @@ pub(super) fn type_of_opaque( "tried to get type of this RPITIT with no definition" ); } - opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner) + opaque::find_opaque_ty_constraints_for_rpit( + tcx, + def_id, + owner, + DefiningScopeKind::MirBorrowck, + ) } })) } else { @@ -350,6 +365,42 @@ pub(super) fn type_of_opaque( } } +pub(super) fn type_of_opaque_hir_typeck( + tcx: TyCtxt<'_>, + def_id: LocalDefId, +) -> ty::EarlyBinder<'_, Ty<'_>> { + ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { + hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { + opaque::find_opaque_ty_constraints_for_tait(tcx, def_id, DefiningScopeKind::HirTypeck) + } + hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => { + opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type( + tcx, + def_id, + DefiningScopeKind::HirTypeck, + ) + } + // Opaque types desugared from `impl Trait`. + hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl } + | hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl } => { + if in_trait_or_impl == Some(hir::RpitContext::Trait) + && !tcx.defaultness(owner).has_value() + { + span_bug!( + tcx.def_span(def_id), + "tried to get type of this RPITIT with no definition" + ); + } + opaque::find_opaque_ty_constraints_for_rpit( + tcx, + def_id, + owner, + DefiningScopeKind::HirTypeck, + ) + } + }) +} + fn infer_placeholder_type<'tcx>( cx: &dyn HirTyLowerer<'tcx>, def_id: LocalDefId, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 8a3a6a8be1104..3fe3d71b32da8 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -3,8 +3,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::DUMMY_SP; +use rustc_middle::ty::{self, DefiningScopeKind, Ty, TyCtxt, TypeVisitableExt}; use tracing::{debug, instrument, trace}; use crate::errors::{TaitForwardCompat2, UnconstrainedOpaqueType}; @@ -15,6 +14,7 @@ use crate::errors::{TaitForwardCompat2, UnconstrainedOpaqueType}; pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( tcx: TyCtxt<'_>, def_id: LocalDefId, + opaque_types_from: DefiningScopeKind, ) -> Ty<'_> { let mut parent_def_id = def_id; while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy { @@ -27,7 +27,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( other => bug!("invalid impl trait in assoc type parent: {other:?}"), } - let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] }; + let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from }; for &assoc_id in tcx.associated_item_def_ids(impl_def_id) { let assoc = tcx.associated_item(assoc_id); @@ -39,25 +39,14 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( } if let Some(hidden) = locator.found { - // Only check against typeck if we didn't already error - if !hidden.ty.references_error() { - for concrete_type in locator.typeck_types { - if concrete_type.ty != tcx.erase_regions(hidden.ty) { - if let Ok(d) = hidden.build_mismatch_error(&concrete_type, tcx) { - d.emit(); - } - } - } - } - hidden.ty } else { - let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType { + let guar = tcx.dcx().emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), name: tcx.item_ident(parent_def_id.to_def_id()), what: "impl", }); - Ty::new_error(tcx, reported) + Ty::new_error(tcx, guar) } } @@ -80,23 +69,16 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( /// fn b() -> Foo { .. } /// ``` #[instrument(skip(tcx), level = "debug")] -pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { - let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] }; +pub(super) fn find_opaque_ty_constraints_for_tait( + tcx: TyCtxt<'_>, + def_id: LocalDefId, + opaque_types_from: DefiningScopeKind, +) -> Ty<'_> { + let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from }; tcx.hir_walk_toplevel_module(&mut locator); if let Some(hidden) = locator.found { - // Only check against typeck if we didn't already error - if !hidden.ty.references_error() { - for concrete_type in locator.typeck_types { - if concrete_type.ty != tcx.erase_regions(hidden.ty) { - if let Ok(d) = hidden.build_mismatch_error(&concrete_type, tcx) { - d.emit(); - } - } - } - } - hidden.ty } else { let mut parent_def_id = def_id; @@ -104,12 +86,12 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local // Account for `type Alias = impl Trait;` (#116031) parent_def_id = tcx.local_parent(parent_def_id); } - let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType { + let guar = tcx.dcx().emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), name: tcx.item_ident(parent_def_id.to_def_id()), what: "crate", }); - Ty::new_error(tcx, reported) + Ty::new_error(tcx, guar) } } @@ -126,22 +108,44 @@ struct TaitConstraintLocator<'tcx> { /// type). found: Option>, - /// In the presence of dead code, typeck may figure out a hidden type - /// while borrowck will not. We collect these cases here and check at - /// the end that we actually found a type that matches (modulo regions). - typeck_types: Vec>, + opaque_types_from: DefiningScopeKind, } -impl TaitConstraintLocator<'_> { +impl<'tcx> TaitConstraintLocator<'tcx> { + fn insert_found(&mut self, hidden_ty: ty::OpaqueHiddenType<'tcx>) { + if let Some(prev) = &mut self.found { + if hidden_ty.ty != prev.ty { + let (Ok(guar) | Err(guar)) = + prev.build_mismatch_error(&hidden_ty, self.tcx).map(|d| d.emit()); + prev.ty = Ty::new_error(self.tcx, guar); + } + } else { + self.found = Some(hidden_ty); + } + } + + fn non_defining_use_in_defining_scope(&mut self, item_def_id: LocalDefId) { + let guar = self.tcx.dcx().emit_err(TaitForwardCompat2 { + span: self + .tcx + .def_ident_span(item_def_id) + .unwrap_or_else(|| self.tcx.def_span(item_def_id)), + opaque_type_span: self.tcx.def_span(self.def_id), + opaque_type: self.tcx.def_path_str(self.def_id), + }); + self.insert_found(ty::OpaqueHiddenType::new_error(self.tcx, guar)); + } + #[instrument(skip(self), level = "debug")] fn check(&mut self, item_def_id: LocalDefId) { // Don't try to check items that cannot possibly constrain the type. - if !self.tcx.has_typeck_results(item_def_id) { + let tcx = self.tcx; + if !tcx.has_typeck_results(item_def_id) { debug!("no constraint: no typeck results"); return; } - let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id); + let opaque_types_defined_by = tcx.opaque_types_defined_by(item_def_id); // Don't try to check items that cannot possibly constrain the type. if !opaque_types_defined_by.contains(&self.def_id) { debug!("no constraint: no opaque types defined"); @@ -152,7 +156,7 @@ impl TaitConstraintLocator<'_> { // "non-defining use" errors for them. // Note that we use `Node::fn_sig` instead of `Node::fn_decl` here, because the former // excludes closures, which are allowed to have `_` in their return type. - let hir_node = self.tcx.hir_node_by_def_id(item_def_id); + let hir_node = tcx.hir_node_by_def_id(item_def_id); debug_assert!( !matches!(hir_node, Node::ForeignItem(..)), "foreign items cannot constrain opaque types", @@ -164,88 +168,39 @@ impl TaitConstraintLocator<'_> { hir_sig.decl.output.span(), "inferring return types and opaque types do not mix well", ); - self.found = - Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) }); - return; - } - - // Calling `mir_borrowck` can lead to cycle errors through - // const-checking, avoid calling it if we don't have to. - // ```rust - // type Foo = impl Fn() -> usize; // when computing type for this - // const fn bar() -> Foo { - // || 0usize - // } - // const BAZR: Foo = bar(); // we would mir-borrowck this, causing cycles - // // because we again need to reveal `Foo` so we can check whether the - // // constant does not contain interior mutability. - // ``` - let tables = self.tcx.typeck(item_def_id); - if let Some(guar) = tables.tainted_by_errors { - self.found = - Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) }); + self.found = Some(ty::OpaqueHiddenType::new_error(tcx, guar)); return; } - let mut constrained = false; - for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types { - if opaque_type_key.def_id != self.def_id { - continue; - } - constrained = true; - - let concrete_type = - self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params( - opaque_type_key, - self.tcx, - true, - )); - if self.typeck_types.iter().all(|prev| prev.ty != concrete_type.ty) { - self.typeck_types.push(concrete_type); - } - } - - if !constrained { - debug!("no constraints in typeck results"); - if opaque_types_defined_by.contains(&self.def_id) { - let guar = self.tcx.dcx().emit_err(TaitForwardCompat2 { - span: self - .tcx - .def_ident_span(item_def_id) - .unwrap_or_else(|| self.tcx.def_span(item_def_id)), - opaque_type_span: self.tcx.def_span(self.def_id), - opaque_type: self.tcx.def_path_str(self.def_id), - }); - // Avoid "opaque type not constrained" errors on the opaque itself. - self.found = Some(ty::OpaqueHiddenType { - span: DUMMY_SP, - ty: Ty::new_error(self.tcx, guar), - }); + match self.opaque_types_from { + DefiningScopeKind::HirTypeck => { + let tables = tcx.typeck(item_def_id); + if let Some(guar) = tables.tainted_by_errors { + self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)); + } else if let Some(&hidden_type) = tables.concrete_opaque_types.get(&self.def_id) { + self.insert_found(hidden_type); + } else { + self.non_defining_use_in_defining_scope(item_def_id); + } } - return; - }; - - // Use borrowck to get the type with unerased regions. - let borrowck_results = &self.tcx.mir_borrowck(item_def_id); - - // If the body was tainted, then assume the opaque may have been constrained and just set it to error. - if let Some(guar) = borrowck_results.tainted_by_errors { - self.found = - Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(self.tcx, guar) }); - return; - } - - debug!(?borrowck_results.concrete_opaque_types); - if let Some(&concrete_type) = borrowck_results.concrete_opaque_types.get(&self.def_id) { - debug!(?concrete_type, "found constraint"); - if let Some(prev) = &mut self.found { - if concrete_type.ty != prev.ty { - let (Ok(guar) | Err(guar)) = - prev.build_mismatch_error(&concrete_type, self.tcx).map(|d| d.emit()); - prev.ty = Ty::new_error(self.tcx, guar); + DefiningScopeKind::MirBorrowck => { + let borrowck_result = tcx.mir_borrowck(item_def_id); + if let Some(guar) = borrowck_result.tainted_by_errors { + self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)); + } else if let Some(&hidden_type) = + borrowck_result.concrete_opaque_types.get(&self.def_id) + { + debug!(?hidden_type, "found constraint"); + self.insert_found(hidden_type); + } else if let Err(guar) = tcx + .type_of_opaque_hir_typeck(self.def_id) + .instantiate_identity() + .error_reported() + { + self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)); + } else { + self.non_defining_use_in_defining_scope(item_def_id); } - } else { - self.found = Some(concrete_type); } } } @@ -287,54 +242,42 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, owner_def_id: LocalDefId, + opaque_types_from: DefiningScopeKind, ) -> Ty<'tcx> { - let tables = tcx.typeck(owner_def_id); + match opaque_types_from { + DefiningScopeKind::HirTypeck => { + let tables = tcx.typeck(owner_def_id); + if let Some(guar) = tables.tainted_by_errors { + Ty::new_error(tcx, guar) + } else if let Some(hidden_ty) = tables.concrete_opaque_types.get(&def_id) { + hidden_ty.ty + } else { + // FIXME(-Znext-solver): This should not be necessary and we should + // instead rely on inference variable fallback inside of typeck itself. - // Check that all of the opaques we inferred during HIR are compatible. - // FIXME: We explicitly don't check that the types inferred during HIR - // typeck are compatible with the one that we infer during borrowck, - // because that one actually sometimes has consts evaluated eagerly so - // using strict type equality will fail. - let mut hir_opaque_ty: Option> = None; - if tables.tainted_by_errors.is_none() { - for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types { - if opaque_type_key.def_id != def_id { - continue; + // We failed to resolve the opaque type or it + // resolves to itself. We interpret this as the + // no values of the hidden type ever being constructed, + // so we can just make the hidden type be `!`. + // For backwards compatibility reasons, we fall back to + // `()` until we the diverging default is changed. + Ty::new_diverging_default(tcx) } - let concrete_type = tcx.erase_regions( - hidden_type.remap_generic_params_to_declaration_params(opaque_type_key, tcx, true), - ); - if let Some(prev) = &mut hir_opaque_ty { - if concrete_type.ty != prev.ty { - if let Ok(d) = prev.build_mismatch_error(&concrete_type, tcx) { - d.emit(); - } - } + } + DefiningScopeKind::MirBorrowck => { + let borrowck_result = tcx.mir_borrowck(owner_def_id); + if let Some(guar) = borrowck_result.tainted_by_errors { + Ty::new_error(tcx, guar) + } else if let Some(hidden_ty) = borrowck_result.concrete_opaque_types.get(&def_id) { + hidden_ty.ty } else { - hir_opaque_ty = Some(concrete_type); + let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity(); + if let Err(guar) = hir_ty.error_reported() { + Ty::new_error(tcx, guar) + } else { + hir_ty + } } } } - - let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied(); - if let Some(mir_opaque_ty) = mir_opaque_ty { - mir_opaque_ty.ty - } else if let Some(guar) = tables.tainted_by_errors { - // Some error in the owner fn prevented us from populating - // the `concrete_opaque_types` table. - Ty::new_error(tcx, guar) - } else { - // Fall back to the RPIT we inferred during HIR typeck - if let Some(hir_opaque_ty) = hir_opaque_ty { - hir_opaque_ty.ty - } else { - // We failed to resolve the opaque type or it - // resolves to itself. We interpret this as the - // no values of the hidden type ever being constructed, - // so we can just make the hidden type be `!`. - // For backwards compatibility reasons, we fall back to - // `()` until we the diverging default is changed. - Ty::new_diverging_default(tcx) - } - } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 588383534f6ba..4d7e2c7629f00 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -12,10 +12,12 @@ use rustc_middle::span_bug; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, fold_regions, + self, DefiningScopeKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, fold_regions, }; use rustc_span::{Span, sym}; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; +use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid; use rustc_trait_selection::solve; use tracing::{debug, instrument}; @@ -553,6 +555,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { #[instrument(skip(self), level = "debug")] fn visit_opaque_types(&mut self) { + let tcx = self.tcx(); // We clone the opaques instead of stealing them here as they are still used for // normalization in the next generation trait solver. // @@ -575,16 +578,46 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - // Here we only detect impl trait definition conflicts when they - // are equal modulo regions. - if let Some(last_opaque_ty) = - self.typeck_results.concrete_opaque_types.insert(opaque_type_key, hidden_type) - && last_opaque_ty.ty != hidden_type.ty + if let Err(guar) = check_opaque_type_parameter_valid( + &self.fcx, + opaque_type_key, + hidden_type.span, + DefiningScopeKind::HirTypeck, + ) { + self.typeck_results + .concrete_opaque_types + .insert(opaque_type_key.def_id, ty::OpaqueHiddenType::new_error(tcx, guar)); + } + + let hidden_type = hidden_type.remap_generic_params_to_declaration_params( + opaque_type_key, + tcx, + DefiningScopeKind::HirTypeck, + ); + + if let Some(prev) = self + .typeck_results + .concrete_opaque_types + .insert(opaque_type_key.def_id, hidden_type) { - assert!(!self.fcx.next_trait_solver()); - if let Ok(d) = hidden_type.build_mismatch_error(&last_opaque_ty, self.tcx()) { - d.emit(); + let entry = &mut self + .typeck_results + .concrete_opaque_types + .get_mut(&opaque_type_key.def_id) + .unwrap(); + if prev.ty != hidden_type.ty { + if let Some(guar) = self.typeck_results.tainted_by_errors { + entry.ty = Ty::new_error(tcx, guar); + } else { + let (Ok(guar) | Err(guar)) = + prev.build_mismatch_error(&hidden_type, tcx).map(|d| d.emit()); + entry.ty = Ty::new_error(tcx, guar); + } } + + // Pick a better span if there is one. + // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. + entry.span = prev.span.substitute_dummy(hidden_type.span); } } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index fa8dea064daaa..20aa8e44f4392 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -966,7 +966,8 @@ impl<'tcx> InferCtxt<'tcx> { pub fn can_define_opaque_ty(&self, id: impl Into) -> bool { debug_assert!(!self.next_trait_solver()); match self.typing_mode() { - TypingMode::Analysis { defining_opaque_types } => { + TypingMode::Analysis { defining_opaque_types } + | TypingMode::Borrowck { defining_opaque_types } => { id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id)) } // FIXME(#132279): This function is quite weird in post-analysis @@ -1260,7 +1261,8 @@ impl<'tcx> InferCtxt<'tcx> { // to handle them without proper canonicalization. This means we may cause cycle // errors and fail to reveal opaques while inside of bodies. We should rename this // function and require explicit comments on all use-sites in the future. - ty::TypingMode::Analysis { defining_opaque_types: _ } => { + ty::TypingMode::Analysis { defining_opaque_types: _ } + | ty::TypingMode::Borrowck { defining_opaque_types: _ } => { TypingMode::non_body_analysis() } mode @ (ty::TypingMode::Coherence diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index d9297fb419446..ce5d2e6e17a96 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::{ use rustc_span::Span; use tracing::{debug, instrument}; -use super::DefineOpaqueTypes; +use super::{DefineOpaqueTypes, RegionVariableOrigin}; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{InferCtxt, InferOk}; use crate::traits::{self, Obligation, PredicateObligations}; @@ -221,6 +221,7 @@ impl<'tcx> InferCtxt<'tcx> { hidden_ty: Ty<'tcx>, goals: &mut Vec>>, ) -> Result<(), TypeError<'tcx>> { + let tcx = self.tcx; // Ideally, we'd get the span where *this specific `ty` came // from*, but right now we just use the span from the overall // value being folded. In simple cases like `-> impl Foo`, @@ -231,7 +232,7 @@ impl<'tcx> InferCtxt<'tcx> { // During intercrate we do not define opaque types but instead always // force ambiguity unless the hidden type is known to not implement // our trait. - goals.push(Goal::new(self.tcx, param_env, ty::PredicateKind::Ambiguous)); + goals.push(Goal::new(tcx, param_env, ty::PredicateKind::Ambiguous)); } ty::TypingMode::Analysis { .. } => { let prev = self @@ -249,6 +250,36 @@ impl<'tcx> InferCtxt<'tcx> { ); } } + ty::TypingMode::Borrowck { .. } => { + let prev = self + .inner + .borrow_mut() + .opaque_types() + .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span }); + + // We either equate the new hidden type with the previous entry or with the type + // inferred by HIR typeck. + let actual = prev.unwrap_or_else(|| { + let actual = tcx + .type_of_opaque_hir_typeck(opaque_type_key.def_id) + .instantiate(self.tcx, opaque_type_key.args); + let actual = ty::fold_regions(tcx, actual, |re, _dbi| match re.kind() { + ty::ReErased => { + self.next_region_var(RegionVariableOrigin::MiscVariable(span)) + } + _ => re, + }); + actual + }); + + goals.extend( + self.at(&ObligationCause::dummy_with_span(span), param_env) + .eq(DefineOpaqueTypes::Yes, hidden_ty, actual)? + .obligations + .into_iter() + .map(|obligation| obligation.as_goal()), + ); + } mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => { bug!("insert hidden type in {mode:?}") } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 698859c663b17..0d5fba3cc69b4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -267,6 +267,8 @@ rustc_queries! { /// /// This is a specialized instance of [`Self::type_of`] that detects query cycles. /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead. + /// This is used to improve the error message in cases where revealing the hidden type + /// for auto-trait leakage cycles. /// /// # Panics /// @@ -278,6 +280,12 @@ rustc_queries! { } cycle_stash } + query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { + desc { |tcx| + "computing type of opaque `{path}` via HIR typeck", + path = tcx.def_path_str(key), + } + } /// Returns whether the type alias given by `DefId` is lazy. /// diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 618a65a018644..b1ace67440461 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -206,6 +206,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { self.type_of(def_id) } + fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { + self.type_of_opaque_hir_typeck(def_id) + } type AdtDef = ty::AdtDef<'tcx>; fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef { @@ -3248,6 +3251,11 @@ impl<'tcx> TyCtxt<'tcx> { self.sess.opts.unstable_opts.next_solver.coherence } + #[allow(rustc::bad_opt_access)] + pub fn use_typing_mode_borrowck(self) -> bool { + self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck + } + pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { self.opt_rpitit_info(def_id).is_some() } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 255d464d26541..8db0c7c9b3aa3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -48,7 +48,7 @@ use rustc_serialize::{Decodable, Encodable}; use rustc_session::lint::LintBuffer; pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; -use rustc_span::{ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; pub use rustc_type_ir::relate::VarianceDiagInfo; pub use rustc_type_ir::*; use tracing::{debug, instrument}; @@ -782,7 +782,22 @@ pub struct OpaqueHiddenType<'tcx> { pub ty: Ty<'tcx>, } +/// Whether we're currently in HIR typeck or MIR borrowck. +#[derive(Debug, Clone, Copy)] +pub enum DefiningScopeKind { + /// During writeback in typeck, we don't care about regions and simply + /// erase them. This means we also don't check whether regions are + /// universal in the opaque type key. This will only be checked in + /// MIR borrowck. + HirTypeck, + MirBorrowck, +} + impl<'tcx> OpaqueHiddenType<'tcx> { + pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> OpaqueHiddenType<'tcx> { + OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) } + } + pub fn build_mismatch_error( &self, other: &Self, @@ -808,8 +823,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> { self, opaque_type_key: OpaqueTypeKey<'tcx>, tcx: TyCtxt<'tcx>, - // typeck errors have subpar spans for opaque types, so delay error reporting until borrowck. - ignore_errors: bool, + defining_scope_kind: DefiningScopeKind, ) -> Self { let OpaqueTypeKey { def_id, args } = opaque_type_key; @@ -828,10 +842,19 @@ impl<'tcx> OpaqueHiddenType<'tcx> { let map = args.iter().zip(id_args).collect(); debug!("map = {:#?}", map); - // Convert the type from the function into a type valid outside - // the function, by replacing invalid regions with 'static, - // after producing an error for each of them. - self.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span, ignore_errors)) + // Convert the type from the function into a type valid outside by mapping generic + // parameters to into the context of the opaque. + // + // We erase regions when doing this during HIR typeck. + let this = match defining_scope_kind { + DefiningScopeKind::HirTypeck => tcx.erase_regions(self), + DefiningScopeKind::MirBorrowck => self, + }; + let result = this.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span)); + if cfg!(debug_assertions) && matches!(defining_scope_kind, DefiningScopeKind::HirTypeck) { + assert_eq!(result.ty, tcx.erase_regions(result.ty)); + } + result } } diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 56c44c8a84c04..c72efde099497 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -20,12 +20,6 @@ pub(super) struct ReverseMapper<'tcx> { /// for an explanation of this field. do_not_error: bool, - /// We do not want to emit any errors in typeck because - /// the spans in typeck are subpar at the moment. - /// Borrowck will do the same work again (this time with - /// lifetime information) and thus report better errors. - ignore_errors: bool, - /// Span of function being checked. span: Span, } @@ -35,9 +29,8 @@ impl<'tcx> ReverseMapper<'tcx> { tcx: TyCtxt<'tcx>, map: FxHashMap, GenericArg<'tcx>>, span: Span, - ignore_errors: bool, ) -> Self { - Self { tcx, map, do_not_error: false, ignore_errors, span } + Self { tcx, map, do_not_error: false, span } } fn fold_kind_no_missing_regions_error(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> { @@ -176,20 +169,18 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { Some(u) => panic!("type mapped to unexpected kind: {u:?}"), None => { debug!(?param, ?self.map); - if !self.ignore_errors { - self.tcx - .dcx() - .struct_span_err( - self.span, - format!( - "type parameter `{ty}` is part of concrete type but not \ + let guar = self + .tcx + .dcx() + .struct_span_err( + self.span, + format!( + "type parameter `{ty}` is part of concrete type but not \ used in parameter list for the `impl Trait` type alias" - ), - ) - .emit(); - } - - Ty::new_misc_error(self.tcx) + ), + ) + .emit(); + Ty::new_error(self.tcx, guar) } } } @@ -217,8 +208,7 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { ct: ct.to_string(), span: self.span, }) - .emit_unless(self.ignore_errors); - + .emit(); ty::Const::new_error(self.tcx, guar) } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 3d3f4e2773a2d..7c437abfe24c9 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -158,7 +158,7 @@ pub struct TypeckResults<'tcx> { /// We also store the type here, so that the compiler can use it as a hint /// for figuring out hidden types, even if they are only set in dead code /// (which doesn't show up in MIR). - pub concrete_opaque_types: FxIndexMap, ty::OpaqueHiddenType<'tcx>>, + pub concrete_opaque_types: FxIndexMap>, /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 199f0c7512e1b..7641e9a16ee62 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -330,6 +330,7 @@ where // During analysis, opaques are rigid unless they may be defined by // the current body. TypingMode::Analysis { defining_opaque_types: non_rigid_opaques } + | TypingMode::Borrowck { defining_opaque_types: non_rigid_opaques } | TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => { !def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id)) } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index 82dae51b3d038..aa89e77bb6fb9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -96,6 +96,42 @@ where ); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } + // Very similar to `TypingMode::Analysis` with some notably differences: + // - we accept opaque types even if they have non-universal arguments + // - we do a structural lookup instead of semantically unifying regions + // - the hidden type starts out as the type from HIR typeck with fresh region + // variables instead of a fully unconstrained inference variable + TypingMode::Borrowck { defining_opaque_types } => { + let Some(def_id) = opaque_ty + .def_id + .as_local() + .filter(|&def_id| defining_opaque_types.contains(&def_id)) + else { + self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); + }; + + let opaque_type_key = ty::OpaqueTypeKey { def_id, args: opaque_ty.args }; + let actual = self + .register_hidden_type_in_storage(opaque_type_key, expected) + .unwrap_or_else(|| { + let actual = + cx.type_of_opaque_hir_typeck(def_id).instantiate(cx, opaque_ty.args); + let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() { + ty::ReErased => self.next_region_var(), + _ => re, + }); + actual + }); + self.eq(goal.param_env, expected, actual)?; + self.add_item_bounds_for_hidden_type( + def_id.into(), + opaque_ty.args, + goal.param_env, + expected, + ); + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } TypingMode::PostBorrowckAnalysis { defined_opaque_types } => { let Some(def_id) = opaque_ty .def_id diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index eba496fa22659..ecffbbff7a2dc 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -62,6 +62,7 @@ where response_no_constraints(cx, input, Certainty::overflow(false)) } TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis => Err(NoSolution), }, diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index b72f776e5cb48..2a1196735cd34 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -72,6 +72,7 @@ where (ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() { TypingMode::Coherence => Certainty::AMBIGUOUS, TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis => return Err(NoSolution), }, diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index a25a80cd45f74..31c4ee0fa0bbf 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -135,7 +135,10 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { /// Returns the hidden type corresponding to this key if the body under analysis is allowed to /// know it. fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option> { - self.typeck_results.concrete_opaque_types.get(&key).map(|x| x.ty) + self.typeck_results + .concrete_opaque_types + .get(&key.def_id) + .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args)) } // This can take a non-revealed `Ty` because it reveals opaques itself. pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index cd5e2c4173e7b..36f7486f1d4cd 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2553,6 +2553,9 @@ written to standard error output)"), "in diagnostics, use heuristics to shorten paths referring to items"), tune_cpu: Option = (None, parse_opt_string, [TRACKED], "select processor to schedule for (`rustc --print target-cpus` for details)"), + #[rustc_lint_opt_deny_field_access("use `TyCtxt::use_typing_mode_borrowck` instead of this field")] + typing_mode_borrowck: bool = (false, parse_bool, [TRACKED], + "enable `TypingMode::Borrowck`, changing the way opaque types are handled during MIR borrowck"), #[rustc_lint_opt_deny_field_access("use `Session::ub_checks` instead of this field")] ub_checks: Option = (None, parse_opt_bool, [TRACKED], "emit runtime checks for Undefined Behavior (default: -Cdebug-assertions)"), diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 5af912fee5492..c7b8f0631962e 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::ty::{ - self, GenericArgKind, GenericArgs, OpaqueTypeKey, TyCtxt, TypeVisitableExt, + self, DefiningScopeKind, GenericArgKind, GenericArgs, OpaqueTypeKey, TyCtxt, TypeVisitableExt, TypingMode, fold_regions, }; use rustc_span::{ErrorGuaranteed, Span}; @@ -21,19 +21,36 @@ pub fn check_opaque_type_parameter_valid<'tcx>( infcx: &InferCtxt<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, + defining_scope_kind: DefiningScopeKind, ) -> Result<(), ErrorGuaranteed> { let tcx = infcx.tcx; let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); + // Avoid duplicate errors in case the opaque has already been malformed in + // HIR typeck. + if let DefiningScopeKind::MirBorrowck = defining_scope_kind { + if let Err(guar) = infcx + .tcx + .type_of_opaque_hir_typeck(opaque_type_key.def_id) + .instantiate_identity() + .error_reported() + { + return Err(guar); + } + } + for (i, arg) in opaque_type_key.iter_captured_args(tcx) { let arg_is_param = match arg.unpack() { + GenericArgKind::Lifetime(lt) => match defining_scope_kind { + DefiningScopeKind::HirTypeck => continue, + DefiningScopeKind::MirBorrowck => { + matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) + || (lt.is_static() && opaque_env.param_equal_static(i)) + } + }, GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), - GenericArgKind::Lifetime(lt) => { - matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) - || (lt.is_static() && opaque_env.param_equal_static(i)) - } GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), }; diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index f2725411e13c3..e0b425fa7391b 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -195,6 +195,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< match self.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => false, TypingMode::PostAnalysis => { let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index ad62b456ad461..4ac45172a0e1c 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -130,6 +130,7 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), TypingMode::PostAnalysis => {} } @@ -226,6 +227,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => ty.super_fold_with(self), TypingMode::PostAnalysis => { let recursion_limit = self.cx().recursion_limit(); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6057b66c483f5..349569d750e08 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -952,6 +952,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( match selcx.infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => { debug!( assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 165c63f3745a2..5dbb4382fd1be 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -216,6 +216,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { match self.infcx.typing_mode() { TypingMode::Coherence | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => ty.try_super_fold_with(self)?, TypingMode::PostAnalysis => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0679dbf1296af..d78938225f1dc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1446,6 +1446,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.infcx.typing_mode() { TypingMode::Coherence => {} TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis => return Ok(()), } @@ -1491,7 +1492,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // However, if we disqualify *all* goals from being cached, perf suffers. // This is likely fixed by better caching in general in the new solver. // See: . - TypingMode::Analysis { defining_opaque_types } => { + TypingMode::Analysis { defining_opaque_types } + | TypingMode::Borrowck { defining_opaque_types } => { defining_opaque_types.is_empty() || !pred.has_opaque_types() } // The hidden types of `defined_opaque_types` is not local to the current diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 962e1353ebcd7..66c18bed5e71a 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -149,6 +149,7 @@ fn resolve_associated_item<'tcx>( match typing_env.typing_mode { ty::TypingMode::Coherence | ty::TypingMode::Analysis { .. } + | ty::TypingMode::Borrowck { .. } | ty::TypingMode::PostBorrowckAnalysis { .. } => false, ty::TypingMode::PostAnalysis => !trait_ref.still_further_specializable(), } diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index e512e8fc838f1..fec6e24e2cb4d 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -66,6 +66,14 @@ pub enum TypingMode { /// } /// ``` Analysis { defining_opaque_types: I::DefiningOpaqueTypes }, + /// The behavior during MIR borrowck is identical to `TypingMode::Analysis` + /// except that the initial value for opaque types is the type computed during + /// HIR typeck with unique unconstrained region inference variables. + /// + /// This is currently only used with by the new solver as it results in new + /// non-universal defining uses of opaque types, which is a breaking change. + /// See tests/ui/impl-trait/non-defining-use/as-projection-term.rs. + Borrowck { defining_opaque_types: I::DefiningOpaqueTypes }, /// Any analysis after borrowck for a given body should be able to use all the /// hidden types defined by borrowck, without being able to define any new ones. /// @@ -95,6 +103,10 @@ impl TypingMode { TypingMode::Analysis { defining_opaque_types: cx.opaque_types_defined_by(body_def_id) } } + pub fn borrowck(cx: I, body_def_id: I::LocalDefId) -> TypingMode { + TypingMode::Borrowck { defining_opaque_types: cx.opaque_types_defined_by(body_def_id) } + } + pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode { TypingMode::PostBorrowckAnalysis { defined_opaque_types: cx.opaque_types_defined_by(body_def_id), diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 8f86270d7dce7..44b260ddd3a2f 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -149,6 +149,8 @@ pub trait Interner: ) -> Option; fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder; + fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) + -> ty::EarlyBinder; type AdtDef: AdtDef; fn adt_def(self, adt_def_id: Self::DefId) -> Self::AdtDef; diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index d49f8d3093db7..8dd7c4df24421 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -137,6 +137,7 @@ where Ok(a) } TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis => structurally_relate_tys(relation, a, b), } diff --git a/tests/crashes/112201.rs b/tests/crashes/112201.rs deleted file mode 100644 index 5d363403b8acb..0000000000000 --- a/tests/crashes/112201.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ known-bug: #112201 - -pub fn compose( - f1: impl FnOnce(f64) -> f64 + Clone, - f2: impl FnOnce(f64) -> f64 + Clone, -) -> impl FnOnce(f64) -> f64 + Clone { - move |x| f1(f2(x)) -} - -fn repeat_helper( - f: impl FnOnce(f64) -> f64 + Clone, - res: impl FnOnce(f64) -> f64 + Clone, - times: usize, -) -> impl FnOnce(f64) -> f64 + Clone { - return res; - repeat_helper(f.clone(), compose(f, res), times - 1) -} - -fn main() {} diff --git a/tests/crashes/137751.rs b/tests/crashes/137751.rs deleted file mode 100644 index 85ae3acd53d30..0000000000000 --- a/tests/crashes/137751.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #137751 -//@ compile-flags: --edition=2021 -Znext-solver=globally -async fn test() { - Box::pin(test()).await; -} -fn main() {} diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr index c223f1f211ac6..213e9e908f56d 100644 --- a/tests/ui/coroutine/clone-rpit.next.stderr +++ b/tests/ui/coroutine/clone-rpit.next.stderr @@ -35,11 +35,11 @@ note: ...which requires type-checking `foo::{closure#0}`... LL | move |_: ()| { | ^^^^^^^^^^^^ = note: ...which again requires type-checking `foo`, completing the cycle -note: cycle used when computing type of opaque `foo::{opaque#0}` - --> $DIR/clone-rpit.rs:13:25 +note: cycle used when match-checking `foo` + --> $DIR/clone-rpit.rs:13:1 | LL | pub fn foo<'a, 'b>() -> impl Clone { - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-87258_a.rs b/tests/ui/generic-associated-types/issue-87258_a.rs index 6f737b21f53cd..2ea77bbca768c 100644 --- a/tests/ui/generic-associated-types/issue-87258_a.rs +++ b/tests/ui/generic-associated-types/issue-87258_a.rs @@ -15,8 +15,8 @@ pub trait Trait2 { impl<'c, S: Trait2> Trait2 for &'c mut S { type FooFuture<'a> = impl Trait1; - //~^ ERROR unconstrained opaque type fn foo<'a>() -> Self::FooFuture<'a> { + //~^ ERROR item does not constrain `<&'c mut S as Trait2>::FooFuture::{opaque#0}` Struct(unimplemented!()) } } diff --git a/tests/ui/generic-associated-types/issue-87258_a.stderr b/tests/ui/generic-associated-types/issue-87258_a.stderr index 01f2a92f94a6b..f175c15bd02b2 100644 --- a/tests/ui/generic-associated-types/issue-87258_a.stderr +++ b/tests/ui/generic-associated-types/issue-87258_a.stderr @@ -1,10 +1,15 @@ -error: unconstrained opaque type +error: item does not constrain `<&'c mut S as Trait2>::FooFuture::{opaque#0}` + --> $DIR/issue-87258_a.rs:18:8 + | +LL | fn foo<'a>() -> Self::FooFuture<'a> { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/issue-87258_a.rs:17:26 | LL | type FooFuture<'a> = impl Trait1; | ^^^^^^^^^^^ - | - = note: `FooFuture` must be used in combination with a concrete type within the same impl error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-87258_b.rs b/tests/ui/generic-associated-types/issue-87258_b.rs index 84c7182cdcbc9..8b820e75f6043 100644 --- a/tests/ui/generic-associated-types/issue-87258_b.rs +++ b/tests/ui/generic-associated-types/issue-87258_b.rs @@ -14,12 +14,12 @@ pub trait Trait2 { } type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1; -//~^ ERROR unconstrained opaque type impl<'c, S: Trait2> Trait2 for &'c mut S { type FooFuture<'a> = Helper<'c, 'a, S>; #[define_opaque(Helper)] fn foo<'a>() -> Self::FooFuture<'a> { + //~^ ERROR item does not constrain `Helper::{opaque#0}` Struct(unimplemented!()) } } diff --git a/tests/ui/generic-associated-types/issue-87258_b.stderr b/tests/ui/generic-associated-types/issue-87258_b.stderr index 906ce1f50da79..56abcef0d3776 100644 --- a/tests/ui/generic-associated-types/issue-87258_b.stderr +++ b/tests/ui/generic-associated-types/issue-87258_b.stderr @@ -1,10 +1,15 @@ -error: unconstrained opaque type +error: item does not constrain `Helper::{opaque#0}` + --> $DIR/issue-87258_b.rs:21:8 + | +LL | fn foo<'a>() -> Self::FooFuture<'a> { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/issue-87258_b.rs:16:49 | LL | type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1; | ^^^^^^^^^^^ - | - = note: `Helper` must be used in combination with a concrete type within the same crate error: aborting due to 1 previous error diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr index 34617448a692a..79ded34d9cd9e 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -1,18 +1,5 @@ -error: item does not constrain `Foo::{opaque#0}` - --> $DIR/norm-before-method-resolution-opaque-type.rs:17:4 - | -LL | fn weird_bound(x: &>::Out) -> X - | ^^^^^^^^^^^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/norm-before-method-resolution-opaque-type.rs:14:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - error[E0507]: cannot move out of `*x` which is behind a shared reference - --> $DIR/norm-before-method-resolution-opaque-type.rs:23:13 + --> $DIR/norm-before-method-resolution-opaque-type.rs:22:13 | LL | let x = *x; | ^^ move occurs because `*x` has type `>::Out`, which does not implement the `Copy` trait @@ -23,6 +10,6 @@ LL - let x = *x; LL + let x = x; | -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs index bb663c82abb0e..f881fcb779fa8 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -15,7 +15,6 @@ type Foo = impl Sized; #[define_opaque(Foo)] fn weird_bound(x: &>::Out) -> X -//[old]~^ ERROR: item does not constrain where for<'a> X: Trait<'a>, for<'a> >::Out<()>: Copy, diff --git a/tests/ui/impl-trait/issue-55872-1.rs b/tests/ui/impl-trait/issue-55872-1.rs index f36a310ddf310..663cdbc2f5cba 100644 --- a/tests/ui/impl-trait/issue-55872-1.rs +++ b/tests/ui/impl-trait/issue-55872-1.rs @@ -13,6 +13,7 @@ impl Bar for S { //~^ ERROR impl has stricter requirements than trait //~| ERROR the trait bound `S: Copy` is not satisfied in `(S, T)` [E0277] //~| ERROR the trait bound `T: Copy` is not satisfied in `(S, T)` [E0277] + //~| ERROR type parameter `T` is part of concrete type (S::default(), T::default()) } } diff --git a/tests/ui/impl-trait/issue-55872-1.stderr b/tests/ui/impl-trait/issue-55872-1.stderr index 81759760bf13e..e048bec1b6d22 100644 --- a/tests/ui/impl-trait/issue-55872-1.stderr +++ b/tests/ui/impl-trait/issue-55872-1.stderr @@ -37,7 +37,13 @@ help: consider further restricting type parameter `T` with trait `Copy` LL | fn foo() -> Self::E { | +++++++++++++++++++ -error: aborting due to 3 previous errors +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-55872-1.rs:12:29 + | +LL | fn foo() -> Self::E { + | ^^^^^^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0276, E0277. For more information about an error, try `rustc --explain E0276`. diff --git a/tests/ui/impl-trait/issue-55872-2.rs b/tests/ui/impl-trait/issue-55872-2.rs index caca5c69a4aea..a3b2225126a22 100644 --- a/tests/ui/impl-trait/issue-55872-2.rs +++ b/tests/ui/impl-trait/issue-55872-2.rs @@ -11,9 +11,9 @@ pub trait Bar { impl Bar for S { type E = impl std::marker::Send; fn foo() -> Self::E { - async {} //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias //~| ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + async {} } } diff --git a/tests/ui/impl-trait/issue-55872-2.stderr b/tests/ui/impl-trait/issue-55872-2.stderr index b5b7f293a40b2..51a7dd00ade63 100644 --- a/tests/ui/impl-trait/issue-55872-2.stderr +++ b/tests/ui/impl-trait/issue-55872-2.stderr @@ -1,14 +1,14 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:14:9 + --> $DIR/issue-55872-2.rs:13:20 | -LL | async {} - | ^^^^^^^^ +LL | fn foo() -> Self::E { + | ^^^^^^^ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:14:9 + --> $DIR/issue-55872-2.rs:13:20 | -LL | async {} - | ^^^^^^^^ +LL | fn foo() -> Self::E { + | ^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/impl-trait/issue-55872-3.rs b/tests/ui/impl-trait/issue-55872-3.rs index 50b9eb3ce0ecd..698e7f362341e 100644 --- a/tests/ui/impl-trait/issue-55872-3.rs +++ b/tests/ui/impl-trait/issue-55872-3.rs @@ -13,6 +13,7 @@ impl Bar for S { type E = impl std::marker::Copy; fn foo() -> Self::E { //~^ ERROR : Copy` is not satisfied [E0277] + //~| ERROR type parameter `T` is part of concrete type async {} } } diff --git a/tests/ui/impl-trait/issue-55872-3.stderr b/tests/ui/impl-trait/issue-55872-3.stderr index 827155d48b827..3281dcc3501d6 100644 --- a/tests/ui/impl-trait/issue-55872-3.stderr +++ b/tests/ui/impl-trait/issue-55872-3.stderr @@ -1,12 +1,18 @@ -error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:16:9: 16:14}: Copy` is not satisfied +error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}: Copy` is not satisfied --> $DIR/issue-55872-3.rs:14:20 | LL | fn foo() -> Self::E { - | ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:16:9: 16:14}` -LL | + | ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}` +... LL | async {} - | -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:16:9: 16:14}` here + | -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}` here -error: aborting due to 1 previous error +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-55872-3.rs:14:20 + | +LL | fn foo() -> Self::E { + | ^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/issue-55872.rs b/tests/ui/impl-trait/issue-55872.rs index 10850f0a9335e..b76f8182b204f 100644 --- a/tests/ui/impl-trait/issue-55872.rs +++ b/tests/ui/impl-trait/issue-55872.rs @@ -10,8 +10,8 @@ impl Bar for S { type E = impl Copy; fn foo() -> Self::E { - || () //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + || () } } diff --git a/tests/ui/impl-trait/issue-55872.stderr b/tests/ui/impl-trait/issue-55872.stderr index 4ff8527bbe9d1..54e852f8edf8d 100644 --- a/tests/ui/impl-trait/issue-55872.stderr +++ b/tests/ui/impl-trait/issue-55872.stderr @@ -1,8 +1,8 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872.rs:13:9 + --> $DIR/issue-55872.rs:12:20 | -LL | || () - | ^^^^^ +LL | fn foo() -> Self::E { + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/issue-99073-2.rs b/tests/ui/impl-trait/issue-99073-2.rs index 37ea211bec368..bfb8850857de2 100644 --- a/tests/ui/impl-trait/issue-99073-2.rs +++ b/tests/ui/impl-trait/issue-99073-2.rs @@ -7,8 +7,7 @@ fn main() { fn test(t: T, recurse: bool) -> impl Display { let f = || { let i: u32 = test::(-1, false); - //~^ ERROR concrete type differs from previous defining opaque type use - //~| ERROR expected generic type parameter, found `i32` + //~^ ERROR expected generic type parameter, found `i32` println!("{i}"); }; if recurse { diff --git a/tests/ui/impl-trait/issue-99073-2.stderr b/tests/ui/impl-trait/issue-99073-2.stderr index 0bcac7c7c534b..519530b539625 100644 --- a/tests/ui/impl-trait/issue-99073-2.stderr +++ b/tests/ui/impl-trait/issue-99073-2.stderr @@ -1,15 +1,3 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/issue-99073-2.rs:9:22 - | -LL | let i: u32 = test::(-1, false); - | ^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `u32` - | -note: previous use here - --> $DIR/issue-99073-2.rs:7:45 - | -LL | fn test(t: T, recurse: bool) -> impl Display { - | ^^^^^^^^^^^^ - error[E0792]: expected generic type parameter, found `i32` --> $DIR/issue-99073-2.rs:9:22 | @@ -19,6 +7,6 @@ LL | let f = || { LL | let i: u32 = test::(-1, false); | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/issue-99073.rs b/tests/ui/impl-trait/issue-99073.rs index b4ef3e66f964a..d2a2a61a40845 100644 --- a/tests/ui/impl-trait/issue-99073.rs +++ b/tests/ui/impl-trait/issue-99073.rs @@ -4,6 +4,5 @@ fn main() { fn fix(f: F) -> impl Fn() { move || f(fix(&f)) - //~^ ERROR concrete type differs from previous defining opaque type use - //~| ERROR expected generic type parameter, found `&F` + //~^ ERROR expected generic type parameter, found `&F` } diff --git a/tests/ui/impl-trait/issue-99073.stderr b/tests/ui/impl-trait/issue-99073.stderr index 19854ef894051..1917c1bfd6b4f 100644 --- a/tests/ui/impl-trait/issue-99073.stderr +++ b/tests/ui/impl-trait/issue-99073.stderr @@ -1,23 +1,11 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/issue-99073.rs:6:13 - | -LL | move || f(fix(&f)) - | ^^^^^^^ expected `{closure@$DIR/issue-99073.rs:6:3: 6:10}`, got `G` - | -note: previous use here - --> $DIR/issue-99073.rs:5:36 - | -LL | fn fix(f: F) -> impl Fn() { - | ^^^^^^^^^ - error[E0792]: expected generic type parameter, found `&F` - --> $DIR/issue-99073.rs:6:11 + --> $DIR/issue-99073.rs:6:13 | LL | fn fix(f: F) -> impl Fn() { | - this generic parameter must be used with a generic type parameter LL | move || f(fix(&f)) - | ^^^^^^^^^^ + | ^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs new file mode 100644 index 0000000000000..a76ed7b094745 --- /dev/null +++ b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.rs @@ -0,0 +1,17 @@ +// Regression test for #112201. This recursive call previously meant that +// we delay an error when checking opaques at the end of writeback but don't +// encounter that incorrect defining use during borrowck as it's in dead code. + +pub fn wrap(x: T) -> impl Sized { + x +} + +fn repeat_helper(x: T) -> impl Sized { + return x; + repeat_helper(wrap(x)) + //~^ ERROR expected generic type parameter, found `impl Sized` + //~| ERROR type parameter `T` is part of concrete type +} + + +fn main() {} diff --git a/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr new file mode 100644 index 0000000000000..f507ad385a171 --- /dev/null +++ b/tests/ui/impl-trait/issues/fuzzer-ice-issue-112201.stderr @@ -0,0 +1,18 @@ +error[E0792]: expected generic type parameter, found `impl Sized` + --> $DIR/fuzzer-ice-issue-112201.rs:11:5 + | +LL | fn repeat_helper(x: T) -> impl Sized { + | - this generic parameter must be used with a generic type parameter +LL | return x; +LL | repeat_helper(wrap(x)) + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/fuzzer-ice-issue-112201.rs:11:5 + | +LL | repeat_helper(wrap(x)) + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs index 9e8ea439dde95..cf82467b72ee3 100644 --- a/tests/ui/impl-trait/issues/issue-86800.rs +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -29,7 +29,6 @@ where F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f, { f - //~^ ERROR expected generic lifetime parameter, found `'_` } impl Context { @@ -39,7 +38,6 @@ impl Context { &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>, ) -> TransactionResult { - //~^ ERROR expected generic lifetime parameter, found `'_` let mut conn = Connection {}; let mut transaction = TestTransaction { conn: &mut conn }; f(&mut transaction).await diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr index 80aa5d75c3c69..e122fc229ccd3 100644 --- a/tests/ui/impl-trait/issues/issue-86800.stderr +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -12,7 +12,7 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future $DIR/issue-86800.rs:37:14 + --> $DIR/issue-86800.rs:36:14 | LL | async fn do_transaction( | ^^^^^^^^^^^^^^ @@ -24,30 +24,5 @@ note: this opaque type is supposed to be constrained LL | type TransactionFuture<'__, O> = impl '__ + Future>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-86800.rs:31:5 - | -LL | type TransactionFuture<'__, O> = impl '__ + Future>; - | --- this generic parameter must be used with a generic lifetime parameter -... -LL | f - | ^ - -error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-86800.rs:41:31 - | -LL | type TransactionFuture<'__, O> = impl '__ + Future>; - | --- this generic parameter must be used with a generic lifetime parameter -... -LL | ) -> TransactionResult { - | _______________________________^ -LL | | -LL | | let mut conn = Connection {}; -LL | | let mut transaction = TestTransaction { conn: &mut conn }; -LL | | f(&mut transaction).await -LL | | } - | |_____^ - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr b/tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr new file mode 100644 index 0000000000000..08c8365b1805a --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/as-projection-term.next.stderr @@ -0,0 +1,12 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/as-projection-term.rs:14:19 + | +LL | fn recur<'a>() -> impl Sized + 'a { + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | prove_proj(|| recur()); + | ^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/non-defining-uses/as-projection-term.rs b/tests/ui/impl-trait/non-defining-uses/as-projection-term.rs new file mode 100644 index 0000000000000..4c5adc7a00ab1 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/as-projection-term.rs @@ -0,0 +1,17 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[current] check-pass + +fn prove_proj(_: impl FnOnce() -> R) {} +fn recur<'a>() -> impl Sized + 'a { + // The closure has the signature `fn() -> opaque<'1>`. `prove_proj` + // requires us to prove `>::Output = opaque<'2>`. + // The old solver uses `replace_opaque_types_with_infer` during normalization + // to replace `opaque<'2>` with its hidden type. If that hidden type is still an + // inference variable at this point, we unify it with `opaque<'1>` and + // end up ignoring that defining use as the hidden type is equal to its key. + prove_proj(|| recur()); + //[next]~^ ERROR expected generic lifetime parameter, found `'_` +} +fn main() {} diff --git a/tests/ui/impl-trait/recursive-ice-101862.stderr b/tests/ui/impl-trait/recursive-ice-101862.stderr index 970373422e8a5..85745c25e2bfa 100644 --- a/tests/ui/impl-trait/recursive-ice-101862.stderr +++ b/tests/ui/impl-trait/recursive-ice-101862.stderr @@ -1,3 +1,12 @@ +error[E0792]: expected generic type parameter, found `&str` + --> $DIR/recursive-ice-101862.rs:6:19 + | +LL | pub fn ice(x: impl AsRef) -> impl IntoIterator { + | --------------- this generic parameter must be used with a generic type parameter +LL | +LL | vec![].append(&mut ice(x.as_ref())); + | ^^^^^^^^^^^^^^^^^^^^ + warning: function cannot return without recursing --> $DIR/recursive-ice-101862.rs:4:1 | @@ -10,15 +19,6 @@ LL | vec![].append(&mut ice(x.as_ref())); = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0792]: expected generic type parameter, found `&str` - --> $DIR/recursive-ice-101862.rs:6:19 - | -LL | pub fn ice(x: impl AsRef) -> impl IntoIterator { - | --------------- this generic parameter must be used with a generic type parameter -LL | -LL | vec![].append(&mut ice(x.as_ref())); - | ^^^^^^^^^^^^^^^^^^^^ - error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/rpit/early_bound.rs b/tests/ui/impl-trait/rpit/early_bound.rs index 005bcea59f243..0337f605e487b 100644 --- a/tests/ui/impl-trait/rpit/early_bound.rs +++ b/tests/ui/impl-trait/rpit/early_bound.rs @@ -1,11 +1,10 @@ use std::convert::identity; fn test<'a: 'a>(n: bool) -> impl Sized + 'a { - //~^ ERROR concrete type differs from previous defining opaque type use let true = n else { loop {} }; let _ = || { let _ = identity::<&'a ()>(test(false)); - //~^ ERROR expected generic lifetime parameter, found `'_` + //~^ ERROR concrete type differs from previous defining opaque type use }; loop {} } diff --git a/tests/ui/impl-trait/rpit/early_bound.stderr b/tests/ui/impl-trait/rpit/early_bound.stderr index 230dde95764bf..d00005f20d4a3 100644 --- a/tests/ui/impl-trait/rpit/early_bound.stderr +++ b/tests/ui/impl-trait/rpit/early_bound.stderr @@ -1,24 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/early_bound.rs:3:29 + --> $DIR/early_bound.rs:6:36 | -LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a { - | ^^^^^^^^^^^^^^^ expected `&()`, got `()` +LL | let _ = identity::<&'a ()>(test(false)); + | ^^^^^^^^^^^ expected `()`, got `&()` | note: previous use here - --> $DIR/early_bound.rs:7:36 - | -LL | let _ = identity::<&'a ()>(test(false)); - | ^^^^^^^^^^^ - -error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/early_bound.rs:7:17 + --> $DIR/early_bound.rs:3:29 | LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a { - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | let _ = identity::<&'a ()>(test(false)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/rpit/non-defining-use.rs b/tests/ui/impl-trait/rpit/non-defining-use.rs index 255a8929a8786..3ab0e0ee4e29f 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use.rs +++ b/tests/ui/impl-trait/rpit/non-defining-use.rs @@ -6,8 +6,7 @@ fn foo() -> impl Sized { fn bar(val: T) -> impl Sized { let _: u8 = bar(0u8); - //~^ ERROR concrete type differs from previous defining opaque type use - //~| ERROR expected generic type parameter, found `u8` + //~^ ERROR expected generic type parameter, found `u8` val } diff --git a/tests/ui/impl-trait/rpit/non-defining-use.stderr b/tests/ui/impl-trait/rpit/non-defining-use.stderr index 10a8232e646d0..c2b1b0f824976 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use.stderr +++ b/tests/ui/impl-trait/rpit/non-defining-use.stderr @@ -1,31 +1,19 @@ error[E0792]: expected generic type parameter, found `u8` - --> $DIR/non-defining-use.rs:4:12 + --> $DIR/non-defining-use.rs:4:17 | LL | fn foo() -> impl Sized { | - this generic parameter must be used with a generic type parameter LL | let _: () = foo::(); - | ^^ - -error: concrete type differs from previous defining opaque type use - --> $DIR/non-defining-use.rs:8:17 - | -LL | let _: u8 = bar(0u8); - | ^^^^^^^^ expected `T`, got `u8` - | -note: previous use here - --> $DIR/non-defining-use.rs:7:22 - | -LL | fn bar(val: T) -> impl Sized { - | ^^^^^^^^^^ + | ^^^^^^^^^^^ error[E0792]: expected generic type parameter, found `u8` - --> $DIR/non-defining-use.rs:8:12 + --> $DIR/non-defining-use.rs:8:17 | LL | fn bar(val: T) -> impl Sized { | - this generic parameter must be used with a generic type parameter LL | let _: u8 = bar(0u8); - | ^^ + | ^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.stderr b/tests/ui/impl-trait/transmute/in-defining-scope.stderr index 7172bfdf0d7e2..3153569517835 100644 --- a/tests/ui/impl-trait/transmute/in-defining-scope.stderr +++ b/tests/ui/impl-trait/transmute/in-defining-scope.stderr @@ -9,6 +9,31 @@ note: ...which requires computing type of opaque `foo::{opaque#0}`... | LL | fn foo() -> impl Sized { | ^^^^^^^^^^ +note: ...which requires borrow-checking `foo`... + --> $DIR/in-defining-scope.rs:6:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `foo`... + --> $DIR/in-defining-scope.rs:6:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires checking if `foo` contains FFI-unwind calls... + --> $DIR/in-defining-scope.rs:6:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building MIR for `foo`... + --> $DIR/in-defining-scope.rs:6:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires match-checking `foo`... + --> $DIR/in-defining-scope.rs:6:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `foo`... --> $DIR/in-defining-scope.rs:6:1 | diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr index 0711af1cad405..11b57ad98c458 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr @@ -1,18 +1,5 @@ -error: item does not constrain `A::{opaque#0}` - --> $DIR/two_tait_defining_each_other2.rs:12:4 - | -LL | fn muh(x: A) -> B { - | ^^^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/two_tait_defining_each_other2.rs:6:10 - | -LL | type A = impl Foo; - | ^^^^^^^^ - error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other2.rs:15:5 + --> $DIR/two_tait_defining_each_other2.rs:14:5 | LL | x // B's hidden type is A (opaquely) | ^ one of the two opaque types used here has to be outside its defining scope @@ -28,5 +15,5 @@ note: opaque type being used as hidden type LL | type A = impl Foo; | ^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs index a3223b07a7ed4..6c454bba5023f 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs @@ -10,8 +10,7 @@ trait Foo {} #[define_opaque(A, B)] fn muh(x: A) -> B { - //[current]~^ ERROR: item does not constrain `A::{opaque#0}` - //[next]~^^ ERROR: cannot satisfy `_ == A` + //[next]~^ ERROR: cannot satisfy `_ == A` x // B's hidden type is A (opaquely) //[current]~^ ERROR opaque type's hidden type cannot be another opaque type } diff --git a/tests/crashes/132335.rs b/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs similarity index 74% rename from tests/crashes/132335.rs rename to tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs index 2294539cfcfa0..e5208e3e47d06 100644 --- a/tests/crashes/132335.rs +++ b/tests/ui/traits/next-solver/opaques/ambig-in-mir-typeck.rs @@ -1,5 +1,8 @@ -//@ known-bug: #132335 +// Regression test for #132335. This previously ICE'd due to ambiguity +// in MIR typeck. + //@ compile-flags: -Znext-solver=globally --crate-type lib --edition=2018 +//@ check-pass use core::future::Future; use core::pin::Pin; diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr index 5625cb24d4265..ff0afd319d90d 100644 --- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr +++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr @@ -1,34 +1,54 @@ -error: unconstrained opaque type +error: item does not constrain `ex1::Tait1::{opaque#0}` + --> $DIR/no-define-in-wf-check.rs:21:8 + | +LL | fn foo(x: Tait1) -> impl Sized { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/no-define-in-wf-check.rs:19:18 | LL | type Tait1 = impl Sized; | ^^^^^^^^^^ - | - = note: `Tait1` must be used in combination with a concrete type within the same crate -error: unconstrained opaque type +error: item does not constrain `ex2::Tait1::{opaque#0}` + --> $DIR/no-define-in-wf-check.rs:31:8 + | +LL | fn foo(x: Tait1) -> Tait2 { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/no-define-in-wf-check.rs:28:18 | LL | type Tait1 = impl Sized; | ^^^^^^^^^^ - | - = note: `Tait1` must be used in combination with a concrete type within the same crate -error: unconstrained opaque type +error: item does not constrain `ex3::Tait1::{opaque#0}` + --> $DIR/no-define-in-wf-check.rs:43:8 + | +LL | fn foo(x: Tait1) -> Tait2 { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/no-define-in-wf-check.rs:38:18 | LL | type Tait1 = impl Sized; | ^^^^^^^^^^ - | - = note: `Tait1` must be used in combination with a concrete type within the same crate -error: unconstrained opaque type +error: item does not constrain `ex4::Tait1::{opaque#0}` + --> $DIR/no-define-in-wf-check.rs:64:8 + | +LL | fn foo(x: Tait1) -> Tait2 { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained --> $DIR/no-define-in-wf-check.rs:50:18 | LL | type Tait1 = impl Sized; | ^^^^^^^^^^ - | - = note: `Tait1` must be used in combination with a concrete type within the same crate error: aborting due to 4 previous errors diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs index 31d07d89d8dc8..26c17edeb93bb 100644 --- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs +++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs @@ -17,38 +17,37 @@ mod ex0 { } mod ex1 { type Tait1 = impl Sized; - //[current]~^ ERROR unconstrained opaque type #[define_opaque(Tait1)] fn foo(x: Tait1) -> impl Sized { + //[current]~^ ERROR item does not constrain `ex1::Tait1::{opaque#0}` let () = x; } } mod ex2 { type Tait1 = impl Sized; - //[current]~^ ERROR unconstrained opaque type type Tait2 = impl Sized; #[define_opaque(Tait1, Tait2)] fn foo(x: Tait1) -> Tait2 { + //[current]~^ ERROR item does not constrain `ex2::Tait1::{opaque#0}` let () = x; } } mod ex3 { type Tait1 = impl Sized; - //[current]~^ ERROR unconstrained opaque type trait Something {} impl Something for T {} type Tait2 = impl Something; #[define_opaque(Tait1, Tait2)] fn foo(x: Tait1) -> Tait2 { + //[current]~^ ERROR item does not constrain `ex3::Tait1::{opaque#0}` let () = x; } } mod ex4 { type Tait1 = impl Sized; - //[current]~^ ERROR unconstrained opaque type trait Trait { type Assoc; } @@ -63,6 +62,7 @@ mod ex4 { type Tait2 = impl Trait<(), Assoc = impl Trait>; #[define_opaque(Tait1, Tait2)] fn foo(x: Tait1) -> Tait2 { + //[current]~^ ERROR item does not constrain `ex4::Tait1::{opaque#0}` let () = x; } } diff --git a/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs b/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs new file mode 100644 index 0000000000000..8388751fea64d --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/revealing-use-in-nested-body.rs @@ -0,0 +1,11 @@ +// Regression test for #137751. This previously ICE'd as +// we did not provide the hidden type of the opaque inside +// of the async block. This caused borrowck of the recursive +// call to ICE. + +//@ compile-flags: --edition=2021 +//@ check-pass +async fn test() { + Box::pin(test()).await; +} +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs index b6870b1645096..5c93bd14d3252 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs @@ -12,7 +12,6 @@ pub enum UninhabitedVariants { #[define_opaque(Alias)] fn uwu(x: UninhabitedVariants) { - //~^ ERROR item does not constrain match x {} //~^ ERROR non-exhaustive patterns } diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr index 59909197e7bc3..72fae0173cbb5 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr @@ -26,21 +26,8 @@ help: add missing generic argument LL | Tuple(Alias), | +++ -error: item does not constrain `Alias::{opaque#0}` - --> $DIR/bad-tait-no-substs.rs:14:4 - | -LL | fn uwu(x: UninhabitedVariants) { - | ^^^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/bad-tait-no-substs.rs:5:21 - | -LL | type Alias<'a, U> = impl Trait; - | ^^^^^^^^^^^^^ - error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` not covered - --> $DIR/bad-tait-no-substs.rs:16:11 + --> $DIR/bad-tait-no-substs.rs:15:11 | LL | match x {} | ^ pattern `UninhabitedVariants::Tuple(_)` not covered @@ -60,7 +47,7 @@ LL + UninhabitedVariants::Tuple(_) => todo!(), LL ~ } | -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0004, E0106, E0107. For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.rs b/tests/ui/type-alias-impl-trait/bound_reduction2.rs index 78288caffefe3..fadc2beba7191 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction2.rs +++ b/tests/ui/type-alias-impl-trait/bound_reduction2.rs @@ -14,6 +14,6 @@ impl Trait for () {} #[define_opaque(Foo)] fn foo_desugared(_: T) -> Foo { - () //~^ ERROR expected generic type parameter, found `::Assoc` + () } diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr index 289826cc1d02e..53b20d61025f0 100644 --- a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,11 +1,11 @@ error[E0792]: expected generic type parameter, found `::Assoc` - --> $DIR/bound_reduction2.rs:17:5 + --> $DIR/bound_reduction2.rs:16:46 | LL | type Foo = impl Trait; | - this generic parameter must be used with a generic type parameter ... -LL | () - | ^^ +LL | fn foo_desugared(_: T) -> Foo { + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs index e56f60a6693e6..b5a9bf4a59f36 100644 --- a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs @@ -9,7 +9,7 @@ fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> { #[define_opaque(Opaque)] fn get_iter<'a>() -> impl IntoIterator> { - //~^ ERROR: item does not constrain + //~^ ERROR item does not constrain `Opaque::{opaque#0}` None::> } diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_defining_uses.rs index 246f255e8fcff..547696b83da56 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses.rs @@ -12,6 +12,6 @@ fn foo() -> Foo { #[define_opaque(Foo)] fn bar() -> Foo { + //~^ ERROR concrete type differs 42i32 - //~^ ERROR concrete type differs from previous } diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr index 9a7f4b416f4b4..36d7e33dca0aa 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses.rs:15:5 + --> $DIR/different_defining_uses.rs:14:13 | -LL | 42i32 - | ^^^^^ expected `&'static str`, got `i32` +LL | fn bar() -> Foo { + | ^^^ expected `&str`, got `i32` | note: previous use here - --> $DIR/different_defining_uses.rs:10:5 + --> $DIR/different_defining_uses.rs:9:13 | -LL | "" - | ^^ +LL | fn foo() -> Foo { + | ^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs index e8c40e8bf926c..bbbc2086bdf5c 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs @@ -12,7 +12,6 @@ fn foo<'a, 'b>() -> Tait<'a> { } let x: Tait<'a> = (); x - //~^ ERROR concrete type differs from previous defining opaque type use } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr index d4bd397592477..4d7dd6b2ad5f5 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr @@ -1,15 +1,3 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/different_defining_uses_never_type-2.rs:14:5 - | -LL | x - | ^ expected `i32`, got `()` - | -note: previous use here - --> $DIR/different_defining_uses_never_type-2.rs:9:31 - | -LL | let y: Tait<'b> = 1i32; - | ^^^^ - error: concrete type differs from previous defining opaque type use --> $DIR/different_defining_uses_never_type-2.rs:9:31 | @@ -17,10 +5,10 @@ LL | let y: Tait<'b> = 1i32; | ^^^^ expected `()`, got `i32` | note: previous use here - --> $DIR/different_defining_uses_never_type-2.rs:8:14 + --> $DIR/different_defining_uses_never_type-2.rs:14:5 | -LL | if { return } { - | ^^^^^^ +LL | x + | ^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr index cb12fddd9a037..eb9001cc6244c 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr @@ -5,10 +5,10 @@ LL | let y: Tait = 1i32; | ^^^^ expected `()`, got `i32` | note: previous use here - --> $DIR/different_defining_uses_never_type-3.rs:13:22 + --> $DIR/different_defining_uses_never_type-3.rs:14:5 | -LL | let x: Tait = (); - | ^^ +LL | x + | ^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr index 38afa3cbcd0ec..0914dd1c546e4 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr @@ -2,13 +2,13 @@ error: concrete type differs from previous defining opaque type use --> $DIR/different_defining_uses_never_type.rs:14:13 | LL | fn bar() -> Foo { - | ^^^ expected `&'static str`, got `()` + | ^^^ expected `&str`, got `()` | note: previous use here - --> $DIR/different_defining_uses_never_type.rs:10:5 + --> $DIR/different_defining_uses_never_type.rs:9:13 | -LL | "" - | ^^ +LL | fn foo() -> Foo { + | ^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr index 21fab8180633f..78a9f6b636543 100644 --- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr @@ -5,10 +5,10 @@ LL | fn two() -> Tait { Two::<()>(todo!()) } | ^^^^ expected `One`, got `Two<()>` | note: previous use here - --> $DIR/different_defining_uses_never_type3.rs:7:20 + --> $DIR/different_defining_uses_never_type3.rs:7:13 | LL | fn one() -> Tait { One } - | ^^^ + | ^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs index 726820bbd5a14..c2578297006b3 100644 --- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs +++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs @@ -31,7 +31,6 @@ impl Fn(&'a ()) -> StateWidget<'a>> Widget<()> for StatefulWidget fn new_stateful_widget Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> { //~^ ERROR item does not constrain StatefulWidget(build) - //~^ ERROR expected generic lifetime parameter, found `'a` } fn main() { diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr index 4f5c65adab9cf..dee729e1f9f40 100644 --- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr +++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr @@ -24,17 +24,8 @@ note: this opaque type is supposed to be constrained LL | type StateWidget<'a> = impl Widget<&'a ()>; | ^^^^^^^^^^^^^^^^^^^ -error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/failed-to-normalize-ice-99945.rs:33:5 - | -LL | type StateWidget<'a> = impl Widget<&'a ()>; - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | StatefulWidget(build) - | ^^^^^^^^^^^^^^^^^^^^^ - error[E0308]: mismatched types - --> $DIR/failed-to-normalize-ice-99945.rs:38:29 + --> $DIR/failed-to-normalize-ice-99945.rs:37:29 | LL | type StateWidget<'a> = impl Widget<&'a ()>; | ------------------- the expected opaque type @@ -45,7 +36,6 @@ LL | new_stateful_widget(|_| ()).make_state(); = note: expected opaque type `StateWidget<'_>` found unit type `()` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0308, E0792. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs index d55a9a376b9fb..41fb6fe8587fc 100644 --- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs +++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs @@ -11,6 +11,6 @@ fn my_iter(t: T) -> MyIter { #[define_opaque(MyIter)] fn my_iter2(t: T) -> MyIter { - Some(t).into_iter() //~^ ERROR concrete type differs from previous + Some(t).into_iter() } diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr index 6d3279144d8fb..b4be8542163fe 100644 --- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr +++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_different_defining_uses.rs:14:5 + --> $DIR/generic_different_defining_uses.rs:13:25 | -LL | Some(t).into_iter() - | ^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once`, got `std::option::IntoIter` +LL | fn my_iter2(t: T) -> MyIter { + | ^^^^^^^^^ expected `std::iter::Once`, got `std::option::IntoIter` | note: previous use here - --> $DIR/generic_different_defining_uses.rs:9:5 + --> $DIR/generic_different_defining_uses.rs:8:24 | -LL | std::iter::once(t) - | ^^^^^^^^^^^^^^^^^^ +LL | fn my_iter(t: T) -> MyIter { + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index e8ed38a24ceb0..6e791a3bdb9dc 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -20,8 +20,8 @@ type TwoConsts = impl Debug; #[define_opaque(TwoTys)] fn one_ty(t: T) -> TwoTys { - t //~^ ERROR non-defining opaque type use in defining scope + t } #[define_opaque(TwoLifetimes)] @@ -32,6 +32,6 @@ fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { #[define_opaque(TwoConsts)] fn one_const(t: *mut [u8; N]) -> TwoConsts { - t //~^ ERROR non-defining opaque type use in defining scope + t } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index 3e048c8138d04..022e534df1a29 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -1,8 +1,8 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:23:5 + --> $DIR/generic_duplicate_param_use.rs:22:30 | -LL | t - | ^ +LL | fn one_ty(t: T) -> TwoTys { + | ^^^^^^^^^^^^ | note: type used multiple times --> $DIR/generic_duplicate_param_use.rs:15:13 @@ -23,10 +23,10 @@ LL | type TwoLifetimes<'a, 'b> = impl Debug; | ^^ ^^ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:35:5 + --> $DIR/generic_duplicate_param_use.rs:34:50 | -LL | t - | ^ +LL | fn one_const(t: *mut [u8; N]) -> TwoConsts { + | ^^^^^^^^^^^^^^^ | note: constant used multiple times --> $DIR/generic_duplicate_param_use.rs:19:16 diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs index f732b23339618..873c7b614b69d 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -14,6 +14,6 @@ fn two(t: T, _: U) -> Two { #[define_opaque(Two)] fn three(_: T, u: U) -> Two { - u //~^ ERROR concrete type differs + u } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr index b0a1bd77f8578..3f5f2c93c59d2 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use3.rs:17:5 + --> $DIR/generic_duplicate_param_use3.rs:16:38 | -LL | u - | ^ expected `T`, got `U` +LL | fn three(_: T, u: U) -> Two { + | ^^^^^^^^^ expected `T`, got `U` | note: previous use here - --> $DIR/generic_duplicate_param_use3.rs:12:5 + --> $DIR/generic_duplicate_param_use3.rs:11:36 | -LL | t - | ^ +LL | fn two(t: T, _: U) -> Two { + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs index d450bef57581d..1d4d3ab737f35 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs @@ -14,6 +14,6 @@ fn two(t: T, u: U) -> Two { #[define_opaque(Two)] fn three(t: T, u: U) -> Two { - (u, t) //~^ ERROR concrete type differs + (u, t) } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr index b8a2a93741614..59b37a8b792c0 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use5.rs:17:5 + --> $DIR/generic_duplicate_param_use5.rs:16:45 | -LL | (u, t) - | ^^^^^^ expected `(T, U)`, got `(U, T)` +LL | fn three(t: T, u: U) -> Two { + | ^^^^^^^^^ expected `(T, U)`, got `(U, T)` | note: previous use here - --> $DIR/generic_duplicate_param_use5.rs:12:5 + --> $DIR/generic_duplicate_param_use5.rs:11:43 | -LL | (t, u) - | ^^^^^^ +LL | fn two(t: T, u: U) -> Two { + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs index 24d03b9e60d24..961e2910dbeec 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs @@ -14,6 +14,6 @@ fn two(t: T, u: U) -> Two { #[define_opaque(Two)] fn three(t: T, u: U) -> Two { - (u, t) //~^ ERROR concrete type differs + (u, t) } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr index 983e58d3c7024..0940d6f541fc3 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use6.rs:17:5 + --> $DIR/generic_duplicate_param_use6.rs:16:52 | -LL | (u, t) - | ^^^^^^ expected `(T, T)`, got `(U, T)` +LL | fn three(t: T, u: U) -> Two { + | ^^^^^^^^^ expected `(T, T)`, got `(U, T)` | note: previous use here - --> $DIR/generic_duplicate_param_use6.rs:12:5 + --> $DIR/generic_duplicate_param_use6.rs:11:50 | -LL | (t, t) - | ^^^^^^ +LL | fn two(t: T, u: U) -> Two { + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs index 03057c8478253..d01cc7ff04eb4 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs @@ -13,6 +13,6 @@ fn two(t: T, _: U) -> Two { #[define_opaque(Two)] fn three(_: T, u: U) -> Two { - (u, 4u32) //~^ concrete type differs + (u, 4u32) } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr index 48c98c1e2b15c..f9615d455d134 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use8.rs:16:5 + --> $DIR/generic_duplicate_param_use8.rs:15:45 | -LL | (u, 4u32) - | ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)` +LL | fn three(_: T, u: U) -> Two { + | ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)` | note: previous use here - --> $DIR/generic_duplicate_param_use8.rs:11:5 + --> $DIR/generic_duplicate_param_use8.rs:10:43 | -LL | (t, 4u32) - | ^^^^^^^^^ +LL | fn two(t: T, _: U) -> Two { + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs index 74176550ab242..ec03ff1675edb 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs @@ -18,6 +18,6 @@ fn two(t: T, u: U) -> Two { #[define_opaque(Two)] fn three(t: T, u: U) -> Two { - (t, u, 42) //~^ ERROR concrete type differs + (t, u, 42) } diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr index 542324c949f19..df9984cd07392 100644 --- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr +++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use9.rs:21:5 + --> $DIR/generic_duplicate_param_use9.rs:20:45 | -LL | (t, u, 42) - | ^^^^^^^^^^ expected `(A, B, ::Bar)`, got `(A, B, i32)` +LL | fn three(t: T, u: U) -> Two { + | ^^^^^^^^^ expected `(A, B, ::Bar)`, got `(A, B, i32)` | note: previous use here - --> $DIR/generic_duplicate_param_use9.rs:16:5 + --> $DIR/generic_duplicate_param_use9.rs:15:49 | -LL | (t, u, T::BAR) - | ^^^^^^^^^^^^^^ +LL | fn two(t: T, u: U) -> Two { + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs index 7791410294c0d..cf38c93bd921e 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -14,8 +14,8 @@ type OneConst = impl Debug; #[define_opaque(OneTy)] fn concrete_ty() -> OneTy { - 5u32 //~^ ERROR: expected generic type parameter, found `u32` + 5u32 } #[define_opaque(OneLifetime)] @@ -26,6 +26,6 @@ fn concrete_lifetime() -> OneLifetime<'static> { #[define_opaque(OneConst)] fn concrete_const() -> OneConst<{ 123 }> { - 7u32 //~^ ERROR: expected generic constant parameter, found `123` + 7u32 } diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr index 1b0ce7cc619f5..71e415271ee82 100644 --- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -1,11 +1,11 @@ error[E0792]: expected generic type parameter, found `u32` - --> $DIR/generic_nondefining_use.rs:17:5 + --> $DIR/generic_nondefining_use.rs:16:21 | LL | type OneTy = impl Debug; | - this generic parameter must be used with a generic type parameter ... -LL | 5u32 - | ^^^^ +LL | fn concrete_ty() -> OneTy { + | ^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'static` --> $DIR/generic_nondefining_use.rs:23:5 @@ -17,13 +17,13 @@ LL | 6u32 | ^^^^ error[E0792]: expected generic constant parameter, found `123` - --> $DIR/generic_nondefining_use.rs:29:5 + --> $DIR/generic_nondefining_use.rs:28:24 | LL | type OneConst = impl Debug; | -------------- this generic parameter must be used with a generic constant parameter ... -LL | 7u32 - | ^^^^ +LL | fn concrete_const() -> OneConst<{ 123 }> { + | ^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.rs b/tests/ui/type-alias-impl-trait/generic_not_used.rs index 6042cdd30a940..f270f65f43ed9 100644 --- a/tests/ui/type-alias-impl-trait/generic_not_used.rs +++ b/tests/ui/type-alias-impl-trait/generic_not_used.rs @@ -7,6 +7,6 @@ type WrongGeneric = impl 'static; #[define_opaque(WrongGeneric)] fn wrong_generic(_: U, v: V) -> WrongGeneric { - v //~^ ERROR type parameter `V` is part of concrete type but not used in parameter list + v } diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.stderr b/tests/ui/type-alias-impl-trait/generic_not_used.stderr index 5fe2fefcecfd0..a480040006eaf 100644 --- a/tests/ui/type-alias-impl-trait/generic_not_used.stderr +++ b/tests/ui/type-alias-impl-trait/generic_not_used.stderr @@ -5,10 +5,10 @@ LL | type WrongGeneric = impl 'static; | ^^^^^^^^^^^^ error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/generic_not_used.rs:10:5 + --> $DIR/generic_not_used.rs:9:57 | -LL | v - | ^ +LL | fn wrong_generic(_: U, v: V) -> WrongGeneric { + | ^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index cbd8150d11775..4b4db8ec2ed3b 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -10,18 +10,15 @@ use std::future::Future; type FutNothing<'a> = impl 'a + Future; async fn operation(_: &mut ()) -> () { - //~^ ERROR: concrete type differs from previous call(operation).await - //~^ ERROR: expected generic lifetime parameter, found `'any` + //~^ ERROR: concrete type differs from previous } #[define_opaque(FutNothing)] async fn call(_f: F) -//~^ ERROR item does not constrain +//~^ ERROR item does not constrain `FutNothing::{opaque#0}` where for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>, -{ - //~^ ERROR: expected generic lifetime parameter, found `'any` -} +{} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 2c0be0cbcdca6..2aacf9698379b 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -1,5 +1,5 @@ error: item does not constrain `FutNothing::{opaque#0}` - --> $DIR/hkl_forbidden4.rs:19:10 + --> $DIR/hkl_forbidden4.rs:18:10 | LL | async fn call(_f: F) | ^^^^ @@ -12,37 +12,16 @@ LL | type FutNothing<'a> = impl 'a + Future; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: concrete type differs from previous defining opaque type use - --> $DIR/hkl_forbidden4.rs:12:1 + --> $DIR/hkl_forbidden4.rs:13:5 | -LL | async fn operation(_: &mut ()) -> () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body of operation()}` +LL | call(operation).await + | ^^^^^^^^^^^^^^^ expected `{async fn body of operation()}`, got `FutNothing<'_>` | note: previous use here - --> $DIR/hkl_forbidden4.rs:14:5 - | -LL | call(operation).await - | ^^^^^^^^^^^^^^^ - -error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:14:5 + --> $DIR/hkl_forbidden4.rs:12:1 | LL | async fn operation(_: &mut ()) -> () { - | - this generic parameter must be used with a generic lifetime parameter -LL | -LL | call(operation).await - | ^^^^^^^^^^^^^^^ - -error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:23:1 - | -LL | type FutNothing<'a> = impl 'a + Future; - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | / { -LL | | -LL | | } - | |_^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr index 114cac64573ce..9fcb26c20a682 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr +++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr @@ -20,6 +20,41 @@ error[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}` LL | type Bar = impl Sized; | ^^^^^^^^^^ | +note: ...which requires borrow-checking `foo`... + --> $DIR/in-where-clause.rs:9:1 + | +LL | / fn foo() -> Bar +LL | | where +LL | | Bar: Send, + | |______________^ +note: ...which requires promoting constants in MIR for `foo`... + --> $DIR/in-where-clause.rs:9:1 + | +LL | / fn foo() -> Bar +LL | | where +LL | | Bar: Send, + | |______________^ +note: ...which requires checking if `foo` contains FFI-unwind calls... + --> $DIR/in-where-clause.rs:9:1 + | +LL | / fn foo() -> Bar +LL | | where +LL | | Bar: Send, + | |______________^ +note: ...which requires building MIR for `foo`... + --> $DIR/in-where-clause.rs:9:1 + | +LL | / fn foo() -> Bar +LL | | where +LL | | Bar: Send, + | |______________^ +note: ...which requires match-checking `foo`... + --> $DIR/in-where-clause.rs:9:1 + | +LL | / fn foo() -> Bar +LL | | where +LL | | Bar: Send, + | |______________^ note: ...which requires type-checking `foo`... --> $DIR/in-where-clause.rs:9:1 | diff --git a/tests/ui/type-alias-impl-trait/issue-109054.rs b/tests/ui/type-alias-impl-trait/issue-109054.rs index 0c9304a42f355..a8bb5ee3301fb 100644 --- a/tests/ui/type-alias-impl-trait/issue-109054.rs +++ b/tests/ui/type-alias-impl-trait/issue-109054.rs @@ -18,7 +18,7 @@ impl std::ops::Deref for CallMe { async move { *val * 2 } } - &inner //~ ERROR: expected generic lifetime parameter, found `'_` + &inner } } diff --git a/tests/ui/type-alias-impl-trait/issue-109054.stderr b/tests/ui/type-alias-impl-trait/issue-109054.stderr index 919b0a287c4f3..5ce6f54e5f9ad 100644 --- a/tests/ui/type-alias-impl-trait/issue-109054.stderr +++ b/tests/ui/type-alias-impl-trait/issue-109054.stderr @@ -11,15 +11,5 @@ note: this opaque type is supposed to be constrained LL | type ReturnType<'a> = impl std::future::Future + 'a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-109054.rs:21:9 - | -LL | type ReturnType<'a> = impl std::future::Future + 'a; - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | &inner - | ^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr index 3062e55dc4909..c8db9fdfc579e 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -9,6 +9,31 @@ note: ...which requires computing type of opaque `Bug::{opaque#0}`... | LL | type Bug = impl Fn(T) -> U + Copy; | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires borrow-checking `CONST_BUG`... + --> $DIR/issue-53092-2.rs:8:1 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `CONST_BUG`... + --> $DIR/issue-53092-2.rs:8:1 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `CONST_BUG`... + --> $DIR/issue-53092-2.rs:8:1 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building MIR for `CONST_BUG`... + --> $DIR/issue-53092-2.rs:8:1 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires match-checking `CONST_BUG`... + --> $DIR/issue-53092-2.rs:8:1 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `CONST_BUG`... --> $DIR/issue-53092-2.rs:8:1 | diff --git a/tests/ui/type-alias-impl-trait/issue-53598.rs b/tests/ui/type-alias-impl-trait/issue-53598.rs index e3e2787b66bb4..3262c69cf5a4e 100644 --- a/tests/ui/type-alias-impl-trait/issue-53598.rs +++ b/tests/ui/type-alias-impl-trait/issue-53598.rs @@ -17,8 +17,8 @@ impl Foo for S2 { type Item = impl Debug; fn foo(_: T) -> Self::Item { - S::(Default::default()) //~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + S::(Default::default()) } } diff --git a/tests/ui/type-alias-impl-trait/issue-53598.stderr b/tests/ui/type-alias-impl-trait/issue-53598.stderr index a31aabedba542..f1dd3c69443cf 100644 --- a/tests/ui/type-alias-impl-trait/issue-53598.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53598.stderr @@ -1,8 +1,8 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-53598.rs:20:9 + --> $DIR/issue-53598.rs:19:31 | -LL | S::(Default::default()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo(_: T) -> Self::Item { + | ^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-60564.rs b/tests/ui/type-alias-impl-trait/issue-60564.rs index f28258b3b2277..ae9a4d0267037 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.rs +++ b/tests/ui/type-alias-impl-trait/issue-60564.rs @@ -18,8 +18,8 @@ where type BitsIter = IterBitsIter; #[define_opaque(IterBitsIter)] fn iter_bits(self, n: u8) -> Self::BitsIter { - (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) //~^ ERROR expected generic type parameter, found `u8` + (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) } } diff --git a/tests/ui/type-alias-impl-trait/issue-60564.stderr b/tests/ui/type-alias-impl-trait/issue-60564.stderr index 6aaed7d4296a5..bfe8d92fedd3a 100644 --- a/tests/ui/type-alias-impl-trait/issue-60564.stderr +++ b/tests/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,11 +1,11 @@ error[E0792]: expected generic type parameter, found `u8` - --> $DIR/issue-60564.rs:21:9 + --> $DIR/issue-60564.rs:20:34 | LL | type IterBitsIter = impl std::iter::Iterator; | - this generic parameter must be used with a generic type parameter ... -LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn iter_bits(self, n: u8) -> Self::BitsIter { + | ^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr index 178aa5cf34535..e58b2d4aa6098 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr @@ -1,11 +1,11 @@ error[E0792]: expected generic type parameter, found `()` - --> $DIR/issue-68368-non-defining-use-2.rs:10:29 + --> $DIR/issue-68368-non-defining-use-2.rs:10:15 | LL | type Alias<'a, U> = impl Trait; | - this generic parameter must be used with a generic type parameter ... LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^ + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr index bfbd506a7a5c0..3ec19e206008d 100644 --- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr +++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -1,11 +1,11 @@ error[E0792]: expected generic type parameter, found `()` - --> $DIR/issue-68368-non-defining-use.rs:10:29 + --> $DIR/issue-68368-non-defining-use.rs:10:15 | LL | type Alias<'a, U> = impl Trait; | - this generic parameter must be used with a generic type parameter ... LL | fn f<'a>() -> Alias<'a, ()> {} - | ^^ + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs index 18afc54dbdc6e..9e0c8fbbd269a 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.rs +++ b/tests/ui/type-alias-impl-trait/issue-77179.rs @@ -6,9 +6,9 @@ type Pointer = impl std::ops::Deref; #[define_opaque(Pointer)] fn test() -> Pointer<_> { - //~^ ERROR: the placeholder `_` is not allowed within types + //~^ ERROR the placeholder `_` is not allowed within types + //~| ERROR expected generic type parameter, found `i32` Box::new(1) - //~^ ERROR: expected generic type parameter, found `i32` } fn main() { @@ -17,5 +17,5 @@ fn main() { extern "Rust" { fn bar() -> Pointer<_>; - //~^ ERROR: the placeholder `_` is not allowed within types + //~^ ERROR the placeholder `_` is not allowed within types } diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr index bc11283f32821..c0f197ec48c37 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.stderr +++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr @@ -1,3 +1,12 @@ +error[E0792]: expected generic type parameter, found `i32` + --> $DIR/issue-77179.rs:8:14 + | +LL | type Pointer = impl std::ops::Deref; + | - this generic parameter must be used with a generic type parameter +... +LL | fn test() -> Pointer<_> { + | ^^^^^^^^^^ + error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-77179.rs:8:22 | @@ -13,15 +22,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | fn bar() -> Pointer<_>; | ^ not allowed in type signatures -error[E0792]: expected generic type parameter, found `i32` - --> $DIR/issue-77179.rs:10:5 - | -LL | type Pointer = impl std::ops::Deref; - | - this generic parameter must be used with a generic type parameter -... -LL | Box::new(1) - | ^^^^^^^^^^^ - error: aborting due to 3 previous errors Some errors have detailed explanations: E0121, E0792. diff --git a/tests/ui/type-alias-impl-trait/multi-error.rs b/tests/ui/type-alias-impl-trait/multi-error.rs index cb4ad4dc63372..2f42f14d4cb49 100644 --- a/tests/ui/type-alias-impl-trait/multi-error.rs +++ b/tests/ui/type-alias-impl-trait/multi-error.rs @@ -16,8 +16,8 @@ impl Foo for () { type Baz = impl Sized; fn foo() -> (Self::Bar, Self::Baz) { //~^ ERROR non-defining opaque type use + //~| ERROR expected generic type parameter, found `u32` ((), ()) - //~^ ERROR expected generic type parameter } } diff --git a/tests/ui/type-alias-impl-trait/multi-error.stderr b/tests/ui/type-alias-impl-trait/multi-error.stderr index 761f01b32acf4..3cb267c7c2615 100644 --- a/tests/ui/type-alias-impl-trait/multi-error.stderr +++ b/tests/ui/type-alias-impl-trait/multi-error.stderr @@ -11,13 +11,13 @@ LL | type Bar = impl Sized; | ^^^^^^^^^^ error[E0792]: expected generic type parameter, found `u32` - --> $DIR/multi-error.rs:19:9 + --> $DIR/multi-error.rs:17:17 | LL | type Bar = impl Sized; | - this generic parameter must be used with a generic type parameter -... -LL | ((), ()) - | ^^^^^^^^ +LL | type Baz = impl Sized; +LL | fn foo() -> (Self::Bar, Self::Baz) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs index 3dd2d53fe3d88..839ac47162382 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs @@ -8,7 +8,8 @@ type Y = impl std::fmt::Debug; #[define_opaque(Y)] fn g() -> (Y, Y) { - (42_i64, 60) //~ ERROR concrete type differs from previous defining opaque type use + //~^ ERROR concrete type differs from previous defining opaque type use + (42_i64, 60) } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr index d6558576577f4..e044cbe819e8c 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn-infer.rs:11:5 + --> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:17 | -LL | (42_i64, 60) - | ^^^^^^^^^^^^ - | | - | expected `i64`, got `i32` - | this expression supplies two conflicting concrete types for the same opaque type +LL | fn g() -> (Y, Y) { + | ^^^^^^^^^^^^^^^^^^ + | | + | expected `i64`, got `i32` + | this expression supplies two conflicting concrete types for the same opaque type error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs index 1357d772be17c..aa31901fc5ef3 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs @@ -8,8 +8,8 @@ type X = impl ToString; #[define_opaque(X)] fn f(a: A, b: B) -> (X, X) { - (a.clone(), a) //~^ ERROR concrete type differs from previous defining opaque type + (a.clone(), a) } fn main() { diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr index 15e9b6fbf7615..8d79b37f0f5f3 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn2.rs:11:5 + --> $DIR/multiple-def-uses-in-one-fn2.rs:10:63 | -LL | (a.clone(), a) - | ^^^^^^^^^^^^^^ - | | - | expected `A`, got `B` - | this expression supplies two conflicting concrete types for the same opaque type +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^ + | | + | expected `A`, got `B` + | this expression supplies two conflicting concrete types for the same opaque type error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs index 5adae476bfe29..57fa86f5eb75d 100644 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs +++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -12,7 +12,7 @@ pub fn get_foo() -> Foo { #[define_opaque(Foot, Foo)] pub fn get_foot(_: Foo) -> Foot { - //~^ ERROR: item does not constrain `Foo::{opaque#0}` + //~^ ERROR item does not constrain `Foo::{opaque#0}` get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type } diff --git a/tests/ui/type-alias-impl-trait/non-defining-method.stderr b/tests/ui/type-alias-impl-trait/non-defining-method.stderr index 49a393ca745bb..22f173b5be9fb 100644 --- a/tests/ui/type-alias-impl-trait/non-defining-method.stderr +++ b/tests/ui/type-alias-impl-trait/non-defining-method.stderr @@ -11,12 +11,12 @@ LL | type Bar = impl Sized; | ^^^^^^^^^^ error[E0792]: expected generic type parameter, found `u32` - --> $DIR/non-defining-method.rs:16:32 + --> $DIR/non-defining-method.rs:16:17 | LL | type Bar = impl Sized; | - this generic parameter must be used with a generic type parameter LL | fn foo() -> Self::Bar {} - | ^^ + | ^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index 75cc5948e93c7..53e312e3e64ff 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -1,26 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/normalize-hidden-types.rs:27:20 + --> $DIR/normalize-hidden-types.rs:38:22 | -LL | fn define() -> Opaque { - | ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` +LL | fn define_2() -> Opaque { dyn_hoops::(0) } + | ^^^^^^ expected `*const dyn for<'a> FnOnce(::Gat<'a>)`, got `*const dyn FnOnce(())` | note: previous use here - --> $DIR/normalize-hidden-types.rs:28:9 - | -LL | dyn_hoops::<_>(0) - | ^^^^^^^^^^^^^^^^^ - -error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:36:22 | LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } - | ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` - | -note: previous use here - --> $DIR/normalize-hidden-types.rs:36:31 - | -LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^ error[E0308]: mismatched types --> $DIR/normalize-hidden-types.rs:47:25 @@ -38,18 +26,6 @@ LL | let _: Opaque = dyn_hoops::(0); = help: consider constraining the associated type `::Gat<'_>` to `()` or calling a method that returns `::Gat<'_>` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -error: concrete type differs from previous defining opaque type use - --> $DIR/normalize-hidden-types.rs:57:25 - | -LL | let _: Opaque = dyn_hoops::<_>(0); - | ^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` - | -note: previous use here - --> $DIR/normalize-hidden-types.rs:58:9 - | -LL | None - | ^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/not_a_defining_use.rs b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs index d20622dc2e05e..cfbbf9ce487cb 100644 --- a/tests/ui/type-alias-impl-trait/not_a_defining_use.rs +++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs @@ -23,8 +23,8 @@ impl Bar for u32 { #[define_opaque(Two)] fn four(t: T) -> Two { - (t, ::FOO) //~^ ERROR concrete type differs + (t, ::FOO) } fn is_sync() {} diff --git a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr index d90e4531879b9..37d28b3883c27 100644 --- a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr +++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/not_a_defining_use.rs:26:5 + --> $DIR/not_a_defining_use.rs:25:36 | -LL | (t, ::FOO) - | ^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, ::Blub)` +LL | fn four(t: T) -> Two { + | ^^^^^^^^^ expected `(T, i8)`, got `(T, ::Blub)` | note: previous use here - --> $DIR/not_a_defining_use.rs:11:5 + --> $DIR/not_a_defining_use.rs:10:32 | -LL | (t, 5i8) - | ^^^^^^^^ +LL | fn three(t: T) -> Two { + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs index cfd7e1bf38235..94597adfed04f 100644 --- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs +++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs @@ -13,7 +13,8 @@ pub fn add( n: Diff, m: Diff, ) -> Diff { - move |x: usize| m(n(x)) //~ ERROR: concrete type differs + //~^ ERROR concrete type differs + move |x: usize| m(n(x)) } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr index 1a8ab21940498..59ff991761247 100644 --- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr +++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/recursive-fn-tait.rs:16:5 + --> $DIR/recursive-fn-tait.rs:15:6 | -LL | move |x: usize| m(n(x)) - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:16:5: 16:20}` +LL | ) -> Diff { + | ^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:17:5: 17:20}` | note: previous use here - --> $DIR/recursive-fn-tait.rs:8:5 + --> $DIR/recursive-fn-tait.rs:7:18 | -LL | |_: usize |loop {} - | ^^^^^^^^^^^^^^^^^^ +LL | pub fn lift() -> Diff { + | ^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs index 26ffd5c16a291..858f2a2feb678 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs @@ -13,8 +13,8 @@ fn transform() -> impl std::fmt::Display { } #[define_opaque(Op)] fn bad() -> Op { - transform::() //~^ ERROR concrete type differs from previous defining opaque type use + transform::() } fn main() { diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr index 259f3b2b9f3dc..e527b5bc7f8f8 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/recursive-tait-conflicting-defn-2.rs:16:5 + --> $DIR/recursive-tait-conflicting-defn-2.rs:15:13 | -LL | transform::() - | ^^^^^^^^^^^^^^^^^ expected `&'static &'static str`, got `impl std::fmt::Display` +LL | fn bad() -> Op { + | ^^ expected `&&str`, got `impl std::fmt::Display` | note: previous use here - --> $DIR/recursive-tait-conflicting-defn-2.rs:8:5 + --> $DIR/recursive-tait-conflicting-defn-2.rs:7:13 | -LL | &"hello world" - | ^^^^^^^^^^^^^^ +LL | fn foo() -> Op { + | ^^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs index c9e2773905d77..90581a98a3468 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs @@ -23,10 +23,9 @@ pub fn test() -> TestImpl { #[define_opaque(TestImpl)] fn make_option2() -> Option { + //~^ ERROR concrete type differs from previous defining opaque type use let inner = make_option().unwrap(); - Some(B { inner }) - //~^ ERROR concrete type differs from previous defining opaque type use } fn make_option() -> Option { diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr index 47471c9728c4a..256f13b622179 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/recursive-tait-conflicting-defn.rs:28:5 + --> $DIR/recursive-tait-conflicting-defn.rs:25:22 | -LL | Some(B { inner }) - | ^^^^^^^^^^^^^^^^^ expected `A`, got `B` +LL | fn make_option2() -> Option { + | ^^^^^^^^^^^^^^^^ expected `A`, got `B` | note: previous use here - --> $DIR/recursive-tait-conflicting-defn.rs:21:5 + --> $DIR/recursive-tait-conflicting-defn.rs:20:18 | -LL | A - | ^ +LL | pub fn test() -> TestImpl { + | ^^^^^^^^ error: aborting due to 1 previous error