Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e745b4d

Browse files
committed
Auto merge of #95767 - oli-obk:all_your_generics_belong_to_the_definitions, r=compiler-errors
Report opaque type mismatches directly during borrowck of the function instead of within the `type_of` query. This allows us to only store a single hidden type per opaque type instead of having to store one per set of substitutions. r? `@compiler-errors` This does not affect diagnostics, because the diagnostic messages are exactly the same.
2 parents dd38eea + 7d2cad6 commit e745b4d

File tree

5 files changed

+44
-34
lines changed

5 files changed

+44
-34
lines changed

‎compiler/rustc_borrowck/src/nll.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
//! The entry point of the NLL borrow checker.
22
33
use rustc_data_structures::vec_map::VecMap;
4+
use rustc_hir::def_id::DefId;
45
use rustc_index::vec::IndexVec;
56
use rustc_infer::infer::InferCtxt;
67
use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
78
use rustc_middle::mir::{
89
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
910
Promoted,
1011
};
11-
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey,Region, RegionVid};
12+
use rustc_middle::ty::{self, OpaqueHiddenType, Region, RegionVid};
1213
use rustc_span::symbol::sym;
1314
use std::env;
1415
use std::fmt::Debug;
@@ -43,7 +44,7 @@ pub type PoloniusOutput = Output<RustcFacts>;
4344
/// closure requirements to propagate, and any generated errors.
4445
crate struct NllOutput<'tcx> {
4546
pub regioncx: RegionInferenceContext<'tcx>,
46-
pub opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
47+
pub opaque_type_values: VecMap<DefId, OpaqueHiddenType<'tcx>>,
4748
pub polonius_input: Option<Box<AllFacts>>,
4849
pub polonius_output: Option<Rc<PoloniusOutput>>,
4950
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
@@ -372,7 +373,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
372373
body: &Body<'tcx>,
373374
regioncx: &RegionInferenceContext<'tcx>,
374375
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
375-
opaque_type_values: &VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
376+
opaque_type_values: &VecMap<DefId, OpaqueHiddenType<'tcx>>,
376377
errors: &mut crate::error::BorrowckErrors<'tcx>,
377378
) {
378379
let tcx = infcx.tcx;

‎compiler/rustc_borrowck/src/region_infer/opaque_types.rs‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc_data_structures::fx::FxHashMap;
22
use rustc_data_structures::vec_map::VecMap;
3+
use rustc_hir::def_id::DefId;
34
use rustc_hir::OpaqueTyOrigin;
45
use rustc_infer::infer::InferCtxt;
56
use rustc_middle::ty::subst::GenericArgKind;
@@ -54,8 +55,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
5455
&self,
5556
infcx: &InferCtxt<'_, 'tcx>,
5657
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
57-
) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> {
58-
let mut result: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> = VecMap::new();
58+
) -> VecMap<DefId, OpaqueHiddenType<'tcx>> {
59+
let mut result: VecMap<DefId, OpaqueHiddenType<'tcx>> = VecMap::new();
5960
for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
6061
let substs = opaque_type_key.substs;
6162
debug!(?concrete_type, ?substs);
@@ -124,21 +125,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
124125
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
125126
// and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
126127
// once we convert the generic parameters to those of the opaque type.
127-
if let Some(prev) = result.get_mut(&opaque_type_key) {
128+
if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
128129
if prev.ty != ty {
129-
letmut err = infcx.tcx.sess.struct_span_err(
130-
concrete_type.span,
131-
&format!("hidden type `{}` differed from previous `{}`", ty, prev.ty),
132-
);
133-
err.span_note(prev.span,"previous hidden type bound here");
134-
err.emit();
130+
if !ty.references_error(){
131+
prev.report_mismatch(
132+
&OpaqueHiddenType{ ty, span: concrete_type.span},
133+
infcx.tcx,
134+
);
135+
}
135136
prev.ty = infcx.tcx.ty_error();
136137
}
137138
// Pick a better span if there is one.
138139
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
139140
prev.span = prev.span.substitute_dummy(concrete_type.span);
140141
} else {
141-
result.insert(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span });
142+
result.insert(
143+
opaque_type_key.def_id,
144+
OpaqueHiddenType { ty, span: concrete_type.span },
145+
);
142146
}
143147
}
144148
result

