Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 375dfa4

Browse files
committedMar 14, 2023
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

Lines changed: 15 additions & 9 deletions
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

Lines changed: 14 additions & 0 deletions
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+
}
Lines changed: 11 additions & 0 deletions
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+
Lines changed: 14 additions & 0 deletions
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+
}
Lines changed: 11 additions & 0 deletions
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+
}
Lines changed: 10 additions & 0 deletions
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)
Please sign in to comment.