Rollup merge of #131699 - compiler-errors:better-errors-for-projections, r=lcnr

Try to improve error messages involving aliases in the solver

1. Treat aliases as rigid only if it may not be defined and it's well formed (i.e. for projections, its trait goal is satisfied).
2. Record goals that are related to alias normalization under a new `GoalKind`, so we can look into them in the `BestObligation` visitor.
3. Try to deduplicate errors due to self types of goals that are un-normalizable aliases.

r? lcnr
This commit is contained in:
Matthias Krüger 2024-10-16 19:18:32 +02:00 committed by GitHub
commit aac91f75e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 324 additions and 187 deletions

View File

@ -6,6 +6,7 @@ use derive_where::derive_where;
use rustc_type_ir::fold::TypeFoldable;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::solve::inspect;
use rustc_type_ir::visit::TypeVisitableExt as _;
use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
use tracing::{debug, instrument};
@ -288,6 +289,25 @@ where
let Ok(normalized_self_ty) =
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
else {
// FIXME: We register a fake candidate when normalization fails so that
// we can point at the reason for *why*. I'm tempted to say that this
// is the wrong way to do this, though.
let result =
self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| {
let normalized_ty = this.next_ty_infer();
let alias_relate_goal = Goal::new(
this.cx(),
goal.param_env,
ty::PredicateKind::AliasRelate(
goal.predicate.self_ty().into(),
normalized_ty.into(),
ty::AliasRelationDirection::Equate,
),
);
this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal);
this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
});
assert_eq!(result, Err(NoSolution));
return vec![];
};

View File

@ -983,7 +983,7 @@ where
hidden_ty,
&mut goals,
);
self.add_goals(GoalSource::Misc, goals);
self.add_goals(GoalSource::AliasWellFormed, goals);
}
// Do something for each opaque/hidden pair defined with `def_id` in the

View File

