Skip to content

Commit e3bf0a1

Browse files
authoredMay 4, 2024
Rollup merge of #124418 - compiler-errors:better-cause, r=lcnr
Use a proof tree visitor to refine the `Obligation` for error reporting in new solver With the magic of `ProofTreeVisitor`, we can close the gap that we have on `ObligationCause`s being not as descriptive in the new trait solver. r? lcnr Needs some work and obviously documentation.
2 parents 09cd00f + 34e91ec commit e3bf0a1

39 files changed

+474
-102
lines changed
 

‎compiler/rustc_middle/src/traits/solve.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ pub enum GoalSource {
273273
/// they are from an impl where-clause. This is necessary due to
274274
/// backwards compatability, cc trait-system-refactor-initiatitive#70.
275275
ImplWhereBound,
276+
/// Instantiating a higher-ranked goal and re-proving it.
277+
InstantiateHigherRanked,
276278
}
277279

278280
/// Possible ways the given goal can be proven.

‎compiler/rustc_middle/src/traits/solve/inspect/format.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
127127
let source = match source {
128128
GoalSource::Misc => "misc",
129129
GoalSource::ImplWhereBound => "impl where-bound",
130+
GoalSource::InstantiateHigherRanked => "higher-ranked goal",
130131
};
131132
writeln!(this.f, "ADDED GOAL ({source}): {goal:?}")?
132133
}

‎compiler/rustc_trait_selection/src/solve/assembly/mod.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ pub(super) trait GoalKind<'tcx>:
5858
/// goal by equating it with the assumption.
5959
fn probe_and_consider_implied_clause(
6060
ecx: &mut EvalCtxt<'_, 'tcx>,
61-
source: CandidateSource,
61+
parent_source: CandidateSource,
6262
goal: Goal<'tcx, Self>,
6363
assumption: ty::Clause<'tcx>,
64-
requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
64+
requirements: impl IntoIterator<Item = (GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>,
6565
) -> Result<Candidate<'tcx>, NoSolution> {
66-
Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
67-
// FIXME(-Znext-solver=coinductive): check whether this should be
68-
// `GoalSource::ImplWhereBound` for any caller.
69-
ecx.add_goals(GoalSource::Misc, requirements);
66+
Self::probe_and_match_goal_against_assumption(ecx, parent_source, goal, assumption, |ecx| {
67+
for (nested_source, goal) in requirements {
68+
ecx.add_goal(nested_source, goal);
69+
}
7070
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
7171
})
7272
}
@@ -85,9 +85,8 @@ pub(super) trait GoalKind<'tcx>:
8585
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
8686
bug!("expected object type in `probe_and_consider_object_bound_candidate`");
8787
};
88-
// FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
8988
ecx.add_goals(
90-
GoalSource::Misc,
89+
GoalSource::ImplWhereBound,
9190
structural_traits::predicates_for_object_candidate(
9291
ecx,
9392
goal.param_env,

‎compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
9090
&mut self,
9191
certainty: Certainty,
9292
) -> QueryResult<'tcx> {
93+
self.inspect.make_canonical_response(certainty);
94+
9395
let goals_certainty = self.try_evaluate_added_goals()?;
9496
assert_eq!(
9597
self.tainted,
@@ -98,8 +100,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
98100
previous call to `try_evaluate_added_goals!`"
99101
);
100102

101-
self.inspect.make_canonical_response(certainty);
102-
103103
// When normalizing, we've replaced the expected term with an unconstrained
104104
// inference variable. This means that we dropped information which could
105105
// have been important. We handle this by instead returning the nested goals

‎compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
454454
} else {
455455
self.infcx.enter_forall(kind, |kind| {
456456
let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
457-
self.add_goal(GoalSource::Misc, goal);
457+
self.add_goal(GoalSource::InstantiateHigherRanked, goal);
458458
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
459459
})
460460
}

‎compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 147 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
use std::mem;
2+
use std::ops::ControlFlow;
23

34
use rustc_infer::infer::InferCtxt;
4-
use rustc_infer::traits::solve::MaybeCause;
5+
use rustc_infer::traits::query::NoSolution;
6+
use rustc_infer::traits::solve::inspect::ProbeKind;
7+
use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause};
58
use rustc_infer::traits::{
6-
query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
7-
PredicateObligation, SelectionError, TraitEngine,
9+
self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation,
10+
ObligationCause, PredicateObligation, SelectionError, TraitEngine,
811
};
9-
use rustc_middle::ty;
1012
use rustc_middle::ty::error::{ExpectedFound, TypeError};
13+
use rustc_middle::ty::{self, TyCtxt};
1114

1215
use super::eval_ctxt::GenerateProofTree;
16+
use super::inspect::{ProofTreeInferCtxtExt, ProofTreeVisitor};
1317
use super::{Certainty, InferCtxtEvalExt};
1418

1519
/// A trait engine using the new trait solver.
@@ -133,9 +137,9 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
133137
.collect();
134138

135139
errors.extend(self.obligations.overflowed.drain(..).map(|obligation| FulfillmentError {
136-
root_obligation: obligation.clone(),
140+
obligation: find_best_leaf_obligation(infcx, &obligation),
137141
code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) },
138-
obligation,
142+
root_obligation: obligation,
139143
}));
140144

141145
errors
@@ -192,8 +196,10 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
192196