‎compiler/rustc_middle/src/mir/query.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use rustc_hir as hir;
99
use rustc_hir::def_id::{DefId, LocalDefId};
1010
use rustc_index::bit_set::BitMatrix;
1111
use rustc_index::vec::IndexVec;
12-
use rustc_middle::ty::OpaqueTypeKey;
1312
use rustc_span::Span;
1413
use rustc_target::abi::VariantIdx;
1514
use smallvec::SmallVec;
@@ -242,7 +241,7 @@ pub struct BorrowCheckResult<'tcx> {
242241
/// All the opaque types that are restricted to concrete types
243242
/// by this function. Unlike the value in `TypeckResults`, this has
244243
/// unerased regions.
245-
pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
244+
pub concrete_opaque_types: VecMap<DefId, OpaqueHiddenType<'tcx>>,
246245
pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
247246
pub used_mut_upvars: SmallVec<[Field; 8]>,
248247
pub tainted_by_errors: Option<ErrorGuaranteed>,

‎compiler/rustc_middle/src/ty/mod.rs‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,26 @@ pub struct OpaqueHiddenType<'tcx> {
11121112
pub ty: Ty<'tcx>,
11131113
}
11141114

1115+
impl<'tcx> OpaqueHiddenType<'tcx> {
1116+
pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) {
1117+
// Found different concrete types for the opaque type.
1118+
let mut err = tcx.sess.struct_span_err(
1119+
other.span,
1120+
"concrete type differs from previous defining opaque type use",
1121+
);
1122+
err.span_label(other.span, format!("expected `{}`, got `{}`", self.ty, other.ty));
1123+
if self.span == other.span {
1124+
err.span_label(
1125+
self.span,
1126+
"this expression supplies two conflicting concrete types for the same opaque type",
1127+
);
1128+
} else {
1129+
err.span_note(self.span, "previous use here");
1130+
}
1131+
err.emit();
1132+
}
1133+
}
1134+
11151135
rustc_index::newtype_index! {
11161136
/// "Universes" are used during type- and trait-checking in the
11171137
/// presence of `for<..>` binders to control what sets of names are

‎compiler/rustc_typeck/src/collect/type_of.rs‎

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
356356
let concrete_ty = tcx
357357
.mir_borrowck(owner)
358358
.concrete_opaque_types
359-
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
359+
.get(&def_id.to_def_id())
360360
.copied()
361361
.map(|concrete| concrete.ty)
362362
.unwrap_or_else(|| {
@@ -591,31 +591,17 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
591591
// Use borrowck to get the type with unerased regions.
592592
let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types;
593593
debug!(?concrete_opaque_types);
594-
for &(opaque_type_key, concrete_type) in concrete_opaque_types {
595-
if opaque_type_key.def_id != self.def_id {
594+
for &(def_id, concrete_type) in concrete_opaque_types {
595+
if def_id != self.def_id {
596596
// Ignore constraints for other opaque types.
597597
continue;
598598
}
599599

600-
debug!(?concrete_type, ?opaque_type_key.substs,"found constraint");
600+
debug!(?concrete_type, "found constraint");
601601

602602
if let Some(prev) = self.found {
603603
if concrete_type.ty != prev.ty && !(concrete_type, prev).references_error() {
604-
// Found different concrete types for the opaque type.
605-
let mut err = self.tcx.sess.struct_span_err(
606-
concrete_type.span,
607-
"concrete type differs from previous defining opaque type use",
608-
);
609-
err.span_label(
610-
concrete_type.span,
611-
format!("expected `{}`, got `{}`", prev.ty, concrete_type.ty),
612-
);
613-
if prev.span == concrete_type.span {
614-
err.span_label(prev.span, "this expression supplies two conflicting concrete types for the same opaque type");
615-
} else {
616-
err.span_note(prev.span, "previous use here");
617-
}
618-
err.emit();
604+
prev.report_mismatch(&concrete_type, self.tcx);
619605
}
620606
} else {
621607
self.found = Some(concrete_type);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /