Skip to content

Commit 3dcdbcd

Browse files
committed
Perform unconstrained param detection in explicit_predicates_of and taint the query result
1 parent e567eab commit 3dcdbcd

File tree

11 files changed

+97
-62
lines changed

11 files changed

+97
-62
lines changed

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+27-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir as hir;
88
use rustc_hir::def::DefKind;
99
use rustc_hir::def_id::{DefId, LocalDefId};
1010
use rustc_hir::intravisit::{self, Visitor};
11-
use rustc_middle::ty::{self, Ty, TyCtxt};
11+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
1212
use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, Upcast};
1313
use rustc_middle::{bug, span_bug};
1414
use rustc_span::symbol::Ident;
@@ -86,6 +86,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
8686
parent: Some(tcx.parent(def_id.to_def_id())),
8787
predicates: tcx.arena.alloc_from_iter(predicates),
8888
effects_min_tys: ty::List::empty(),
89+
errored_due_to_unconstrained_params: Ok(()),
8990
};
9091
}
9192

@@ -108,6 +109,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
108109
parent: Some(impl_def_id),
109110
predicates: tcx.arena.alloc_from_iter(impl_predicates),
110111
effects_min_tys: ty::List::empty(),
112+
errored_due_to_unconstrained_params: trait_assoc_predicates
113+
.errored_due_to_unconstrained_params,
111114
};
112115
}
113116

@@ -128,6 +131,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
128131
// Preserving the order of insertion is important here so as not to break UI tests.
129132
let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
130133
let mut effects_min_tys = Vec::new();
134+
let mut errored_due_to_unconstrained_params = Ok(());
131135

132136
let hir_generics = node.generics().unwrap_or(NO_GENERICS);
133137
if let Node::Item(item) = node {
@@ -291,11 +295,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
291295
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
292296
let self_ty = tcx.type_of(def_id).instantiate_identity();
293297
let trait_ref = tcx.impl_trait_ref(def_id).map(ty::EarlyBinder::instantiate_identity);
294-
cgp::setup_constraining_predicates(
295-
tcx,
296-
&mut predicates,
297-
trait_ref,
298-
&mut cgp::parameters_for_impl(tcx, self_ty, trait_ref),
298+
let mut input_parameters = cgp::parameters_for_impl(tcx, self_ty, trait_ref);
299+
cgp::setup_constraining_predicates(tcx, &mut predicates, trait_ref, &mut input_parameters);
300+
errored_due_to_unconstrained_params = errored_due_to_unconstrained_params.and(
301+
self_ty.error_reported().and(trait_ref.error_reported()).and_then(|()| {
302+
crate::impl_wf_check::enforce_impl_params_are_constrained(
303+
tcx,
304+
def_id,
305+
input_parameters,
306+
)
307+
}),
299308
);
300309
}
301310

@@ -338,6 +347,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
338347
parent: generics.parent,
339348
predicates: tcx.arena.alloc_from_iter(predicates),
340349
effects_min_tys: tcx.mk_type_list(&effects_min_tys),
350+
errored_due_to_unconstrained_params,
341351
}
342352
}
343353

@@ -489,6 +499,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
489499
parent: predicates_and_bounds.parent,
490500
predicates: tcx.arena.alloc_slice(&predicates),
491501
effects_min_tys: predicates_and_bounds.effects_min_tys,
502+
errored_due_to_unconstrained_params: predicates_and_bounds
503+
.errored_due_to_unconstrained_params,
492504
}
493505
}
494506
} else {
@@ -541,6 +553,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
541553
parent: parent_preds.parent,
542554
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
543555
effects_min_tys: parent_preds.effects_min_tys,
556+
errored_due_to_unconstrained_params: parent_preds
557+
.errored_due_to_unconstrained_params,
544558
};
545559
}
546560
gather_explicit_predicates_of(tcx, def_id)
@@ -653,6 +667,7 @@ pub(super) fn implied_predicates_with_filter(
653667
parent: None,
654668
predicates: implied_bounds,
655669
effects_min_tys: ty::List::empty(),
670+
errored_due_to_unconstrained_params: Ok(()),
656671
}
657672
}
658673

@@ -688,7 +703,12 @@ pub(super) fn type_param_predicates(
688703
let icx = ItemCtxt::new(tcx, parent);
689704
icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
690705
})
691-
.unwrap_or_default();
706+
.unwrap_or(GenericPredicates {
707+
parent: None,
708+
predicates: &[],
709+
effects_min_tys: ty::List::empty(),
710+
errored_due_to_unconstrained_params: Ok(()),
711+
});
692712
let mut extend = None;
693713