193197
fn fulfillment_error_for_no_solution<'tcx>(
194198
infcx: &InferCtxt<'tcx>,
195-
obligation: PredicateObligation<'tcx>,
199+
root_obligation: PredicateObligation<'tcx>,
196200
) -> FulfillmentError<'tcx> {
201+
let obligation = find_best_leaf_obligation(infcx, &root_obligation);
202+
197203
let code = match obligation.predicate.kind().skip_binder() {
198204
ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
199205
FulfillmentErrorCode::ProjectionError(
@@ -234,7 +240,8 @@ fn fulfillment_error_for_no_solution<'tcx>(
234240
bug!("unexpected goal: {obligation:?}")
235241
}
236242
};
237-
FulfillmentError { root_obligation: obligation.clone(), code, obligation }
243+
244+
FulfillmentError { obligation, code, root_obligation }
238245
}
239246

240247
fn fulfillment_error_for_stalled<'tcx>(
@@ -258,5 +265,136 @@ fn fulfillment_error_for_stalled<'tcx>(
258265
}
259266
});
260267

261-
FulfillmentError { obligation: obligation.clone(), code, root_obligation: obligation }
268+
FulfillmentError {
269+
obligation: find_best_leaf_obligation(infcx, &obligation),
270+
code,
271+
root_obligation: obligation,
272+
}
273+
}
274+
275+
fn find_best_leaf_obligation<'tcx>(
276+
infcx: &InferCtxt<'tcx>,
277+
obligation: &PredicateObligation<'tcx>,
278+
) -> PredicateObligation<'tcx> {
279+
let obligation = infcx.resolve_vars_if_possible(obligation.clone());
280+
infcx
281+
.visit_proof_tree(
282+
obligation.clone().into(),
283+
&mut BestObligation { obligation: obligation.clone() },
284+
)
285+
.break_value()
286+
.unwrap_or(obligation)
287+
}
288+
289+
struct BestObligation<'tcx> {
290+
obligation: PredicateObligation<'tcx>,
291+
}
292+
293+
impl<'tcx> BestObligation<'tcx> {
294+
fn with_derived_obligation(
295+
&mut self,
296+
derived_obligation: PredicateObligation<'tcx>,
297+
and_then: impl FnOnce(&mut Self) -> <Self as ProofTreeVisitor<'tcx>>::Result,
298+
) -> <Self as ProofTreeVisitor<'tcx>>::Result {
299+
let old_obligation = std::mem::replace(&mut self.obligation, derived_obligation);
300+
let res = and_then(self);
301+
self.obligation = old_obligation;
302+
res
303+
}
304+
}
305+
306+
impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
307+
type Result = ControlFlow<PredicateObligation<'tcx>>;
308+
309+
fn span(&self) -> rustc_span::Span {
310+
self.obligation.cause.span
311+
}
312+
313+
fn visit_goal(&mut self, goal: &super::inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
314+
// FIXME: Throw out candidates that have no failing WC and >0 failing misc goal.
315+
// This most likely means that the goal just didn't unify at all, e.g. a param
316+
// candidate with an alias in it.
317+
let candidates = goal.candidates();
318+
319+
let [candidate] = candidates.as_slice() else {
320+
return ControlFlow::Break(self.obligation.clone());
321+
};
322+
323+
// FIXME: Could we extract a trait ref from a projection here too?
324+
// FIXME: Also, what about considering >1 layer up the stack? May be necessary
325+
// for normalizes-to.
326+
let Some(parent_trait_pred) = goal.goal().predicate.to_opt_poly_trait_pred() else {
327+
return ControlFlow::Break(self.obligation.clone());
328+
};
329+
330+
let tcx = goal.infcx().tcx;
331+
let mut impl_where_bound_count = 0;
332+
for nested_goal in candidate.instantiate_nested_goals(self.span()) {
333+
let obligation;
334+
match nested_goal.source() {
335+
GoalSource::Misc => {
336+
continue;
337+
}
338+
GoalSource::ImplWhereBound => {
339+
obligation = Obligation {
340+
cause: derive_cause(
341+
tcx,
342+
candidate.kind(),
343+
self.obligation.cause.clone(),
344+
impl_where_bound_count,
345+
parent_trait_pred,
346+
),
347+
param_env: nested_goal.goal().param_env,
348+
predicate: nested_goal.goal().predicate,
349+
recursion_depth: self.obligation.recursion_depth + 1,
350+
};
351+
impl_where_bound_count += 1;
352+
}
353+
GoalSource::InstantiateHigherRanked => {
354+
obligation = self.obligation.clone();
355+
}
356+
}
357+
358+
// Skip nested goals that hold.
359+
//FIXME: We should change the max allowed certainty based on if we're
360+
// visiting an ambiguity or error obligation.
361+
if matches!(nested_goal.result(), Ok(Certainty::Yes)) {
362+
continue;
363+
}
364+
365+
self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
366+
}
367+
368+
ControlFlow::Break(self.obligation.clone())
369+
}
370+
}
371+
372+
fn derive_cause<'tcx>(
373+
tcx: TyCtxt<'tcx>,
374+
candidate_kind: ProbeKind<'tcx>,
375+
mut cause: ObligationCause<'tcx>,
376+
idx: usize,
377+
parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
378+
) -> ObligationCause<'tcx> {
379+
match candidate_kind {
380+
ProbeKind::TraitCandidate { source: CandidateSource::Impl(impl_def_id), result: _ } => {
381+
if let Some((_, span)) =
382+
tcx.predicates_of(impl_def_id).instantiate_identity(tcx).iter().nth(idx)
383+
{
384+
cause = cause.derived_cause(parent_trait_pred, |derived| {
385+
traits::ImplDerivedObligation(Box::new(traits::ImplDerivedObligationCause {
386+
derived,
387+
impl_or_alias_def_id: impl_def_id,
388+
impl_def_predicate_index: Some(idx),
389+
span,
390+
}))
391+
})
392+
}
393+
}
394+
ProbeKind::TraitCandidate { source: CandidateSource::BuiltinImpl(..), result: _ } => {
395+
cause = cause.derived_cause(parent_trait_pred, traits::BuiltinDerivedObligation);
396+
}
397+
_ => {}
398+
};
399+
cause
262400
}

