Skip to content

Commit dbbcbf9

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

File tree

11 files changed

+84
-60
lines changed

11 files changed

+84
-60
lines changed

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+24-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+
tainted_by_errors: Ok(()),
8990
};
9091
}
9192

@@ -108,6 +109,7 @@ 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+
tainted_by_errors: trait_assoc_predicates.tainted_by_errors,
111113
};
112114
}
113115

@@ -128,6 +130,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
128130
// Preserving the order of insertion is important here so as not to break UI tests.
129131
let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
130132
let mut effects_min_tys = Vec::new();
133+
let mut tainted_by_errors = Ok(());
131134

132135
let hir_generics = node.generics().unwrap_or(NO_GENERICS);
133136
if let Node::Item(item) = node {
@@ -291,11 +294,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
291294
if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
292295
let self_ty = tcx.type_of(def_id).instantiate_identity();
293296
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),
297+
let mut input_parameters = cgp::parameters_for_impl(tcx, self_ty, trait_ref);
298+
cgp::setup_constraining_predicates(tcx, &mut predicates, trait_ref, &mut input_parameters);
299+
tainted_by_errors = tainted_by_errors.and(
300+
self_ty.error_reported().and(trait_ref.error_reported()).and_then(|()| {
301+
crate::impl_wf_check::enforce_impl_params_are_constrained(
302+
tcx,
303+
def_id,
304+
input_parameters,
305+
)
306+
}),
299307
);
300308
}
301309

@@ -338,6 +346,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
338346
parent: generics.parent,
339347
predicates: tcx.arena.alloc_from_iter(predicates),
340348
effects_min_tys: tcx.mk_type_list(&effects_min_tys),
349+
tainted_by_errors,
341350
}
342351
}
343352

@@ -489,6 +498,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
489498
parent: predicates_and_bounds.parent,
490499
predicates: tcx.arena.alloc_slice(&predicates),
491500
effects_min_tys: predicates_and_bounds.effects_min_tys,
501+
tainted_by_errors: predicates_and_bounds.tainted_by_errors,
492502
}
493503
}
494504
} else {
@@ -541,6 +551,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
541551
parent: parent_preds.parent,
542552
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
543553
effects_min_tys: parent_preds.effects_min_tys,
554+
tainted_by_errors: parent_preds.tainted_by_errors,
544555
};
545556
}
546557
gather_explicit_predicates_of(tcx, def_id)
@@ -653,6 +664,7 @@ pub(super) fn implied_predicates_with_filter(
653664
parent: None,
654665
predicates: implied_bounds,
655666
effects_min_tys: ty::List::empty(),
667+
tainted_by_errors: Ok(()),
656668
}
657669
}
658670

@@ -688,7 +700,12 @@ pub(super) fn type_param_predicates(
688700
let icx = ItemCtxt::new(tcx, parent);
689701
icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_name)
690702
})
691-
.unwrap_or_default();
703+
.unwrap_or(GenericPredicates {
704+
parent: None,
705+
predicates: &[],
706+
effects_min_tys: ty::List::empty(),
707+
tainted_by_errors: Ok(()),
708+
});
692709
let mut extend = None;
693710

694711
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).tainted_by_errors);
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+
tainted_by_errors: 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 tainted_by_errors: Result<(), ErrorGuaranteed>,
375376
}
376377

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

compiler/rustc_smir/src/rustc_smir/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ 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: _ } =
163+
let GenericPredicates { parent, predicates, effects_min_tys: _, tainted_by_errors: _ } =
164164
tables.tcx.predicates_of(def_id);
165165
stable_mir::ty::GenericPredicates {
166166
parent: parent.map(|did| tables.trait_def(did)),
@@ -182,7 +182,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
182182
) -> stable_mir::ty::GenericPredicates {
183183
let mut tables = self.0.borrow_mut();
184184
let def_id = tables[def_id];
185-
let GenericPredicates { parent, predicates, effects_min_tys: _ } =
185+
let GenericPredicates { parent, predicates, effects_min_tys: _, tainted_by_errors: _ } =
186186
tables.tcx.explicit_predicates_of(def_id);
187187
stable_mir::ty::GenericPredicates {
188188
parent: parent.map(|did| tables.trait_def(did)),

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+
tainted_by_errors: 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+
tainted_by_errors: 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)