Skip to content

Commit e20f301

Browse files
authored
Unrolled build for rust-lang#140678
Rollup merge of rust-lang#140678 - compiler-errors:dont-ice-on-infer-in-upvar, r=lcnr Be a bit more relaxed about not yet constrained infer vars in closure upvar analysis See the writeup in `tests/ui/closures/opaque-upvar.rs`. TL;DR is that this has to do with the fact that the recursive revealing uses, which have not yet been constrained from the defining use by the time that closure upvar inference is performed, remain as infer vars during upvar analysis. We don't really care, though, since anywhere we structurally match on a type in upvar analysis, we already call `structurally_resolve_type` right before `.kind()`, which would emit a true ambiguity error. Fixes rust-lang/trait-system-refactor-initiative#197 r? lcnr
2 parents 7295b08 + c0dfa44 commit e20f301

File tree

4 files changed

+54
-41
lines changed

4 files changed

+54
-41
lines changed

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+19-30
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ pub trait TypeInformationCtxt<'tcx> {
158158

159159
fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T;
160160

161-
fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
161+
fn structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
162162

163163
fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error;
164164

@@ -191,8 +191,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
191191
self.infcx.resolve_vars_if_possible(t)
192192
}
193193

194-
fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
195-
(**self).try_structurally_resolve_type(sp, ty)
194+
fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
195+
(**self).structurally_resolve_type(sp, ty)
196196
}
197197

198198
fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error {
@@ -236,7 +236,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
236236
self.0.maybe_typeck_results().expect("expected typeck results")
237237
}
238238

239-
fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
239+
fn structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
240240
// FIXME: Maybe need to normalize here.
241241
ty
242242
}
@@ -776,7 +776,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
776776

