Skip to content

Commit 375dfa4

Browse files
committed
Make closures and anon consts report that their parent item is the one that is supposed to be restricted
1 parent 86a360d commit 375dfa4

File tree

6 files changed

+75
-9
lines changed

6 files changed

+75
-9
lines changed

compiler/rustc_hir_analysis/src/collect/type_of.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,9 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
640640
let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types;
641641
debug!(?concrete_opaque_types);
642642
if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) {
643-
if !may_define_opaque_type(self.tcx, item_def_id, self.def_id, concrete_type.span) {
643+
if let Err(item_def_id) =
644+
may_define_opaque_type(self.tcx, item_def_id, self.def_id, concrete_type.span)
645+
{
644646
self.tcx.sess.emit_err(OpaqueTypeConstrainedButNotInSig {
645647
span: concrete_type.span,
646648
item_span: self.tcx.def_span(item_def_id),
@@ -666,8 +668,12 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
666668
self.tcx.hir()
667669
}
668670
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
669-
if let hir::ExprKind::Closure(closure) = ex.kind {
670-
self.check(closure.def_id);
671+
match ex.kind {
672+
hir::ExprKind::Closure(closure) => {
673+
self.check(closure.def_id);
674+
}
675+
hir::ExprKind::ConstBlock(anon) => self.check(anon.def_id),
676+
_ => (),
671677
}
672678
intravisit::walk_expr(self, ex);
673679
}
@@ -760,14 +766,14 @@ fn may_define_opaque_type<'tcx>(
760766
def_id: LocalDefId,
761767
opaque_def_id: LocalDefId,
762768
span: Span,
763-
) -> bool {
769+
) -> Result<(), LocalDefId> {
764770
if tcx.is_descendant_of(opaque_def_id.to_def_id(), def_id.to_def_id()) {
765771
// If the opaque type is defined in the body of a function, that function
766772
// may constrain the opaque type since it can't mention it in bounds.
767-
return true;
773+
return Ok(());
768774
}
769775

770-
if tcx.is_closure(def_id.to_def_id()) {
776+
if tcx.is_typeck_child(def_id.to_def_id()) {
771777
return may_define_opaque_type(tcx, tcx.local_parent(def_id), opaque_def_id, span);
772778
}
773779

@@ -863,12 +869,12 @@ fn may_define_opaque_type<'tcx>(
863869
};
864870
trace!(?tait_in_fn_sig);
865871
if tait_in_fn_sig {
866-
return true;
872+
return Ok(());
867873
}
868874
let tait_in_where_bounds =
869875
has_tait(tcx.predicates_of(def_id.to_def_id()).predicates, opaque_def_id, tcx, param_env);
870876
if tcx.features().type_alias_impl_trait_in_where_bounds {
871-
tait_in_where_bounds
877+
if tait_in_where_bounds { Ok(()) } else { Err(def_id) }
872878
} else {
873879
if tait_in_where_bounds {
874880
feature_err(
@@ -879,7 +885,7 @@ fn may_define_opaque_type<'tcx>(
879885
)
880886
.emit();
881887
}
882-
false
888+
Err(def_id)
883889
}
884890
}
885891

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Regression test for issue #63263.
2+
// Tests that we properly handle closures with an explicit return type
3+
// that return an opaque type.
4+
5+
#![feature(type_alias_impl_trait, inline_const)]
6+
7+
pub type Closure = impl FnOnce();
8+
9+
fn main() {
10+
const {
11+
let x: Closure = || {};
12+
//~^ ERROR: opaque type constrained without being represented in the signature
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: opaque type constrained without being represented in the signature
2+
--> $DIR/issue-63263-anon-const-fail.rs:11:26
3+
|
4+
LL | fn main() {
5+
| --------- this item must mention the opaque type in its signature or where bounds
6+
LL | const {
7+
LL | let x: Closure = || {};
8+
| ^^^^^
9+
10+
error: aborting due to previous error
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Regression test for issue #63263.
2+
// Tests that we properly handle closures with an explicit return type
3+
// that return an opaque type.
4+
5+
// check-pass
6+
7+
#![feature(type_alias_impl_trait, inline_const)]
8+
9+
fn main() {
10+
pub type Closure = impl FnOnce();
11+
const {
12+
let x: Closure = || {};
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Tests that we don't allow closures to constrain opaque types
2+
// unless their surrounding item has the opaque type in its signature.
3+
4+
#![feature(type_alias_impl_trait)]
5+
6+
pub type Closure = impl FnOnce();
7+
8+
fn main() {
9+
|| -> Closure { || () };
10+
//~^ ERROR: opaque type constrained without being represented in the signature
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: opaque type constrained without being represented in the signature
2+
--> $DIR/issue-63263-closure-return-fail.rs:9:21
3+
|
4+
LL | fn main() {
5+
| --------- this item must mention the opaque type in its signature or where bounds
6+
LL | || -> Closure { || () };
7+
| ^^^^^
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)