‎compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub struct InspectGoal<'a, 'tcx> {
4141
result: Result<Certainty, NoSolution>,
4242
evaluation_kind: inspect::CanonicalGoalEvaluationKind<'tcx>,
4343
normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
44+
source: GoalSource,
4445
}
4546

4647
/// The expected term of a `NormalizesTo` goal gets replaced
@@ -90,7 +91,7 @@ impl<'tcx> NormalizesToTermHack<'tcx> {
9091
pub struct InspectCandidate<'a, 'tcx> {
9192
goal: &'a InspectGoal<'a, 'tcx>,
9293
kind: inspect::ProbeKind<'tcx>,
93-
nested_goals: Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
94+
nested_goals: Vec<(GoalSource, inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>)>,
9495
final_state: inspect::CanonicalState<'tcx, ()>,
9596
result: QueryResult<'tcx>,
9697
shallow_certainty: Certainty,
@@ -125,10 +126,8 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
125126
/// back their inference constraints. This function modifies
126127
/// the state of the `infcx`.
127128
pub fn visit_nested_no_probe<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
128-
if self.goal.depth < visitor.config().max_depth {
129-
for goal in self.instantiate_nested_goals(visitor.span()) {
130-
try_visit!(visitor.visit_goal(&goal));
131-
}
129+
for goal in self.instantiate_nested_goals(visitor.span()) {
130+
try_visit!(goal.visit_with(visitor));
132131
}
133132

134133
V::Result::output()
@@ -143,13 +142,16 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
143142
let instantiated_goals: Vec<_> = self
144143
.nested_goals
145144
.iter()
146-
.map(|goal| {
147-
canonical::instantiate_canonical_state(
148-
infcx,
149-
span,
150-
param_env,
151-
&mut orig_values,
152-
*goal,
145+
.map(|(source, goal)| {
146+
(
147+
*source,
148+
canonical::instantiate_canonical_state(
149+
infcx,
150+
span,
151+
param_env,
152+
&mut orig_values,
153+
*goal,
154+
),
153155
)
154156
})
155157
.collect();
@@ -171,7 +173,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
171173

172174
instantiated_goals
173175
.into_iter()
174-
.map(|goal| match goal.predicate.kind().no_bound_vars() {
176+
.map(|(source, goal)| match goal.predicate.kind().no_bound_vars() {
175177
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
176178
let unconstrained_term = match term.unpack() {
177179
ty::TermKind::Ty(_) => infcx
@@ -195,13 +197,15 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
195197
self.goal.depth + 1,
196198
proof_tree.unwrap(),
197199
Some(NormalizesToTermHack { term, unconstrained_term }),
200+
source,
198201
)
199202
}
200203
_ => InspectGoal::new(
201204
infcx,
202205
self.goal.depth + 1,
203206
infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1.unwrap(),
204207
None,
208+
source,
205209
),
206210
})
207211
.collect()
@@ -227,16 +231,23 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
227231
self.result
228232
}
229233

234+
pub fn source(&self) -> GoalSource {
235+
self.source
236+
}
237+
230238
fn candidates_recur(
231239
&'a self,
232240
candidates: &mut Vec<InspectCandidate<'a, 'tcx>>,
233-
nested_goals: &mut Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
241+
nested_goals: &mut Vec<(
242+
GoalSource,
243+
inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>,
244+
)>,
234245
probe: &inspect::Probe<'tcx>,
235246
) {
236247
let mut shallow_certainty = None;
237248
for step in &probe.steps {
238249
match step {
239-
&inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal),
250+
&inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)),
240251
inspect::ProbeStep::NestedProbe(ref probe) => {
241252
// Nested probes have to prove goals added in their parent
242253
// but do not leak them, so we truncate the added goals
@@ -319,6 +330,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
319330
depth: usize,
320331
root: inspect::GoalEvaluation<'tcx>,
321332
normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
333+
source: GoalSource,
322334
) -> Self {
323335
let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root;
324336
let inspect::GoalEvaluationKind::Root { orig_values } = kind else { unreachable!() };
@@ -341,8 +353,17 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
341353
result,
342354
evaluation_kind: evaluation.kind,
343355
normalizes_to_term_hack,
356+
source,
344357
}
345358
}
359+
360+
pub(crate) fn visit_with<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
361+
if self.depth < visitor.config().max_depth {
362+
try_visit!(visitor.visit_goal(self));
363+
}
364+
365+
V::Result::output()
366+
}
346367
}
347368

348369
/// The public API to interact with proof trees.
@@ -367,6 +388,6 @@ impl<'tcx> InferCtxt<'tcx> {
367388
) -> V::Result {
368389
let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
369390
let proof_tree = proof_tree.unwrap();
370-
visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None))
391+
visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None, GoalSource::Misc))
371392
}
372393
}