@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
use crate::solve::inspect::ProbeKind;
use crate::solve::{
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
NoSolution, QueryResult,
NoSolution, QueryResult, Reveal,
};
impl<D, I> EvalCtxt<'_, D>
@ -37,13 +37,64 @@ where
match normalize_result {
Ok(res) => Ok(res),
Err(NoSolution) => {
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
this.add_rigid_constraints(param_env, alias)?;
this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
}
}
/// Register any obligations that are used to validate that an alias should be
/// treated as rigid.
///
/// An alias may be considered rigid if it fails normalization, but we also don't
/// want to consider aliases that are not well-formed to be rigid simply because
/// they fail normalization.
///
/// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
/// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
fn add_rigid_constraints(
&mut self,
param_env: I::ParamEnv,
rigid_alias: ty::AliasTerm<I>,
) -> Result<(), NoSolution> {
let cx = self.cx();
match rigid_alias.kind(cx) {
// Projections are rigid only if their trait ref holds,
// and the GAT where-clauses hold.
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
let trait_ref = rigid_alias.trait_ref(cx);
self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref));
Ok(())
}
ty::AliasTermKind::OpaqueTy => {
match param_env.reveal() {
// In user-facing mode, paques are only rigid if we may not define it.
Reveal::UserFacing => {
if rigid_alias
.def_id
.as_local()
.is_some_and(|def_id| self.can_define_opaque_ty(def_id))
{
Err(NoSolution)
} else {
Ok(())
}
}
// Opaques are never rigid in reveal-all mode.
Reveal::All => Err(NoSolution),
}
}
// FIXME(generic_const_exprs): we would need to support generic consts here
ty::AliasTermKind::UnevaluatedConst => Err(NoSolution),
// Inherent and weak types are never rigid. This type must not be well-formed.
ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution),
}
}
/// Normalize the given alias by at least one step. If the alias is rigid, this
/// returns `NoSolution`.
#[instrument(level = "trace", skip(self), ret)]
@ -124,6 +175,7 @@ where
ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
// Add GAT where clauses from the trait's definition
// FIXME: We don't need these, since these are the type's own WF obligations.
ecx.add_goals(
GoalSource::Misc,
cx.own_predicates_of(goal.predicate.def_id())
@ -179,7 +231,8 @@ where
.map(|pred| goal.with(cx, pred));
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
// Add GAT where clauses from the trait's definition
// Add GAT where clauses from the trait's definition.
// FIXME: We don't need these, since these are the type's own WF obligations.
ecx.add_goals(
GoalSource::Misc,
cx.own_predicates_of(goal.predicate.def_id())

View File

@ -14,7 +14,7 @@ use rustc_middle::bug;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, TyCtxt};
use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _};
use tracing::instrument;
use tracing::{instrument, trace};
use super::Certainty;
use super::delegate::SolverDelegate;
@ -401,6 +401,7 @@ impl<'tcx> BestObligation<'tcx> {
nested_goal.source(),
GoalSource::ImplWhereBound
| GoalSource::InstantiateHigherRanked
| GoalSource::AliasWellFormed
) && match self.consider_ambiguities {
true => {
matches!(
@ -415,6 +416,13 @@ impl<'tcx> BestObligation<'tcx> {
})
});
}
// Prefer a non-rigid candidate if there is one.
if candidates.len() > 1 {
candidates.retain(|candidate| {
!matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. })
});
}
}
}
@ -429,8 +437,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
self.obligation.cause.span
}
#[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))]
fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
let candidates = self.non_trivial_candidates(goal);
trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::<Vec<_>>());
let [candidate] = candidates.as_slice() else {
return ControlFlow::Break(self.obligation.clone());
};
@ -464,17 +475,13 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
polarity: ty::PredicatePolarity::Positive,
}))
}
ty::PredicateKind::Clause(
ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..),
)
| ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough,
_ => {
return ControlFlow::Break(self.obligation.clone());
}
_ => ChildMode::PassThrough,
};
let mut impl_where_bound_count = 0;
for nested_goal in candidate.instantiate_nested_goals(self.span()) {
trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
let make_obligation = |cause| Obligation {
cause,
param_env: nested_goal.goal().param_env,
@ -501,7 +508,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
(_, GoalSource::InstantiateHigherRanked) => {
obligation = self.obligation.clone();
}
(ChildMode::PassThrough, _) => {
(ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => {
obligation = make_obligation(self.obligation.cause.clone());
}
}

View File

@ -292,7 +292,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
| inspect::ProbeKind::Root { .. }
| inspect::ProbeKind::TryNormalizeNonRigid { .. }
| inspect::ProbeKind::TraitCandidate { .. }
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => {
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. }
| inspect::ProbeKind::RigidAlias { .. } => {
// Nested probes have to prove goals added in their parent
// but do not leak them, so we truncate the added goals
// afterwards.
@ -316,7 +317,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
inspect::ProbeKind::Root { result }
| inspect::ProbeKind::TryNormalizeNonRigid { result }
| inspect::ProbeKind::TraitCandidate { source: _, result }
| inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
| inspect::ProbeKind::OpaqueTypeStorageLookup { result }
| inspect::ProbeKind::RigidAlias { result } => {
// We only add a candidate if `shallow_certainty` was set, which means
// that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
if let Some(shallow_certainty) = shallow_certainty {

View File

@ -177,7 +177,8 @@ fn to_selection<'tcx>(
| ProbeKind::UpcastProjectionCompatibility
| ProbeKind::OpaqueTypeStorageLookup { result: _ }
| ProbeKind::Root { result: _ }
| ProbeKind::ShadowedEnvProbing => {
| ProbeKind::ShadowedEnvProbing
| ProbeKind::RigidAlias { result: _ } => {
span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
}
})

View File

@ -135,4 +135,6 @@ pub enum ProbeKind<I: Interner> {
ShadowedEnvProbing,
/// Try to unify an opaque type with an existing key in the storage.
OpaqueTypeStorageLookup { result: QueryResult<I> },
/// Checking that a rigid alias is well-formed.
RigidAlias { result: QueryResult<I> },
}

View File

@ -130,6 +130,10 @@ pub enum GoalSource {
ImplWhereBound,
/// Instantiating a higher-ranked goal and re-proving it.
InstantiateHigherRanked,
/// Predicate required for an alias projection to be well-formed.
/// This is used in two places: projecting to an opaque whose hidden type
/// is already registered in the opaque type storage, and for rigid projections.
AliasWellFormed,
}
#[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]

View File

@ -11,13 +11,6 @@ help: consider mutably borrowing here
LL | for item in &mut *things { *item = 0 }
| ++++
error[E0614]: type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
--> $DIR/issue-20605.rs:6:27
|
LL | for item in *things { *item = 0 }
| ^^^^^
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0614.
For more information about an error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0277`.

View File

@ -4,12 +4,7 @@
fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
for item in *things { *item = 0 }
//[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
//[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
//[next]~| ERROR type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
// FIXME(-Znext-solver): these error messages are horrible and have to be
// improved before we stabilize the new solver.
//~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
}
fn main() {}

View File

@ -1,5 +1,5 @@
error[E0283]: type annotations needed
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
--> $DIR/ambig-hr-projection-issue-93340.rs:17:5
|
LL | cmp_eq
| ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
@ -15,6 +15,16 @@ help: consider specifying the generic arguments
LL | cmp_eq::<A, B, O>
| +++++++++++
error: aborting due to 1 previous error
error[E0277]: expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
--> $DIR/ambig-hr-projection-issue-93340.rs:14:1
|
LL | / fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
| |_________________________________________________^ expected an `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
|
= help: the trait `for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>)` is not implemented for fn item `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
For more information about this error, try `rustc --explain E0283`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0283.
For more information about an error, try `rustc --explain E0277`.

View File

@ -1,5 +1,5 @@
error[E0283]: type annotations needed
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
--> $DIR/ambig-hr-projection-issue-93340.rs:17:5
|
LL | cmp_eq
| ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`

View File

@ -13,6 +13,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT
fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
//[next]~^^ expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure
cmp_eq
//~^ ERROR type annotations needed
}

View File

@ -11,6 +11,7 @@ type Assoc<'a, T> = <T as ToUnit<'a>>::Unit;
impl<T> Overlap<T> for T {}
impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
//~^ ERROR conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>`
//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
fn main() {}

View File

@ -1,18 +1,26 @@
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
--> $DIR/structually-relate-aliases.rs:13:1
error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
--> $DIR/structually-relate-aliases.rs:13:36
|
LL | impl<T> Overlap<T> for T {}
| ------------------------ first implementation here
LL |
LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)`
| ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
|
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
help: consider restricting type parameter `T`
|
LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
| ++++++++++++++++++++
error: aborting due to 1 previous error
error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
--> $DIR/structually-relate-aliases.rs:13:17
|
LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
| ++++++++++++++++++++
For more information about this error, try `rustc --explain E0119`.
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -14,6 +14,8 @@ struct W<T>(T);
// `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still
// encounter weak types in `assemble_alias_bound_candidates_recur`.
fn hello(_: W<A<usize>>) {}
//~^ ERROR the size for values of type `A<usize>` cannot be known at compilation time
//~^ ERROR the trait bound `usize: Foo` is not satisfied
//~| ERROR the trait bound `usize: Foo` is not satisfied
//~| ERROR the trait bound `usize: Foo` is not satisfied
fn main() {}

View File

@ -7,14 +7,42 @@ LL | #![feature(lazy_type_alias)]
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0277]: the size for values of type `A<usize>` cannot be known at compilation time
error[E0277]: the trait bound `usize: Foo` is not satisfied
--> $DIR/alias-bounds-when-not-wf.rs:16:13
|
LL | fn hello(_: W<A<usize>>) {}
| ^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
|
= help: the trait `Sized` is not implemented for `A<usize>`
help: this trait has no implementations, consider adding one
--> $DIR/alias-bounds-when-not-wf.rs:6:1
|
LL | trait Foo {}
| ^^^^^^^^^
error: aborting due to 1 previous error; 1 warning emitted
error[E0277]: the trait bound `usize: Foo` is not satisfied
--> $DIR/alias-bounds-when-not-wf.rs:16:10
|
LL | fn hello(_: W<A<usize>>) {}
| ^ the trait `Foo` is not implemented for `usize`
|
help: this trait has no implementations, consider adding one
--> $DIR/alias-bounds-when-not-wf.rs:6:1
|
LL | trait Foo {}
| ^^^^^^^^^
error[E0277]: the trait bound `usize: Foo` is not satisfied
--> $DIR/alias-bounds-when-not-wf.rs:16:1
|
LL | fn hello(_: W<A<usize>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
|
help: this trait has no implementations, consider adding one
--> $DIR/alias-bounds-when-not-wf.rs:6:1
|
LL | trait Foo {}
| ^^^^^^^^^
error: aborting due to 3 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0277`.

View File

@ -4,19 +4,6 @@ error[E0282]: type annotations needed
LL | foo(false).next().unwrap();
| ^^^^^^^^^^ cannot infer type
error[E0308]: mismatched types
--> $DIR/method-resolution4.rs:16:5
|
LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
| ------------------------ the expected opaque type
...
LL | std::iter::empty()
| ^^^^^^^^^^^^^^^^^^ types differ
|
= note: expected opaque type `impl Iterator<Item = ()>`
found struct `std::iter::Empty<_>`
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.
For more information about this error, try `rustc --explain E0282`.

View File

@ -14,7 +14,6 @@ fn foo(b: bool) -> impl Iterator<Item = ()> {
//[next]~^ type annotations needed
}
std::iter::empty()
//[next]~^ mismatched types
}
fn main() {}

View File

@ -1,5 +1,5 @@
error[E0282]: type annotations needed
--> $DIR/recursive-coroutine-boxed.rs:15:23
--> $DIR/recursive-coroutine-boxed.rs:14:23
|
LL | let mut gen = Box::pin(foo());
| ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box`
@ -12,29 +12,6 @@ help: consider specifying the generic argument
LL | let mut gen = Box::<T>::pin(foo());
| +++++
error[E0308]: mismatched types
--> $DIR/recursive-coroutine-boxed.rs:14:18
|
LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
| ---------------------------------------
| |
| the expected opaque type
| expected `impl Coroutine<Yield = (), Return = ()>` because of return type
...
LL | #[coroutine] || {
| __________________^
LL | | let mut gen = Box::pin(foo());
LL | |
LL | | let mut r = gen.as_mut().resume(());
... |
LL | | }
LL | | }
| |_____^ types differ
|
= note: expected opaque type `impl Coroutine<Yield = (), Return = ()>`
found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:14:18: 14:20}`
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.
For more information about this error, try `rustc --explain E0282`.

View File

@ -10,8 +10,7 @@ fn foo() -> impl Coroutine<Yield = (), Return = ()> {
// FIXME(-Znext-solver): this fails with a mismatched types as the
// hidden type of the opaque ends up as {type error}. We should not
// emit errors for such goals.
#[coroutine] || { //[next]~ ERROR mismatched types
#[coroutine] || {
let mut gen = Box::pin(foo());
//[next]~^ ERROR type annotations needed
let mut r = gen.as_mut().resume(());

View File

@ -1,26 +1,35 @@
error[E0271]: type mismatch resolving `impl Trait <: dyn Trait`
--> $DIR/unsized_coercion.rs:14:17
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
--> $DIR/unsized_coercion.rs:15:17
|
LL | let x = hello();
| ^^^^^^^ types differ
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Trait`
error[E0308]: mismatched types
--> $DIR/unsized_coercion.rs:18:14
--> $DIR/unsized_coercion.rs:19:5
|
LL | fn hello() -> Box<impl Trait> {
| ---------- the expected opaque type
| ---------------
| | |
| | the expected opaque type
| expected `Box<impl Trait>` because of return type
...
LL | Box::new(1u32)
| -------- ^^^^ types differ
| |
| arguments to this function are incorrect
| ^^^^^^^^^^^^^^ types differ
|
= note: expected opaque type `impl Trait`
found type `u32`
note: associated function defined here
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
= note: expected struct `Box<impl Trait>`
found struct `Box<u32>`
error: aborting due to 2 previous errors
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
--> $DIR/unsized_coercion.rs:12:1
|
LL | fn hello() -> Box<impl Trait> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Trait`
Some errors have detailed explanations: E0271, E0308.
For more information about an error, try `rustc --explain E0271`.
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.

View File

@ -10,9 +10,10 @@ trait Trait {}
impl Trait for u32 {}
fn hello() -> Box<impl Trait> {
//[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time
if true {
let x = hello();
//[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait`
//[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time
let y: Box<dyn Trait> = x;
}
Box::new(1u32) //[next]~ ERROR: mismatched types

View File

@ -1,38 +1,35 @@
error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
--> $DIR/unsized_coercion3.rs:13:17
error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
--> $DIR/unsized_coercion3.rs:14:17
|
LL | let x = hello();
| ^^^^^^^ types differ
| ^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
|
= help: the trait `Trait` is implemented for `u32`
error[E0308]: mismatched types
--> $DIR/unsized_coercion3.rs:18:14
--> $DIR/unsized_coercion3.rs:19:5
|
LL | fn hello() -> Box<impl Trait + ?Sized> {
| ------------------- the expected opaque type
| ------------------------
| | |
| | the expected opaque type
| expected `Box<impl Trait + ?Sized>` because of return type
...
LL | Box::new(1u32)
| -------- ^^^^ types differ
| |
| arguments to this function are incorrect
| ^^^^^^^^^^^^^^ types differ
|
= note: expected opaque type `impl Trait + ?Sized`
found type `u32`
note: associated function defined here
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
= note: expected struct `Box<impl Trait + ?Sized>`
found struct `Box<u32>`
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
--> $DIR/unsized_coercion3.rs:18:14
error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
--> $DIR/unsized_coercion3.rs:11:1
|
LL | Box::new(1u32)
| -------- ^^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
LL | fn hello() -> Box<impl Trait + ?Sized> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
|
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
note: required by a bound in `Box::<T>::new`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
= help: the trait `Trait` is implemented for `u32`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0271, E0277, E0308.
For more information about an error, try `rustc --explain E0271`.
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.

View File

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
--> $DIR/unsized_coercion3.rs:15:32
--> $DIR/unsized_coercion3.rs:16:32
|
LL | let y: Box<dyn Send> = x;
| ^ doesn't have a size known at compile-time

View File

@ -9,15 +9,15 @@ trait Trait {}
impl Trait for u32 {}
fn hello() -> Box<impl Trait + ?Sized> {
//[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
if true {
let x = hello();
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
//[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
let y: Box<dyn Send> = x;
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
}
Box::new(1u32)
//[next]~^ ERROR: mismatched types
//[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
}
fn main() {}

View File

@ -13,9 +13,14 @@ fn main() {
}
fn weird0() -> impl Sized + !Sized {}
//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
//~^ ERROR the trait bound `(): !Sized` is not satisfied
//~| ERROR the trait bound `(): !Sized` is not satisfied
//~| ERROR the trait bound `(): !Sized` is not satisfied
fn weird1() -> impl !Sized + Sized {}
//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
//~^ ERROR the trait bound `(): !Sized` is not satisfied
//~| ERROR the trait bound `(): !Sized` is not satisfied
//~| ERROR the trait bound `(): !Sized` is not satisfied
fn weird2() -> impl !Sized {}
//~^ ERROR type mismatch resolving `impl !Sized == ()`
//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time
//~^ ERROR the trait bound `(): !Sized` is not satisfied
//~| ERROR the trait bound `(): !Sized` is not satisfied
//~| ERROR the trait bound `(): !Sized` is not satisfied

View File

@ -1,29 +1,56 @@
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
LL | fn weird0() -> impl Sized + !Sized {}
| ^^^^^^^^^^^^^^^^^^^ types differ
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:15:36
|
LL | fn weird0() -> impl Sized + !Sized {}
| ^^ the trait bound `(): !Sized` is not satisfied
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:15:1
|
LL | fn weird0() -> impl Sized + !Sized {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
LL | fn weird1() -> impl !Sized + Sized {}
| ^^^^^^^^^^^^^^^^^^^ types differ
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
error[E0271]: type mismatch resolving `impl !Sized == ()`
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:19:36
|
LL | fn weird1() -> impl !Sized + Sized {}
| ^^ the trait bound `(): !Sized` is not satisfied
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:19:1
|
LL | fn weird1() -> impl !Sized + Sized {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:23:16
|
LL | fn weird2() -> impl !Sized {}
| ^^^^^^^^^^^ types differ
| ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:23:28
|
LL | fn weird2() -> impl !Sized {}
| ^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^ the trait bound `(): !Sized` is not satisfied
error[E0277]: the trait bound `(): !Sized` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:23:1
|
= help: the trait `Sized` is not implemented for `impl !Sized`
= note: the return type of a function must have a statically known size
LL | fn weird2() -> impl !Sized {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
@ -39,7 +66,6 @@ note: required by a bound in `consume`
LL | fn consume(_: impl Trait) {}
| ^^^^^ required by this bound in `consume`
error: aborting due to 5 previous errors
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0271, E0277.
For more information about an error, try `rustc --explain E0271`.
For more information about this error, try `rustc --explain E0277`.

View File

@ -3,6 +3,8 @@
#![feature(negative_bounds, unboxed_closures)]
fn produce() -> impl !Fn<(u32,)> {}
//~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()`
//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
fn main() {}

View File

@ -1,9 +1,21 @@
error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
LL | fn produce() -> impl !Fn<(u32,)> {}
| ^^^^^^^^^^^^^^^^ types differ
| ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
error: aborting due to 1 previous error
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
|
LL | fn produce() -> impl !Fn<(u32,)> {}
| ^^ the trait bound `(): !Fn(u32)` is not satisfied
For more information about this error, try `rustc --explain E0271`.
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
|
LL | fn produce() -> impl !Fn<(u32,)> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -17,7 +17,7 @@ type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
impl<T> Overlap<T> for T {}
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
//~| ERROR cannot find type `Missing` in this scope
//~^ ERROR cannot find type `Missing` in this scope
//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
fn main() {}

View File

@ -26,21 +26,19 @@ LL | trait ToUnit<'a> {
| ^^^^^^^^^^^^^^^^
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
--> $DIR/issue-118950-root-region.rs:19:1
error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
--> $DIR/issue-118950-root-region.rs:19:17
|
LL | impl<T> Overlap<T> for T {}
| ------------------------ first implementation here
LL |
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
|
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
help: this trait has no implementations, consider adding one
--> $DIR/issue-118950-root-region.rs:8:1
|
LL | trait ToUnit<'a> {
| ^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors; 1 warning emitted
Some errors have detailed explanations: E0119, E0277, E0412.
For more information about an error, try `rustc --explain E0119`.
Some errors have detailed explanations: E0277, E0412.
For more information about an error, try `rustc --explain E0277`.

View File

@ -15,7 +15,7 @@ trait Mirror { type Assoc: ?Sized; }
impl<T: ?Sized> Mirror for T { type Assoc = T; }
trait MirrorRegion<'a> { type Assoc: ?Sized; }
impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; }
impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; }
impl<T> Foo for T {
#[cfg(normalize_param_env)]

View File

@ -1,11 +1,9 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@[next] check-pass
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[current] check-fail
//@[current] failure-status: 101
//@[current] dont-check-compiler-stderr
//@[current] known-bug: #103899
//@ check-fail
//@ failure-status: 101
//@ dont-check-compiler-stderr
//@ known-bug: #103899
trait BaseWithAssoc {
type Assoc;