diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 1d57fd9e4b285..34333351a7e89 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -26,7 +26,7 @@ pub use crate::traits::DynCompatibilityViolation; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{ AssocConstViolation, MethodViolation, Obligation, ObligationCause, - normalize_param_env_or_error, util, + normalize_param_env_or_delay_bugs, util, }; /// Returns the dyn-compatibility violations that affect HIR ty lowering. @@ -719,7 +719,7 @@ fn receiver_is_dispatchable<'tcx>( // N.B. We generally want to emulate the construction of the `unnormalized_param_env` // in the param-env query here. The fact that we don't just start with the clauses // in the param-env of the method is because those are already normalized, and mixing - // normalized and unnormalized copies of predicates in `normalize_param_env_or_error` + // normalized and unnormalized copies of predicates in `normalize_param_env_or_delay_bugs` // will cause ambiguity that the user can't really avoid. // // We leave out certain complexities of the param-env query here. Specifically, we: @@ -764,7 +764,11 @@ fn receiver_is_dispatchable<'tcx>( }; clauses.push(meta_sized_predicate.upcast(tcx)); - normalize_param_env_or_error( + // To suppress duplicate errors and errors mentioning `U` (shown as `RustaceansAreAwesome`), + // we convert errors from param-env normalization into delayed bugs. If this is the only + // place we encounter errors (e.g. if we constructed the param-env improperly), something's + // gone wrong, so we should ICE. + normalize_param_env_or_delay_bugs( tcx, ty::ParamEnv::new(tcx, clauses), ObligationCause::dummy_with_span(tcx.def_span(method.def_id)), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8ad7fd4ac3a69..c9edfe80bade0 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -326,12 +326,19 @@ where }) } +#[derive(Copy, Clone, Debug)] +enum ReportErrors { + Yes, + DelayBugs, +} + #[instrument(level = "debug", skip(tcx, elaborated_env))] fn do_normalize_clauses<'tcx>( tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, elaborated_env: ty::ParamEnv<'tcx>, clauses: Vec>, + report_errors: ReportErrors, ) -> Vec> { // FIXME. We should really... do something with these region // obligations. But this call just continues the older @@ -382,7 +389,12 @@ fn do_normalize_clauses<'tcx>( let errors = ocx.evaluate_obligations_error_on_ambiguity(); let clauses = if let TraitErrors::HasErrors(errors) = errors { debug!("do_normalize_clauses: failed to normalize clauses"); - let guar = infcx.err_ctxt().report_fulfillment_errors(errors); + let guar = match report_errors { + ReportErrors::Yes => infcx.err_ctxt().report_fulfillment_errors(errors), + ReportErrors::DelayBugs => tcx + .dcx() + .span_delayed_bug(cause.span, format!("failed to normalize clauses: {errors:?}")), + }; replace_infer_and_non_rigid_alias_with_error(&infcx, clauses, guar, ReplaceRegions::No) } else { clauses @@ -430,13 +442,11 @@ fn do_normalize_clauses<'tcx>( } } -// FIXME: this is gonna need to be removed ... -/// Normalizes the parameter environment, reporting errors if they occur. -#[instrument(level = "debug", skip(tcx))] -pub fn normalize_param_env_or_error<'tcx>( +fn normalize_param_env_or_optionally_error<'tcx>( tcx: TyCtxt<'tcx>, unnormalized_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, + report_errors: ReportErrors, ) -> ty::ParamEnv<'tcx> { // I'm not wild about reporting errors here; I'd prefer to // have the errors get reported at a defined place (e.g., @@ -560,7 +570,8 @@ pub fn normalize_param_env_or_error<'tcx>( "normalize_param_env_or_error: clauses=(non-outlives={:?}, outlives={:?})", clauses, outlives_clauses ); - let non_outlives_clauses = do_normalize_clauses(tcx, cause.clone(), elaborated_env, clauses); + let non_outlives_clauses = + do_normalize_clauses(tcx, cause.clone(), elaborated_env, clauses, report_errors); debug!("normalize_param_env_or_error: non-outlives clauses={:?}", non_outlives_clauses); @@ -569,7 +580,8 @@ pub fn normalize_param_env_or_error<'tcx>( // clauses here anyway. Keeping them here anyway because it seems safer. let outlives_env = non_outlives_clauses.iter().chain(&outlives_clauses).cloned(); let outlives_env = ty::ParamEnv::new(tcx, outlives_env); - let outlives_clauses = do_normalize_clauses(tcx, cause, outlives_env, outlives_clauses); + let outlives_clauses = + do_normalize_clauses(tcx, cause, outlives_env, outlives_clauses, report_errors); debug!("normalize_param_env_or_error: outlives clauses={:?}", outlives_clauses); let mut clauses = non_outlives_clauses; @@ -578,6 +590,28 @@ pub fn normalize_param_env_or_error<'tcx>( ty::ParamEnv::new(tcx, clauses) } +// FIXME: this is gonna need to be removed ... +/// Normalizes the parameter environment, reporting errors if they occur. +#[instrument(level = "debug", skip(tcx))] +pub fn normalize_param_env_or_error<'tcx>( + tcx: TyCtxt<'tcx>, + unnormalized_env: ty::ParamEnv<'tcx>, + cause: ObligationCause<'tcx>, +) -> ty::ParamEnv<'tcx> { + normalize_param_env_or_optionally_error(tcx, unnormalized_env, cause, ReportErrors::Yes) +} + +/// Variant of [`normalize_param_env_or_error`] that creates delayed bugs instead of reporting +/// errors, for use in cases where we shouldn't be reporting errors (such as normalizing the +/// synthetic param-env used when testing whether method receivers are dispatchable). +pub fn normalize_param_env_or_delay_bugs<'tcx>( + tcx: TyCtxt<'tcx>, + unnormalized_env: ty::ParamEnv<'tcx>, + cause: ObligationCause<'tcx>, +) -> ty::ParamEnv<'tcx> { + normalize_param_env_or_optionally_error(tcx, unnormalized_env, cause, ReportErrors::DelayBugs) +} + #[derive(Debug)] pub enum EvaluateConstErr { /// The constant being evaluated was either a generic parameter or inference variable, *or*, diff --git a/tests/ui/associated-types/issue-59324.rs b/tests/ui/associated-types/issue-59324.rs index f9b310f6f9b31..83b6598cbdd9d 100644 --- a/tests/ui/associated-types/issue-59324.rs +++ b/tests/ui/associated-types/issue-59324.rs @@ -14,7 +14,6 @@ pub trait ThriftService: { fn get_service( //~^ ERROR the trait bound `Bug: Foo` is not satisfied - //~| ERROR the trait bound `Bug: Foo` is not satisfied &self, ) -> Self::AssocType; } diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr index 929238dc29b15..3c5adc53ed972 100644 --- a/tests/ui/associated-types/issue-59324.stderr +++ b/tests/ui/associated-types/issue-59324.stderr @@ -11,18 +11,8 @@ help: consider further restricting type parameter `Bug` with trait `Foo` LL | pub trait ThriftService: | +++++ -error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:15:5 - | -LL | / fn get_service( -LL | | -LL | | -LL | | &self, -LL | | ) -> Self::AssocType; - | |_________________________^ the trait `Foo` is not implemented for `Bug` - error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:22:29 + --> $DIR/issue-59324.rs:21:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` @@ -38,7 +28,6 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied | LL | / fn get_service( LL | | -LL | | LL | | &self, LL | | ) -> Self::AssocType; | |_________________________^ the trait `Foo` is not implemented for `Bug` @@ -49,7 +38,7 @@ LL | pub trait ThriftService: | +++++ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:22:29 + --> $DIR/issue-59324.rs:21:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` @@ -62,7 +51,7 @@ LL | pub trait Foo: NotFoo { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time - --> $DIR/issue-59324.rs:22:29 + --> $DIR/issue-59324.rs:21:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -79,6 +68,6 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn with_factory(factory: &dyn ThriftService<()>) {} | + -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs index 188f63fa94bab..faaac050285ee 100644 --- a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs +++ b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs @@ -24,10 +24,6 @@ where //~^ ERROR cannot find trait `B` in this scope //~| ERROR type mismatch resolving //~| ERROR the size for values of type `Self` cannot be known - //~| ERROR type mismatch resolving - //~| ERROR the size for values of type `Self` cannot be known - //~| ERROR type mismatch resolving - //~| ERROR the size for values of type `RustaceansAreAwesome` cannot be known } trait Mirror { diff --git a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr index 06fd8bced4af1..1be5d8368e30a 100644 --- a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr +++ b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr @@ -5,75 +5,11 @@ LL | fn transmute(&self, t: T) -> ::Assoc; | ^ not found in this scope error[E0601]: `main` function not found in crate `ice_generics_of_crate_root_152335` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:57 + --> $DIR/ice-generics-of-crate-root-152335.rs:32:57 | LL | impl> Mirror for T {} | ^ consider adding a `main` function to `$DIR/ice-generics-of-crate-root-152335.rs` -error[E0271]: type mismatch resolving `>::Assoc == RustaceansAreAwesome` - --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 - | -LL | fn transmute(&self, t: T) -> ::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `RustaceansAreAwesome`, found type parameter `T` - | - = note: expected type parameter `RustaceansAreAwesome` - found type parameter `T` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -note: required for `RustaceansAreAwesome` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 - | -LL | impl> Mirror for T {} - | --------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0271]: type mismatch resolving `>::Assoc == Self` - --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 - | -LL | fn transmute(&self, t: T) -> ::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `Self`, found type parameter `T` - | - = note: expected type parameter `Self` - found type parameter `T` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 - | -LL | impl> Mirror for T {} - | --------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0277]: the size for values of type `RustaceansAreAwesome` cannot be known at compilation time - --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 - | -LL | fn transmute(&self, t: T) -> ::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | -note: required for `RustaceansAreAwesome` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here - -error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 - | -LL | fn transmute(&self, t: T) -> ::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | -note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here - error[E0038]: the trait `Foo` is not dyn compatible --> $DIR/ice-generics-of-crate-root-152335.rs:14:20 | @@ -101,7 +37,7 @@ LL | trait Foo: Super = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:32:42 | LL | impl> Mirror for T {} | --------- ^^^^^^ ^ @@ -115,7 +51,7 @@ LL | trait Foo: Super | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:32:42 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -127,7 +63,7 @@ LL | trait Foo: Super + Sized | +++++++ error[E0046]: not all trait items implemented, missing: `Assoc` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:1 + --> $DIR/ice-generics-of-crate-root-152335.rs:32:1 | LL | type Assoc: ?Sized; | ------------------ `Assoc` from trait @@ -152,7 +88,7 @@ LL | fn transmute(&self, t: T) -> ::Assoc; = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:32:42 | LL | impl> Mirror for T {} | --------- ^^^^^^ ^ @@ -166,7 +102,7 @@ LL | fn transmute(&self, t: T) -> ::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:36:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:32:42 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -177,7 +113,7 @@ help: consider further restricting `Self` LL | fn transmute(&self, t: T) -> ::Assoc where Self: Sized; | +++++++++++++++++ -error: aborting due to 12 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0038, E0046, E0271, E0277, E0405, E0601. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/unhandled-crate-mod-issue-144888.rs b/tests/ui/traits/unhandled-crate-mod-issue-144888.rs index 41f233398d83b..762bf2b6a2c28 100644 --- a/tests/ui/traits/unhandled-crate-mod-issue-144888.rs +++ b/tests/ui/traits/unhandled-crate-mod-issue-144888.rs @@ -16,10 +16,6 @@ where fn transmute(&self) {} //~^ ERROR type mismatch resolving //~| ERROR the size for values of type `Self` cannot be known at compilation time - //~| ERROR type mismatch resolving - //~| ERROR the size for values of type `Self` cannot be known at compilation time - //~| ERROR type mismatch resolving - //~| ERROR the size for values of type `RustaceansAreAwesome` cannot be known at compilation time } trait Mirror { diff --git a/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr b/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr index 4cc5b41588efa..9265919322bb8 100644 --- a/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr +++ b/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr @@ -1,63 +1,3 @@ -error[E0271]: type mismatch resolving `::Assoc == ()` - --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 - | -LL | fn transmute(&self) {} - | ^^^^^^^^^^^^^^^^^^^ expected `()`, found type parameter `T` - | - = note: expected unit type `()` - found type parameter `T` -note: required for `RustaceansAreAwesome` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 - | -LL | impl> Mirror for T {} - | ---------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0271]: type mismatch resolving `::Assoc == ()` - --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 - | -LL | fn transmute(&self) {} - | ^^^^^^^^^^^^^^^^^^^ expected `()`, found type parameter `T` - | - = note: expected unit type `()` - found type parameter `T` -note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 - | -LL | impl> Mirror for T {} - | ---------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0277]: the size for values of type `RustaceansAreAwesome` cannot be known at compilation time - --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 - | -LL | fn transmute(&self) {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | -note: required for `RustaceansAreAwesome` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here - -error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 - | -LL | fn transmute(&self) {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | -note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here - error[E0271]: type mismatch resolving `::Assoc == ()` --> $DIR/unhandled-crate-mod-issue-144888.rs:10:1 | @@ -67,7 +7,7 @@ LL | trait Foo: Super = note: expected unit type `()` found type parameter `T` note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:25:28 | LL | impl> Mirror for T {} | ---------- ^^^^^^ ^ @@ -81,7 +21,7 @@ LL | trait Foo: Super | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:25:28 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -93,7 +33,7 @@ LL | trait Foo: Super + Sized | +++++++ error[E0046]: not all trait items implemented, missing: `Assoc` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:1 + --> $DIR/unhandled-crate-mod-issue-144888.rs:25:1 | LL | type Assoc; | ---------- `Assoc` from trait @@ -113,7 +53,7 @@ LL | fn transmute(&self) {} = note: expected unit type `()` found type parameter `T` note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:25:28 | LL | impl> Mirror for T {} | ---------- ^^^^^^ ^ @@ -127,7 +67,7 @@ LL | fn transmute(&self) {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:29:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:25:28 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -138,7 +78,7 @@ help: consider further restricting `Self` LL | fn transmute(&self) where Self: Sized {} | +++++++++++++++++ -error: aborting due to 9 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0046, E0271, E0277. For more information about an error, try `rustc --explain E0046`.