‎compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
389389
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
390390
goal,
391391
pred,
392-
[goal.with(tcx, output_is_sized_pred)],
392+
[(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))],
393393
)
394394
}
395395

@@ -473,7 +473,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
473473
pred,
474474
[goal.with(tcx, output_is_sized_pred)]
475475
.into_iter()
476-
.chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))),
476+
.chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred)))
477+
.map(|goal| (GoalSource::ImplWhereBound, goal)),
477478
)
478479
}
479480

‎compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
321321
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
322322
goal,
323323
pred,
324-
[goal.with(tcx, output_is_sized_pred)],
324+
[(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))],
325325
)
326326
}
327327

@@ -367,7 +367,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
367367
pred,
368368
[goal.with(tcx, output_is_sized_pred)]
369369
.into_iter()
370-
.chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))),
370+
.chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred)))
371+
.map(|goal| (GoalSource::ImplWhereBound, goal)),
371372
)
372373
}
373374

‎tests/ui/coherence/occurs-check/opaques.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ error[E0282]: type annotations needed
1111
--> $DIR/opaques.rs:13:20
1212
|
1313
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
14-
| ^ cannot infer type for struct `Container<T, T>`
14+
| ^ cannot infer type for associated type `<T as Trait<T>>::Assoc`
1515

1616
error: aborting due to 2 previous errors
1717

‎tests/ui/for/issue-20605.next.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
22
--> $DIR/issue-20605.rs:6:17
33
|
44
LL | for item in *things { *item = 0 }
5-
| ^^^^^^^ `dyn Iterator<Item = &'a mut u8>` is not an iterator
5+
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
66
|
7-
= help: the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
7+
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
8+
= note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
9+
help: consider mutably borrowing here
10+
|
11+
LL | for item in &mut *things { *item = 0 }
12+
| ++++
813

914
error: the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
1015
--> $DIR/issue-20605.rs:6:17

