Skip to content

Commit db235a0

Browse files
Remove unnecessary call to select_from_obligation
The only regression is one ambiguity in the new trait solver, having to do with two param-env candidates that may apply. I think this is fine, since the error message already kinda sucks.
1 parent 4651421 commit db235a0

File tree

2 files changed

+35
-49
lines changed

2 files changed

+35
-49
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+34-49
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod suggestions;
55
use super::{
66
FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
77
ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
8-
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
8+
PredicateObligation, SelectionError, TraitNotObjectSafe,
99
};
1010
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
1111
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -2269,55 +2269,40 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
22692269
)
22702270
};
22712271

2272-
let obligation = obligation.with(self.tcx, trait_ref);
2273-
let mut selcx = SelectionContext::new(&self);
2274-
match selcx.select_from_obligation(&obligation) {
2275-
Ok(None) => {
2276-
let ambiguities =
2277-
ambiguity::recompute_applicable_impls(self.infcx, &obligation);
2278-
let has_non_region_infer = trait_ref
2279-
.skip_binder()
2280-
.substs
2281-
.types()
2282-
.any(|t| !t.is_ty_or_numeric_infer());
2283-
// It doesn't make sense to talk about applicable impls if there are more
2284-
// than a handful of them.
2285-
if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
2286-
if self.tainted_by_errors().is_some() && subst.is_none() {
2287-
// If `subst.is_none()`, then this is probably two param-env
2288-
// candidates or impl candidates that are equal modulo lifetimes.
2289-
// Therefore, if we've already emitted an error, just skip this
2290-
// one, since it's not particularly actionable.
2291-
err.cancel();
2292-
return;
2293-
}
2294-
self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
2295-
} else {
2296-
if self.tainted_by_errors().is_some() {
2297-
err.cancel();
2298-
return;
2299-
}
2300-
err.note(format!("cannot satisfy `{}`", predicate));
2301-
let impl_candidates = self.find_similar_impl_candidates(
2302-
predicate.to_opt_poly_trait_pred().unwrap(),
2303-
);
2304-
if impl_candidates.len() < 10 {
2305-
self.report_similar_impl_candidates(
2306-
impl_candidates.as_slice(),
2307-
trait_ref,
2308-
obligation.cause.body_id,
2309-
&mut err,
2310-
false,
2311-
);
2312-
}
2313-
}
2272+
let ambiguities = ambiguity::recompute_applicable_impls(
2273+
self.infcx,
2274+
&obligation.with(self.tcx, trait_ref),
2275+
);
2276+
let has_non_region_infer =
2277+
trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_or_numeric_infer());
2278+
// It doesn't make sense to talk about applicable impls if there are more
2279+
// than a handful of them.
2280+
if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
2281+
if self.tainted_by_errors().is_some() && subst.is_none() {
2282+
// If `subst.is_none()`, then this is probably two param-env
2283+
// candidates or impl candidates that are equal modulo lifetimes.
2284+
// Therefore, if we've already emitted an error, just skip this
2285+
// one, since it's not particularly actionable.
2286+
err.cancel();
2287+
return;
23142288
}
2315-
_ => {
2316-
if self.tainted_by_errors().is_some() {
2317-
err.cancel();
2318-
return;
2319-
}
2320-
err.note(format!("cannot satisfy `{}`", predicate));
2289+
self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
2290+
} else {
2291+
if self.tainted_by_errors().is_some() {
2292+
err.cancel();
2293+
return;
2294+
}
2295+
err.note(format!("cannot satisfy `{}`", predicate));
2296+
let impl_candidates = self
2297+
.find_similar_impl_candidates(predicate.to_opt_poly_trait_pred().unwrap());
2298+
if impl_candidates.len() < 10 {
2299+
self.report_similar_impl_candidates(
2300+
impl_candidates.as_slice(),
2301+
trait_ref,
2302+
obligation.cause.body_id,
2303+
&mut err,
2304+
false,
2305+
);
23212306
}
23222307
}
23232308

tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | needs_bar::<T>();
55
| ^^^^^^^^^^^^^^
66
|
77
= note: cannot satisfy `T: Bar`
8+
= help: the trait `Bar` is implemented for `T`
89
note: required by a bound in `needs_bar`
910
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17
1011
|

0 commit comments

Comments
 (0)