Skip to content

Commit 7d4e47f

Browse files
authored
Unrolled build for rust-lang#118112
Rollup merge of rust-lang#118112 - compiler-errors:index-ambiguity-ice, r=aliemjay Don't ICE when ambiguity is found when selecting `Index` implementation in typeck Fixes rust-lang#118111 The problem here is when we're manually "selecting" an impl for `base_ty: Index<?0>`, we don't consider placeholder region errors (leak check) or ambiguous predicates. Those can lead to us not actually emitting any fulfillment errors on line 3131.
2 parents fec80b4 + 273dc22 commit 7d4e47f

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -3063,7 +3063,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30633063
return None;
30643064
};
30653065

3066-
self.commit_if_ok(|_| {
3066+
self.commit_if_ok(|snapshot| {
3067+
let outer_universe = self.universe();
3068+
30673069
let ocx = ObligationCtxt::new(self);
30683070
let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id);
30693071
let impl_trait_ref =
@@ -3073,7 +3075,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30733075
// Match the impl self type against the base ty. If this fails,
30743076
// we just skip this impl, since it's not particularly useful.
30753077
let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref);
3076-
ocx.eq(&cause, self.param_env, impl_trait_ref.self_ty(), base_ty)?;
3078+
ocx.eq(&cause, self.param_env, base_ty, impl_trait_ref.self_ty())?;
30773079

30783080
// Register the impl's predicates. One of these predicates
30793081
// must be unsatisfied, or else we wouldn't have gotten here
@@ -3109,11 +3111,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31093111
Ty::new_projection(self.tcx, index_trait_output_def_id, impl_trait_ref.args),
31103112
);
31113113

3112-
let errors = ocx.select_where_possible();
3114+
let true_errors = ocx.select_where_possible();
3115+
3116+
// Do a leak check -- we can't really report report a useful error here,
3117+
// but it at least avoids an ICE when the error has to do with higher-ranked
3118+
// lifetimes.
3119+
self.leak_check(outer_universe, Some(snapshot))?;
3120+
3121+
// Bail if we have ambiguity errors, which we can't report in a useful way.
3122+
let ambiguity_errors = ocx.select_all_or_error();
3123+
if true_errors.is_empty() && !ambiguity_errors.is_empty() {
3124+
return Err(NoSolution);
3125+
}
3126+
31133127
// There should be at least one error reported. If not, we
31143128
// will still delay a span bug in `report_fulfillment_errors`.
31153129
Ok::<_, NoSolution>((
3116-
self.err_ctxt().report_fulfillment_errors(errors),
3130+
self.err_ctxt().report_fulfillment_errors(true_errors),
31173131
impl_trait_ref.args.type_at(1),
31183132
element_ty,
31193133
))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Test against ICE in #118111
2+
3+
use std::ops::Index;
4+
5+
struct Map<T, F> {
6+
f: F,
7+
inner: T,
8+
}
9+
10+
impl<T, F, Idx> Index<Idx> for Map<T, F>
11+
where
12+
T: Index<Idx>,
13+
F: FnOnce(&T, Idx) -> Idx,
14+
{
15+
type Output = T::Output;
16+
17+
fn index(&self, index: Idx) -> &Self::Output {
18+
todo!()
19+
}
20+
}
21+
22+
fn main() {
23+
Map { inner: [0_usize], f: |_, i: usize| 1_usize }[0];
24+
//~^ ERROR cannot index into a value of type
25+
// Problem here is that
26+
// `f: |_, i: usize| ...`
27+
// should be
28+
// `f: |_: &_, i: usize| ...`
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0608]: cannot index into a value of type `Map<[usize; 1], {closure@$DIR/bad-index-modulo-higher-ranked-regions.rs:23:32: 23:45}>`
2+
--> $DIR/bad-index-modulo-higher-ranked-regions.rs:23:55
3+
|
4+
LL | Map { inner: [0_usize], f: |_, i: usize| 1_usize }[0];
5+
| ^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0608`.

0 commit comments

Comments
 (0)