‎tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,20 @@ error[E0283]: type annotations needed
2323
LL | impls_indirect_leak::<Box<_>>();
2424
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak`
2525
|
26-
= note: cannot satisfy `for<'a> Box<_>: IndirectLeak<'a>`
26+
note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
27+
--> $DIR/leak-check-in-selection-3.rs:9:1
28+
|
29+
LL | impl Leak<'_> for Box<u32> {}
30+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
LL | impl Leak<'static> for Box<u16> {}
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
note: required for `Box<_>` to implement `for<'a> IndirectLeak<'a>`
34+
--> $DIR/leak-check-in-selection-3.rs:23:23
35+
|
36+
LL | impl<'a, T: Leak<'a>> IndirectLeak<'a> for T {}
37+
| -------- ^^^^^^^^^^^^^^^^ ^
38+
| |
39+
| unsatisfied trait bound introduced here
2740
note: required by a bound in `impls_indirect_leak`
2841
--> $DIR/leak-check-in-selection-3.rs:25:27
2942
|

‎tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
1-
error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
1+
error: future cannot be sent between threads safely
22
--> $DIR/auto-with-drop_tracking_mir.rs:25:13
33
|
44
LL | is_send(foo());
5-
| ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
6-
| |
7-
| required by a bound introduced by this call
5+
| ^^^^^ future returned by `foo` is not `Send`
86
|
9-
= help: the trait `Send` is not implemented for `impl Future<Output = ()>`
7+
= help: the trait `Sync` is not implemented for `impl Future<Output = ()>`, which is required by `impl Future<Output = ()>: Send`
8+
note: future is not `Send` as this value is used across an await
9+
--> $DIR/auto-with-drop_tracking_mir.rs:16:11
10+
|
11+
LL | let x = &NotSync;
12+
| - has type `&NotSync` which is not `Send`
13+
LL | bar().await;
14+
| ^^^^^ await occurs here, with `x` maybe used later
1015
note: required by a bound in `is_send`
1116
--> $DIR/auto-with-drop_tracking_mir.rs:24:24
1217
|
1318
LL | fn is_send(_: impl Send) {}
1419
| ^^^^ required by this bound in `is_send`
20+
help: consider dereferencing here
21+
|
22+
LL | is_send(*foo());
23+
| +
1524

1625
error: aborting due to 1 previous error
1726

18-
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ async fn bar() {}
2323
fn main() {
2424
fn is_send(_: impl Send) {}
2525
is_send(foo());
26-
//[fail]~^ ERROR `impl Future<Output = ()>` cannot be sent between threads safely
26+
//[fail]~^ ERROR future cannot be sent between threads safely
2727
}

‎tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ fn foo<F: Fn<T>, T: Tuple>(f: Option<F>, t: T) {
1313

1414
fn main() {
1515
foo::<fn() -> str, _>(None, ());
16-
//~^ expected a `Fn<_>` closure, found `fn() -> str`
16+
//~^ the size for values of type `str` cannot be known at compilation time
1717
}

‎tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
error[E0277]: expected a `Fn<_>` closure, found `fn() -> str`
1+
error[E0277]: the size for values of type `str` cannot be known at compilation time
22
--> $DIR/builtin-fn-must-return-sized.rs:15:11
33
|
44
LL | foo::<fn() -> str, _>(None, ());
5-
| ^^^^^^^^^^^ expected an `Fn<_>` closure, found `fn() -> str`
5+
| ^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
7-
= help: the trait `Fn<_>` is not implemented for `fn() -> str`
7+
= help: within `fn() -> str`, the trait `Sized` is not implemented for `str`, which is required by `fn() -> str: Fn<_>`
8+
= note: required because it appears within the type `fn() -> str`
89
note: required by a bound in `foo`
910
--> $DIR/builtin-fn-must-return-sized.rs:10:11
1011
|

‎tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
1+
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
22
--> $DIR/coherence-fulfill-overflow.rs:12:1
33
|
44
LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
55
| ------------------------------------- first implementation here
66
LL | impl<T: ?Sized + TwoW> Trait for T {}
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
88
|
9-
= note: overflow evaluating the requirement `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>: TwoW`
9+
= note: overflow evaluating the requirement `W<W<W<W<_>>>>: TwoW`
1010
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
1111

1212
error: aborting due to 1 previous error

‎tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
1+
error[E0275]: overflow evaluating the requirement `_: Sized`
22
--> $DIR/fixpoint-exponential-growth.rs:33:13
33
|
44
LL | impls::<W<_>>();
55
| ^^^^
66
|
7+
note: required for `W<(W<_>, W<_>)>` to implement `Trait`
8+
--> $DIR/fixpoint-exponential-growth.rs:23:12
9+
|
10+
LL | impl<T, U> Trait for W<(W<T>, W<U>)>
11+
| - ^^^^^ ^^^^^^^^^^^^^^^
12+
| |
13+
| unsatisfied trait bound introduced here
714
note: required by a bound in `impls`
815
--> $DIR/fixpoint-exponential-growth.rs:30:13
916
|

‎tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ where
6161
// entering the cycle from `A` fails, but would work if we were to use the cache
6262
// result of `B<X>`.
6363
impls_trait::<A<X>, _, _, _>();
64-
//~^ ERROR the trait bound `A<X>: Trait<_, _, _>` is not satisfied
64+
//~^ ERROR the trait bound `X: IncompleteGuidance<_, _>` is not satisfied
6565
}
6666

6767
fn main() {

‎tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
1-
error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
1+
error[E0277]: the trait bound `X: IncompleteGuidance<_, _>` is not satisfied
22
--> $DIR/incompleteness-unstable-result.rs:63:19
33
|
44
LL | impls_trait::<A<X>, _, _, _>();
5-
| ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>`
5+
| ^^^^ the trait `IncompleteGuidance<_, _>` is not implemented for `X`, which is required by `A<X>: Trait<_, _, _>`
66
|
7-
= help: the trait `Trait<U, V, D>` is implemented for `A<T>`
7+
= help: the following other types implement trait `IncompleteGuidance<T, V>`:
8+
<T as IncompleteGuidance<U, i16>>
9+
<T as IncompleteGuidance<U, i8>>
10+
<T as IncompleteGuidance<U, u8>>
11+
note: required for `A<X>` to implement `Trait<_, _, u8>`
12+
--> $DIR/incompleteness-unstable-result.rs:32:50
13+
|
14+
LL | impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T>
15+
| ^^^^^^^^^^^^^^ ^^^^
16+
LL | where
17+
LL | T: IncompleteGuidance<U, V>,
18+
| ------------------------ unsatisfied trait bound introduced here
819
note: required by a bound in `impls_trait`
920
--> $DIR/incompleteness-unstable-result.rs:51:28
1021
|

‎tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,53 @@
1-
error[E0275]: overflow evaluating the requirement `(): Trait`
1+
error[E0275]: overflow evaluating the requirement `(): Inductive`
22
--> $DIR/double-cycle-inductive-coinductive.rs:32:19
33
|
44
LL | impls_trait::<()>();
55
| ^^
66
|
7+
note: required for `()` to implement `Trait`
8+
--> $DIR/double-cycle-inductive-coinductive.rs:9:34
9+
|
10+
LL | impl<T: Inductive + Coinductive> Trait for T {}
11+
| --------- ^^^^^ ^
12+
| |
13+
| unsatisfied trait bound introduced here
14+
note: required for `()` to implement `Inductive`
15+
--> $DIR/double-cycle-inductive-coinductive.rs:12:16
16+
|
17+
LL | impl<T: Trait> Inductive for T {}
18+
| ----- ^^^^^^^^^ ^
19+
| |
20+
| unsatisfied trait bound introduced here
21+
= note: 7 redundant requirements hidden
22+
= note: required for `()` to implement `Trait`
723
note: required by a bound in `impls_trait`
824
--> $DIR/double-cycle-inductive-coinductive.rs:17:19
925
|
1026
LL | fn impls_trait<T: Trait>() {}
1127
| ^^^^^ required by this bound in `impls_trait`
1228

