Skip to content

Commit d96003d

Browse files
aliemjayjackh726
authored andcommitted
Correctly handle normalization in implied bounds
Special-case Bevy dependents to not error
1 parent 6ae4cfb commit d96003d

File tree

20 files changed

+373
-168
lines changed

20 files changed

+373
-168
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ fn check_opaque_meets_bounds<'tcx>(
368368
// Can have different predicates to their defining use
369369
hir::OpaqueTyOrigin::TyAlias { .. } => {
370370
let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, def_id)?;
371-
let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys);
371+
let implied_bounds = infcx.implied_bounds_tys_compat(param_env, def_id, &wf_tys);
372372
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
373373
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
374374
}

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ fn compare_method_predicate_entailment<'tcx>(
378378
// lifetime parameters.
379379
let outlives_env = OutlivesEnvironment::with_bounds(
380380
param_env,
381-
infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
381+
infcx.implied_bounds_tys_compat(param_env, impl_m_def_id, &wf_tys),
382382
);
383383
let errors = infcx.resolve_regions(&outlives_env);
384384
if !errors.is_empty() {
@@ -702,7 +702,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
702702
// lifetime parameters.
703703
let outlives_env = OutlivesEnvironment::with_bounds(
704704
param_env,
705-
infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
705+
infcx.implied_bounds_tys_compat(param_env, impl_m_def_id, &wf_tys),
706706
);
707707
ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?;
708708

@@ -2070,7 +2070,8 @@ pub(super) fn check_type_bounds<'tcx>(
20702070

20712071
// Finally, resolve all regions. This catches wily misuses of
20722072
// lifetime parameters.
2073-
let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types);
2073+
let implied_bounds =
2074+
infcx.implied_bounds_tys_compat(param_env, impl_ty_def_id, &assumed_wf_types);
20742075
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
20752076
ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env)
20762077
}

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
158158
}
159159
let outlives_env = OutlivesEnvironment::with_bounds(
160160
param_env,
161-
infcx.implied_bounds_tys(param_env, impl_m.def_id.expect_local(), implied_wf_types),
161+
infcx.implied_bounds_tys_compat(param_env, impl_m.def_id.expect_local(), &implied_wf_types),
162162
);
163163
let errors = infcx.resolve_regions(&outlives_env);
164164
if !errors.is_empty() {

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+52-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_infer::infer::outlives::obligations::TypeOutlives;
1515
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
1616
use rustc_middle::mir::ConstraintCategory;
1717
use rustc_middle::query::Providers;
18+
use rustc_middle::ty::print::with_no_trimmed_paths;
1819
use rustc_middle::ty::trait_def::TraitSpecializationKind;
1920
use rustc_middle::ty::{
2021
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
@@ -112,8 +113,6 @@ where
112113

113114
let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
114115

115-
let implied_bounds = infcx.implied_bounds_tys(param_env, body_def_id, assumed_wf_types);
116-
117116
let errors = wfcx.select_all_or_error();
118117
if !errors.is_empty() {
119118
let err = infcx.err_ctxt().report_fulfillment_errors(errors);
@@ -128,10 +127,58 @@ where
128127
}
129128
}
130129

130+
let infcx_compat = infcx.fork();
131+
132+
debug!(?assumed_wf_types);
133+
let implied_bounds = infcx.implied_bounds_tys(param_env, body_def_id, &assumed_wf_types);
131134
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
132135

133-
wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env)?;
134-
infcx.tainted_by_errors().error_reported()
136+
let errors = infcx.resolve_regions(&outlives_env);
137+
if errors.is_empty() {
138+
return Ok(());
139+
}
140+
141+
let is_bevy = 'is_bevy: {
142+
// We don't want to emit this for dependents of Bevy, for now.
143+
// See #119956
144+
let is_bevy_paramset = |def: ty::AdtDef<'_>| {
145+
let adt_did = with_no_trimmed_paths!(infcx.tcx.def_path_str(def.0.did));
146+
adt_did.contains("ParamSet")
147+
};
148+
for ty in assumed_wf_types.iter() {
149+
match ty.kind() {
150+
ty::Adt(def, _) => {
151+
if is_bevy_paramset(*def) {
152+
break 'is_bevy true;
153+
}
154+
}
155+
ty::Ref(_, ty, _) => match ty.kind() {
156+
ty::Adt(def, _) => {
157+
if is_bevy_paramset(*def) {
158+
break 'is_bevy true;
159+
}
160+
}
161+
_ => {}
162+
},
163+
_ => {}
164+
}
165+
}
166+
false
167+
};
168+
169+
if is_bevy {
170+
let implied_bounds =
171+
infcx_compat.implied_bounds_tys_compat(param_env, body_def_id, &assumed_wf_types);
172+
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
173+
let errors_compat = infcx_compat.resolve_regions(&outlives_env);
174+
if errors_compat.is_empty() {
175+
Ok(())
176+
} else {
177+
Err(infcx_compat.err_ctxt().report_region_errors(body_def_id, &errors_compat))
178+
}
179+
} else {
180+
Err(infcx.err_ctxt().report_region_errors(body_def_id, &errors))
181+
}
135182
}
136183

