From b54d72264aebf88e1099004c52aac6e4a06affd8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 10:38:54 +0000 Subject: [PATCH 01/15] Use `DefineOpaqueTypes::Yes` in diagnostics code --- .../src/traits/error_reporting/suggestions.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index fe2691e9d4d..af90372b97c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3842,7 +3842,9 @@ fn note_function_argument_obligation( self.probe(|_| { match self .at(&ObligationCause::misc(expr.span, body_id), param_env) - .eq(DefineOpaqueTypes::No, expected, actual) + // Doesn't actually matter if we define opaque types here, this is just used for + // diagnostics, and the result is never kept around. + .eq(DefineOpaqueTypes::Yes, expected, actual) { Ok(_) => (), // We ignore nested obligations here for now. Err(err) => type_diffs.push(err), From 150448d2e043061cfa39f94b0d87e1c80fb6a121 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 10:43:50 +0000 Subject: [PATCH 02/15] use `DefineOpaqueTypes::Yes` in rustdoc Since we have a `DefiningAnchor::Error`, we will reject registering hidden types already --- src/librustdoc/clean/blanket_impl.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 47cfe651e31..72d4cc7c465 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -47,7 +47,7 @@ pub(crate) fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec { // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. let Ok(eq_result) = infcx.at(&traits::ObligationCause::dummy(), param_env).eq( - DefineOpaqueTypes::No, + DefineOpaqueTypes::Yes, impl_trait_ref.self_ty(), impl_ty, ) else { From b8bd9815455ac3c1bff865dee30aa694ad19beb6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 11:30:57 +0000 Subject: [PATCH 03/15] Specialization already rejects defining opaque types --- .../min_specialization/impl-on-opaque.rs | 31 +++++++++++++++++++ .../min_specialization/impl-on-opaque2.rs | 28 +++++++++++++++++ .../min_specialization/impl-on-opaque2.stderr | 12 +++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/ui/specialization/min_specialization/impl-on-opaque.rs create mode 100644 tests/ui/specialization/min_specialization/impl-on-opaque2.rs create mode 100644 tests/ui/specialization/min_specialization/impl-on-opaque2.stderr diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque.rs b/tests/ui/specialization/min_specialization/impl-on-opaque.rs new file mode 100644 index 00000000000..7531dcaccf2 --- /dev/null +++ b/tests/ui/specialization/min_specialization/impl-on-opaque.rs @@ -0,0 +1,31 @@ +// Test that specializing on opaque types is allowed + +//@ check-pass + +#![feature(min_specialization, type_alias_impl_trait)] + +trait SpecTrait { + fn f(); +} + +impl SpecTrait for () { + default fn f() {} +} + +type Opaque = impl Tuple; + +trait Tuple {} + +impl Tuple for () {} + +impl SpecTrait for () { + fn f() {} +} + +impl SpecTrait for () { + fn f() {} +} + +fn foo() -> Opaque {} + +fn main() {} diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque2.rs b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs new file mode 100644 index 00000000000..0cd8be84ed3 --- /dev/null +++ b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs @@ -0,0 +1,28 @@ +// Test that specializing on opaque types is allowed + +#![feature(min_specialization, type_alias_impl_trait)] + +trait SpecTrait { + fn f(); +} + +impl SpecTrait for () { + default fn f() {} +} + +type Opaque = impl Tuple; + +trait Tuple {} + +impl Tuple for () {} + +// FIXME: this passes if we use `<(), ()>` here instead of `<(), Opaque>`, +// even though there can't be more overlap from the opaque version +impl SpecTrait<(), Opaque> for () { + //~^ ERROR: conflicting implementations + fn f() {} +} + +fn foo() -> Opaque {} + +fn main() {} diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque2.stderr b/tests/ui/specialization/min_specialization/impl-on-opaque2.stderr new file mode 100644 index 00000000000..3c0bc8f8f83 --- /dev/null +++ b/tests/ui/specialization/min_specialization/impl-on-opaque2.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `SpecTrait<(), ()>` for type `()` + --> $DIR/impl-on-opaque2.rs:21:1 + | +LL | impl SpecTrait for () { + | ------------------------------- first implementation here +... +LL | impl SpecTrait<(), Opaque> for () { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. From 82ceed2add79244d53a960735a68ce85d55a4232 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 11:35:50 +0000 Subject: [PATCH 04/15] Specialization can switch to `DefineOpaqueTypes::Yes` without having an effect. The reason is that in specialization graph computation we use `DefiningAnchor::Error`, so there's no difference anyway. And in the other use cases, we * already errored in the specialization_graph computation, or * already errored in coherence, or * are comparing opaque types with inference variables already, or * there are no opaque types involved --- .../rustc_trait_selection/src/traits/specialize/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 43c750ebbb5..ab8d7d31e43 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -247,7 +247,12 @@ fn fulfill_implication<'tcx>( // do the impls unify? If not, no specialization. let Ok(InferOk { obligations: more_obligations, .. }) = infcx .at(&ObligationCause::dummy(), param_env) - .eq(DefineOpaqueTypes::No, source_trait, target_trait) + // Ok to use `Yes`, as all the generic params are already replaced by inference variables, + // which will match the opaque type no matter if it is defining or not. + // Any concrete type that would match the opaque would already be handled by coherence rules, + // and thus either be ok to match here and already have errored, or it won't match, in which + // case there is no issue anyway. + .eq(DefineOpaqueTypes::Yes, source_trait, target_trait) else { debug!("fulfill_implication: {:?} does not unify with {:?}", source_trait, target_trait); return Err(()); From 2247aaf276029888fc7c14a372d9033276ec0c86 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 11:42:39 +0000 Subject: [PATCH 05/15] Use `DefineOpaqueTypes::Yes` where the new solver is unconditionally used already --- .../rustc_trait_selection/src/solve/eval_ctxt/mod.rs | 12 ++++++++---- .../src/solve/eval_ctxt/select.rs | 12 ++++++++---- .../rustc_trait_selection/src/traits/coherence.rs | 10 +++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index a0fe6eca0fc..5d9b588b55b 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -720,7 +720,8 @@ pub(super) fn eq>( ) -> Result<(), NoSolution> { self.infcx .at(&ObligationCause::dummy(), param_env) - .eq(DefineOpaqueTypes::No, lhs, rhs) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .eq(DefineOpaqueTypes::Yes, lhs, rhs) .map(|InferOk { value: (), obligations }| { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) @@ -759,7 +760,8 @@ pub(super) fn sub>( ) -> Result<(), NoSolution> { self.infcx .at(&ObligationCause::dummy(), param_env) - .sub(DefineOpaqueTypes::No, sub, sup) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .sub(DefineOpaqueTypes::Yes, sub, sup) .map(|InferOk { value: (), obligations }| { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) @@ -779,7 +781,8 @@ pub(super) fn relate>( ) -> Result<(), NoSolution> { self.infcx .at(&ObligationCause::dummy(), param_env) - .relate(DefineOpaqueTypes::No, lhs, variance, rhs) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .relate(DefineOpaqueTypes::Yes, lhs, variance, rhs) .map(|InferOk { value: (), obligations }| { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) @@ -803,7 +806,8 @@ pub(super) fn eq_and_get_goals>( ) -> Result>>, NoSolution> { self.infcx .at(&ObligationCause::dummy(), param_env) - .eq(DefineOpaqueTypes::No, lhs, rhs) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .eq(DefineOpaqueTypes::Yes, lhs, rhs) .map(|InferOk { value: (), obligations }| { obligations.into_iter().map(|o| o.into()).collect() }) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index e0c7804b6db..6644d3c77af 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -182,7 +182,8 @@ fn rematch_impl<'tcx>( let mut nested = infcx .at(&ObligationCause::dummy(), goal.param_env) - .eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .eq(DefineOpaqueTypes::Yes, goal.predicate.trait_ref, impl_trait_ref) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(); @@ -257,7 +258,8 @@ fn rematch_unsize<'tcx>( nested.extend( infcx .at(&ObligationCause::dummy(), goal.param_env) - .eq(DefineOpaqueTypes::No, a_elem_ty, b_elem_ty) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .eq(DefineOpaqueTypes::Yes, a_elem_ty, b_elem_ty) .expect("expected rematch to succeed") .into_obligations(), ); @@ -300,7 +302,8 @@ fn rematch_unsize<'tcx>( nested.extend( infcx .at(&ObligationCause::dummy(), goal.param_env) - .eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty) .expect("expected rematch to succeed") .into_obligations(), ); @@ -329,7 +332,8 @@ fn rematch_unsize<'tcx>( nested.extend( infcx .at(&ObligationCause::dummy(), goal.param_env) - .eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty) + // New solver ignores DefineOpaqueTypes, so choose Yes for consistency + .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty) .expect("expected rematch to succeed") .into_obligations(), ); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 90e337a53b6..8625ad378f7 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -477,7 +477,8 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) { if ty.is_ty_var() { let Ok(InferOk { value: (), obligations }) = self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( - DefineOpaqueTypes::No, + // Comparing against a type variable never registers hidden types anyway + DefineOpaqueTypes::Yes, ty, Ty::new_placeholder( self.infcx.tcx, @@ -504,7 +505,9 @@ fn visit_const(&mut self, ct: ty::Const<'tcx>) { if ct.is_ct_infer() { let Ok(InferOk { value: (), obligations }) = self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( - DefineOpaqueTypes::No, + // The types of the constants are the same, so there is no hidden type + // registration happening anyway. + DefineOpaqueTypes::Yes, ct, ty::Const::new_placeholder( self.infcx.tcx, @@ -532,7 +535,8 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) { if r.is_var() { let Ok(InferOk { value: (), obligations }) = self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( - DefineOpaqueTypes::No, + // Lifetimes don't contain opaque types (or any types for that matter). + DefineOpaqueTypes::Yes, r, ty::Region::new_placeholder( self.infcx.tcx, From 95948b75b2e036f07462c3f7a51d7ced659057a3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 11:44:59 +0000 Subject: [PATCH 06/15] Use `DefineOpaqueTypes::Yes` since we are guaranteed to error already --- compiler/rustc_hir_typeck/src/demand.rs | 4 ++-- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 564de4ab9e7..75a68f16cf1 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -400,7 +400,7 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { // what our ideal rcvr ty would look like. let _ = self .at(&ObligationCause::dummy(), self.param_env) - .eq(DefineOpaqueTypes::No, method.sig.inputs()[idx + 1], arg_ty) + .eq(DefineOpaqueTypes::Yes, method.sig.inputs()[idx + 1], arg_ty) .ok()?; self.select_obligations_where_possible(|errs| { // Yeet the errors, we're already reporting errors. @@ -479,7 +479,7 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { .and_then(|method| { let _ = self .at(&ObligationCause::dummy(), self.param_env) - .eq(DefineOpaqueTypes::No, ideal_rcvr_ty, expected_ty) + .eq(DefineOpaqueTypes::Yes, ideal_rcvr_ty, expected_ty) .ok()?; Some(method) }); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index f1feffcc82c..64b816553df 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -687,7 +687,7 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator>) -> bool { // Using probe here, since we don't want this subtyping to affect inference. let subtyping_error = self.probe(|_| { self.at(&self.misc(arg_span), self.param_env) - .sup(DefineOpaqueTypes::No, formal_input_ty, coerced_ty) + .sup(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty) .err() }); From 10e8bca7fe00b4b10eca33a8d70ebb06d71cd621 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 12:31:41 +0000 Subject: [PATCH 07/15] FRU remaining fields does not actually define opaque types --- compiler/rustc_hir_typeck/src/expr.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index d3e6eb124f7..d8f62f7a2b6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -44,10 +44,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; -use rustc_middle::ty::error::{ - ExpectedFound, - TypeError::{FieldMisMatch, Sorts}, -}; +use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt}; use rustc_session::errors::ExprParenthesesNeeded; @@ -1811,7 +1808,10 @@ fn check_expr_struct_fields( let target_ty = self.field_ty(base_expr.span, f, args); let cause = self.misc(base_expr.span); match self.at(&cause, self.param_env).sup( - DefineOpaqueTypes::No, + // We're already using inference variables for any params, and don't allow converting + // between different structs, so there is no way this ever actually defines an opaque type. + // Thus choosing `Yes` is fine. + DefineOpaqueTypes::Yes, target_ty, fru_ty, ) { @@ -1819,16 +1819,12 @@ fn check_expr_struct_fields( self.register_predicates(obligations) } Err(_) => { - // This should never happen, since we're just subtyping the - // remaining_fields, but it's fine to emit this, I guess. - self.err_ctxt() - .report_mismatched_types( - &cause, - target_ty, - fru_ty, - FieldMisMatch(variant.name, ident.name), - ) - .emit(); + span_bug!( + cause.span(), + "subtyping remaining fields of type changing FRU failed: {target_ty} != {fru_ty}: {}::{}", + variant.name, + ident.name, + ); } } } From cdcca7e8f4842fe4a3b64c0e5ac7d25025950889 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 14:29:28 +0000 Subject: [PATCH 08/15] Switch `can_eq` and `can_sub` to `DefineOpaqueTypes::Yes` They are mostly used in diagnostics anyway --- compiler/rustc_infer/src/infer/mod.rs | 8 ++++++-- tests/ui/impl-trait/nested_impl_trait.stderr | 8 ++++---- tests/ui/self/arbitrary-self-opaque.rs | 12 ++++++++++++ tests/ui/self/arbitrary-self-opaque.stderr | 20 ++++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 tests/ui/self/arbitrary-self-opaque.rs create mode 100644 tests/ui/self/arbitrary-self-opaque.stderr diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 3e89327d20f..6e5ed0a31cb 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -843,7 +843,9 @@ pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) { let origin = &ObligationCause::dummy(); self.probe(|_| { - self.at(origin, param_env).sub(DefineOpaqueTypes::No, expected, actual).is_ok() + // We're only answering whether there could be a subtyping relation, and with + // opaque types, "there could be one", via registering a hidden type. + self.at(origin, param_env).sub(DefineOpaqueTypes::Yes, expected, actual).is_ok() }) } @@ -852,7 +854,9 @@ pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool T: at::ToTrace<'tcx>, { let origin = &ObligationCause::dummy(); - self.probe(|_| self.at(origin, param_env).eq(DefineOpaqueTypes::No, a, b).is_ok()) + // We're only answering whether the types could be the same, and with + // opaque types, "they can be the same", via registering a hidden type. + self.probe(|_| self.at(origin, param_env).eq(DefineOpaqueTypes::Yes, a, b).is_ok()) } #[instrument(skip(self), level = "debug")] diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index 83d1347aff4..1f9a2a5e9d6 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -42,20 +42,20 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | = note: `impl Trait` is only allowed in arguments and return types of functions and methods -error[E0277]: the trait bound `impl Debug: From>` is not satisfied +error[E0277]: the trait bound `impl Into: Into` is not satisfied --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Debug`, which is required by `impl Into: Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` | = help: the trait `Into` is implemented for `T` = note: required for `impl Into` to implement `Into` -error[E0277]: the trait bound `impl Debug: From>` is not satisfied +error[E0277]: the trait bound `impl Into: Into` is not satisfied --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Debug`, which is required by `impl Into: Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` | = help: the trait `Into` is implemented for `T` = note: required for `impl Into` to implement `Into` diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs new file mode 100644 index 00000000000..99357dde3e1 --- /dev/null +++ b/tests/ui/self/arbitrary-self-opaque.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] +struct Foo; + +type Bar = impl Sized; +//~^ ERROR unconstrained opaque type + +impl Foo { + fn foo(self: Bar) {} + //~^ ERROR: invalid `self` parameter type: Bar +} + +fn main() {} diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr new file mode 100644 index 00000000000..6b5db8d8493 --- /dev/null +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -0,0 +1,20 @@ +error: unconstrained opaque type + --> $DIR/arbitrary-self-opaque.rs:4:12 + | +LL | type Bar = impl Sized; + | ^^^^^^^^^^ + | + = note: `Bar` must be used in combination with a concrete type within the same module + +error[E0307]: invalid `self` parameter type: Bar + --> $DIR/arbitrary-self-opaque.rs:8:18 + | +LL | fn foo(self: Bar) {} + | ^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0307`. From 169a045dca0e8cc7c720a962cef274fb5f8fafef Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 14:50:17 +0000 Subject: [PATCH 09/15] Switch upcast projections to allowing opaque types and add a test showing it works. The old solver was already ICEing on this test before this change --- ...gal-upcast-from-impl-opaque.current.stderr | 17 +++++++++++ ...llegal-upcast-from-impl-opaque.next.stderr | 14 +++++++++ .../illegal-upcast-from-impl-opaque.rs | 29 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr create mode 100644 tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr create mode 100644 tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr new file mode 100644 index 00000000000..c54a1c42bad --- /dev/null +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/illegal-upcast-from-impl-opaque.rs:26:5 + | +LL | type Foo = impl Sized; + | ---------- the found opaque type +LL | +LL | fn illegal(x: &dyn Sub) -> &dyn Super { + | ----------------------- expected `&dyn Super` because of return type +LL | x + | ^ expected trait `Super`, found trait `Sub` + | + = note: expected reference `&dyn Super` + found reference `&dyn Sub` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr new file mode 100644 index 00000000000..3c2bc0b9190 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr @@ -0,0 +1,14 @@ +error: internal compiler error: error performing operation: query type op + --> $DIR/illegal-upcast-from-impl-opaque.rs:25:1 + | +LL | fn illegal(x: &dyn Sub) -> &dyn Super { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: + --> $DIR/illegal-upcast-from-impl-opaque.rs:25:1 + | +LL | fn illegal(x: &dyn Sub) -> &dyn Super { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +query stack during panic: +end of query stack diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs new file mode 100644 index 00000000000..f344474054a --- /dev/null +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs @@ -0,0 +1,29 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[next] failure-status: 101 +//@[next] known-bug: unknown +//@[next] normalize-stderr-test "note: .*\n\n" -> "" +//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" +//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@[next] normalize-stderr-test "delayed at .*" -> "" +//@[next] rustc-env:RUST_BACKTRACE=0 + +#![feature(trait_upcasting, type_alias_impl_trait)] + +trait Super { + type Assoc; +} + +trait Sub: Super {} + +impl Super for T { + type Assoc = i32; +} + +type Foo = impl Sized; + +fn illegal(x: &dyn Sub) -> &dyn Super { + x //[current]~ mismatched types +} + +fn main() {} From ba316a902d4a350f41bfaeba17df66b582de9d99 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 4 Apr 2024 14:53:31 +0000 Subject: [PATCH 10/15] amend to Switch `can_eq` and `can_sub` to `DefineOpaqueTypes::Yes` --- tests/ui/impl-trait/nested_impl_trait.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/impl-trait/nested_impl_trait.rs b/tests/ui/impl-trait/nested_impl_trait.rs index 760102794c3..502b2af2bc6 100644 --- a/tests/ui/impl-trait/nested_impl_trait.rs +++ b/tests/ui/impl-trait/nested_impl_trait.rs @@ -5,7 +5,7 @@ fn fine(x: impl Into) -> impl Into { x } fn bad_in_ret_position(x: impl Into) -> impl Into { x } //~^ ERROR nested `impl Trait` is not allowed -//~| ERROR the trait bound `impl Debug: From>` is not satisfied +//~| ERROR the trait bound `impl Into: Into` is not satisfied fn bad_in_fn_syntax(x: fn() -> impl Into) {} //~^ ERROR nested `impl Trait` is not allowed @@ -18,7 +18,7 @@ fn bad_in_arg_position(_: impl Into) { } impl X { fn bad(x: impl Into) -> impl Into { x } //~^ ERROR nested `impl Trait` is not allowed - //~| ERROR the trait bound `impl Debug: From>` is not satisfied + //~| ERROR the trait bound `impl Into: Into` is not satisfied } fn allowed_in_assoc_type() -> impl Iterator { From 8e226e092eba650ce0e71d1336519e4045a8ba0e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 14:59:43 +0000 Subject: [PATCH 11/15] Add some regression tests for opaque types and const generics --- .../src/traits/fulfill.rs | 3 +- .../src/traits/select/mod.rs | 3 +- tests/ui/const-generics/opaque_types.rs | 13 ++ tests/ui/const-generics/opaque_types.stderr | 125 ++++++++++++++++++ tests/ui/const-generics/opaque_types2.rs | 17 +++ tests/ui/const-generics/opaque_types2.stderr | 15 +++ 6 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 tests/ui/const-generics/opaque_types.rs create mode 100644 tests/ui/const-generics/opaque_types.stderr create mode 100644 tests/ui/const-generics/opaque_types2.rs create mode 100644 tests/ui/const-generics/opaque_types2.stderr diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index b5be9a2bcb3..77704460257 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -429,7 +429,8 @@ fn process_obligation( // as the cause of an overflow. ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( - DefineOpaqueTypes::No, + // Only really excercised by generic_const_exprs + DefineOpaqueTypes::Yes, ct.ty(), ty, ) { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 926044bd6a8..cd37f9db3e6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -982,7 +982,8 @@ fn evaluate_predicate_recursively<'o>( ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { match self.infcx.at(&obligation.cause, obligation.param_env).eq( - DefineOpaqueTypes::No, + // Only really excercised by generic_const_exprs + DefineOpaqueTypes::Yes, ct.ty(), ty, ) { diff --git a/tests/ui/const-generics/opaque_types.rs b/tests/ui/const-generics/opaque_types.rs new file mode 100644 index 00000000000..ccf70f4fb37 --- /dev/null +++ b/tests/ui/const-generics/opaque_types.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; +//~^ ERROR: cycle +//~| ERROR: cycle + +fn foo() {} +//~^ ERROR: `Foo` is forbidden as the type of a const generic parameter + +fn main() { + foo::<42>(); + //~^ ERROR: mismatched types +} diff --git a/tests/ui/const-generics/opaque_types.stderr b/tests/ui/const-generics/opaque_types.stderr new file mode 100644 index 00000000000..f03bca69a8b --- /dev/null +++ b/tests/ui/const-generics/opaque_types.stderr @@ -0,0 +1,125 @@ +error[E0308]: mismatched types + --> $DIR/opaque_types.rs:11:11 + | +LL | type Foo = impl Sized; + | ---------- the expected opaque type +... +LL | foo::<42>(); + | ^^ expected opaque type, found integer + | + = note: expected opaque type `Foo` + found type `{integer}` + +error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` + --> $DIR/opaque_types.rs:3:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | +note: ...which requires computing type of opaque `Foo::{opaque#0}`... + --> $DIR/opaque_types.rs:3:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ +note: ...which requires type-checking `main`... + --> $DIR/opaque_types.rs:10:1 + | +LL | fn main() { + | ^^^^^^^^^ +note: ...which requires evaluating type-level constant... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires const-evaluating + checking `main::{constant#0}`... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires caching mir of `main::{constant#0}` for CTFE... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires elaborating drops for `main::{constant#0}`... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ + = note: ...which requires normalizing `Foo`... + = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle +note: cycle used when checking that `Foo::{opaque#0}` is well-formed + --> $DIR/opaque_types.rs:3:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + = 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: `Foo` is forbidden as the type of a const generic parameter + --> $DIR/opaque_types.rs:7:17 + | +LL | fn foo() {} + | ^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}` + --> $DIR/opaque_types.rs:3:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | +note: ...which requires type-checking `main`... + --> $DIR/opaque_types.rs:10:1 + | +LL | fn main() { + | ^^^^^^^^^ +note: ...which requires evaluating type-level constant... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires const-evaluating + checking `main::{constant#0}`... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires caching mir of `main::{constant#0}` for CTFE... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires elaborating drops for `main::{constant#0}`... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires borrow-checking `main::{constant#0}`... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires promoting constants in MIR for `main::{constant#0}`... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ +note: ...which requires const checking `main::{constant#0}`... + --> $DIR/opaque_types.rs:11:11 + | +LL | foo::<42>(); + | ^^ + = note: ...which requires computing whether `Foo` is freeze... + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`... + = note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle +note: cycle used when computing type of `Foo::{opaque#0}` + --> $DIR/opaque_types.rs:3:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + = 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 4 previous errors + +Some errors have detailed explanations: E0308, E0391. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/opaque_types2.rs b/tests/ui/const-generics/opaque_types2.rs new file mode 100644 index 00000000000..fd57438bb61 --- /dev/null +++ b/tests/ui/const-generics/opaque_types2.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; + +fn foo() {} + +const C: Foo = 42; + +fn bar() +where + Foo:, +{ + foo::(); + //~^ ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/const-generics/opaque_types2.stderr b/tests/ui/const-generics/opaque_types2.stderr new file mode 100644 index 00000000000..2fb1669b7bf --- /dev/null +++ b/tests/ui/const-generics/opaque_types2.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/opaque_types2.rs:13:11 + | +LL | type Foo = impl Sized; + | ---------- the found opaque type +... +LL | foo::(); + | ^ expected `u32`, found opaque type + | + = note: expected type `u32` + found opaque type `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 29fba9f994d5c32448cb6937aaae9b319ddcf392 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 15:29:44 +0000 Subject: [PATCH 12/15] Add regression test --- .../generic_const_exprs/opaque_type.rs | 18 +++++++++++++++ .../generic_const_exprs/opaque_type.stderr | 22 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/opaque_type.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/opaque_type.stderr diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs new file mode 100644 index 00000000000..1d4ef15fecf --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs @@ -0,0 +1,18 @@ +#![feature(generic_const_exprs, type_alias_impl_trait)] +#![allow(incomplete_features)] + +type Foo = impl Sized; +//~^ ERROR: cycle detected + +fn with_bound() -> Foo +where + [u8; (N / 2) as usize]: Sized, +{ + let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; + //~^ ERROR: mismatched types + todo!() +} + +fn main() { + with_bound::<4>(); +} diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr new file mode 100644 index 00000000000..9f48a8563c8 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/opaque_type.rs:11:17 + | +LL | type Foo = impl Sized; + | ---------- the found opaque type +... +LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; + | ^^^^^^^^^^^^^^ expected `usize`, found opaque type + | + = note: expected type `usize` + found opaque type `Foo` + +error[E0605]: non-primitive cast: `usize` as `Foo` + --> $DIR/opaque_type.rs:11:17 + | +LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; + | ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0605. +For more information about an error, try `rustc --explain E0308`. From 0183d92df0591b25363b3e12ae0a4a8f1b0b076c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 15:33:09 +0000 Subject: [PATCH 13/15] Allow defining opaque types when checking const equality bounds --- compiler/rustc_trait_selection/src/traits/fulfill.rs | 12 +++++++++--- .../rustc_trait_selection/src/traits/select/mod.rs | 12 +++++++++--- .../generic_const_exprs/opaque_type.rs | 4 ++-- .../generic_const_exprs/opaque_type.stderr | 4 ++-- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 77704460257..88ac9d4dbe5 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -572,7 +572,9 @@ fn process_obligation( if let Ok(new_obligations) = infcx .at(&obligation.cause, obligation.param_env) .trace(c1, c2) - .eq(DefineOpaqueTypes::No, a.args, b.args) + // Can define opaque types as this is only reachable with + // `generic_const_exprs` + .eq(DefineOpaqueTypes::Yes, a.args, b.args) { return ProcessResult::Changed(mk_pending( new_obligations.into_obligations(), @@ -583,7 +585,9 @@ fn process_obligation( (_, _) => { if let Ok(new_obligations) = infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, c1, c2) + // Can define opaque types as this is only reachable with + // `generic_const_exprs` + .eq(DefineOpaqueTypes::Yes, c1, c2) { return ProcessResult::Changed(mk_pending( new_obligations.into_obligations(), @@ -624,7 +628,9 @@ fn process_obligation( match (evaluate(c1), evaluate(c2)) { (Ok(c1), Ok(c2)) => { match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( - DefineOpaqueTypes::No, + // Can define opaque types as this is only reachable with + // `generic_const_exprs` + DefineOpaqueTypes::Yes, c1, c2, ) { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index cd37f9db3e6..8fb8d21ac90 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -906,7 +906,9 @@ fn evaluate_predicate_recursively<'o>( .infcx .at(&obligation.cause, obligation.param_env) .trace(c1, c2) - .eq(DefineOpaqueTypes::No, a.args, b.args) + // Can define opaque types as this is only reachable with + // `generic_const_exprs` + .eq(DefineOpaqueTypes::Yes, a.args, b.args) { return self.evaluate_predicates_recursively( previous_stack, @@ -919,7 +921,9 @@ fn evaluate_predicate_recursively<'o>( if let Ok(InferOk { obligations, value: () }) = self .infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, c1, c2) + // Can define opaque types as this is only reachable with + // `generic_const_exprs` + .eq(DefineOpaqueTypes::Yes, c1, c2) { return self.evaluate_predicates_recursively( previous_stack, @@ -949,7 +953,9 @@ fn evaluate_predicate_recursively<'o>( match (evaluate(c1), evaluate(c2)) { (Ok(c1), Ok(c2)) => { match self.infcx.at(&obligation.cause, obligation.param_env).eq( - DefineOpaqueTypes::No, + // Can define opaque types as this is only reachable with + // `generic_const_exprs` + DefineOpaqueTypes::Yes, c1, c2, ) { diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs index 1d4ef15fecf..56b8acbf88c 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs @@ -2,14 +2,14 @@ #![allow(incomplete_features)] type Foo = impl Sized; -//~^ ERROR: cycle detected fn with_bound() -> Foo where [u8; (N / 2) as usize]: Sized, { let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; - //~^ ERROR: mismatched types + //~^ ERROR mismatched types + //~| ERROR non-primitive cast: `usize` as `Foo` todo!() } diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr index 9f48a8563c8..e9fb8c0f403 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/opaque_type.rs:11:17 + --> $DIR/opaque_type.rs:10:17 | LL | type Foo = impl Sized; | ---------- the found opaque type @@ -11,7 +11,7 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; found opaque type `Foo` error[E0605]: non-primitive cast: `usize` as `Foo` - --> $DIR/opaque_type.rs:11:17 + --> $DIR/opaque_type.rs:10:17 | LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; | ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object From ede0556ab538ccaa928299812519db95aff9d7ca Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 15:36:49 +0000 Subject: [PATCH 14/15] Effects are boolean consts and don't contain opaque types --- compiler/rustc_hir_typeck/src/callee.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 0e75a47683d..aa94632b2b0 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -918,7 +918,8 @@ pub(super) fn enforce_context_effects( let param = callee_args.const_at(host_effect_index); let cause = self.misc(span); - match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) { + // We know the type of `effect` to be `bool`, there will be no opaque type inference. + match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::Yes, effect, param) { Ok(infer::InferOk { obligations, value: () }) => { self.register_predicates(obligations); } From 4e8d2f0040f108e3f07854b231a5987005217763 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Feb 2024 15:50:40 +0000 Subject: [PATCH 15/15] Add regression test --- tests/ui/methods/opaque_param_in_ufc.rs | 30 +++++++++++++++++ tests/ui/methods/opaque_param_in_ufc.stderr | 36 +++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 tests/ui/methods/opaque_param_in_ufc.rs create mode 100644 tests/ui/methods/opaque_param_in_ufc.stderr diff --git a/tests/ui/methods/opaque_param_in_ufc.rs b/tests/ui/methods/opaque_param_in_ufc.rs new file mode 100644 index 00000000000..a4b27a0131f --- /dev/null +++ b/tests/ui/methods/opaque_param_in_ufc.rs @@ -0,0 +1,30 @@ +#![feature(type_alias_impl_trait)] +struct Foo(T); + +impl Foo { + fn method() {} + fn method2(self) {} +} + +type Bar = impl Sized; + +fn bar() -> Bar { + 42_u32 +} + +impl Foo { + fn foo() -> Bar { + Self::method(); + //~^ ERROR: no function or associated item named `method` found for struct `Foo` + Foo::::method(); + //~^ ERROR: no function or associated item named `method` found for struct `Foo` + let x = Foo(bar()); + Foo::method2(x); + let x = Self(bar()); + Self::method2(x); + //~^ ERROR: no function or associated item named `method2` found for struct `Foo` + todo!() + } +} + +fn main() {} diff --git a/tests/ui/methods/opaque_param_in_ufc.stderr b/tests/ui/methods/opaque_param_in_ufc.stderr new file mode 100644 index 00000000000..7e5bbbac8a9 --- /dev/null +++ b/tests/ui/methods/opaque_param_in_ufc.stderr @@ -0,0 +1,36 @@ +error[E0599]: no function or associated item named `method` found for struct `Foo` in the current scope + --> $DIR/opaque_param_in_ufc.rs:17:15 + | +LL | struct Foo(T); + | ------------- function or associated item `method` not found for this struct +... +LL | Self::method(); + | ^^^^^^ function or associated item not found in `Foo` + | + = note: the function or associated item was found for + - `Foo` + +error[E0599]: no function or associated item named `method` found for struct `Foo` in the current scope + --> $DIR/opaque_param_in_ufc.rs:19:21 + | +LL | struct Foo(T); + | ------------- function or associated item `method` not found for this struct +... +LL | Foo::::method(); + | ^^^^^^ function or associated item not found in `Foo` + | + = note: the function or associated item was found for + - `Foo` + +error[E0599]: no function or associated item named `method2` found for struct `Foo` in the current scope + --> $DIR/opaque_param_in_ufc.rs:24:15 + | +LL | struct Foo(T); + | ------------- function or associated item `method2` not found for this struct +... +LL | Self::method2(x); + | ^^^^^^^ function or associated item not found in `Foo` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0599`.