Skip to content

Commit 6c26336

Browse files
committed
Require any function with a tait in its signature to actually constrain a hidden type
1 parent 5f1de07 commit 6c26336

File tree

127 files changed

+1567
-759
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+1567
-759
lines changed

compiler/rustc_codegen_cranelift/example/issue-72793.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@
22

33
#![feature(type_alias_impl_trait)]
44

5-
trait T {
6-
type Item;
7-
}
5+
mod helper {
6+
pub trait T {
7+
type Item;
8+
}
89

9-
type Alias<'a> = impl T<Item = &'a ()>;
10+
pub type Alias<'a> = impl T<Item = &'a ()>;
1011

11-
struct S;
12-
impl<'a> T for &'a S {
13-
type Item = &'a ();
14-
}
12+
struct S;
13+
impl<'a> T for &'a S {
14+
type Item = &'a ();
15+
}
1516

16-
fn filter_positive<'a>() -> Alias<'a> {
17-
&S
17+
pub fn filter_positive<'a>() -> Alias<'a> {
18+
&S
19+
}
1820
}
21+
use helper::*;
1922

2023
fn with_positive(fun: impl Fn(Alias<'_>)) {
2124
fun(filter_positive());

compiler/rustc_data_structures/src/obligation_forest/mod.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,6 @@ pub enum ProcessResult<O, E> {
146146
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
147147
struct ObligationTreeId(usize);
148148

149-
type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
150-
151149
pub struct ObligationForest<O: ForestObligation> {
152150
/// The list of obligations. In between calls to [Self::process_obligations],
153151
/// this list only contains nodes in the `Pending` or `Waiting` state.
@@ -310,18 +308,25 @@ pub struct Error<O, E> {
310308
pub backtrace: Vec<O>,
311309
}
312310

313-
impl<O: ForestObligation> ObligationForest<O> {
314-
pub fn new() -> ObligationForest<O> {
315-
ObligationForest {
316-
nodes: vec![],
317-
done_cache: Default::default(),
318-
active_cache: Default::default(),
319-
reused_node_vec: vec![],
320-
obligation_tree_id_generator: (0..).map(ObligationTreeId),
321-
error_cache: Default::default(),
311+
mod helper {
312+
use super::*;
313+
pub type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
314+
impl<O: ForestObligation> ObligationForest<O> {
315+
pub fn new() -> ObligationForest<O> {
316+
ObligationForest {
317+
nodes: vec![],
318+
done_cache: Default::default(),
319+
active_cache: Default::default(),
320+
reused_node_vec: vec![],
321+
obligation_tree_id_generator: (0..).map(ObligationTreeId),
322+
error_cache: Default::default(),
323+
}
322324
}
323325
}
326+
}
327+
use helper::*;
324328

329+
impl<O: ForestObligation> ObligationForest<O> {
325330
/// Returns the total number of nodes in the forest that have not
326331
/// yet been fully resolved.
327332
pub fn len(&self) -> usize {

compiler/rustc_hir_analysis/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ hir_analysis_static_specialize = cannot specialize on `'static` lifetime
460460
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
461461
.note = this item must mention the opaque type in its signature in order to be able to register hidden types
462462
463+
hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`, but has it in its signature
464+
.note = consider moving the opaque type's declaration and defining uses into a separate module
465+
.opaque = this opaque type is in the signature
466+
463467
hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]`
464468
465469
hir_analysis_too_large_static = extern static is too large for the current architecture

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

+16-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::hir::nested_filter;
88
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
99
use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
1010

11-
use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType};
11+
use crate::errors::{TaitForwardCompat, TaitForwardCompat2, TypeOf, UnconstrainedOpaqueType};
1212

1313
pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
1414
let mut res = Ok(());
@@ -229,15 +229,17 @@ impl TaitConstraintLocator<'_> {
229229
return;
230230
}
231231

232+
let opaques = self.tcx.opaque_types_defined_by(item_def_id);
233+
let opaque_type_must_be_defined = opaques.in_signature.contains(&self.def_id);
234+
let opaque_type_may_be_defined = opaques.in_body.contains(&self.def_id);
235+
232236
let mut constrained = false;
233237
for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
234238
if opaque_type_key.def_id != self.def_id {
235239
continue;
236240
}
237241
constrained = true;
238-
let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
239-
240-
if !opaque_types_defined_by.contains(&self.def_id) {
242+
if !opaque_type_must_be_defined && !opaque_type_may_be_defined {
241243
self.tcx.dcx().emit_err(TaitForwardCompat {
242244
span: hidden_type.span,
243245
item_span: self
@@ -259,6 +261,16 @@ impl TaitConstraintLocator<'_> {
259261

260262
if !constrained {
261263
debug!("no constraints in typeck results");
264+
if opaque_type_must_be_defined {
265+
self.tcx.dcx().emit_err(TaitForwardCompat2 {
266+
span: self
267+
.tcx
268+
.def_ident_span(item_def_id)
269+
.unwrap_or_else(|| self.tcx.def_span(item_def_id)),
270+
opaque_type_span: self.tcx.def_span(self.def_id),
271+
opaque_type: self.tcx.def_path_str(self.def_id),
272+
});
273+
}
262274
return;
263275
};
264276

compiler/rustc_hir_analysis/src/errors.rs

+11
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,17 @@ pub struct TaitForwardCompat {
390390
pub item_span: Span,
391391
}
392392

393+
#[derive(Diagnostic)]
394+
#[diag(hir_analysis_tait_forward_compat2)]
395+
#[note]
396+
pub struct TaitForwardCompat2 {
397+
#[primary_span]
398+
pub span: Span,
399+
#[note(hir_analysis_opaque)]
400+
pub opaque_type_span: Span,
401+
pub opaque_type: String,
402+
}
403+
393404
pub struct MissingTypeParams {
394405
pub span: Span,
395406
pub def_span: Span,

compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,10 @@ impl<T> Trait<T> for X {
362362
| DefKind::AssocConst
363363
)
364364
&& tcx.is_type_alias_impl_trait(opaque_ty.def_id)
365-
&& !tcx
366-
.opaque_types_defined_by(body_owner_def_id.expect_local())
367-
.contains(&opaque_ty.def_id.expect_local())
365+
&& let opaques =
366+
tcx.opaque_types_defined_by(body_owner_def_id.expect_local())
367+
&& !opaques.in_body.contains(&opaque_ty.def_id.expect_local())
368+
&& !opaques.in_signature.contains(&opaque_ty.def_id.expect_local())
368369
{
369370
let sp = tcx
370371
.def_ident_span(body_owner_def_id)
@@ -432,6 +433,7 @@ impl<T> Trait<T> for X {
432433
}
433434
}
434435
}
436+
435437
(ty::FnPtr(sig), ty::FnDef(def_id, _))
436438
| (ty::FnDef(def_id, _), ty::FnPtr(sig)) => {
437439
if tcx.fn_sig(def_id).skip_binder().safety() < sig.safety() {

compiler/rustc_infer/src/infer/mod.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ pub struct InferCtxt<'tcx> {
243243
pub tcx: TyCtxt<'tcx>,
244244

245245
/// The `DefIds` of the opaque types that may have their hidden types constrained.
246-
defining_opaque_types: &'tcx ty::List<LocalDefId>,
246+
defining_opaque_types: ty::OpaqueTypes<'tcx>,
247247

248248
/// Whether this inference context should care about region obligations in
249249
/// the root universe. Most notably, this is used during hir typeck as region
@@ -370,7 +370,7 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
370370
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
371371
}
372372

373-
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
373+
fn defining_opaque_types(&self) -> ty::OpaqueTypes<'tcx> {
374374
self.defining_opaque_types
375375
}
376376

@@ -620,7 +620,7 @@ impl fmt::Display for FixupError {
620620
/// Used to configure inference contexts before their creation.
621621
pub struct InferCtxtBuilder<'tcx> {
622622
tcx: TyCtxt<'tcx>,
623-
defining_opaque_types: &'tcx ty::List<LocalDefId>,
623+
defining_opaque_types: ty::OpaqueTypes<'tcx>,
624624
considering_regions: bool,
625625
skip_leak_check: bool,
626626
/// Whether we are in coherence mode.
@@ -635,7 +635,7 @@ impl<'tcx> TyCtxt<'tcx> {
635635
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
636636
InferCtxtBuilder {
637637
tcx: self,
638-
defining_opaque_types: ty::List::empty(),
638+
defining_opaque_types: Default::default(),
639639
considering_regions: true,
640640
skip_leak_check: false,
641641
intercrate: false,
@@ -651,14 +651,14 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
651651
/// It is only meant to be called in two places, for typeck
652652
/// (via `Inherited::build`) and for the inference context used
653653
/// in mir borrowck.
654-
pub fn with_opaque_type_inference(mut self, defining_anchor: LocalDefId) -> Self {
655-
self.defining_opaque_types = self.tcx.opaque_types_defined_by(defining_anchor);
656-
self
654+
pub fn with_opaque_type_inference(self, defining_anchor: LocalDefId) -> Self {
655+
let defining_opaque_types = self.tcx.opaque_types_defined_by(defining_anchor);
656+
self.with_defining_opaque_types(defining_opaque_types)
657657
}
658658

659659
pub fn with_defining_opaque_types(
660660
mut self,
661-
defining_opaque_types: &'tcx ty::List<LocalDefId>,
661+
defining_opaque_types: ty::OpaqueTypes<'tcx>,
662662
) -> Self {
663663
self.defining_opaque_types = defining_opaque_types;
664664
self
@@ -1213,7 +1213,8 @@ impl<'tcx> InferCtxt<'tcx> {
12131213
#[inline(always)]
12141214
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
12151215
let Some(id) = id.into().as_local() else { return false };
1216-
self.defining_opaque_types.contains(&id)
1216+
self.defining_opaque_types.in_signature.contains(&id)
1217+
|| self.defining_opaque_types.in_body.contains(&id)
12171218
}
12181219

12191220
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {

compiler/rustc_middle/src/infer/canonical.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
182182
max_universe: ty::UniverseIndex::ROOT,
183183
variables: List::empty(),
184184
value: key,
185-
defining_opaque_types: ty::List::empty(),
185+
defining_opaque_types: Default::default(),
186186
};
187187
}
188188

0 commit comments

Comments
 (0)