694714
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);

compiler/rustc_hir_analysis/src/impl_wf_check.rs

+5-17
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
use crate::{constrained_generic_params as cgp, errors::UnconstrainedGenericParameter};
1212
use min_specialization::check_min_specialization;
1313

14+
use rustc_data_structures::fx::FxHashSet;
1415
use rustc_errors::codes::*;
1516
use rustc_hir::def::DefKind;
1617
use rustc_hir::def_id::LocalDefId;
17-
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
18+
use rustc_middle::ty::{self, TyCtxt};
1819
use rustc_span::ErrorGuaranteed;
1920

2021
mod min_specialization;
@@ -53,34 +54,21 @@ pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), Err
5354
let min_specialization = tcx.features().min_specialization;
5455
let mut res = Ok(());
5556
debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }));
56-
res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id));
57+
res = res.and(tcx.explicit_predicates_of(impl_def_id).errored_due_to_unconstrained_params);
5758
if min_specialization {
5859
res = res.and(check_min_specialization(tcx, impl_def_id));
5960
}
6061

6162
res
6263
}
6364

64-
fn enforce_impl_params_are_constrained(
65+
pub(crate) fn enforce_impl_params_are_constrained(
6566
tcx: TyCtxt<'_>,
6667
impl_def_id: LocalDefId,
68+
input_parameters: FxHashSet<cgp::Parameter>,
6769
) -> Result<(), ErrorGuaranteed> {
6870
// Every lifetime used in an associated type must be constrained.
69-
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
70-
impl_self_ty.error_reported()?;
7171
let impl_generics = tcx.generics_of(impl_def_id);
72-
let impl_predicates = tcx.predicates_of(impl_def_id);
73-
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
74-
75-
impl_trait_ref.error_reported()?;
76-
77-
let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref);
78-
cgp::identify_constrained_generic_params(
79-
tcx,
80-
impl_predicates,
81-
impl_trait_ref,
82-
&mut input_parameters,
83-
);
8472

8573
let mut res = Ok(());
8674
for param in &impl_generics.own_params {

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
279279
}),
280280
),
281281
effects_min_tys: ty::List::empty(),
282+
errored_due_to_unconstrained_params: Ok(()),
282283
}
283284
}
284285

compiler/rustc_middle/src/ty/generics.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap;
55
use rustc_hir::def_id::DefId;
66
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
77
use rustc_span::symbol::{kw, Symbol};
8-
use rustc_span::Span;
8+
use rustc_span::{ErrorGuaranteed, Span};
99
use tracing::instrument;
1010

1111
use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt};
@@ -367,11 +367,12 @@ impl<'tcx> Generics {
367367
}
368368

369369
/// Bounds on generics.
370-
#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
370+
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
371371
pub struct GenericPredicates<'tcx> {
372372
pub parent: Option<DefId>,
373373
pub predicates: &'tcx [(Clause<'tcx>, Span)],
374374
pub effects_min_tys: &'tcx ty::List<Ty<'tcx>>,
375+
pub errored_due_to_unconstrained_params: Result<(), ErrorGuaranteed>,
375376
}
376377