13-
error[E0275]: overflow evaluating the requirement `(): TraitRev`
29+
error[E0275]: overflow evaluating the requirement `(): CoinductiveRev`
1430
--> $DIR/double-cycle-inductive-coinductive.rs:35:23
1531
|
1632
LL | impls_trait_rev::<()>();
1733
| ^^
1834
|
35+
note: required for `()` to implement `TraitRev`
36+
--> $DIR/double-cycle-inductive-coinductive.rs:21:40
37+
|
38+
LL | impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
39+
| -------------- ^^^^^^^^ ^
40+
| |
41+
| unsatisfied trait bound introduced here
42+
note: required for `()` to implement `CoinductiveRev`
43+
--> $DIR/double-cycle-inductive-coinductive.rs:27:19
44+
|
45+
LL | impl<T: TraitRev> CoinductiveRev for T {}
46+
| -------- ^^^^^^^^^^^^^^ ^
47+
| |
48+
| unsatisfied trait bound introduced here
49+
= note: 7 redundant requirements hidden
50+
= note: required for `()` to implement `TraitRev`
1951
note: required by a bound in `impls_trait_rev`
2052
--> $DIR/double-cycle-inductive-coinductive.rs:29:23
2153
|

‎tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
1+
error[E0275]: overflow evaluating the requirement `W<W<_>>: Trait`
22
--> $DIR/inductive-fixpoint-hang.rs:31:19
33
|
44
LL | impls_trait::<W<_>>();
55
| ^^^^
66
|
7+
note: required for `W<W<W<_>>>` to implement `Trait`
8+
--> $DIR/inductive-fixpoint-hang.rs:22:17
9+
|
10+
LL | impl<T: ?Sized> Trait for W<W<T>>
11+
| ^^^^^ ^^^^^^^
12+
LL | where
13+
LL | W<T>: Trait,
14+
| ----- unsatisfied trait bound introduced here
15+
= note: 8 redundant requirements hidden
16+
= note: required for `W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>` to implement `Trait`
717
note: required by a bound in `impls_trait`
818
--> $DIR/inductive-fixpoint-hang.rs:28:19
919
|

‎tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn impls_ar<T: AR>() {}
3939