777777
// Select just those fields of the `with`
778778
// expression that will actually be used
779-
match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
779+
match self.cx.structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
780780
ty::Adt(adt, args) if adt.is_struct() => {
781781
// Consume those fields of the with expression that are needed.
782782
for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
@@ -1176,7 +1176,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
11761176
/// two operations: a dereference to reach the array data and then an index to
11771177
/// jump forward to the relevant item.
11781178
impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
1179-
fn resolve_type_vars_or_bug(
1179+
fn expect_and_resolve_type(
11801180
&self,
11811181
id: HirId,
11821182
ty: Option<Ty<'tcx>>,
@@ -1185,12 +1185,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
11851185
Some(ty) => {
11861186
let ty = self.cx.resolve_vars_if_possible(ty);
11871187
self.cx.error_reported_in_ty(ty)?;
1188-
if ty.is_ty_var() {
1189-
debug!("resolve_type_vars_or_bug: infer var from {:?}", ty);
1190-
Err(self.cx.report_bug(self.cx.tcx().hir_span(id), "encountered type variable"))
1191-
} else {
1192-
Ok(ty)
1193-
}
1188+
Ok(ty)
11941189
}
11951190
None => {
11961191
// FIXME: We shouldn't be relying on the infcx being tainted.
@@ -1201,15 +1196,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
12011196
}
12021197

12031198
fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error> {
1204-
self.resolve_type_vars_or_bug(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
1199+
self.expect_and_resolve_type(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
12051200
}
12061201

12071202
fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1208-
self.resolve_type_vars_or_bug(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
1203+
self.expect_and_resolve_type(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
12091204
}
12101205

12111206
fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1212-
self.resolve_type_vars_or_bug(
1207+
self.expect_and_resolve_type(
12131208
expr.hir_id,
12141209
self.cx.typeck_results().expr_ty_adjusted_opt(expr),
12151210
)
@@ -1264,10 +1259,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
12641259
// a bind-by-ref means that the base_ty will be the type of the ident itself,
12651260
// but what we want here is the type of the underlying value being borrowed.
12661261
// So peel off one-level, turning the &T into T.
1267-
match self
1268-
.cx
1269-
.try_structurally_resolve_type(pat.span, base_ty)
1270-
.builtin_deref(false)
1262+
match self.cx.structurally_resolve_type(pat.span, base_ty).builtin_deref(false)
12711263
{
12721264
Some(ty) => Ok(ty),
12731265
None => {
@@ -1513,10 +1505,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
15131505
if node_ty != place_ty
15141506
&& self
15151507
.cx
1516-
.try_structurally_resolve_type(
1517-
self.cx.tcx().hir_span(base_place.hir_id),
1518-
place_ty,
1519-
)
1508+
.structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
15201509
.is_impl_trait()
15211510
{
15221511
projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
@@ -1538,7 +1527,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
15381527
let base_ty = self.expr_ty_adjusted(base)?;
15391528

15401529
let ty::Ref(region, _, mutbl) =
1541-
*self.cx.try_structurally_resolve_type(base.span, base_ty).kind()
1530+
*self.cx.structurally_resolve_type(base.span, base_ty).kind()
15421531
else {
15431532
span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
15441533
};
@@ -1556,7 +1545,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
15561545
let base_curr_ty = base_place.place.ty();
15571546
let deref_ty = match self
15581547
.cx
1559-
.try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
1548+
.structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
15601549
.builtin_deref(true)
15611550
{
15621551
Some(ty) => ty,
@@ -1584,7 +1573,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
15841573
) -> Result<VariantIdx, Cx::Error> {
15851574
let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id);
15861575
let ty = self.cx.typeck_results().node_type(pat_hir_id);
1587-
let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else {
1576+
let ty::Adt(adt_def, _) = self.cx.structurally_resolve_type(span, ty).kind() else {
15881577
return Err(self
15891578
.cx
15901579
.report_bug(span, "struct or tuple struct pattern not applied to an ADT"));
@@ -1616,7 +1605,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
16161605
span: Span,
16171606
) -> Result<usize, Cx::Error> {
16181607
let ty = self.cx.typeck_results().node_type(pat_hir_id);
1619-
match self.cx.try_structurally_resolve_type(span, ty).kind() {
1608+
match self.cx.structurally_resolve_type(span, ty).kind() {
16201609
ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
16211610
_ => {
16221611
self.cx
@@ -1631,7 +1620,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
16311620
/// Here `pat_hir_id` is the HirId of the pattern itself.
16321621
fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result<usize, Cx::Error> {
16331622
let ty = self.cx.typeck_results().node_type(pat_hir_id);
1634-
match self.cx.try_structurally_resolve_type(span, ty).kind() {
1623+
match self.cx.structurally_resolve_type(span, ty).kind() {
16351624
ty::Tuple(args) => Ok(args.len()),
16361625
_ => Err(self.cx.report_bug(span, "tuple pattern not applied to a tuple")),
16371626
}
@@ -1820,7 +1809,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
18201809
PatKind::Slice(before, ref slice, after) => {
18211810
let Some(element_ty) = self
18221811
.cx
1823-
.try_structurally_resolve_type(pat.span, place_with_id.place.ty())
1812+
.structurally_resolve_type(pat.span, place_with_id.place.ty())
18241813
.builtin_index()
18251814
else {
18261815
debug!("explicit index of non-indexable type {:?}", place_with_id);
@@ -1890,7 +1879,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
18901879
}
18911880

18921881
fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool {
1893-
if let ty::Adt(def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() {
1882+
if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() {
18941883
// Note that if a non-exhaustive SingleVariant is defined in another crate, we need
18951884
// to assume that more cases will be added to the variant in the future. This mean
18961885
// that we should handle non-exhaustive SingleVariant the same way we would handle

tests/crashes/131758.rs

-11
This file was deleted.

tests/ui/closures/opaque-upvar.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
5+
6+
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/197>.
7+
// This is only an issue in the new solver, but I'm testing it in both solvers for now.
8+
// This has to do with the fact that the recursive `walk_dir` is a revealing use, which has not
9+
// yet been constrained from the defining use by the time that closure signature inference is
10+
// performed. We don't really care, though, since anywhere we structurally match on a type in
11+
// upvar analysis, we already call `structurally_resolve_type` right before `.kind()`.
12+
13+
fn walk_dir(cb: &()) -> impl Sized {
14+
|| {
15+
let fut = walk_dir(cb);
16+
};
17+
}
18+
19+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(unboxed_closures)]
2+
3+
//@ check-pass
4+
5+
// Regression test for #131758. We only know the type of `x` after closure upvar
6+
// inference is done, even if we don't need to structurally resolve the type of `x`.
7+
8+
trait Foo {}
9+
10+
impl<T: Fn<(i32,)>> Foo for T {}
11+
12+
fn baz<T: Foo>(_: T) {}
13+
14+
fn main() {
15+
baz(|x| ());
16+
}

0 commit comments

Comments
 (0)