377378
impl<'tcx> GenericPredicates<'tcx> {

compiler/rustc_smir/src/rustc_smir/context.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
160160
fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
161161
let mut tables = self.0.borrow_mut();
162162
let def_id = tables[def_id];
163-
let GenericPredicates { parent, predicates, effects_min_tys: _ } =
164-
tables.tcx.predicates_of(def_id);
163+
let GenericPredicates {
164+
parent,
165+
predicates,
166+
effects_min_tys: _,
167+
errored_due_to_unconstrained_params: _,
168+
} = tables.tcx.predicates_of(def_id);
165169
stable_mir::ty::GenericPredicates {
166170
parent: parent.map(|did| tables.trait_def(did)),
167171
predicates: predicates
@@ -182,8 +186,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
182186
) -> stable_mir::ty::GenericPredicates {
183187
let mut tables = self.0.borrow_mut();
184188
let def_id = tables[def_id];
185-
let GenericPredicates { parent, predicates, effects_min_tys: _ } =
186-
tables.tcx.explicit_predicates_of(def_id);
189+
let GenericPredicates {
190+
parent,
191+
predicates,
192+
effects_min_tys: _,
193+
errored_due_to_unconstrained_params: _,
194+
} = tables.tcx.explicit_predicates_of(def_id);
187195
stable_mir::ty::GenericPredicates {
188196
parent: parent.map(|did| tables.trait_def(did)),
189197
predicates: predicates

src/librustdoc/clean/auto_trait.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,12 @@ fn synthesize_auto_trait_impl<'tcx>(
105105
let mut generics = clean_ty_generics(
106106
cx,
107107
tcx.generics_of(item_def_id),
108-
ty::GenericPredicates::default(),
108+
ty::GenericPredicates {
109+
parent: None,
110+
predicates: &[],
111+
effects_min_tys: ty::List::empty(),
112+
errored_due_to_unconstrained_params: Ok(()),
113+
},
109114
);
110115
generics.where_predicates.clear();
111116

src/librustdoc/clean/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
14231423
parent: None,
14241424
predicates,
14251425
effects_min_tys: ty::List::empty(),
1426+
errored_due_to_unconstrained_params: Ok(()),
14261427
},
14271428
);
14281429
simplify::move_bounds_to_generic_parameters(&mut generics);

tests/crashes/126646.rs renamed to tests/ui/associated-item/missing_method_in_impl_with_unconstrained_type_param.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
//@ known-bug: rust-lang/rust#126646
1+
//! This test used to ICE when trying to resolve the method call in the `test` function.
2+
23
mod foo {
34
pub trait Callable {
45
type Output;
56
fn call() -> Self::Output;
67
}
78

89
impl<'a, V: ?Sized> Callable for &'a () {
10+
//~^ ERROR: `V` is not constrained
911
type Output = ();
1012
}
1113
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
2+
--> $DIR/missing_method_in_impl_with_unconstrained_type_param.rs:9:14
3+
|
4+
LL | impl<'a, V: ?Sized> Callable for &'a () {
5+
| ^ unconstrained type parameter
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0207`.

tests/ui/impl-unused-tps.stderr

+24-24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
2+
--> $DIR/impl-unused-tps.rs:47:8
3+
|
4+
LL | impl<T,U,V> Foo<T> for T
5+
| ^ unconstrained type parameter
6+
7+
error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
8+
--> $DIR/impl-unused-tps.rs:47:10
9+
|
10+
LL | impl<T,U,V> Foo<T> for T
11+
| ^ unconstrained type parameter
12+
13+
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
14+
--> $DIR/impl-unused-tps.rs:31:8
15+
|
16+
LL | impl<T,U> Bar for T {
17+
| ^ unconstrained type parameter
18+
19+
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
20+
--> $DIR/impl-unused-tps.rs:39:8
21+
|
22+
LL | impl<T,U> Bar for T
23+
| ^ unconstrained type parameter
24+
125
error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
226
--> $DIR/impl-unused-tps.rs:27:1
327
|
@@ -26,30 +50,6 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self
2650
LL | impl<T,U> Foo<T> for [isize;1] {
2751
| ^ unconstrained type parameter
2852

29-
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
30-
--> $DIR/impl-unused-tps.rs:31:8
31-
|
32-
LL | impl<T,U> Bar for T {
33-
| ^ unconstrained type parameter
34-
35-
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
36-
--> $DIR/impl-unused-tps.rs:39:8
37-
|
38-
LL | impl<T,U> Bar for T
39-
| ^ unconstrained type parameter
40-
41-
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
42-
--> $DIR/impl-unused-tps.rs:47:8
43-
|
44-
LL | impl<T,U,V> Foo<T> for T
45-
| ^ unconstrained type parameter
46-
47-
error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
48-
--> $DIR/impl-unused-tps.rs:47:10
49-
|
50-
LL | impl<T,U,V> Foo<T> for T
51-
| ^ unconstrained type parameter
52-
5353
error: aborting due to 7 previous errors
5454

5555
Some errors have detailed explanations: E0119, E0207, E0275.

tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ note: this opaque type is in the signature
1111
LL | type DummyT<T> = impl F;
1212
| ^^^^^^
1313

14+
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
15+
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
16+
|
17+
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
18+
| ^ unconstrained type parameter
19+
1420
error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature
1521
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:44:8
1622
|
@@ -24,12 +30,6 @@ note: this opaque type is in the signature
2430
LL | type DummyT<T> = impl F;
2531
| ^^^^^^
2632

27-
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
28-
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
29-
|
30-
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
31-
| ^ unconstrained type parameter
32-
3333
error: aborting due to 3 previous errors
3434

3535
For more information about this error, try `rustc --explain E0207`.

0 commit comments

Comments
 (0)