4040
fn main() {
4141
impls_a::<()>();
42-
//~^ ERROR overflow evaluating the requirement `(): A`
42+
//~^ ERROR overflow evaluating the requirement `(): B`
4343

4444
impls_ar::<()>();
4545
//~^ ERROR overflow evaluating the requirement `(): AR`

‎tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
1-
error[E0275]: overflow evaluating the requirement `(): A`
1+
error[E0275]: overflow evaluating the requirement `(): B`
22
--> $DIR/inductive-not-on-stack.rs:41:15
33
|
44
LL | impls_a::<()>();
55
| ^^
66
|
7+
note: required for `()` to implement `A`
8+
--> $DIR/inductive-not-on-stack.rs:21:16
9+
|
10+
LL | impl<T: B + C> A for T {}
11+
| - ^ ^
12+
| |
13+
| unsatisfied trait bound introduced here
14+
note: required for `()` to implement `B`
15+
--> $DIR/inductive-not-on-stack.rs:22:12
16+
|
17+
LL | impl<T: A> B for T {}
18+
| - ^ ^
19+
| |
20+
| unsatisfied trait bound introduced here
21+
= note: 7 redundant requirements hidden
22+
= note: required for `()` to implement `A`
723
note: required by a bound in `impls_a`
824
--> $DIR/inductive-not-on-stack.rs:25:15
925
|
@@ -16,6 +32,29 @@ error[E0275]: overflow evaluating the requirement `(): AR`
1632
LL | impls_ar::<()>();
1733
| ^^
1834
|
35+
note: required for `()` to implement `BR`
36+
--> $DIR/inductive-not-on-stack.rs:35:13
37+
|
38+
LL | impl<T: AR> BR for T {}
39+
| -- ^^ ^
40+
| |
41+
| unsatisfied trait bound introduced here
42+
note: required for `()` to implement `CR`
43+
--> $DIR/inductive-not-on-stack.rs:36:13
44+
|
45+
LL | impl<T: BR> CR for T {}
46+
| -- ^^ ^
47+
| |
48+
| unsatisfied trait bound introduced here
49+
note: required for `()` to implement `AR`
50+
--> $DIR/inductive-not-on-stack.rs:34:18
51+
|
52+
LL | impl<T: CR + BR> AR for T {}
53+
| -- ^^ ^
54+
| |
55+
| unsatisfied trait bound introduced here
56+
= note: 6 redundant requirements hidden
57+
= note: required for `()` to implement `AR`
1958
note: required by a bound in `impls_ar`
2059
--> $DIR/inductive-not-on-stack.rs:38:16
2160
|

‎tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ fn impls_a<T: A>() {}
3535

3636
fn main() {
3737
impls_a::<()>();
38-
//~^ ERROR overflow evaluating the requirement `(): A`
38+
//~^ ERROR overflow evaluating the requirement `(): CInd`
3939
}

‎tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,46 @@
1-
error[E0275]: overflow evaluating the requirement `(): A`
1+
error[E0275]: overflow evaluating the requirement `(): CInd`
22
--> $DIR/mixed-cycles-1.rs:37:15
33
|
44
LL | impls_a::<()>();
55
| ^^
66
|
7+
note: required for `()` to implement `B`
8+
--> $DIR/mixed-cycles-1.rs:31:28
9+
|
10+
LL | impl<T: ?Sized + CInd + C> B for T {}
11+
| ---- ^ ^
12+
| |
13+
| unsatisfied trait bound introduced here
14+
note: required for `()` to implement `C`
15+
--> $DIR/mixed-cycles-1.rs:32:25
16+
|
17+
LL | impl<T: ?Sized + B + A> C for T {}
18+
| - ^ ^
19+
| |
20+
| unsatisfied trait bound introduced here
21+
note: required for `()` to implement `CInd`
22+
--> $DIR/mixed-cycles-1.rs:28:21
23+
|
24+
LL | impl<T: ?Sized + C> CInd for T {}
25+
| - ^^^^ ^
26+
| |
27+
| unsatisfied trait bound introduced here
28+
= note: 4 redundant requirements hidden
29+
= note: required for `()` to implement `B`
30+
note: required for `()` to implement `BInd`
31+
--> $DIR/mixed-cycles-1.rs:23:21
32+
|
33+
LL | impl<T: ?Sized + B> BInd for T {}
34+
| - ^^^^ ^
35+
| |
36+
| unsatisfied trait bound introduced here
37+
note: required for `()` to implement `A`
38+
--> $DIR/mixed-cycles-1.rs:30:28
39+
|
40+
LL | impl<T: ?Sized + BInd + C> A for T {}
41+
| ---- ^ ^
42+
| |
43+
| unsatisfied trait bound introduced here
744
note: required by a bound in `impls_a`
845
--> $DIR/mixed-cycles-1.rs:34:15
946
|

‎tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@ fn impls_a<T: A>() {}
2828

2929
fn main() {
3030
impls_a::<()>();
31-
//~^ ERROR overflow evaluating the requirement `(): A`
31+
//~^ ERROR overflow evaluating the requirement `(): BInd`
3232
}

‎tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
1-
error[E0275]: overflow evaluating the requirement `(): A`
1+
error[E0275]: overflow evaluating the requirement `(): BInd`
22
--> $DIR/mixed-cycles-2.rs:30:15
33
|
44
LL | impls_a::<()>();
55
| ^^
66
|
7+
note: required for `()` to implement `B`
8+
--> $DIR/mixed-cycles-2.rs:25:24
9+
|
10+
LL | impl<T: ?Sized + BInd> B for T {}
11+
| ---- ^ ^
12+
| |
13+
| unsatisfied trait bound introduced here
14+
note: required for `()` to implement `BInd`
15+
--> $DIR/mixed-cycles-2.rs:22:21
16+
|
17+
LL | impl<T: ?Sized + B> BInd for T {}
18+
| - ^^^^ ^
19+
| |
20+
| unsatisfied trait bound introduced here
21+
= note: 6 redundant requirements hidden
22+
= note: required for `()` to implement `BInd`
23+
note: required for `()` to implement `A`
24+
--> $DIR/mixed-cycles-2.rs:24:28
25+
|
26+
LL | impl<T: ?Sized + BInd + B> A for T {}
27+
| ---- ^ ^
28+
| |
29+
| unsatisfied trait bound introduced here
730
note: required by a bound in `impls_a`
831
--> $DIR/mixed-cycles-2.rs:27:15
932
|

‎tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fn foo<T: Foo>() {
2525
//
2626
// https://github.com/rust-lang/trait-system-refactor-initiative/issues/76
2727
require_bar::<T>();
28-
//~^ ERROR the trait bound `T: Bar` is not satisfied
28+
//~^ ERROR type mismatch resolving `<T as Foo>::Assoc == i32`
2929
}
3030

3131
fn main() {}
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
1-
error[E0277]: the trait bound `T: Bar` is not satisfied
1+
error[E0271]: type mismatch resolving `<T as Foo>::Assoc == i32`
22
--> $DIR/param-candidate-shadows-project.rs:27:19
33
|
44
LL | require_bar::<T>();
5-
| ^ the trait `Bar` is not implemented for `T`
5+
| ^ type mismatch resolving `<T as Foo>::Assoc == i32`
66
|
7+
note: types differ
8+
--> $DIR/param-candidate-shadows-project.rs:10:18
9+
|
10+
LL | type Assoc = i32;
11+
| ^^^
12+
note: required for `T` to implement `Bar`
13+
--> $DIR/param-candidate-shadows-project.rs:13:9
14+
|
15+
LL | impl<T> Bar for T where T: Foo<Assoc = i32> {}
16+
| ^^^ ^ ----------- unsatisfied trait bound introduced here
717
note: required by a bound in `require_bar`
818
--> $DIR/param-candidate-shadows-project.rs:15:19
919
|
1020
LL | fn require_bar<T: Bar>() {}
1121
| ^^^ required by this bound in `require_bar`
12-
help: consider further restricting this bound
13-
|
14-
LL | fn foo<T: Foo + Bar>() {
15-
| +++++
1622

1723
error: aborting due to 1 previous error
1824

19-
For more information about this error, try `rustc --explain E0277`.
25+
For more information about this error, try `rustc --explain E0271`.

‎tests/ui/traits/next-solver/more-object-bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
1010

1111
fn transmute<A, B>(x: A) -> B {
1212
foo::<A, B, dyn Trait<A = A, B = B>>(x)
13-
//~^ ERROR the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
13+
//~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
1414
}
1515

1616
fn foo<A, B, T: ?Sized>(x: T::A) -> B
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
1+
error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
22
--> $DIR/more-object-bound.rs:12:5
33
|
44
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
66
|
7+
= note: required because it appears within the type `dyn Trait<A = A, B = B>`
78
note: required by a bound in `foo`
89
--> $DIR/more-object-bound.rs:18:8
910
|
@@ -12,11 +13,7 @@ LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
1213
LL | where
1314
LL | T: Trait<B = B>,
1415
| ^^^^^^^^^^^^ required by this bound in `foo`
15-
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
16-
|
17-
LL | fn transmute<A, B>(x: A) -> B where dyn Trait<A = A, B = B>: Trait {
18-
| ++++++++++++++++++++++++++++++++++++
1916

2017
error: aborting due to 1 previous error
2118

22-
For more information about this error, try `rustc --explain E0277`.
19+
For more information about this error, try `rustc --explain E0271`.

‎tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn needs_bar<T: Bar>() {}
2424

2525
fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() {
2626
needs_bar::<T>();
27-
//~^ ERROR type annotations needed: cannot satisfy `T: Bar`
27+
//~^ ERROR type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
2828
}
2929

3030
fn main() {}
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
error[E0283]: type annotations needed: cannot satisfy `T: Bar`
1+
error[E0284]: type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
22
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:17
33
|
44
LL | needs_bar::<T>();
5-
| ^
5+
| ^ cannot satisfy `<T as Foo>::Assoc == i32`
66
|
7-
= note: cannot satisfy `T: Bar`
8-
= help: the trait `Bar` is implemented for `T`
7+
note: required for `T` to implement `Bar`
8+
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:21:9
9+
|
10+
LL | impl<T> Bar for T where T: Foo<Assoc = i32> {}
11+
| ^^^ ^ ----------- unsatisfied trait bound introduced here
912
note: required by a bound in `needs_bar`
1013
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17
1114
|
@@ -14,4 +17,4 @@ LL | fn needs_bar<T: Bar>() {}
1417

1518
error: aborting due to 1 previous error
1619

17-
For more information about this error, try `rustc --explain E0283`.
20+
For more information about this error, try `rustc --explain E0284`.

‎tests/ui/traits/next-solver/object-unsafety.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
1111
pub fn copy_any<T>(t: &T) -> T {
1212
copy::<dyn Setup<From=T>>(t)
1313
//~^ ERROR the type `&<dyn Setup<From = T> as Setup>::From` is not well-formed
14-
//~| ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied
1514
//~| ERROR mismatched types
1615
//~| ERROR the type `<dyn Setup<From = T> as Setup>::From` is not well-formed
16+
//~| ERROR the trait bound `T: Copy` is not satisfied
1717

1818
// FIXME(-Znext-solver): These error messages are horrible and some of them
1919
// are even simple fallout from previous error.

‎tests/ui/traits/next-solver/object-unsafety.stderr

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
error[E0277]: the trait bound `dyn Setup<From = T>: Setup` is not satisfied
1+
error[E0277]: the trait bound `T: Copy` is not satisfied in `dyn Setup<From = T>`
22
--> $DIR/object-unsafety.rs:12:12
33
|
44
LL | copy::<dyn Setup<From=T>>(t)
5-
| ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup<From = T>`
5+
| ^^^^^^^^^^^^^^^^^ within `dyn Setup<From = T>`, the trait `Copy` is not implemented for `T`, which is required by `dyn Setup<From = T>: Setup`
66
|
7+
= note: required because it appears within the type `dyn Setup<From = T>`
78
note: required by a bound in `copy`
89
--> $DIR/object-unsafety.rs:7:12
910
|
1011
LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
1112
| ^^^^^ required by this bound in `copy`
12-
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
13+
help: consider restricting type parameter `T`
1314
|
14-
LL | pub fn copy_any<T>(t: &T) -> T where dyn Setup<From = T>: Setup {
15-
| ++++++++++++++++++++++++++++++++
15+
LL | pub fn copy_any<T: std::marker::Copy>(t: &T) -> T {
16+
| +++++++++++++++++++
1617

1718
error: the type `&<dyn Setup<From = T> as Setup>::From` is not well-formed
1819
--> $DIR/object-unsafety.rs:12:31

‎tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ fn impls<T: Trait>() {}
1515

1616
fn main() {
1717
impls::<W<_>>();
18-
//~^ ERROR overflow evaluating the requirement `W<_>: Trait`
18+
//~^ ERROR overflow evaluating the requirement `_: Sized`
1919
}

‎tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
1+
error[E0275]: overflow evaluating the requirement `_: Sized`
22
--> $DIR/exponential-trait-goals.rs:17:13
33
|
44
LL | impls::<W<_>>();
55
| ^^^^
66
|
7+
note: required for `W<(W<_>, W<_>)>` to implement `Trait`
8+
--> $DIR/exponential-trait-goals.rs:7:12
9+
|
10+
LL | impl<T, U> Trait for W<(W<T>, W<U>)>
11+
| - ^^^^^ ^^^^^^^^^^^^^^^
12+
| |
13+
| unsatisfied trait bound introduced here
714
note: required by a bound in `impls`
815
--> $DIR/exponential-trait-goals.rs:14:13
916
|

‎tests/ui/traits/next-solver/overflow/global-cache.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ LL | impls_trait::<Four<Four<Four<Four<()>>>>>();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`)
8+
note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>` to implement `Trait`
9+
--> $DIR/global-cache.rs:12:16
10+
|
11+
LL | impl<T: Trait> Trait for Inc<T> {}
12+
| ----- ^^^^^ ^^^^^^
13+
| |
14+
| unsatisfied trait bound introduced here
15+
= note: 5 redundant requirements hidden
16+
= note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>>>>>>` to implement `Trait`
817
note: required by a bound in `impls_trait`
918
--> $DIR/global-cache.rs:15:19
1019
|

0 commit comments

Comments
 (0)
Please sign in to comment.