137184
fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
@@ -723,7 +770,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
723770
let infcx = tcx.infer_ctxt().build();
724771
let outlives_environment = OutlivesEnvironment::with_bounds(
725772
param_env,
726-
infcx.implied_bounds_tys(param_env, id, wf_tys.clone()),
773+
infcx.implied_bounds_tys_compat(param_env, id, wf_tys),
727774
);
728775
let region_bound_pairs = outlives_environment.region_bound_pairs();
729776

compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ fn get_impl_args(
202202
return Err(guar);
203203
}
204204

205-
let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types);
205+
let implied_bounds =
206+
infcx.implied_bounds_tys_compat(param_env, impl1_def_id, &assumed_wf_types);
206207
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
207208
let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
208209
let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else {

compiler/rustc_middle/src/query/erase.rs

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ impl<T> EraseType for Result<&'_ T, traits::query::NoSolution> {
7474
type Result = [u8; size_of::<Result<&'static (), traits::query::NoSolution>>()];
7575
}
7676

77+
impl<T> EraseType for Result<&'_ [T], traits::query::NoSolution> {
78+
type Result = [u8; size_of::<Result<&'static [()], traits::query::NoSolution>>()];
79+
}
80+
7781
impl<T> EraseType for Result<&'_ T, rustc_errors::ErrorGuaranteed> {
7882
type Result = [u8; size_of::<Result<&'static (), rustc_errors::ErrorGuaranteed>>()];
7983
}

compiler/rustc_middle/src/query/mod.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,7 @@ rustc_queries! {
19491949
desc { "normalizing `{}`", goal.value }
19501950
}
19511951

1952-
query implied_outlives_bounds(
1952+
query implied_outlives_bounds_compat(
19531953
goal: CanonicalTyGoal<'tcx>
19541954
) -> Result<
19551955
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
@@ -1958,6 +1958,15 @@ rustc_queries! {
19581958
desc { "computing implied outlives bounds for `{}`", goal.value.value }
19591959
}
19601960

1961+
query implied_outlives_bounds(
1962+
goal: CanonicalTyGoal<'tcx>
1963+
) -> Result<
1964+
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
1965+
NoSolution,
1966+
> {
1967+
desc { "computing implied outlives bounds v2 for `{}`", goal.value.value }
1968+
}
1969+
19611970
/// Do not call this query directly:
19621971
/// invoke `DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx)` instead.
19631972
query dropck_outlives(

compiler/rustc_middle/src/traits/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ pub struct NormalizationResult<'tcx> {
191191
/// case they are called implied bounds). They are fed to the
192192
/// `OutlivesEnv` which in turn is supplied to the region checker and
193193
/// other parts of the inference system.
194-
#[derive(Clone, Debug, TypeFoldable, TypeVisitable, HashStable)]
194+
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable)]
195195
pub enum OutlivesBound<'tcx> {
196196
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
197197
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),

compiler/rustc_trait_selection/src/traits/misc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ pub fn all_fields_implement_trait<'tcx>(
191191
// Check regions assuming the self type of the impl is WF
192192
let outlives_env = OutlivesEnvironment::with_bounds(
193193
param_env,
194-
infcx.implied_bounds_tys(
194+
infcx.implied_bounds_tys_compat(
195195
param_env,
196196
parent_cause.body_id,
197-
FxIndexSet::from_iter([self_type]),
197+
&FxIndexSet::from_iter([self_type]),
198198
),
199199
);
200200
let errors = infcx.resolve_regions(&outlives_env);

0 commit comments

Comments
 (0)