Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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(
Comment thread
dianne marked this conversation as resolved.
tcx,
ty::ParamEnv::new(tcx, clauses),
ObligationCause::dummy_with_span(tcx.def_span(method.def_id)),
Expand Down
48 changes: 41 additions & 7 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ty::Clause<'tcx>>,
report_errors: ReportErrors,
) -> Vec<ty::Clause<'tcx>> {
// FIXME. We should really... do something with these region
// obligations. But this call just continues the older
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -430,13 +442,11 @@ fn do_normalize_clauses<'tcx>(
}
}

// FIXME: this is gonna need to be removed ...

@dianne dianne Sep 23, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this FIXME should be duplicated? for now I've just kept it on the function it was originally on

View changes since the review

/// 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.,
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand All @@ -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<E> {
/// The constant being evaluated was either a generic parameter or inference variable, *or*,
Expand Down
1 change: 0 additions & 1 deletion tests/ui/associated-types/issue-59324.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub trait ThriftService<Bug: NotFoo>:
{
fn get_service(
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
//~| ERROR the trait bound `Bug: Foo` is not satisfied
&self,
) -> Self::AssocType;
}
Expand Down
19 changes: 4 additions & 15 deletions tests/ui/associated-types/issue-59324.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,8 @@ help: consider further restricting type parameter `Bug` with trait `Foo`
LL | pub trait ThriftService<Bug: NotFoo + Foo>:
| +++++

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<H>(factory: dyn ThriftService<()>) {}
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
Expand All @@ -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`
Expand All @@ -49,7 +38,7 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
| +++++

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<H>(factory: dyn ThriftService<()>) {}
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
Expand All @@ -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<H>(factory: dyn ThriftService<()>) {}
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
Expand All @@ -79,6 +68,6 @@ help: function arguments must have a statically known size, borrowed types alway
LL | fn with_factory<H>(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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,11 @@ LL | fn transmute(&self, t: T) -> <Self as B>::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<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
| ^ consider adding a `main` function to `$DIR/ice-generics-of-crate-root-152335.rs`

error[E0271]: type mismatch resolving `<RustaceansAreAwesome as Super<ActuallySuper>>::Assoc == RustaceansAreAwesome`
--> $DIR/ice-generics-of-crate-root-152335.rs:23:5
|
LL | fn transmute(&self, t: T) -> <Self as B>::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<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
| --------- ^^^^^^ ^
| |
| unsatisfied trait bound introduced here

error[E0271]: type mismatch resolving `<Self as Super<ActuallySuper>>::Assoc == Self`
--> $DIR/ice-generics-of-crate-root-152335.rs:23:5
|
LL | fn transmute(&self, t: T) -> <Self as B>::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<T: Super<ActuallySuper, Assoc = T>> 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) -> <Self as B>::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<T: Super<ActuallySuper, Assoc = T>> 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) -> <Self as B>::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<T: Super<ActuallySuper, Assoc = T>> 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
|
Expand Down Expand Up @@ -101,7 +37,7 @@ LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = 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
--> $DIR/ice-generics-of-crate-root-152335.rs:32:42
|
LL | impl<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
| --------- ^^^^^^ ^
Expand All @@ -115,7 +51,7 @@ LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
| - ^^^^^^ ^
Expand All @@ -127,7 +63,7 @@ LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T> + 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
Expand All @@ -152,7 +88,7 @@ LL | fn transmute(&self, t: T) -> <Self as B>::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<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
| --------- ^^^^^^ ^
Expand All @@ -166,7 +102,7 @@ LL | fn transmute(&self, t: T) -> <Self as B>::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<T: Super<ActuallySuper, Assoc = T>> Mirror for T {}
| - ^^^^^^ ^
Expand All @@ -177,7 +113,7 @@ help: consider further restricting `Self`
LL | fn transmute(&self, t: T) -> <Self as B>::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`.
4 changes: 0 additions & 4 deletions tests/ui/traits/unhandled-crate-mod-issue-144888.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading
Loading