Skip to content

Commit a387a3c

Browse files
Let's see what those opaque types actually are
1 parent fd92bc6 commit a387a3c

File tree

11 files changed

+76
-8
lines changed

11 files changed

+76
-8
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
825825
rustc_attr!(TEST, rustc_strict_coherence, Normal, template!(Word), WarnFollowing),
826826
rustc_attr!(TEST, rustc_variance, Normal, template!(Word), WarnFollowing),
827827
rustc_attr!(TEST, rustc_variance_of_opaques, Normal, template!(Word), WarnFollowing),
828+
rustc_attr!(TEST, rustc_hidden_type_of_opaques, Normal, template!(Word), WarnFollowing),
828829
rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
829830
rustc_attr!(TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
830831
rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing),

compiler/rustc_hir_analysis/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de
339339
.label = needs at most one field with non-trivial size or alignment, but has {$field_count}
340340
.labels = this field has non-zero size or requires alignment
341341
342+
hir_analysis_type_of = {$type_of}
343+
342344
hir_analysis_typeof_reserved_keyword_used =
343345
`typeof` is a reserved keyword but unimplemented
344346
.suggestion = consider replacing `typeof(...)` with an actual type

compiler/rustc_hir_analysis/src/collect.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,11 @@
1414
//! At present, however, we do run collection across all items in the
1515
//! crate as a kind of pass. This should eventually be factored away.
1616
17-
use crate::astconv::AstConv;
18-
use crate::check::intrinsic::intrinsic_operation_unsafety;
19-
use crate::errors;
20-
use hir::def::DefKind;
2117
use rustc_data_structures::captures::Captures;
2218
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2319
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
2420
use rustc_hir as hir;
21+
use rustc_hir::def::DefKind;
2522
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
2623
use rustc_hir::intravisit::{self, Visitor};
2724
use rustc_hir::{GenericParamKind, Node};
@@ -40,6 +37,11 @@ use rustc_trait_selection::traits::ObligationCtxt;
4037
use std::iter;
4138
use std::ops::Bound;
4239

40+
use crate::astconv::AstConv;
41+
use crate::check::intrinsic::intrinsic_operation_unsafety;
42+
use crate::errors;
43+
pub use type_of::test_opaque_hidden_types;
44+
4345
mod generics_of;
4446
mod item_bounds;
4547
mod predicates_of;

compiler/rustc_hir_analysis/src/collect/type_of.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_span::{Span, DUMMY_SP};
1111

1212
use super::ItemCtxt;
1313
use super::{bad_placeholder, is_suggestable_infer_ty};
14+
pub use opaque::test_opaque_hidden_types;
1415

1516
mod opaque;
1617

compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
use rustc_errors::StashKey;
2-
use rustc_hir::def_id::LocalDefId;
2+
use rustc_hir::def::DefKind;
3+
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
34
use rustc_hir::intravisit::{self, Visitor};
45
use rustc_hir::{self as hir, def, Expr, ImplItem, Item, Node, TraitItem};
56
use rustc_middle::hir::nested_filter;
67
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
7-
use rustc_span::DUMMY_SP;
8+
use rustc_span::{sym, DUMMY_SP};
89

9-
use crate::errors::{TaitForwardCompat, UnconstrainedOpaqueType};
10+
use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType};
11+
12+
pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) {
13+
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_hidden_type_of_opaques) {
14+
for id in tcx.hir().items() {
15+
if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
16+
let type_of = tcx.type_of(id.owner_id).instantiate_identity();
17+
18+
tcx.sess.emit_err(TypeOf { span: tcx.def_span(id.owner_id), type_of });
19+
}
20+
}
21+
}
22+
}
1023

1124
/// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions
1225
/// laid for "higher-order pattern unification".

compiler/rustc_hir_analysis/src/errors.rs

+8
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,14 @@ pub(crate) struct VariancesOf {
467467
pub variances_of: String,
468468
}
469469

470+
#[derive(Diagnostic)]
471+
#[diag(hir_analysis_type_of)]
472+
pub(crate) struct TypeOf<'tcx> {
473+
#[primary_span]
474+
pub span: Span,
475+
pub type_of: Ty<'tcx>,
476+
}
477+
470478
#[derive(Diagnostic)]
471479
#[diag(hir_analysis_pass_to_variadic_function, code = "E0617")]
472480
pub(crate) struct PassToVariadicFunction<'tcx, 'a> {

compiler/rustc_hir_analysis/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
214214
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
215215
});
216216

217+
if tcx.features().rustc_attrs {
218+
tcx.sess.track_errors(|| collect::test_opaque_hidden_types(tcx))?;
219+
}
220+
217221
// Freeze definitions as we don't add new ones at this point. This improves performance by
218222
// allowing lock-free access to them.
219223
tcx.untracked().definitions.freeze();

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,7 @@ symbols! {
13691369
rustc_evaluate_where_clauses,
13701370
rustc_expected_cgu_reuse,
13711371
rustc_has_incoherent_inherent_impls,
1372+
rustc_hidden_type_of_opaques,
13721373
rustc_host,
13731374
rustc_if_this_changed,
13741375
rustc_inherit_overflow_checks,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: {foo<ReEarlyBound(DefId(..), 0, 'a)>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()}
2+
--> $DIR/erased-regions-in-hidden-ty.rs:11:36
3+
|
4+
LL | fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Fn() + 'static {
5+
| ^^^^^^^^^^^^^^^^^^^
6+
7+
error: Opaque(DefId(..), [ReErased])
8+
--> $DIR/erased-regions-in-hidden-ty.rs:17:13
9+
|
10+
LL | fn bar() -> impl Fn() + 'static {
11+
| ^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: {foo<ReEarlyBound(DefId(..), 0, 'a)>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()}
2+
--> $DIR/erased-regions-in-hidden-ty.rs:11:36
3+
|
4+
LL | fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Fn() + 'static {
5+
| ^^^^^^^^^^^^^^^^^^^
6+
7+
error: Opaque(DefId(..), [ReErased])
8+
--> $DIR/erased-regions-in-hidden-ty.rs:17:13
9+
|
10+
LL | fn bar() -> impl Fn() + 'static {
11+
| ^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+

tests/ui/impl-trait/erased-regions-in-hidden-ty.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
// revisions: current next
2+
// compile-flags: -Zverbose
23
//[next] compile-flags: -Ztrait-solver=next
3-
// check-pass
4+
// normalize-stderr-test "DefId\([^\)]+\)" -> "DefId(..)"
5+
6+
#![feature(rustc_attrs)]
7+
#![rustc_hidden_type_of_opaques]
48

59
// Make sure that the compiler can handle `ReErased` in the hidden type of an opaque.
610

711
fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Fn() + 'static {
12+
//~^ ERROR 0, 'a)>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()}
13+
// Can't write whole type because of lack of path sanitization
814
|| ()
915
}
1016

1117
fn bar() -> impl Fn() + 'static {
18+
//~^ ERROR , [ReErased])
19+
// Can't write whole type because of lack of path sanitization
1220
foo(&vec![])
1321
}
1422

0 commit comments

Comments
 (0)